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?
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.