[U-Boot] [PATCH 1/1] efi_loader: refactor efi_setup_loaded_image()

Heinrich Schuchardt xypron.glpk at gmx.de
Mon Sep 17 17:18:42 UTC 2018


Create the handle of loaded images and the EFI_LOADED_IMAGE_PROTOCOL
inside efi_setup_loaded_image(). Do not use local variables.

Signed-off-by: Heinrich Schuchardt <xypron.glpk at gmx.de>
---
 cmd/bootefi.c                 | 61 +++++++++++++++++++----------------
 include/efi_loader.h          |  8 ++---
 lib/efi_loader/efi_boottime.c | 48 ++++++++++++++-------------
 3 files changed, 64 insertions(+), 53 deletions(-)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index a890f414e8..db753aaf7c 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -342,19 +342,26 @@ static efi_status_t efi_install_fdt(ulong fdt_addr)
 	return ret;
 }
 
-/*
- * Load an EFI payload into a newly allocated piece of memory, register all
- * EFI objects it would want to access and jump to it.
+/**
+ * do_bootefi_exec() - execute EFI binary
+ *
+ * @efi:		address of the binary
+ * @device_path:	path of the device from which the binary was loaded
+ * @image_path:		device path of the binary
+ * Return:		status code
+ *
+ * Load the EFI binary into a newly assigned memory unwinding the relocation
+ * information, install the loaded image protocol, and call the binary.
  */
 static efi_status_t do_bootefi_exec(void *efi,
 				    struct efi_device_path *device_path,
 				    struct efi_device_path *image_path)
 {
-	struct efi_loaded_image loaded_image_info = {};
-	struct efi_object loaded_image_info_obj = {};
 	efi_handle_t mem_handle = NULL;
 	struct efi_device_path *memdp = NULL;
 	efi_status_t ret;
+	efi_handle_t image_handle;
+	struct efi_loaded_image *loaded_image_info;
 
 	EFIAPI efi_status_t (*entry)(efi_handle_t image_handle,
 				     struct efi_system_table *st);
@@ -384,8 +391,8 @@ static efi_status_t do_bootefi_exec(void *efi,
 		assert(device_path && image_path);
 	}
 
-	efi_setup_loaded_image(&loaded_image_info, &loaded_image_info_obj,
-			       device_path, image_path);
+	efi_setup_loaded_image(device_path, image_path, &image_handle,
+			       &loaded_image_info);
 
 	/*
 	 * gd lives in a fixed register which may get clobbered while we execute
@@ -394,9 +401,9 @@ static efi_status_t do_bootefi_exec(void *efi,
 	efi_save_gd();
 
 	/* Transfer environment variable bootargs as load options */
-	set_load_options(&loaded_image_info, "bootargs");
+	set_load_options(loaded_image_info, "bootargs");
 	/* Load the EFI payload */
-	entry = efi_load_pe(efi, &loaded_image_info);
+	entry = efi_load_pe(efi, loaded_image_info);
 	if (!entry) {
 		ret = EFI_LOAD_ERROR;
 		goto exit;
@@ -404,10 +411,10 @@ static efi_status_t do_bootefi_exec(void *efi,
 
 	if (memdp) {
 		struct efi_device_path_memory *mdp = (void *)memdp;
-		mdp->memory_type = loaded_image_info.image_code_type;
-		mdp->start_address = (uintptr_t)loaded_image_info.image_base;
+		mdp->memory_type = loaded_image_info->image_code_type;
+		mdp->start_address = (uintptr_t)loaded_image_info->image_base;
 		mdp->end_address = mdp->start_address +
-				loaded_image_info.image_size;
+				loaded_image_info->image_size;
 	}
 
 	/* we don't support much: */
@@ -417,8 +424,8 @@ static efi_status_t do_bootefi_exec(void *efi,
 	/* Call our payload! */
 	debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry);
 
-	if (setjmp(&loaded_image_info.exit_jmp)) {
-		ret = loaded_image_info.exit_status;
+	if (setjmp(&loaded_image_info->exit_jmp)) {
+		ret = loaded_image_info->exit_status;
 		goto exit;
 	}
 
@@ -430,7 +437,7 @@ static efi_status_t do_bootefi_exec(void *efi,
 
 		/* Move into EL2 and keep running there */
 		armv8_switch_to_el2((ulong)entry,
-				    (ulong)&loaded_image_info_obj.handle,
+				    (ulong)&image_handle,
 				    (ulong)&systab, 0, (ulong)efi_run_in_el2,
 				    ES_TO_AARCH64);
 
@@ -447,7 +454,7 @@ static efi_status_t do_bootefi_exec(void *efi,
 		secure_ram_addr(_do_nonsec_entry)(
 					efi_run_in_hyp,
 					(uintptr_t)entry,
-					(uintptr_t)loaded_image_info_obj.handle,
+					(uintptr_t)image_handle,
 					(uintptr_t)&systab);
 
 		/* Should never reach here, efi exits with longjmp */
@@ -455,11 +462,12 @@ static efi_status_t do_bootefi_exec(void *efi,
 	}
 #endif
 
-	ret = efi_do_enter(loaded_image_info_obj.handle, &systab, entry);
+	ret = efi_do_enter(image_handle, &systab, entry);
 
 exit:
 	/* image has returned, loaded-image obj goes *poof*: */
-	list_del(&loaded_image_info_obj.link);
+	if (image_handle)
+		efi_delete_handle(image_handle);
 	if (mem_handle)
 		efi_delete_handle(mem_handle);
 
@@ -500,6 +508,8 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	char *saddr;
 	efi_status_t r;
 	unsigned long fdt_addr;
+	efi_handle_t image_handle;
+	struct efi_loaded_image *loaded_image_info;
 
 	/* Allow unaligned memory access */
 	allow_unaligned();
@@ -544,8 +554,6 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #endif
 #ifdef CONFIG_CMD_BOOTEFI_SELFTEST
 	if (!strcmp(argv[1], "selftest")) {
-		struct efi_loaded_image loaded_image_info = {};
-		struct efi_object loaded_image_info_obj = {};
 
 		/* Construct a dummy device path. */
 		bootefi_device_path = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
@@ -553,9 +561,8 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 						      (uintptr_t)&efi_selftest);
 		bootefi_image_path = efi_dp_from_file(NULL, 0, "\\selftest");
 
-		efi_setup_loaded_image(&loaded_image_info,
-				       &loaded_image_info_obj,
-				       bootefi_device_path, bootefi_image_path);
+		efi_setup_loaded_image(bootefi_device_path, bootefi_image_path,
+				       &image_handle, &loaded_image_info);
 		/*
 		 * gd lives in a fixed register which may get clobbered while we
 		 * execute the payload. So save it here and restore it on every
@@ -563,12 +570,12 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		 */
 		efi_save_gd();
 		/* Transfer environment variable efi_selftest as load options */
-		set_load_options(&loaded_image_info, "efi_selftest");
+		set_load_options(loaded_image_info, "efi_selftest");
 		/* Execute the test */
-		r = efi_selftest(loaded_image_info_obj.handle, &systab);
+		r = efi_selftest(image_handle, &systab);
 		efi_restore_gd();
-		free(loaded_image_info.load_options);
-		list_del(&loaded_image_info_obj.link);
+		free(loaded_image_info->load_options);
+		efi_delete_handle(image_handle);
 		return r != EFI_SUCCESS;
 	} else
 #endif
diff --git a/include/efi_loader.h b/include/efi_loader.h
index f0d086daff..e5bc7d043e 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -342,10 +342,10 @@ int efi_memory_init(void);
 /* Adds new or overrides configuration table entry to the system table */
 efi_status_t efi_install_configuration_table(const efi_guid_t *guid, void *table);
 /* Sets up a loaded image */
-efi_status_t efi_setup_loaded_image(
-			struct efi_loaded_image *info, struct efi_object *obj,
-			struct efi_device_path *device_path,
-			struct efi_device_path *file_path);
+efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path,
+				    struct efi_device_path *file_path,
+				    efi_handle_t *handle_ptr,
+				    struct efi_loaded_image **info_ptr);
 efi_status_t efi_load_image_from_path(struct efi_device_path *file_path,
 				      void **buffer);
 /* Print information about a loaded image */
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index 3bcea647c8..730124a119 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -1478,18 +1478,34 @@ static efi_status_t EFIAPI efi_install_configuration_table_ext(efi_guid_t *guid,
  *
  * Return: status code
  */
-efi_status_t efi_setup_loaded_image(
-			struct efi_loaded_image *info, struct efi_object *obj,
-			struct efi_device_path *device_path,
-			struct efi_device_path *file_path)
+efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path,
+				    struct efi_device_path *file_path,
+				    efi_handle_t *handle_ptr,
+				    struct efi_loaded_image **info_ptr)
 {
 	efi_status_t ret;
+	struct efi_loaded_image *info;
+	struct efi_object *obj;
+
+	info = calloc(1, sizeof(*info));
+	if (!info)
+		return EFI_OUT_OF_RESOURCES;
+	obj = calloc(1, sizeof(*obj));
+	if (!obj) {
+		free(info);
+		return EFI_OUT_OF_RESOURCES;
+	}
 
 	/* Add internal object to object list */
 	efi_add_handle(obj);
 	/* efi_exit() assumes that the handle points to the info */
 	obj->handle = info;
 
+	if (handle_ptr)
+		*handle_ptr = obj->handle;
+	if (info_ptr)
+		*info_ptr = info;
+
 	info->revision =  EFI_LOADED_IMAGE_PROTOCOL_REVISION;
 	info->file_path = file_path;
 	info->system_table = &systab;
@@ -1629,7 +1645,6 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,
 					  efi_handle_t *image_handle)
 {
 	struct efi_loaded_image *info;
-	struct efi_object *obj;
 	efi_status_t ret;
 
 	EFI_ENTRY("%d, %p, %pD, %p, %zd, %p", boot_policy, parent_image,
@@ -1645,18 +1660,6 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,
 		goto error;
 	}
 
-	info = calloc(1, sizeof(*info));
-	if (!info) {
-		ret = EFI_OUT_OF_RESOURCES;
-		goto error;
-	}
-	obj = calloc(1, sizeof(*obj));
-	if (!obj) {
-		free(info);
-		ret = EFI_OUT_OF_RESOURCES;
-		goto error;
-	}
-
 	if (!source_buffer) {
 		struct efi_device_path *dp, *fp;
 
@@ -1668,16 +1671,17 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,
 		 * file parts:
 		 */
 		efi_dp_split_file_path(file_path, &dp, &fp);
-		ret = efi_setup_loaded_image(info, obj, dp, fp);
+		ret = efi_setup_loaded_image(dp, fp, image_handle, &info);
 		if (ret != EFI_SUCCESS)
 			goto failure;
 	} else {
 		/* In this case, file_path is the "device" path, i.e.
 		 * something like a HARDWARE_DEVICE:MEMORY_MAPPED
 		 */
-		ret = efi_setup_loaded_image(info, obj, file_path, NULL);
+		ret = efi_setup_loaded_image(file_path, NULL, image_handle,
+					     &info);
 		if (ret != EFI_SUCCESS)
-			goto failure;
+			goto error;
 	}
 	info->reserved = efi_load_pe(source_buffer, info);
 	if (!info->reserved) {
@@ -1686,11 +1690,11 @@ static efi_status_t EFIAPI efi_load_image(bool boot_policy,
 	}
 	info->system_table = &systab;
 	info->parent_handle = parent_image;
-	*image_handle = obj->handle;
 	return EFI_EXIT(EFI_SUCCESS);
 failure:
+	efi_delete_handle(*image_handle);
+	*image_handle = NULL;
 	free(info);
-	efi_delete_handle(obj);
 error:
 	return EFI_EXIT(ret);
 }
-- 
2.18.0



More information about the U-Boot mailing list