From 9302c1bb8e475829330146423626c3d32e8cb012 Mon Sep 17 00:00:00 2001 From: Ard Biesheuvel Date: Mon, 10 Feb 2020 17:02:44 +0100 Subject: efi/libstub: Rewrite file I/O routine The file I/O routine that is used to load initrd or dtb files from the EFI system partition suffers from a few issues: - it converts the u8[] command line back to a UTF-16 string, which is pointless since we only handle initrd or dtb arguments provided via the loaded image protocol anyway, which is where we got the UTF-16[] command line from in the first place when booting via the PE entry point, - in the far majority of cases, only a single initrd= option is present, but it optimizes for multiple options, by going over the command line twice, allocating heap buffers for dynamically sized arrays, etc. - the coding style is hard to follow, with few comments, and all logic including string parsing etc all combined in a single routine. Let's fix this by rewriting most of it, based on the idea that in the case of multiple initrds, we can just allocate a new, bigger buffer and copy over the data before freeing the old one. Signed-off-by: Ard Biesheuvel --- drivers/firmware/efi/libstub/arm-stub.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers/firmware/efi/libstub/arm-stub.c') diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c index 1e0ff23ef3c3..ad44783ae128 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c @@ -154,7 +154,7 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg) unsigned long dram_base; /* addr/point and size pairs for memory management*/ unsigned long initrd_addr; - u64 initrd_size = 0; + unsigned long initrd_size = 0; unsigned long fdt_addr = 0; /* Original DTB */ unsigned long fdt_size = 0; char *cmdline_ptr = NULL; @@ -247,8 +247,7 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg) if (strstr(cmdline_ptr, "dtb=")) pr_efi("Ignoring DTB from command line.\n"); } else { - status = handle_cmdline_files(image, cmdline_ptr, "dtb=", - ~0UL, &fdt_addr, &fdt_size); + status = efi_load_dtb(image, &fdt_addr, &fdt_size); if (status != EFI_SUCCESS) { pr_efi_err("Failed to load device tree!\n"); @@ -268,11 +267,8 @@ efi_status_t efi_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg) if (!fdt_addr) pr_efi("Generating empty DTB\n"); - status = handle_cmdline_files(image, cmdline_ptr, "initrd=", - efi_get_max_initrd_addr(dram_base, - image_addr), - (unsigned long *)&initrd_addr, - (unsigned long *)&initrd_size); + status = efi_load_initrd(image, &initrd_addr, &initrd_size, + efi_get_max_initrd_addr(dram_base, image_addr)); if (status != EFI_SUCCESS) pr_efi_err("Failed initrd from command line!\n"); -- cgit v1.2.3