On 2026-06-05 13:46 +0300, Ilias Apalodimas wrote:
> Hi Harsiman
> 
> [...]
> 
> > +/**
> > + * ffa_map_sp_event() - Map MM SP response to errno
> > + * @sp_event_ret: MM SP return code from MM SP notification
> > + *
> > + * Convert the MM SP return code into a standard U-Boot errno. This helper
> > + * is marked __efi_runtime so it can be shared by both the boot and runtime
> > + * FF-A notification paths.
> > + *
> > + * Return: 0 on success, negative errno on failure
> > + */
> > +static int __efi_runtime ffa_map_sp_event(int sp_event_ret)
> > +{
> > +       int idx = -sp_event_ret;
> > +
> > +       if (sp_event_ret == MM_SUCCESS)
> > +               return 0;
> > +       if (idx > 0 && idx < (int)ARRAY_SIZE(mm_sp_errmap) &&
> > +           mm_sp_errmap[idx])
> > +               return mm_sp_errmap[idx];
> > +       return -EACCES;
> > +}
> > +
> >  /**
> >   * ffa_notify_mm_sp() - Announce there is data in the shared buffer
> >   *
> > @@ -177,52 +225,36 @@ static efi_status_t optee_mm_communicate(void 
> > *comm_buf, ulong dsize)
> >   * This is a blocking call during which trusted world has exclusive access
> >   * to the MM shared buffer.
> >   *
> > - * Return:
> > - *
> > - * 0 on success
> > + * Return: 0 on success
> >   */
> > -static int ffa_notify_mm_sp(void)
> > +static int __efi_runtime ffa_notify_mm_sp(void)
> >  {
> >         struct ffa_send_direct_data msg = {0};
> >         int ret;
> >         int sp_event_ret;
> > -       struct udevice *dev;
> > +       bool at_runtime = efi_at_runtime();
> >
> > -       ret = uclass_first_device_err(UCLASS_FFA, &dev);
> > -       if (ret) {
> > -               log_err("EFI: Cannot find FF-A bus device, notify MM SP 
> > failure\n");
> > -               return ret;
> > -       }
> > +       msg.data0 = CONFIG_FFA_SHARED_MM_BUF_OFFSET;
> > +
> > +       if (at_runtime) {
> > +               ret = ffa_sync_send_receive_runtime(mm_sp_id, &msg, 1);
> > +       } else {
> > +               struct udevice *dev;
> >
> > -       msg.data0 = CONFIG_FFA_SHARED_MM_BUF_OFFSET; /* x3 */
> > +               ret = uclass_first_device_err(UCLASS_FFA, &dev);
> > +               if (ret) {
> > +                       log_err("EFI: Cannot find FF-A bus device, notify 
> > MM SP failure\n");
> 
> This will crash at runtime, we don't have access to log_XXX.
> Please go through the entire patchset and make sure you aren't calling
> core functions that haven't been marked as such for v3
> Thre functions that do make sense can be converted to __efit_runtime.
> log_XXXX is not one of them though.
> 
> > +                       return ret;
> > +               }
> >
> > -       ret = ffa_sync_send_receive(dev, mm_sp_id, &msg, 1);
> > +               ret = ffa_sync_send_receive(dev, mm_sp_id, &msg, 1);
> > +       }
> >         if (ret)
> >                 return ret;
> >
> > -       sp_event_ret = msg.data0; /* x3 */
> > -
> > -       switch (sp_event_ret) {
> > -       case MM_SUCCESS:
> > -               ret = 0;
> > -               break;
> > -       case MM_NOT_SUPPORTED:
> > -               ret = -EINVAL;
> > -               break;
> > -       case MM_INVALID_PARAMETER:
> > -               ret = -EPERM;
> > -               break;
> > -       case MM_DENIED:
> > -               ret = -EACCES;
> > -               break;
> > -       case MM_NO_MEMORY:
> > -               ret = -EBUSY;
> > -               break;
> > -       default:
> > -               ret = -EACCES;
> > -       }
> > +       sp_event_ret = msg.data0;
> >
> > -       return ret;
> > +       return ffa_map_sp_event(sp_event_ret);
> >  }
> >
> >  /**
> > @@ -266,36 +298,41 @@ static int ffa_discover_mm_sp_id(void)
> >  }
> >
> >  /**
> > - * ffa_mm_communicate() - Exchange EFI services data with  the MM 
> > partition using FF-A
> > + * ffa_mm_communicate() - Exchange EFI services data with the MM partition 
> > using FF-A
> >   * @comm_buf:          locally allocated communication buffer used for 
> > rx/tx
> > - * @dsize:                             communication buffer size
> > + * @comm_buf_size:     communication buffer size
> >   *
> >   * Issue a door bell event to notify the MM partition (SP) running in 
> > OP-TEE
> >   * that there is data to read from the shared buffer.
> >   * Communication with the MM SP is performed using FF-A transport.
> >   * On the event, MM SP can read the data from the buffer and
> >   * update the MM shared buffer with response data.
> > - * The response data is copied back to the communication buffer.
> > - *
> > - * Return:
> > + * The response data is copied back to the communication buffer during the
> > + * boot phase. At runtime, the communication buffer is already the FF-A
> > + * shared buffer and is updated in place.
> >   *
> > - * EFI status code
> > + * Return: EFI status code
> >   */
> > -static efi_status_t ffa_mm_communicate(void *comm_buf, ulong comm_buf_size)
> > +static efi_status_t __efi_runtime ffa_mm_communicate(void *comm_buf,
> > +                                                    ulong comm_buf_size)
> >  {
> >         ulong tx_data_size;
> >         int ffa_ret;
> >         efi_status_t efi_ret;
> >         struct efi_mm_communicate_header *mm_hdr;
> > -       void *virt_shared_buf;
> > +       u8 *shared_buf;
> > +       bool at_runtime = efi_at_runtime();
> >
> >         if (!comm_buf)
> >                 return EFI_INVALID_PARAMETER;
> >
> > -       /* Discover MM partition ID at boot time */
> > -       if (!mm_sp_id && ffa_discover_mm_sp_id()) {
> > -               log_err("EFI: Failure to discover MM SP ID at boot time, 
> > FF-A MM comms failure\n");
> > -               return EFI_UNSUPPORTED;
> > +       if (!mm_sp_id) {
> > +               if (at_runtime)
> > +                       return EFI_UNSUPPORTED;
> > +               if (ffa_discover_mm_sp_id()) {
> > +                       log_err("EFI: Failure to discover MM SP ID at boot 
> > time, FF-A MM comms failure\n");
> > +                       return EFI_UNSUPPORTED;
> > +               }
> >         }
> >
> >         mm_hdr = (struct efi_mm_communicate_header *)comm_buf;
> > @@ -304,30 +341,61 @@ static efi_status_t ffa_mm_communicate(void 
> > *comm_buf, ulong comm_buf_size)
> >         if (comm_buf_size != tx_data_size || tx_data_size > 
> > CONFIG_FFA_SHARED_MM_BUF_SIZE)
> >                 return EFI_INVALID_PARAMETER;
> >
> > -       /* Copy the data to the shared buffer */
> > -
> > -       virt_shared_buf = 
> > map_sysmem((phys_addr_t)CONFIG_FFA_SHARED_MM_BUF_ADDR, 0);
> > -       memcpy(virt_shared_buf, comm_buf, tx_data_size);
> > +       if (at_runtime) {
> > +               shared_buf = comm_buf;
> > +       } else {
> > +               /* Copy the data to the shared buffer */
> > +               shared_buf = 
> > map_sysmem((phys_addr_t)CONFIG_FFA_SHARED_MM_BUF_ADDR, 0);
> > +               memcpy(shared_buf, comm_buf, tx_data_size);
> > +       }
> 
> Does the shared_buf live in the same memory space for linux ? How is
> that communicated to the OS?
>

Hi Ilias,
Yes, the FF-A shared buffer is added to the EFI
memory map as EFI_RUNTIME_SERVICES_DATA, so the OS sees it as runtime
memory. In v3, we will register an EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE callback
and convert ffa_shared_buf with efi_convert_pointer(), so if the OS calls
SetVirtualAddressMap(), runtime variable calls use the converted virtual
address instead of relying on identity mapping. This will be handles in
v3 patchset.

Regards
Harsimran Singh Tungal

> [...]
> 
> 
> Thanks
> /Ilias
> 


Reply via email to