From 6287021ff9143718310075c414e535f1679a3929 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sun, 18 Jun 2023 09:00:45 +0200 Subject: [PATCH 1/7] efi_loader: simplify efi_uninstall_protocol() The call to efi_search_obj() is redundant as the function is called in efi_search_protocol() too. Signed-off-by: Heinrich Schuchardt Reviewed-by: Ilias Apalodimas --- lib/efi_loader/efi_boottime.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 2ca7359f3e1..69f2daa8acc 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1357,18 +1357,11 @@ static efi_status_t efi_uninstall_protocol (efi_handle_t handle, const efi_guid_t *protocol, void *protocol_interface) { - struct efi_object *efiobj; struct efi_handler *handler; struct efi_open_protocol_info_item *item; struct efi_open_protocol_info_item *pos; efi_status_t r; - /* Check handle */ - efiobj = efi_search_obj(handle); - if (!efiobj) { - r = EFI_INVALID_PARAMETER; - goto out; - } /* Find the protocol on the handle */ r = efi_search_protocol(handle, protocol, &handler); if (r != EFI_SUCCESS) @@ -1376,7 +1369,7 @@ static efi_status_t efi_uninstall_protocol if (handler->protocol_interface != protocol_interface) return EFI_NOT_FOUND; /* Disconnect controllers */ - r = efi_disconnect_all_drivers(efiobj, protocol, NULL); + r = efi_disconnect_all_drivers(handle, protocol, NULL); if (r != EFI_SUCCESS) { r = EFI_ACCESS_DENIED; goto out; From 4a3baf9da6f721ada4d603a1d1d20c491a54d609 Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Mon, 19 Jun 2023 14:14:02 +0300 Subject: [PATCH 2/7] efi_loader: use efi_install_multiple_protocol_interfaces() The TCG2 protocol currently adds and removes protocols with efi_(add/remove)_protocol(). Removing protocols with efi_remove_protocol() might prove problematic since it doesn't call DisconnectController() when uninstalling the protocol and does not comply with the UEFI specification. It's also beneficial for readability to have protocol installations and removals in pairs -- IOW when efi_install_multiple_protocol_interfaces() is called, efi_uninstall_multiple_protocol_interfaces() should be used to remove it. So let's swap the efi_add_protocol() as well. Signed-off-by: Ilias Apalodimas --- lib/efi_loader/efi_tcg2.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c index a83ae7a46cf..49f8a5e77cb 100644 --- a/lib/efi_loader/efi_tcg2.c +++ b/lib/efi_loader/efi_tcg2.c @@ -1680,8 +1680,8 @@ void tcg2_uninit(void) if (!is_tcg2_protocol_installed()) return; - ret = efi_remove_protocol(efi_root, &efi_guid_tcg2_protocol, - (void *)&efi_tcg2_protocol); + ret = efi_uninstall_multiple_protocol_interfaces(efi_root, &efi_guid_tcg2_protocol, + &efi_tcg2_protocol, NULL); if (ret != EFI_SUCCESS) log_err("Failed to remove EFI TCG2 protocol\n"); } @@ -2507,8 +2507,8 @@ efi_status_t efi_tcg2_register(void) goto fail; } - ret = efi_add_protocol(efi_root, &efi_guid_tcg2_protocol, - (void *)&efi_tcg2_protocol); + ret = efi_install_multiple_protocol_interfaces(&efi_root, &efi_guid_tcg2_protocol, + &efi_tcg2_protocol, NULL); if (ret != EFI_SUCCESS) { tcg2_uninit(); goto fail; From 21eb7c16ec86e239482386238ea606170ef4e90d Mon Sep 17 00:00:00 2001 From: Ilias Apalodimas Date: Mon, 19 Jun 2023 14:14:03 +0300 Subject: [PATCH 3/7] efi_loader: make efi_remove_protocol() static A previous patch is removing the last consumer of efi_remove_protocol(). Switch that to static and treat it as an internal API in order to force users install and remove protocols with the appropriate EFI functions. It's worth noting that we still have files using efi_add_protocol(). We should convert all these to efi_install_multiple_protocol_interfaces() and treat efi_add_protocol() in a similar manner Reviewed-by: Heinrich Schuchardt Signed-off-by: Ilias Apalodimas --- include/efi_loader.h | 4 ---- lib/efi_loader/efi_boottime.c | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 604fd765f75..b5fa0fe01de 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -662,10 +662,6 @@ efi_status_t efi_protocol_open(struct efi_handler *handler, void **protocol_interface, void *agent_handle, void *controller_handle, uint32_t attributes); -/* Delete protocol from a handle */ -efi_status_t efi_remove_protocol(const efi_handle_t handle, - const efi_guid_t *protocol, - void *protocol_interface); /* Install multiple protocol interfaces */ efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(efi_handle_t *handle, ...); diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 69f2daa8acc..052fe481e47 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -575,9 +575,9 @@ efi_status_t efi_search_protocol(const efi_handle_t handle, * * Return: status code */ -efi_status_t efi_remove_protocol(const efi_handle_t handle, - const efi_guid_t *protocol, - void *protocol_interface) +static efi_status_t efi_remove_protocol(const efi_handle_t handle, + const efi_guid_t *protocol, + void *protocol_interface) { struct efi_handler *handler; efi_status_t ret; From 06fc19ca4de943827f5aa026f7aa9c3a05411677 Mon Sep 17 00:00:00 2001 From: Masahisa Kojima Date: Mon, 3 Jul 2023 15:08:45 +0900 Subject: [PATCH 4/7] efi_driver: fix duplicate efiblk#0 issue The devnum value of the blk_desc structure starts from 0, current efi_bl_create_block_device() function creates two "efiblk#0" devices for the cases that blk_find_max_devnum() returns -ENODEV and blk_find_max_devnum() returns 0(one device found in this case). This commit uses blk_next_free_devnum() instead of blk_find_max_devnum(). Signed-off-by: Masahisa Kojima Reviewed-by: Heinrich Schuchardt --- lib/efi_driver/efi_block_device.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c index add00eeebbe..e3abd90275c 100644 --- a/lib/efi_driver/efi_block_device.c +++ b/lib/efi_driver/efi_block_device.c @@ -124,10 +124,8 @@ efi_bl_create_block_device(efi_handle_t handle, void *interface) struct efi_block_io *io = interface; struct efi_blk_plat *plat; - devnum = blk_find_max_devnum(UCLASS_EFI_LOADER); - if (devnum == -ENODEV) - devnum = 0; - else if (devnum < 0) + devnum = blk_next_free_devnum(UCLASS_EFI_LOADER); + if (devnum < 0) return EFI_OUT_OF_RESOURCES; name = calloc(1, 18); /* strlen("efiblk#2147483648") + 1 */ From 4f399f277cd0116944642ea7246795678fcb495f Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Sat, 15 Jul 2023 10:48:39 +0200 Subject: [PATCH 5/7] test: avoid function name 'setup' pytest 7.3.2 treats the function name 'setup' as a fixture [1]. This leads to errors like: TypeError: setup() missing 2 required positional arguments: 'disk_img' and 'osindications' Rename setup() to capsule_setup(). [1] How to run tests written for nose https://docs.pytest.org/en/7.3.x/how-to/nose.html Fixes: 482ef90aeb4c ("test: efi_capsule: refactor efi_capsule test") Signed-off-by: Heinrich Schuchardt Reviewed-by: Simon Glass --- test/py/tests/test_efi_capsule/capsule_common.py | 2 +- .../test_efi_capsule/test_capsule_firmware_fit.py | 10 +++++----- .../test_efi_capsule/test_capsule_firmware_raw.py | 12 ++++++------ .../test_capsule_firmware_signed_fit.py | 12 ++++++------ .../test_capsule_firmware_signed_raw.py | 12 ++++++------ 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/test/py/tests/test_efi_capsule/capsule_common.py b/test/py/tests/test_efi_capsule/capsule_common.py index 9eef6767a6e..fc0d851c619 100644 --- a/test/py/tests/test_efi_capsule/capsule_common.py +++ b/test/py/tests/test_efi_capsule/capsule_common.py @@ -6,7 +6,7 @@ from capsule_defs import CAPSULE_DATA_DIR, CAPSULE_INSTALL_DIR -def setup(u_boot_console, disk_img, osindications): +def capsule_setup(u_boot_console, disk_img, osindications): """setup the test Args: diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py index a3094c33f4d..11bcdc2bb29 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_fit.py @@ -8,7 +8,7 @@ This test verifies capsule-on-disk firmware update for FIT images import pytest from capsule_common import ( - setup, + capsule_setup, init_content, place_capsule_file, exec_manual_update, @@ -49,7 +49,7 @@ class TestEfiCapsuleFirmwareFit(): disk_img = efi_capsule_data capsule_files = ['Test05'] with u_boot_console.log.section('Test Case 1-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -81,7 +81,7 @@ class TestEfiCapsuleFirmwareFit(): disk_img = efi_capsule_data capsule_files = ['Test04'] with u_boot_console.log.section('Test Case 2-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -116,7 +116,7 @@ class TestEfiCapsuleFirmwareFit(): disk_img = efi_capsule_data capsule_files = ['Test104'] with u_boot_console.log.section('Test Case 3-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -165,7 +165,7 @@ class TestEfiCapsuleFirmwareFit(): disk_img = efi_capsule_data capsule_files = ['Test105'] with u_boot_console.log.section('Test Case 4-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') place_capsule_file(u_boot_console, capsule_files) diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py index 80d791e3de2..a5b5c8a3853 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_raw.py @@ -8,7 +8,7 @@ This test verifies capsule-on-disk firmware update for raw images import pytest from capsule_common import ( - setup, + capsule_setup, init_content, place_capsule_file, exec_manual_update, @@ -51,7 +51,7 @@ class TestEfiCapsuleFirmwareRaw: disk_img = efi_capsule_data capsule_files = ['Test03'] with u_boot_console.log.section('Test Case 1-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -83,7 +83,7 @@ class TestEfiCapsuleFirmwareRaw: disk_img = efi_capsule_data capsule_files = ['Test01', 'Test02'] with u_boot_console.log.section('Test Case 2-a, before reboot'): - setup(u_boot_console, disk_img, None) + capsule_setup(u_boot_console, disk_img, None) init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -111,7 +111,7 @@ class TestEfiCapsuleFirmwareRaw: disk_img = efi_capsule_data capsule_files = ['Test01', 'Test02'] with u_boot_console.log.section('Test Case 3-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -157,7 +157,7 @@ class TestEfiCapsuleFirmwareRaw: disk_img = efi_capsule_data capsule_files = ['Test101', 'Test102'] with u_boot_console.log.section('Test Case 4-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') init_content(u_boot_console, '150000', 'u-boot.env.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -211,7 +211,7 @@ class TestEfiCapsuleFirmwareRaw: disk_img = efi_capsule_data capsule_files = ['Test103'] with u_boot_console.log.section('Test Case 5-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') place_capsule_file(u_boot_console, capsule_files) diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py index 94d6c3eef06..44a58baa310 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_fit.py @@ -11,7 +11,7 @@ with signed capsule files containing FIT images import pytest from capsule_common import ( - setup, + capsule_setup, init_content, place_capsule_file, exec_manual_update, @@ -47,7 +47,7 @@ class TestEfiCapsuleFirmwareSignedFit(): disk_img = efi_capsule_data capsule_files = ['Test13'] with u_boot_console.log.section('Test Case 1-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -76,7 +76,7 @@ class TestEfiCapsuleFirmwareSignedFit(): disk_img = efi_capsule_data capsule_files = ['Test14'] with u_boot_console.log.section('Test Case 2-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -107,7 +107,7 @@ class TestEfiCapsuleFirmwareSignedFit(): disk_img = efi_capsule_data capsule_files = ['Test02'] with u_boot_console.log.section('Test Case 3-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -137,7 +137,7 @@ class TestEfiCapsuleFirmwareSignedFit(): disk_img = efi_capsule_data capsule_files = ['Test114'] with u_boot_console.log.section('Test Case 4-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -176,7 +176,7 @@ class TestEfiCapsuleFirmwareSignedFit(): disk_img = efi_capsule_data capsule_files = ['Test115'] with u_boot_console.log.section('Test Case 5-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') place_capsule_file(u_boot_console, capsule_files) diff --git a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py index ad2b1c63242..83a10e160b8 100644 --- a/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py +++ b/test/py/tests/test_efi_capsule/test_capsule_firmware_signed_raw.py @@ -9,7 +9,7 @@ with signed capsule files containing raw images import pytest from capsule_common import ( - setup, + capsule_setup, init_content, place_capsule_file, exec_manual_update, @@ -44,7 +44,7 @@ class TestEfiCapsuleFirmwareSignedRaw(): disk_img = efi_capsule_data capsule_files = ['Test11'] with u_boot_console.log.section('Test Case 1-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -72,7 +72,7 @@ class TestEfiCapsuleFirmwareSignedRaw(): disk_img = efi_capsule_data capsule_files = ['Test12'] with u_boot_console.log.section('Test Case 2-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -101,7 +101,7 @@ class TestEfiCapsuleFirmwareSignedRaw(): disk_img = efi_capsule_data capsule_files = ['Test02'] with u_boot_console.log.section('Test Case 3-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -131,7 +131,7 @@ class TestEfiCapsuleFirmwareSignedRaw(): disk_img = efi_capsule_data capsule_files = ['Test111', 'Test112'] with u_boot_console.log.section('Test Case 4-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') place_capsule_file(u_boot_console, capsule_files) @@ -175,7 +175,7 @@ class TestEfiCapsuleFirmwareSignedRaw(): disk_img = efi_capsule_data capsule_files = ['Test113'] with u_boot_console.log.section('Test Case 5-a, before reboot'): - setup(u_boot_console, disk_img, '0x0000000000000004') + capsule_setup(u_boot_console, disk_img, '0x0000000000000004') init_content(u_boot_console, '100000', 'u-boot.bin.old', 'Old') place_capsule_file(u_boot_console, capsule_files) From dc7a2f1d9fcd642ba8c2a6d544244c7852c5f6ec Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 19 Jul 2023 16:49:46 +0200 Subject: [PATCH 6/7] efi_loader: fix dp_fill() for BLKMAP, HOST, VIRTIO Do not assume that the preceding device path contains a single VenHW node. Instead use the return value of dp_fill() which provides the address of the next node. Fixes: 23ad52fff4da ("efi_loader: device_path: support Sandbox's "host" devices") Fixes: 19ecced71cfb ("efi_loader: device path for virtio block devices") Fixes: 272ec6b45304 ("efi_loader: device_path: support blkmap devices") Signed-off-by: Heinrich Schuchardt --- lib/efi_loader/efi_device_path.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 04ebb449caa..c135e2883db 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -631,9 +631,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev) struct efi_device_path_vendor *dp; struct blk_desc *desc = dev_get_uclass_plat(dev); - dp_fill(buf, dev->parent); - dp = buf; - ++dp; + dp = dp_fill(buf, dev->parent); dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE; dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR; dp->dp.length = sizeof(*dp) + 1; @@ -649,9 +647,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev) struct efi_device_path_vendor *dp; struct blk_desc *desc = dev_get_uclass_plat(dev); - dp_fill(buf, dev->parent); - dp = buf; - ++dp; + dp = dp_fill(buf, dev->parent); dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE; dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR; dp->dp.length = sizeof(*dp) + 1; @@ -666,9 +662,7 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev) struct efi_device_path_vendor *dp; struct blk_desc *desc = dev_get_uclass_plat(dev); - dp_fill(buf, dev->parent); - dp = buf; - ++dp; + dp = dp_fill(buf, dev->parent); dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE; dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR; dp->dp.length = sizeof(*dp) + 1; From e07368ea57d224557570a6715dcffdbc883a8079 Mon Sep 17 00:00:00 2001 From: Heinrich Schuchardt Date: Wed, 19 Jul 2023 06:43:08 +0200 Subject: [PATCH 7/7] efi_loader: support all uclasses in device path On devices with multiple USB mass storage devices errors like Path /../USB(0x0,0x0)/USB(0x1,0x0)/Ctrl(0x0) already installed. are seen. This is due to creating non-unique device paths. To uniquely identify devices we must provide path nodes for all devices on the path from the root device. Add support for generating device path nodes for all uclasses. Reported-by: Suniel Mahesh Signed-off-by: Heinrich Schuchardt --- include/efi_api.h | 7 ++++ lib/efi_loader/efi_device_path.c | 56 ++++++++++++++------------------ 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/include/efi_api.h b/include/efi_api.h index 55a4c989fc7..8f5ef5f680f 100644 --- a/include/efi_api.h +++ b/include/efi_api.h @@ -579,6 +579,13 @@ struct efi_device_path_vendor { u8 vendor_data[]; } __packed; +struct efi_device_path_udevice { + struct efi_device_path dp; + efi_guid_t guid; + int uclass_id; + int dev_number; +} __packed; + struct efi_device_path_controller { struct efi_device_path dp; u32 controller_number; diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index c135e2883db..19e8861ef49 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -38,16 +39,6 @@ const struct efi_device_path END = { .length = sizeof(END), }; -/* template ROOT node: */ -static const struct efi_device_path_vendor ROOT = { - .dp = { - .type = DEVICE_PATH_TYPE_HARDWARE_DEVICE, - .sub_type = DEVICE_PATH_SUB_TYPE_VENDOR, - .length = sizeof(ROOT), - }, - .guid = U_BOOT_GUID, -}; - #if defined(CONFIG_MMC) /* * Determine if an MMC device is an SD card. @@ -497,13 +488,12 @@ bool efi_dp_is_multi_instance(const struct efi_device_path *dp) __maybe_unused static unsigned int dp_size(struct udevice *dev) { if (!dev || !dev->driver) - return sizeof(ROOT); + return sizeof(struct efi_device_path_udevice); switch (device_get_uclass_id(dev)) { case UCLASS_ROOT: - case UCLASS_SIMPLE_BUS: /* stop traversing parents at this point: */ - return sizeof(ROOT); + return sizeof(struct efi_device_path_udevice); case UCLASS_ETH: return dp_size(dev->parent) + sizeof(struct efi_device_path_mac_addr); @@ -582,8 +572,8 @@ __maybe_unused static unsigned int dp_size(struct udevice *dev) return dp_size(dev->parent) + sizeof(struct efi_device_path_usb); default: - /* just skip over unknown classes: */ - return dp_size(dev->parent); + return dp_size(dev->parent) + + sizeof(struct efi_device_path_udevice); } } @@ -600,13 +590,6 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev) return buf; switch (device_get_uclass_id(dev)) { - case UCLASS_ROOT: - case UCLASS_SIMPLE_BUS: { - /* stop traversing parents at this point: */ - struct efi_device_path_vendor *vdp = buf; - *vdp = ROOT; - return &vdp[1]; - } #ifdef CONFIG_NETDEVICES case UCLASS_ETH: { struct efi_device_path_mac_addr *dp = @@ -805,11 +788,24 @@ __maybe_unused static void *dp_fill(void *buf, struct udevice *dev) return &udp[1]; } - default: - /* If the uclass driver is missing, this will show NULL */ - log_debug("unhandled device class: %s (%s)\n", dev->name, - dev_get_uclass_name(dev)); - return dp_fill(buf, dev->parent); + default: { + struct efi_device_path_udevice *vdp; + enum uclass_id uclass_id = device_get_uclass_id(dev); + + if (uclass_id == UCLASS_ROOT) + vdp = buf; + else + vdp = dp_fill(buf, dev->parent); + + vdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE; + vdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR; + vdp->dp.length = sizeof(*vdp); + memcpy(&vdp->guid, &efi_u_boot_guid, sizeof(efi_guid_t)); + vdp->uclass_id = uclass_id; + vdp->dev_number = dev->seq_; + + return &vdp[1]; + } } } @@ -1046,14 +1042,12 @@ struct efi_device_path *efi_dp_from_uart(void) { void *buf, *pos; struct efi_device_path_uart *uart; - size_t dpsize = sizeof(ROOT) + sizeof(*uart) + sizeof(END); + size_t dpsize = dp_size(dm_root()) + sizeof(*uart) + sizeof(END); buf = efi_alloc(dpsize); if (!buf) return NULL; - pos = buf; - memcpy(pos, &ROOT, sizeof(ROOT)); - pos += sizeof(ROOT); + pos = dp_fill(buf, dm_root()); uart = pos; uart->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; uart->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_UART;