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.

> +             }
> +#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;
>  }

Reply via email to