Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86/efistub: Revert to heap allocated boot_params for PE entrypoint

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>

+15 -5
+15 -5
drivers/firmware/efi/libstub/x86-stub.c
··· 534 534 efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, 535 535 efi_system_table_t *sys_table_arg) 536 536 { 537 - static struct boot_params boot_params __page_aligned_bss; 538 - struct setup_header *hdr = &boot_params.hdr; 539 537 efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; 538 + struct boot_params *boot_params; 539 + struct setup_header *hdr; 540 540 int options_size = 0; 541 541 efi_status_t status; 542 + unsigned long alloc; 542 543 char *cmdline_ptr; 543 544 544 545 efi_system_table = sys_table_arg; ··· 554 553 efi_exit(handle, status); 555 554 } 556 555 556 + status = efi_allocate_pages(PARAM_SIZE, &alloc, ULONG_MAX); 557 + if (status != EFI_SUCCESS) 558 + efi_exit(handle, status); 559 + 560 + boot_params = memset((void *)alloc, 0x0, PARAM_SIZE); 561 + hdr = &boot_params->hdr; 562 + 557 563 /* Assign the setup_header fields that the kernel actually cares about */ 558 564 hdr->root_flags = 1; 559 565 hdr->vid_mode = 0xffff; ··· 570 562 571 563 /* Convert unicode cmdline to ascii */ 572 564 cmdline_ptr = efi_convert_cmdline(image, &options_size); 573 - if (!cmdline_ptr) 565 + if (!cmdline_ptr) { 566 + efi_free(PARAM_SIZE, alloc); 574 567 efi_exit(handle, EFI_OUT_OF_RESOURCES); 568 + } 575 569 576 570 efi_set_u64_split((unsigned long)cmdline_ptr, &hdr->cmd_line_ptr, 577 - &boot_params.ext_cmd_line_ptr); 571 + &boot_params->ext_cmd_line_ptr); 578 572 579 - efi_stub_entry(handle, sys_table_arg, &boot_params); 573 + efi_stub_entry(handle, sys_table_arg, boot_params); 580 574 /* not reached */ 581 575 } 582 576