From 556d8dc937f74fa8a5fa849b7e1393db3446f3b2 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Tue, 30 Apr 2019 17:57:30 +0200 Subject: efi_loader: implement support of exit data In case of a failure exit data may be passed to Exit() which in turn is returned by StartImage(). Let the `bootefi` command print the exit data string in case of an error. Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_boottime.c | 47 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'lib/efi_loader/efi_boottime.c') diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index a72cbe1559..6d2dc2dda3 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -2626,6 +2626,9 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, efi_is_direct_boot = false; + image_obj->exit_data_size = exit_data_size; + image_obj->exit_data = exit_data; + /* call the image! */ if (setjmp(&image_obj->exit_jmp)) { /* @@ -2669,6 +2672,41 @@ efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, return EFI_CALL(systab.boottime->exit(image_handle, ret, 0, NULL)); } +/** + * efi_update_exit_data() - fill exit data parameters of StartImage() + * + * @image_obj image handle + * @exit_data_size size of the exit data buffer + * @exit_data buffer with data returned by UEFI payload + * Return: status code + */ +static efi_status_t efi_update_exit_data(struct efi_loaded_image_obj *image_obj, + efi_uintn_t exit_data_size, + u16 *exit_data) +{ + efi_status_t ret; + + /* + * If exit_data is not provided to StartImage(), exit_data_size must be + * ignored. + */ + if (!image_obj->exit_data) + return EFI_SUCCESS; + if (image_obj->exit_data_size) + *image_obj->exit_data_size = exit_data_size; + if (exit_data_size && exit_data) { + ret = efi_allocate_pool(EFI_BOOT_SERVICES_DATA, + exit_data_size, + (void **)image_obj->exit_data); + if (ret != EFI_SUCCESS) + return ret; + memcpy(*image_obj->exit_data, exit_data, exit_data_size); + } else { + image_obj->exit_data = NULL; + } + return EFI_SUCCESS; +} + /** * efi_exit() - leave an EFI application or driver * @image_handle: handle of the application or driver that is exiting @@ -2709,6 +2747,15 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle, if (ret != EFI_SUCCESS) goto out; + /* Exit data is only foreseen in case of failure. */ + if (exit_status != EFI_SUCCESS) { + ret = efi_update_exit_data(image_obj, exit_data_size, + exit_data); + /* Exiting has priority. Don't return error to caller. */ + if (ret != EFI_SUCCESS) + EFI_PRINT("%s: out of memory\n", __func__); + } + /* Make sure entry/exit counts for EFI world cross-overs match */ EFI_EXIT(exit_status); -- cgit v1.2.3