We changed the logic of the initrd discovery and the installation of the protocol in the previous patch. Instead of a config now option it now resides in an EFI variable. Adjust the existing tests accordingly and add self-tests which will cover the new features.
Signed-off-by: Ilias Apalodimas <[email protected]> --- lib/efi_selftest/efi_selftest_load_initrd.c | 100 +++++++++++++++++++- 1 file changed, 97 insertions(+), 3 deletions(-) diff --git a/lib/efi_selftest/efi_selftest_load_initrd.c b/lib/efi_selftest/efi_selftest_load_initrd.c index fe060a664402..1534c2ba24fa 100644 --- a/lib/efi_selftest/efi_selftest_load_initrd.c +++ b/lib/efi_selftest/efi_selftest_load_initrd.c @@ -14,10 +14,12 @@ * * CONFIG_EFI_SELFTEST=y * CONFIG_EFI_LOAD_FILE2_INITRD=y - * CONFIG_EFI_INITRD_FILESPEC="host 0:1 initrd" * - * * Run ./u-boot and execute + * * Create files + * mkdir init_test && cp initrd init_test/ + * virt-make-fs -t ext4 init_test test.img * + * * Run ./u-boot and execute * host bind 0 image * setenv efi_selftest load initrd * bootefi selftest @@ -43,6 +45,7 @@ #include <efi_load_initrd.h> static struct efi_boot_services *boottime; +static struct efi_runtime_services *runtime; static struct efi_initrd_dp dp = { .vendor = { @@ -76,10 +79,13 @@ static struct efi_initrd_dp dp_invalid = { } }; +static efi_handle_t handle; + static int setup(const efi_handle_t handle, const struct efi_system_table *systable) { boottime = systable->boottime; + runtime = systable->runtime; return EFI_ST_SUCCESS; } @@ -87,16 +93,97 @@ static int setup(const efi_handle_t handle, static int execute(void) { efi_guid_t lf2_proto_guid = EFI_LOAD_FILE2_PROTOCOL_GUID; + efi_guid_t efi_global_variable_guid = EFI_GLOBAL_VARIABLE_GUID; struct efi_load_file_protocol *lf2; struct efi_device_path *dp2, *dp2_invalid; efi_status_t status; - efi_handle_t handle; char buffer[64]; efi_uintn_t buffer_size; void *buf; u32 crc32; + u16 boot_current = 0; + efi_uintn_t boot_current_size = sizeof(boot_current); + char path[] = "host 0 initrd"; + char invalid_path[] = "host 1 initrd"; + efi_uintn_t path_size = sizeof(path); + efi_uintn_t invalid_path_size = sizeof(invalid_path); + u32 attrs = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; memset(buffer, 0, sizeof(buffer)); + /* Set variable BootCurrent and Initrd#### to a wrong value */ + status = runtime->set_variable(L"BootCurrent", &efi_global_variable_guid, + attrs, boot_current_size, &boot_current); + if (status != EFI_SUCCESS) { + efi_st_error("SetVariable for BootCurrent failed\n"); + return EFI_ST_FAILURE; + } + + /* + * We don't need NV for Initrd here. + * Set the file to an invalid file path + */ + status = runtime->set_variable(L"Initrd0010", &efi_global_variable_guid, + attrs, invalid_path_size, invalid_path); + if (status != EFI_SUCCESS) { + efi_st_error("SetVariable for Initrd failed\n"); + return EFI_ST_FAILURE; + } + + /* We only install the protocol during efibootmgr */ + status = efi_initrd_register(&handle); + if (status != EFI_SUCCESS) { + efi_st_error("Failed to install initrd protocol\n"); + return EFI_ST_FAILURE; + } + + /* + * We should only install the protocol if the file's found + * Right now both BootCurrent and file path are invalid + */ + dp2 = (struct efi_device_path *)&dp; + status = boottime->locate_device_path(&lf2_proto_guid, &dp2, &handle); + if (status != EFI_NOT_FOUND) { + efi_st_error("Initrd protocol should't be installed\n"); + return EFI_ST_FAILURE; + } + + /* Update BootCurrent to the correct value */ + boot_current = 0x0010; + status = runtime->set_variable(L"BootCurrent", &efi_global_variable_guid, + attrs, boot_current_size, &boot_current); + if (status != EFI_SUCCESS) { + efi_st_error("SetVariable for BootCurrent failed\n"); + return EFI_ST_FAILURE; + } + + /* re-install with invalid file path */ + status = efi_initrd_register(&handle); + if (status != EFI_SUCCESS) { + efi_st_error("Failed to install initrd protocol\n"); + return EFI_ST_FAILURE; + } + + /* file path is invalid */ + dp2 = (struct efi_device_path *)&dp; + status = boottime->locate_device_path(&lf2_proto_guid, &dp2, &handle); + if (status != EFI_NOT_FOUND) { + efi_st_error("Initrd protocol should't be installed\n"); + return EFI_ST_FAILURE; + } + + /* re-install with correct values now */ + status = runtime->set_variable(L"Initrd0010", &efi_global_variable_guid, + attrs, path_size, path); + if (status != EFI_SUCCESS) { + efi_st_error("SetVariable for Initrd failed\n"); + return EFI_ST_FAILURE; + } + + status = efi_initrd_register(&handle); + if (status != EFI_SUCCESS) { + efi_st_error("Failed to install initrd protocol\n"); + return EFI_ST_FAILURE; + } dp2 = (struct efi_device_path *)&dp; status = boottime->locate_device_path(&lf2_proto_guid, &dp2, &handle); @@ -211,10 +298,17 @@ static int execute(void) return EFI_ST_SUCCESS; } +static int teardown(void) +{ + efi_delete_handle(handle); + return EFI_ST_SUCCESS; +} + EFI_UNIT_TEST(load_initrd) = { .name = "load initrd", .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT, .setup = setup, .execute = execute, + .teardown = teardown, .on_request = true, }; -- 2.30.0

