[PATCH 2/2] Load option with short device path for boot vars

Raymond Mao
2023-03-28T21:07:39Z

The boot variables automatically generated for removable medias
should be with short form of device path without device nodes.
This is a requirement for the case that a removable media is
plugged into a different port but is still able to work with the
existing boot variables.

Signed-off-by: Raymond Mao <raymond.mao@linaro.org>
---
cmd/bootmenu.c | 2 +-
cmd/eficonfig.c | 2 +-
include/efi_loader.h | 2 +-
lib/efi_loader/efi_bootmgr.c | 16 +++++++++++++---
lib/efi_loader/efi_disk.c | 2 +-
lib/efi_loader/efi_variable.c | 2 +-
lib/efi_loader/efi_variable_tee.c | 2 +-
7 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/cmd/bootmenu.c b/cmd/bootmenu.c
index 01daddca7b..058b47c69a 100644
--- a/cmd/bootmenu.c
+++ b/cmd/bootmenu.c
@@ -351,7 +351,7 @@ static struct bootmenu_data *bootmenu_create(int delay)
* UEFI specification requires booting from removal media using
* a architecture-specific default image name such as BOOTAA64.EFI.
*/
- efi_ret = efi_bootmgr_update_media_device_boot_option();
+ efi_ret = efi_bootmgr_update_media_device_boot_option(true);
if (efi_ret != EFI_SUCCESS && efi_ret != EFI_NOT_FOUND)
goto cleanup;

diff --git a/cmd/eficonfig.c b/cmd/eficonfig.c
index 82a80306f4..38371bfea6 100644
--- a/cmd/eficonfig.c
+++ b/cmd/eficonfig.c
@@ -2313,7 +2313,7 @@ static int do_eficonfig(struct cmd_tbl *cmdtp, int flag, int argc, char *const a
if (ret != EFI_SUCCESS)
return CMD_RET_FAILURE;

- ret = efi_bootmgr_update_media_device_boot_option();
+ ret = efi_bootmgr_update_media_device_boot_option(true);
if (ret != EFI_SUCCESS && ret != EFI_NOT_FOUND)
return ret;

diff --git a/include/efi_loader.h b/include/efi_loader.h
index 31ca1f5d1d..0a69f08d6c 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -522,7 +522,7 @@ efi_status_t efi_bootmgr_append_bootorder(u16 index);
efi_status_t efi_bootmgr_get_unused_bootoption(u16 *buf,
efi_uintn_t buf_size, u32 *index);
/* Generate the media device boot option */
-efi_status_t efi_bootmgr_update_media_device_boot_option(void);
+efi_status_t efi_bootmgr_update_media_device_boot_option(bool short_path);
/* Delete selected boot option */
efi_status_t efi_bootmgr_delete_boot_option(u16 boot_index);
/* search the boot option index in BootOrder */
diff --git a/lib/efi_loader/efi_bootmgr.c b/lib/efi_loader/efi_bootmgr.c
index c329428973..c4bc8b354f 100644
--- a/lib/efi_loader/efi_bootmgr.c
+++ b/lib/efi_loader/efi_bootmgr.c
@@ -354,11 +354,13 @@ error:
* @opt: pointer to the media boot option structure
* @volume_handles: pointer to the efi handles
* @count: number of efi handle
+ * @short_path: use short form device path for matching
* Return: status code
*/
static efi_status_t efi_bootmgr_enumerate_boot_option(struct eficonfig_media_boot_option *opt,
efi_handle_t *volume_handles,
- efi_status_t count)
+ efi_status_t count,
+ bool short_path)
{
u32 i;
struct efi_handler *handler;
@@ -387,6 +389,13 @@ static efi_status_t efi_bootmgr_enumerate_boot_option(struct eficonfig_media_boo
p = dev_name;
utf8_utf16_strncpy(&p, buf, strlen(buf));

+ /* use short form device path */
+ if (short_path) {
+ device_path = efi_dp_shorten(device_path);
+ if (!device_path)
+ continue;
+ }
+
lo.label = dev_name;
lo.attributes = LOAD_OPTION_ACTIVE;
lo.file_path = device_path;
@@ -651,9 +660,10 @@ efi_status_t efi_bootmgr_delete_boot_option(u16 boot_index)
* - If the device is not attached to the system, the associated BOOT#### variable
* is automatically deleted.
*
+ * @short_path: use short form device path for matching
* Return: status code
*/
-efi_status_t efi_bootmgr_update_media_device_boot_option(void)
+efi_status_t efi_bootmgr_update_media_device_boot_option(bool short_path)
{
u32 i;
efi_status_t ret;
@@ -673,7 +683,7 @@ efi_status_t efi_bootmgr_update_media_device_boot_option(void)
goto out;

/* enumerate all devices supporting EFI_SIMPLE_FILE_SYSTEM_PROTOCOL */
- ret = efi_bootmgr_enumerate_boot_option(opt, volume_handles, count);
+ ret = efi_bootmgr_enumerate_boot_option(opt, volume_handles, count, short_path);
if (ret != EFI_SUCCESS)
goto out;

diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index 1309e28134..de7a173c5a 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -689,7 +689,7 @@ int efi_disk_probe(void *ctx, struct event *event)

/* only do the boot option management when UEFI sub-system is initialized */
if (efi_obj_list_initialized == EFI_SUCCESS) {
- ret = efi_bootmgr_update_media_device_boot_option();
+ ret = efi_bootmgr_update_media_device_boot_option(true);
if (ret)
return -1;
}
diff --git a/lib/efi_loader/efi_variable.c b/lib/efi_loader/efi_variable.c
index 2f251553e1..b38ed83e90 100644
--- a/lib/efi_loader/efi_variable.c
+++ b/lib/efi_loader/efi_variable.c
@@ -481,5 +481,5 @@ efi_status_t efi_init_variables(void)
return ret;

/* update boot option management after variable service initialized */
- return efi_bootmgr_update_media_device_boot_option();
+ return efi_bootmgr_update_media_device_boot_option(true);
}
diff --git a/lib/efi_loader/efi_variable_tee.c b/lib/efi_loader/efi_variable_tee.c
index a48d313ef0..499ac74fdc 100644
--- a/lib/efi_loader/efi_variable_tee.c
+++ b/lib/efi_loader/efi_variable_tee.c
@@ -749,5 +749,5 @@ efi_status_t efi_init_variables(void)
return ret;

/* update boot option management after variable service initialized */
- return efi_bootmgr_update_media_device_boot_option();
+ return efi_bootmgr_update_media_device_boot_option(true);
}
--
2.25.1