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
>