]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
x86/efistub: Revert to heap allocated boot_params for PE entrypoint
authorArd Biesheuvel <ardb@kernel.org>
Fri, 22 Mar 2024 17:11:32 +0000 (18:11 +0100)
committerArd Biesheuvel <ardb@kernel.org>
Thu, 18 Jul 2024 21:05:02 +0000 (23:05 +0200)
This is a partial revert of commit

  8117961d98f ("x86/efi: Disregard setup header of loaded image")

which triggers boot issues on older Dell laptops. As it turns out,
switching back to a heap allocation for the struct boot_params
constructed by the EFI stub works around this, even though it is unclear
why.

Cc: Christian Heusel <christian@heusel.eu>
Reported-by: <mavrix#kernel@simplelogin.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
drivers/firmware/efi/libstub/x86-stub.c

index 078055b054e3395892cc1f4ae7069c65a0e1ac75..f8e465da344d54572b5bd66fabd4517b39caeedf 100644 (file)
@@ -534,11 +534,12 @@ void __noreturn efi_stub_entry(efi_handle_t handle,
 efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
                                   efi_system_table_t *sys_table_arg)
 {
-       static struct boot_params boot_params __page_aligned_bss;
-       struct setup_header *hdr = &boot_params.hdr;
        efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID;
+       struct boot_params *boot_params;
+       struct setup_header *hdr;
        int options_size = 0;
        efi_status_t status;
+       unsigned long alloc;
        char *cmdline_ptr;
 
        efi_system_table = sys_table_arg;
@@ -553,6 +554,13 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
                efi_exit(handle, status);
        }
 
+       status = efi_allocate_pages(PARAM_SIZE, &alloc, ULONG_MAX);
+       if (status != EFI_SUCCESS)
+               efi_exit(handle, status);
+
+       boot_params = memset((void *)alloc, 0x0, PARAM_SIZE);
+       hdr         = &boot_params->hdr;
+
        /* Assign the setup_header fields that the kernel actually cares about */
        hdr->root_flags = 1;
        hdr->vid_mode   = 0xffff;
@@ -562,13 +570,15 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle,
 
        /* Convert unicode cmdline to ascii */
        cmdline_ptr = efi_convert_cmdline(image, &options_size);
-       if (!cmdline_ptr)
+       if (!cmdline_ptr) {
+               efi_free(PARAM_SIZE, alloc);
                efi_exit(handle, EFI_OUT_OF_RESOURCES);
+       }
 
        efi_set_u64_split((unsigned long)cmdline_ptr, &hdr->cmd_line_ptr,
-                         &boot_params.ext_cmd_line_ptr);
+                         &boot_params->ext_cmd_line_ptr);
 
-       efi_stub_entry(handle, sys_table_arg, &boot_params);
+       efi_stub_entry(handle, sys_table_arg, boot_params);
        /* not reached */
 }