diff options
Diffstat (limited to 'drivers/firmware/efi/libstub/x86-stub.c')
-rw-r--r-- | drivers/firmware/efi/libstub/x86-stub.c | 52 |
1 files changed, 29 insertions, 23 deletions
diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c index 863910e9eefc..cafc90d4caaf 100644 --- a/drivers/firmware/efi/libstub/x86-stub.c +++ b/drivers/firmware/efi/libstub/x86-stub.c @@ -397,17 +397,13 @@ static void __noreturn efi_exit(efi_handle_t handle, efi_status_t status) asm("hlt"); } -void __noreturn efi_stub_entry(efi_handle_t handle, - efi_system_table_t *sys_table_arg, - struct boot_params *boot_params); - /* * Because the x86 boot code expects to be passed a boot_params we * need to create one ourselves (usually the bootloader would create * one for us). */ -efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, - efi_system_table_t *sys_table_arg) +static efi_status_t efi_allocate_bootparams(efi_handle_t handle, + struct boot_params **bp) { efi_guid_t proto = LOADED_IMAGE_PROTOCOL_GUID; struct boot_params *boot_params; @@ -416,21 +412,15 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, unsigned long alloc; char *cmdline_ptr; - efi_system_table = sys_table_arg; - - /* Check if we were booted by the EFI firmware */ - if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) - efi_exit(handle, EFI_INVALID_PARAMETER); - status = efi_bs_call(handle_protocol, handle, &proto, (void **)&image); if (status != EFI_SUCCESS) { efi_err("Failed to get handle for LOADED_IMAGE_PROTOCOL\n"); - efi_exit(handle, status); + return status; } status = efi_allocate_pages(PARAM_SIZE, &alloc, ULONG_MAX); if (status != EFI_SUCCESS) - efi_exit(handle, status); + return status; boot_params = memset((void *)alloc, 0x0, PARAM_SIZE); hdr = &boot_params->hdr; @@ -446,14 +436,14 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, cmdline_ptr = efi_convert_cmdline(image); if (!cmdline_ptr) { efi_free(PARAM_SIZE, alloc); - efi_exit(handle, EFI_OUT_OF_RESOURCES); + return EFI_OUT_OF_RESOURCES; } efi_set_u64_split((unsigned long)cmdline_ptr, &hdr->cmd_line_ptr, &boot_params->ext_cmd_line_ptr); - efi_stub_entry(handle, sys_table_arg, boot_params); - /* not reached */ + *bp = boot_params; + return EFI_SUCCESS; } static void add_e820ext(struct boot_params *params, @@ -740,13 +730,16 @@ static efi_status_t parse_options(const char *cmdline) return efi_parse_options(cmdline); } -static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry) +static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry, + struct boot_params *boot_params) { unsigned long virt_addr = LOAD_PHYSICAL_ADDR; unsigned long addr, alloc_size, entry; efi_status_t status; u32 seed[2] = {}; + boot_params_ptr = boot_params; + /* determine the required size of the allocation */ alloc_size = ALIGN(max_t(unsigned long, output_len, kernel_total_size), MIN_KERNEL_ALIGN); @@ -777,7 +770,7 @@ static efi_status_t efi_decompress_kernel(unsigned long *kernel_entry) seed[0] = 0; } - boot_params_ptr->hdr.loadflags |= KASLR_FLAG; + boot_params->hdr.loadflags |= KASLR_FLAG; } status = efi_random_alloc(alloc_size, CONFIG_PHYSICAL_ALIGN, &addr, @@ -815,20 +808,27 @@ static void __noreturn enter_kernel(unsigned long kernel_addr, void __noreturn efi_stub_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg, struct boot_params *boot_params) + { efi_guid_t guid = EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID; - struct setup_header *hdr = &boot_params->hdr; const struct linux_efi_initrd *initrd = NULL; unsigned long kernel_entry; + struct setup_header *hdr; efi_status_t status; - boot_params_ptr = boot_params; - efi_system_table = sys_table_arg; /* Check if we were booted by the EFI firmware */ if (efi_system_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) efi_exit(handle, EFI_INVALID_PARAMETER); + if (!IS_ENABLED(CONFIG_EFI_HANDOVER_PROTOCOL) || !boot_params) { + status = efi_allocate_bootparams(handle, &boot_params); + if (status != EFI_SUCCESS) + efi_exit(handle, status); + } + + hdr = &boot_params->hdr; + if (have_unsupported_snp_features()) efi_exit(handle, EFI_UNSUPPORTED); @@ -870,7 +870,7 @@ void __noreturn efi_stub_entry(efi_handle_t handle, if (efi_mem_encrypt > 0) hdr->xloadflags |= XLF_MEM_ENCRYPTION; - status = efi_decompress_kernel(&kernel_entry); + status = efi_decompress_kernel(&kernel_entry, boot_params); if (status != EFI_SUCCESS) { efi_err("Failed to decompress kernel\n"); goto fail; @@ -940,6 +940,12 @@ fail: efi_exit(handle, status); } +efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, + efi_system_table_t *sys_table_arg) +{ + efi_stub_entry(handle, sys_table_arg, NULL); +} + #ifdef CONFIG_EFI_HANDOVER_PROTOCOL void efi_handover_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg, struct boot_params *boot_params) |