diff options
author | Tom Rini <trini@konsulko.com> | 2020-10-06 15:36:38 +0300 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2020-10-06 15:36:38 +0300 |
commit | 5dcf7cc590b348f1e730ec38242df64c179f10a8 (patch) | |
tree | 7ba5948897352b913338be6cf27061570e96a128 /lib | |
parent | 987ab49366f3fcd25039eab431bf099b587b3265 (diff) | |
parent | 4cbb2930bd8c67f40f848528941930cf4c2a1841 (diff) | |
download | u-boot-5dcf7cc590b348f1e730ec38242df64c179f10a8.tar.xz |
Merge tag 'efi-2021-01-rc1' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi
Pull request for UEFI sub-system for efi-2021-01-rc1
The following bugs in the UEFI system are resolved:
* illegal free in EFI_LOAD_FILE2_PROTOCOL implementation
* incorrect documentation of EFI_LOAD_FILE2_PROTOCOL implementation
* output of CRC32 as decimal instead hexadecimal in unit test
* use EfiReservedMemoryType for no-map reserved memory
* avoid unnecessary resets in UEFI unit tests
* call EFI bootmgr even without having /EFI/boot
Diffstat (limited to 'lib')
-rw-r--r-- | lib/efi_loader/Kconfig | 1 | ||||
-rw-r--r-- | lib/efi_loader/efi_load_initrd.c | 59 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest.c | 31 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_console.c | 35 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_load_initrd.c | 2 | ||||
-rw-r--r-- | lib/efi_selftest/efi_selftest_set_virtual_address_map.c | 2 |
6 files changed, 88 insertions, 42 deletions
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig index bad1a29ba8..ab42f3ba75 100644 --- a/lib/efi_loader/Kconfig +++ b/lib/efi_loader/Kconfig @@ -164,6 +164,7 @@ config EFI_HAVE_RUNTIME_RESET config EFI_GRUB_ARM32_WORKAROUND bool "Workaround for GRUB on 32bit ARM" + default n if ARCH_QEMU default y depends on ARM && !ARM64 help diff --git a/lib/efi_loader/efi_load_initrd.c b/lib/efi_loader/efi_load_initrd.c index 574a83d7e3..d517d686c3 100644 --- a/lib/efi_loader/efi_load_initrd.c +++ b/lib/efi_loader/efi_load_initrd.c @@ -47,9 +47,9 @@ static const struct efi_initrd_dp dp = { /** * get_file_size() - retrieve the size of initramfs, set efi status on error * - * @dev: device to read from. i.e "mmc" - * @part: device partition. i.e "0:1" - * @file: name fo file + * @dev: device to read from, e.g. "mmc" + * @part: device partition, e.g. "0:1" + * @file: name of file * @status: EFI exit code in case of failure * * Return: size of file @@ -78,15 +78,16 @@ out: } /** - * load_file2() - get information about random number generation + * efi_load_file2initrd() - load initial RAM disk + * + * This function implements the LoadFile service of the EFI_LOAD_FILE2_PROTOCOL + * in order to load an initial RAM disk requested by the Linux kernel stub. * - * This function implement the LoadFile2() service in order to load an initram - * disk requested by the Linux kernel stub. * See the UEFI spec for details. * - * @this: loadfile2 protocol instance - * @file_path: relative path of the file. "" in this case - * @boot_policy: must be false for Loadfile2 + * @this: EFI_LOAD_FILE2_PROTOCOL instance + * @file_path: media device path of the file, "" in this case + * @boot_policy: must be false * @buffer_size: size of allocated buffer * @buffer: buffer to load the file * @@ -97,19 +98,20 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this, struct efi_device_path *file_path, bool boot_policy, efi_uintn_t *buffer_size, void *buffer) { - const char *filespec = CONFIG_EFI_INITRD_FILESPEC; + char *filespec; efi_status_t status = EFI_NOT_FOUND; loff_t file_sz = 0, read_sz = 0; char *dev, *part, *file; - char *s; + char *pos; int ret; EFI_ENTRY("%p, %p, %d, %p, %p", this, file_path, boot_policy, buffer_size, buffer); - s = strdup(filespec); - if (!s) + filespec = strdup(CONFIG_EFI_INITRD_FILESPEC); + if (!filespec) goto out; + pos = filespec; if (!this || this != &efi_lf2_protocol || !buffer_size) { @@ -128,14 +130,20 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this, goto out; } - /* expect something like 'mmc 0:1 initrd.cpio.gz' */ - dev = strsep(&s, " "); + /* + * expect a string with three space separated parts: + * + * * a block device type, e.g. "mmc" + * * a device and partition identifier, e.g. "0:1" + * * a file path on the block device, e.g. "/boot/initrd.cpio.gz" + */ + dev = strsep(&pos, " "); if (!dev) goto out; - part = strsep(&s, " "); + part = strsep(&pos, " "); if (!part) goto out; - file = strsep(&s, " "); + file = strsep(&pos, " "); if (!file) goto out; @@ -163,28 +171,25 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this, } out: - free(s); + free(filespec); return EFI_EXIT(status); } /** - * efi_initrd_register() - Register a handle and loadfile2 protocol + * efi_initrd_register() - create handle for loading initial RAM disk * - * This function creates a new handle and installs a linux specific GUID - * to handle initram disk loading during boot. - * See the UEFI spec for details. + * This function creates a new handle and installs a Linux specific vendor + * device path and an EFI_LOAD_FILE_2_PROTOCOL. Linux uses the device path + * to identify the handle and then calls the LoadFile service of the + * EFI_LOAD_FILE_2_PROTOCOL to read the initial RAM disk. * - * Return: status code + * Return: status code */ efi_status_t efi_initrd_register(void) { efi_handle_t efi_initrd_handle = NULL; efi_status_t ret; - /* - * Set up the handle with the EFI_LOAD_FILE2_PROTOCOL which Linux may - * use to load the initial ramdisk. - */ ret = EFI_CALL(efi_install_multiple_protocol_interfaces (&efi_initrd_handle, /* initramfs */ diff --git a/lib/efi_selftest/efi_selftest.c b/lib/efi_selftest/efi_selftest.c index 165fa265f2..85e819bdfa 100644 --- a/lib/efi_selftest/efi_selftest.c +++ b/lib/efi_selftest/efi_selftest.c @@ -143,6 +143,27 @@ static int teardown(struct efi_unit_test *test, unsigned int *failures) } /* + * Check that a test requiring reset exists. + * + * @testname: name of the test + * @return: test, or NULL if not found + */ +static bool need_reset(const u16 *testname) +{ + struct efi_unit_test *test; + + for (test = ll_entry_start(struct efi_unit_test, efi_unit_test); + test < ll_entry_end(struct efi_unit_test, efi_unit_test); ++test) { + if (testname && efi_st_strcmp_16_8(testname, test->name)) + continue; + if (test->phase == EFI_SETUP_BEFORE_BOOTTIME_EXIT || + test->phase == EFI_SETUP_AFTER_BOOTTIME_EXIT) + return true; + } + return false; +} + +/* * Check that a test exists. * * @testname: name of the test @@ -290,6 +311,16 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle, EFI_ST_SETUP | EFI_ST_EXECUTE | EFI_ST_TEARDOWN, &failures); + if (!need_reset(testname)) { + if (failures) + ret = EFI_PROTOCOL_ERROR; + + /* Give feedback */ + efi_st_printc(EFI_WHITE, "\nSummary: %u failures\n\n", + failures); + return ret; + } + /* Execute mixed tests */ efi_st_do_tests(testname, EFI_SETUP_BEFORE_BOOTTIME_EXIT, EFI_ST_SETUP, &failures); diff --git a/lib/efi_selftest/efi_selftest_console.c b/lib/efi_selftest/efi_selftest_console.c index 13f3ee6bc1..0219bd70e0 100644 --- a/lib/efi_selftest/efi_selftest_console.c +++ b/lib/efi_selftest/efi_selftest_console.c @@ -44,25 +44,28 @@ static void mac(void *pointer, u16 **buf) } /* - * Print a pointer to an u16 string + * printx() - print hexadecimal number to an u16 string * - * @pointer: pointer - * @buf: pointer to buffer address - * on return position of terminating zero word + * @pointer: pointer + * @prec: minimum number of digits to print + * @buf: pointer to buffer address, + * on return position of terminating zero word + * @size: size of value to be printed in bytes */ -static void pointer(void *pointer, u16 **buf) +static void printx(u64 p, int prec, u16 **buf) { int i; u16 c; - uintptr_t p = (uintptr_t)pointer; u16 *pos = *buf; - for (i = 8 * sizeof(p) - 4; i >= 0; i -= 4) { - c = (p >> i) & 0x0f; - c += '0'; - if (c > '9') - c += 'a' - '9' - 1; - *pos++ = c; + for (i = 2 * sizeof(p) - 1; i >= 0; --i) { + c = (p >> (4 * i)) & 0x0f; + if (c || pos != *buf || !i || i < prec) { + c += '0'; + if (c > '9') + c += 'a' - '9' - 1; + *pos++ = c; + } } *pos = 0; *buf = pos; @@ -212,7 +215,9 @@ void efi_st_printc(int color, const char *fmt, ...) break; default: --c; - pointer(va_arg(args, void*), &pos); + printx((uintptr_t)va_arg(args, void *), + 2 * sizeof(void *), &pos); + break; } break; case 's': @@ -223,6 +228,10 @@ void efi_st_printc(int color, const char *fmt, ...) case 'u': uint2dec(va_arg(args, u32), prec, &pos); break; + case 'x': + printx((u64)va_arg(args, unsigned int), + prec, &pos); + break; default: break; } diff --git a/lib/efi_selftest/efi_selftest_load_initrd.c b/lib/efi_selftest/efi_selftest_load_initrd.c index e16163caca..fe060a6644 100644 --- a/lib/efi_selftest/efi_selftest_load_initrd.c +++ b/lib/efi_selftest/efi_selftest_load_initrd.c @@ -200,7 +200,7 @@ static int execute(void) efi_st_error("Could not determine CRC32\n"); return EFI_ST_FAILURE; } - efi_st_printf("CRC32 %u\n", (unsigned int)crc32); + efi_st_printf("CRC32 %.8x\n", (unsigned int)crc32); status = boottime->free_pool(buf); if (status != EFI_SUCCESS) { diff --git a/lib/efi_selftest/efi_selftest_set_virtual_address_map.c b/lib/efi_selftest/efi_selftest_set_virtual_address_map.c index a4e5a50f63..b097a81136 100644 --- a/lib/efi_selftest/efi_selftest_set_virtual_address_map.c +++ b/lib/efi_selftest/efi_selftest_set_virtual_address_map.c @@ -23,7 +23,7 @@ static u32 notify_call_count; static bool convert_pointer_failed; /** - * notify () - notification function + * notify() - notification function * * This function is called when the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event * occurs. The correct output of ConvertPointer() is checked. |