Add the TEE-backed runtime GetNextVariableName() implementation for the
FF-A/MM variable backend. The runtime path uses EFI runtime-safe memory
helpers and the shared MM communication path so variable enumeration can
continue after ExitBootServices().

Reviewed-by: Simon Glass <[email protected]>
Signed-off-by: Harsimran Singh Tungal <[email protected]>
---
 lib/efi_loader/efi_variable_tee.c | 64 ++++++++++++++++++++++++++++++-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/lib/efi_loader/efi_variable_tee.c 
b/lib/efi_loader/efi_variable_tee.c
index 89991fb72b2..5f324b4d09f 100644
--- a/lib/efi_loader/efi_variable_tee.c
+++ b/lib/efi_loader/efi_variable_tee.c
@@ -1075,6 +1075,68 @@ efi_get_variable_int_runtime(u16 *variable_name, const 
efi_guid_t *vendor,
        return ret;
 }
 
+efi_status_t __efi_runtime EFIAPI
+efi_get_next_variable_name_int_runtime(efi_uintn_t *variable_name_size,
+                                      u16 *variable_name, efi_guid_t *guid)
+{
+       struct smm_variable_getnext *var_getnext;
+       efi_uintn_t payload_size;
+       efi_uintn_t out_name_size;
+       efi_uintn_t in_name_size;
+       u8 *comm_buf = NULL;
+       efi_status_t ret;
+
+       if (!variable_name_size || !variable_name || !guid) {
+               ret = EFI_INVALID_PARAMETER;
+               return ret;
+       }
+
+       out_name_size = *variable_name_size;
+       in_name_size = u16_strsize(variable_name);
+
+       if (out_name_size < in_name_size) {
+               ret = EFI_INVALID_PARAMETER;
+               return ret;
+       }
+
+       if (in_name_size > max_payload_size - MM_VARIABLE_GET_NEXT_HEADER_SIZE) 
{
+               ret = EFI_INVALID_PARAMETER;
+               return ret;
+       }
+
+       /* Trim output buffer size */
+       if (out_name_size > max_payload_size - MM_VARIABLE_GET_NEXT_HEADER_SIZE)
+               out_name_size = max_payload_size - 
MM_VARIABLE_GET_NEXT_HEADER_SIZE;
+
+       payload_size = MM_VARIABLE_GET_NEXT_HEADER_SIZE + out_name_size;
+       comm_buf = setup_mm_hdr((void **)&var_getnext, payload_size,
+                               SMM_VARIABLE_FUNCTION_GET_NEXT_VARIABLE_NAME,
+                               &ret);
+       if (!comm_buf)
+               return ret;
+
+       /* Fill in contents */
+       efi_memcpy_runtime(&var_getnext->guid, guid, sizeof(*guid));
+       var_getnext->name_size = out_name_size;
+       efi_memcpy_runtime(var_getnext->name, variable_name, in_name_size);
+       efi_memset_runtime((u8 *)var_getnext->name + in_name_size, 0x0,
+                          out_name_size - in_name_size);
+
+       /* Communicate */
+       ret = mm_communicate(comm_buf, payload_size);
+       if (ret == EFI_SUCCESS || ret == EFI_BUFFER_TOO_SMALL) {
+               /* Update with reported data size for trimmed case */
+               *variable_name_size = var_getnext->name_size;
+       }
+       if (ret != EFI_SUCCESS)
+               return ret;
+
+       efi_memcpy_runtime(guid, &var_getnext->guid, sizeof(*guid));
+       efi_memcpy_runtime(variable_name, var_getnext->name, 
var_getnext->name_size);
+
+       return ret;
+}
+
 efi_status_t efi_set_variable_int(const u16 *variable_name,
                                  const efi_guid_t *vendor, u32 attributes,
                                  efi_uintn_t data_size, const void *data,
@@ -1342,7 +1404,7 @@ void efi_variables_boot_exit_notify(void)
                        efi_query_variable_info_runtime;
        efi_runtime_services.get_variable = efi_get_variable_int_runtime;
        efi_runtime_services.get_next_variable_name =
-                       efi_get_next_variable_name_runtime;
+                       efi_get_next_variable_name_int_runtime;
        efi_runtime_services.set_variable = efi_set_variable_int_runtime;
        efi_update_table_header_crc32(&efi_runtime_services.hdr);
 
-- 
2.34.1

Reply via email to