diff mbox series

[1/2] efi_loader: factor out efi_set_load_options()

Message ID 20200807174634.127495-2-xypron.glpk@gmx.de
State Accepted, archived
Commit 1064d04920beba5564c84fde1993dd39c809ed49
Delegated to: Heinrich Schuchardt
Headers show
Series efi_loader: set load options in boot manager | expand

Commit Message

Heinrich Schuchardt Aug. 7, 2020, 5:46 p.m. UTC
The bootefi bootmgr command has to set the load options for a loaded image
from the value of BootXXXX variable. If the boot manager is not used, the
value is set from the environment variable bootargs (or efi_selftest).

Factor out a common function efi_set_load_options().

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
 cmd/bootefi.c                | 55 +++++++++++++-----------------------
 include/efi_loader.h         |  3 ++
 lib/efi_loader/efi_bootmgr.c | 32 +++++++++++++++++++++
 3 files changed, 54 insertions(+), 36 deletions(-)

--
2.28.0
diff mbox series

Patch

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 8154efde52..5523405e13 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -31,55 +31,37 @@  static struct efi_device_path *bootefi_image_path;
 static struct efi_device_path *bootefi_device_path;

 /**
- * Set the load options of an image from an environment variable.
+ * efi_env_set_load_options() - set load options from environment variable
  *
  * @handle:		the image handle
  * @env_var:		name of the environment variable
  * @load_options:	pointer to load options (output)
  * Return:		status code
  */
-static efi_status_t set_load_options(efi_handle_t handle, const char *env_var,
-				     u16 **load_options)
+static efi_status_t efi_env_set_load_options(efi_handle_t handle,
+					     const char *env_var,
+					     u16 **load_options)
 {
-	struct efi_loaded_image *loaded_image_info;
-	size_t size;
 	const char *env = env_get(env_var);
+	size_t size;
 	u16 *pos;
 	efi_status_t ret;

 	*load_options = NULL;
-	ret = EFI_CALL(systab.boottime->open_protocol(
-					handle,
-					&efi_guid_loaded_image,
-					(void **)&loaded_image_info,
-					efi_root, NULL,
-					EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));
-	if (ret != EFI_SUCCESS)
-		return EFI_INVALID_PARAMETER;
-
-	loaded_image_info->load_options = NULL;
-	loaded_image_info->load_options_size = 0;
 	if (!env)
-		goto out;
-
-	size = utf8_utf16_strlen(env) + 1;
-	loaded_image_info->load_options = calloc(size, sizeof(u16));
-	if (!loaded_image_info->load_options) {
-		log_err("ERROR: Out of memory\n");
-		EFI_CALL(systab.boottime->close_protocol(handle,
-							 &efi_guid_loaded_image,
-							 efi_root, NULL));
+		return EFI_SUCCESS;
+	size = sizeof(u16) * (utf8_utf16_strlen(env) + 1);
+	pos = calloc(size, 1);
+	if (!pos)
 		return EFI_OUT_OF_RESOURCES;
-	}
-	pos = loaded_image_info->load_options;
 	*load_options = pos;
 	utf8_utf16_strcpy(&pos, env);
-	loaded_image_info->load_options_size = size * 2;
-
-out:
-	return EFI_CALL(systab.boottime->close_protocol(handle,
-							&efi_guid_loaded_image,
-							efi_root, NULL));
+	ret = efi_set_load_options(handle, size, *load_options);
+	if (ret != EFI_SUCCESS) {
+		free(*load_options);
+		*load_options = NULL;
+	}
+	return ret;
 }

 #if !CONFIG_IS_ENABLED(GENERATE_ACPI_TABLE)
@@ -336,7 +318,7 @@  static efi_status_t do_bootefi_exec(efi_handle_t handle)
 	u16 *load_options;

 	/* Transfer environment variable as load options */
-	ret = set_load_options(handle, "bootargs", &load_options);
+	ret = efi_env_set_load_options(handle, "bootargs", &load_options);
 	if (ret != EFI_SUCCESS)
 		return ret;

@@ -509,8 +491,9 @@  static efi_status_t bootefi_run_prepare(const char *load_options_path,
 		return ret;

 	/* Transfer environment variable as load options */
-	return set_load_options((efi_handle_t)*image_objp, load_options_path,
-				&load_options);
+	return efi_env_set_load_options((efi_handle_t)*image_objp,
+					load_options_path,
+					&load_options);
 }

 /**
diff --git a/include/efi_loader.h b/include/efi_loader.h
index 98944640be..ad580bd226 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -717,6 +717,9 @@  struct efi_load_option {
 efi_status_t efi_deserialize_load_option(struct efi_load_option *lo, u8 *data,
 					 efi_uintn_t *size);
 unsigned long efi_serialize_load_option(struct efi_load_option *lo, u8 **data);
+efi_status_t efi_set_load_options(efi_handle_t handle,
+				  efi_uintn_t load_options_size,
+				  void *load_options);
 efi_status_t efi_bootmgr_load(efi_handle_t *handle);

 /**
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index e03198b57a..a4bc272c34 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -30,6 +30,38 @@  static const struct efi_runtime_services *rs;
  * should do normal or recovery boot.
  */

+/**
+ * efi_set_load_options() - set the load options of a loaded image
+ *
+ * @handle:		the image handle
+ * @load_options_size:	size of load options
+ * @load_options:	pointer to load options
+ * Return:		status code
+ */
+efi_status_t efi_set_load_options(efi_handle_t handle,
+				  efi_uintn_t load_options_size,
+				  void *load_options)
+{
+	struct efi_loaded_image *loaded_image_info;
+	efi_status_t ret;
+
+	ret = EFI_CALL(systab.boottime->open_protocol(
+					handle,
+					&efi_guid_loaded_image,
+					(void **)&loaded_image_info,
+					efi_root, NULL,
+					EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL));
+	if (ret != EFI_SUCCESS)
+		return EFI_INVALID_PARAMETER;
+
+	loaded_image_info->load_options = load_options;
+	loaded_image_info->load_options_size = load_options_size;
+
+	return EFI_CALL(systab.boottime->close_protocol(handle,
+							&efi_guid_loaded_image,
+							efi_root, NULL));
+}
+

 /**
  * efi_deserialize_load_option() - parse serialized data