From: Abdellatif El Khlifi <abdellatif.elkhl...@arm.com> Read ESRT data from Secure world in GetImageInfo()
Use FWU_READ_STREAM ABI to read ESRT data from Secure world. Signed-off-by: Abdellatif El Khlifi <abdellatif.elkhl...@arm.com> Cc: Sughosh Ganu <sughosh.g...@linaro.org> Cc: Tom Rini <tr...@konsulko.com> Cc: Ilias Apalodimas <ilias.apalodi...@linaro.org> Cc: Simon Glass <s...@chromium.org> Cc: Michal Simek <michal.si...@amd.com> Cc: Marek Vasut <marek.vasut+rene...@mailbox.org> Cc: Casey Connolly <casey.conno...@linaro.org> --- include/fwu_arm_psa.h | 13 ++++ lib/fwu_updates/fwu_arm_psa.c | 116 +++++++++++++++++++++++++++++++--- 2 files changed, 119 insertions(+), 10 deletions(-) diff --git a/include/fwu_arm_psa.h b/include/fwu_arm_psa.h index 451d8b614e3..e29c0b2c05d 100644 --- a/include/fwu_arm_psa.h +++ b/include/fwu_arm_psa.h @@ -16,6 +16,9 @@ #define DEFAULT_HW_INSTANCE (1) +/* The minimum supported ESRT version */ +#define EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION (1) + /* Default values of the ESRT fields which are not supported at this stage */ #define PACKAGE_VERSION_NOT_SUP (0xffffffff) #define LAST_ATTEMPT_NOT_SUP (0) @@ -355,6 +358,16 @@ struct __packed fwu_image_directory { struct fwu_image_info_entry entries[FWU_DIRECTORY_IMAGE_ENTRIES_COUNT]; }; +/* + * struct fwu_esrt_data_wrapper - Wrapper for the ESRT data + * @data: The ESRT data read from secure world + * @entries: The ESRT entries + */ +struct __packed fwu_esrt_data_wrapper { + struct efi_system_resource_table data; + struct efi_system_resource_entry entries[CONFIG_FWU_NUM_IMAGES_PER_BANK]; +}; + /** * fwu_agent_init() - Setup the FWU agent * diff --git a/lib/fwu_updates/fwu_arm_psa.c b/lib/fwu_updates/fwu_arm_psa.c index 40746eee6ce..7297e724569 100644 --- a/lib/fwu_updates/fwu_arm_psa.c +++ b/lib/fwu_updates/fwu_arm_psa.c @@ -27,6 +27,7 @@ static u8 g_fwu_version_minor; static bool g_fwu_initialized; struct fwu_image_directory g_fwu_cached_directory; efi_guid_t g_update_guid[CONFIG_FWU_NUM_IMAGES_PER_BANK]; +struct fwu_esrt_data_wrapper g_esrt_data; /* Error mapping declarations */ @@ -898,6 +899,100 @@ close_handle: return ret; } +/** + * fwu_esrt_sanity_check() - Verify ESRT data + * + * Make sure the ESRT data matches the directory data. + * + * Return: + * + * 0 on success + */ +static int fwu_esrt_sanity_check(void) +{ + int i; + + log_debug("FWU: ESRT data check ...\n"); + + if (g_esrt_data.data.fw_resource_count != + CONFIG_FWU_NUM_IMAGES_PER_BANK) { + log_err("FWU: Unexpected ESRT entries count (%d , %d)\n", + g_esrt_data.data.fw_resource_count, + CONFIG_FWU_NUM_IMAGES_PER_BANK); + return -EINVAL; + } + + if (g_esrt_data.data.fw_resource_version < + EFI_SYSTEM_RESOURCE_TABLE_FIRMWARE_RESOURCE_VERSION) { + log_err("FWU: Secure world ESRT version %llu not supported\n", + g_esrt_data.data.fw_resource_version); + return -EINVAL; + } + + for (i = 0; i < g_fwu_cached_directory.num_images; i++) { + if (guidcmp(&g_fwu_cached_directory.entries[i].image_guid, + &g_esrt_data.data.entries[i].fw_class)) { + log_err("FWU: GUID mismatch for image %d\n", i + 1); + return -EINVAL; + } + } + + log_debug("FWU: ESRT data check passed\n"); + + return 0; +} + +/** + * fwu_read_esrt() - Read the ESRT data + * + * Read the ESRT data from the Secure world. + * + * Return: + * + * 0 on success + */ +static int fwu_read_esrt(void) +{ + int ret, close_ret; + u32 handle = 0; + efi_guid_t esrt_guid = EFI_SYSTEM_RESOURCE_TABLE_GUID; + u32 esrt_data_size; + + ret = fwu_open(&esrt_guid, FWU_OP_TYPE_READ, &handle); + if (ret) { + log_err("FWU: Open ESRT image failed (err: %d)\n", + ret); + return ret; + } + + log_debug("FWU: ESRT image handle (0x%x)\n", handle); + + esrt_data_size = sizeof(g_esrt_data); + + ret = fwu_read_stream(handle, (u8 *)&g_esrt_data, esrt_data_size); + if (ret) { + log_err("FWU: Read ESRT image failed (err: %d)\n", + ret); + goto close_handle; + } + + ret = fwu_esrt_sanity_check(); + if (ret) + goto close_handle; + + log_debug("FWU: ESRT version supported by Secure world (%llu)\n", + g_esrt_data.data.fw_resource_version); + +close_handle: + /* The Update Agent can execute for an unbounded time */ + close_ret = fwu_commit(handle, FWU_IMG_NOT_ACCEPTED, 0); + if (close_ret) + log_err("FWU: Close ESRT image handle failed (err: %d)\n", + close_ret); + + return ret; +} + /** * fwu_discover_ts_sp_id() - Query the FWU partition ID * @@ -1192,7 +1287,6 @@ static void EFIAPI fwu_accept_notify_exit_boot_services(struct efi_event *event, efi_ret = EFI_ACCESS_DENIED; goto out; } - } else { log_info("FWU: ExitBootServices: Booting in regular state\n"); } @@ -1333,6 +1427,10 @@ efi_status_t fwu_arm_psa_get_image_info(efi_uintn_t *image_info_size, if (ret) return EFI_NOT_READY; + ret = fwu_read_esrt(); + if (ret) + return EFI_NOT_READY; + required_image_info_size = g_fwu_cached_directory.num_images * image_info_desc_size; @@ -1352,15 +1450,13 @@ efi_status_t fwu_arm_psa_get_image_info(efi_uintn_t *image_info_size, image_info[i].image_index = i + 1; /* Corresponding ESRT field: FwClass */ - guidcpy(&image_info[i].image_type_id, - &g_fwu_cached_directory.entries[i].image_guid); + guidcpy(&image_info[i].image_type_id, &g_esrt_data.entries[i].fw_class); image_info[i].image_id = image_info[i].image_index; image_info[i].image_id_name = NULL; /* Not supported */ /* Corresponding ESRT field: FwVersion */ - image_info[i].version = - g_fwu_cached_directory.entries[i].img_version; + image_info[i].version = g_esrt_data.entries[i].fw_version; image_info[i].version_name = NULL; /* Not supported */ image_info[i].size = @@ -1379,13 +1475,13 @@ efi_status_t fwu_arm_psa_get_image_info(efi_uintn_t *image_info_size, /* Corresponding ESRT field: LowestSupportedFwVersion */ image_info[i].lowest_supported_image_version = - g_fwu_cached_directory.entries[i].lowest_acceptable_version; + g_esrt_data.entries[i].lowest_supported_fw_version; - /* Corresponding ESRT field: LastAttemptVersion (not supported) */ - image_info[i].last_attempt_version = LAST_ATTEMPT_NOT_SUP; + /* Corresponding ESRT field: LastAttemptVersion */ + image_info[i].last_attempt_version = g_esrt_data.entries[i].last_attempt_version; - /* Corresponding ESRT field: LastAttemptStatus (not supported) */ - image_info[i].last_attempt_status = LAST_ATTEMPT_NOT_SUP; + /* Corresponding ESRT field: LastAttemptStatus */ + image_info[i].last_attempt_status = g_esrt_data.entries[i].last_attempt_status; image_info[i].hardware_instance = DEFAULT_HW_INSTANCE; image_info[i].dependencies = NULL; /* Not supported */ -- 2.25.1