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
