On Mon, 5 Oct 2026 at 14:13, Harsimran Singh Tungal
<[email protected]> wrote:
>
>
>
> On 18/09/2026 19:30, Ilias Apalodimas wrote:
> > Hi Harsimran
> >
> >>
> >> /**
> >> - * setup_mm_hdr() - Allocate a buffer for StandAloneMM and initialize the
> >> - * header data.
> >> + * get_comm_buf() - Obtain a communication buffer for MM/FF-A exchange
> >> + * @payload_size: size of the payload that will be appended to the
> >> + * MM communication header
> >> + *
> >> + * This helper returns a buffer suitable for constructing an
> >> + * EFI_MM_COMMUNICATE message. During the boot phase a new buffer is
> >> + * dynamically allocated. After ExitBootServices(), dynamic
> >> + * allocation is no longer permitted, and all runtime communication must
> >> + * use the statically reserved FF-A shared buffer.
> >> + *
> >> + * The caller owns the returned buffer only during the boot phase and
> >> + * must release it with free(). During the runtime phase, the returned
> >> + * pointer aliases the static FF-A shared buffer and must not be freed.
> >> + *
> >> + * Return:
> >> + * Pointer to a valid communication buffer on success.
> >> + * NULL if no suitable communication buffer is available.
> >> + */
> >> +static __efi_runtime u8 *get_comm_buf(efi_uintn_t payload_size)
> >> +{
> >> + efi_uintn_t comm_buf_size;
> >> + u8 *comm_buf;
> >> +
> >> + comm_buf_size = MM_COMMUNICATE_HEADER_SIZE +
> >> + MM_VARIABLE_COMMUNICATE_SIZE +
> >> + payload_size;
> >> +
> >> + /*
> >> + * After ExitBootServices(), dynamic allocation is no longer
> >> permitted.
> >> + * Use the predefined FF-A shared buffer at runtime; otherwise
> >> allocate
> >> + * a fresh buffer during the boot phase.
> >> + */
> >> + if (efi_at_runtime()) {
> >> +#if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT)
> >> + if (IS_ENABLED(CONFIG_ARM_FFA_RT_MODE)) {
> >> + if (comm_buf_size > CONFIG_FFA_SHARED_MM_BUF_SIZE)
> >> + return NULL;
> >> + comm_buf = ffa_shared_buf;
> >> + if (!comm_buf)
> >> + return NULL;
> >> + efi_memset_runtime(comm_buf, 0, comm_buf_size);
> >> + } else {
> >> + return NULL;
> >
> > This is problematic for the existing use case. With the changes in the
> > later patches
> > that swap all runtime call unconditionally every call to setup_mm_hdr()
> > will return
> > EFI_OUT_OF_RESOURCES and none of the runtime services will work without
> > FF-A.
> > There's nothing elegant we can do about this .We either Let the fucntions
> > from efi_var_common.c
> > deal with the runtime part (which I think I prefer), or we define a similar
> > runtime
> > available buffer for comm_buf.
> >
> Thanks Ilias.
>
> Yes, I agree this would break the existing non-FF-A runtime path once
> the later patches install the TEE runtime handlers unconditionally.
>
> I am planning to keep the existing efi_var_common.c runtime handlers for
> the non-FF-A case, and only replace the runtime service table with the
> TEE/FF-A runtime handlers when CONFIG_ARM_FFA_RT_MODE is enabled. That
> keeps the existing OP-TEE behaviour unchanged, while the FF-A runtime
> transport continues to use the static shared buffer after
> ExitBootServices().
>
> Does that approach make sense to you?
>
Yes it does
Thanks
/Ilias
> Regards
> Harsimran Singh Tungal>> + }
> >> +#else
> >> + return NULL;
> >> +#endif
> >> + } else {
> >> + comm_buf = calloc(1, comm_buf_size);
> >> + if (!comm_buf)
> >> + return NULL;
> >> + }
> >> + return comm_buf;
> >> +}
> >> +
> >> +/**
> >> +static __efi_runtime u8 *setup_mm_hdr(void **dptr, efi_uintn_t
> >> payload_size,
> >> + efi_uintn_t func, efi_status_t *ret)
> >> {
> >> - const efi_guid_t mm_var_guid = EFI_MM_VARIABLE_GUID;
> >> + static const __efi_runtime_rodata efi_guid_t mm_var_guid =
> >> + EFI_MM_VARIABLE_GUID;
> >> struct efi_mm_communicate_header *mm_hdr;
> >> struct smm_variable_communicate_header *var_hdr;
> >> u8 *comm_buf;
> >> @@ -555,16 +615,15 @@ static u8 *setup_mm_hdr(void **dptr, efi_uintn_t
> >> payload_size,
> >> return NULL;
> >> }
> >>
> >> - comm_buf = calloc(1, MM_COMMUNICATE_HEADER_SIZE +
> >> - MM_VARIABLE_COMMUNICATE_SIZE +
> >> - payload_size);
> >> + comm_buf = get_comm_buf(payload_size);
> >> if (!comm_buf) {
> >> *ret = EFI_OUT_OF_RESOURCES;
> >> return NULL;
> >> }
> >>
> >> mm_hdr = (struct efi_mm_communicate_header *)comm_buf;
> >> - guidcpy(&mm_hdr->header_guid, &mm_var_guid);
> >> + efi_memcpy_runtime(&mm_hdr->header_guid, &mm_var_guid,
> >> + sizeof(mm_hdr->header_guid));
> >> mm_hdr->message_len = MM_VARIABLE_COMMUNICATE_SIZE + payload_size;
> >>
> >> var_hdr = (struct smm_variable_communicate_header *)mm_hdr->data;
> >> @@ -1077,6 +1136,20 @@ void efi_variables_boot_exit_notify(void)
> >> ebs_called = true;
> >> }
> >>
> >> +/**
> >> + * ffa_shared_buf_notify_virtual_address_map() - SetVirtualAddressMap
> >> callback
> >> + *
> >> + * @event: callback event
> >> + * @context: callback context
> >> + */
> >> +#if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT) &&
> >> IS_ENABLED(CONFIG_ARM_FFA_RT_MODE)
> >> +static void EFIAPI __efi_runtime
> >> +ffa_shared_buf_notify_virtual_address_map(struct efi_event *event, void
> >> *context)
> >> +{
> >> + efi_convert_pointer(0, (void **)&ffa_shared_buf);
> >> +}
> >> +#endif
> >> +
> >> /**
> >> * efi_init_variables() - initialize variable services
> >> *
> >> @@ -1085,6 +1158,9 @@ void efi_variables_boot_exit_notify(void)
> >> efi_status_t efi_init_variables(void)
> >> {
> >> efi_status_t ret;
> >> +#if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT) &&
> >> IS_ENABLED(CONFIG_ARM_FFA_RT_MODE)
> >> + struct efi_event *event;
> >> +#endif
> >>
> >> /* Create a cached copy of the variables that will be enabled on
> >> ExitBootServices() */
> >> ret = efi_var_mem_init();
> >> @@ -1103,5 +1179,37 @@ efi_status_t efi_init_variables(void)
> >> if (ret != EFI_SUCCESS)
> >> return ret;
> >>
> >> +#if CONFIG_IS_ENABLED(ARM_FFA_TRANSPORT) &&
> >> IS_ENABLED(CONFIG_ARM_FFA_RT_MODE)
> >> + if (IS_ENABLED(CONFIG_ARM_FFA_RT_MODE)) {
> >> + /*
> >> + * The FF-A shared buffer is accessed by EFI runtime
> >> services, so
> >> + * keep the resident pointer convertible across
> >> + * SetVirtualAddressMap() and mark the region as runtime
> >> memory.
> >> + *
> >> + * CONFIG_FFA_SHARED_MM_BUF_ADDR is expected to be EFI-page
> >> aligned.
> >> + */
> >> + BUILD_BUG_ON(CONFIG_FFA_SHARED_MM_BUF_ADDR & EFI_PAGE_MASK);
> >> + ffa_shared_buf = (void *)CONFIG_FFA_SHARED_MM_BUF_ADDR;
> >> + ret = efi_create_event(EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
> >> + TPL_CALLBACK,
> >> +
> >> ffa_shared_buf_notify_virtual_address_map,
> >> + NULL, NULL, &event);
> >> + if (ret != EFI_SUCCESS)
> >> + return ret;
> >> + ret = efi_add_memory_map(CONFIG_FFA_SHARED_MM_BUF_ADDR,
> >> + CONFIG_FFA_SHARED_MM_BUF_SIZE,
> >> + EFI_RUNTIME_SERVICES_DATA);
> >> + if (ret != EFI_SUCCESS) {
> >> + efi_close_event(event);
> >> + log_err("EFI: failed to add FF-A shared buffer to
> >> runtime map (%lu)\n",
> >> + ret);
> >> + return ret;
> >> + }
> >> + log_info("EFI: FF-A shared buffer runtime map: addr=0x%lx
> >> size=0x%lx\n",
> >> + (ulong)CONFIG_FFA_SHARED_MM_BUF_ADDR,
> >> + (ulong)CONFIG_FFA_SHARED_MM_BUF_SIZE);
> >> + }
> >> +#endif
> >> +
> >> return EFI_SUCCESS;
> >> }
> >
>
> IMPORTANT NOTICE: The contents of this email and any attachments are
> confidential and may also be privileged. If you are not the intended
> recipient, please notify the sender immediately and do not disclose the
> contents to any other person, use it for any purpose, or store or copy the
> information in any medium. Thank you.