Commit d2d7a54f authored by Ard Biesheuvel's avatar Ard Biesheuvel Committed by Borislav Petkov (AMD)

x86/efistub: Branch straight to kernel entry point from C code

Instead of returning to the calling code in assembler that does nothing
more than perform an indirect call with the boot_params pointer in
register ESI/RSI, perform the jump directly from the EFI stub C code.
This will allow the asm entrypoint code to be dropped entirely in
subsequent patches.
Signed-off-by: default avatarArd Biesheuvel <ardb@kernel.org>
Signed-off-by: default avatarBorislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20230807162720.545787-4-ardb@kernel.org
parent 2f69a81a
...@@ -290,7 +290,7 @@ adjust_memory_range_protection(unsigned long start, unsigned long size) ...@@ -290,7 +290,7 @@ adjust_memory_range_protection(unsigned long start, unsigned long size)
#define TRAMPOLINE_PLACEMENT_BASE ((128 - 8)*1024) #define TRAMPOLINE_PLACEMENT_BASE ((128 - 8)*1024)
#define TRAMPOLINE_PLACEMENT_SIZE (640*1024 - (128 - 8)*1024) #define TRAMPOLINE_PLACEMENT_SIZE (640*1024 - (128 - 8)*1024)
void startup_32(struct boot_params *boot_params); extern const u8 startup_32[], startup_64[];
static void static void
setup_memory_protection(unsigned long image_base, unsigned long image_size) setup_memory_protection(unsigned long image_base, unsigned long image_size)
...@@ -803,10 +803,19 @@ static efi_status_t exit_boot(struct boot_params *boot_params, void *handle) ...@@ -803,10 +803,19 @@ static efi_status_t exit_boot(struct boot_params *boot_params, void *handle)
return EFI_SUCCESS; return EFI_SUCCESS;
} }
static void __noreturn enter_kernel(unsigned long kernel_addr,
struct boot_params *boot_params)
{
/* enter decompressed kernel with boot_params pointer in RSI/ESI */
asm("jmp *%0"::"r"(kernel_addr), "S"(boot_params));
unreachable();
}
/* /*
* On success, we return the address of startup_32, which has potentially been * On success, this routine will jump to the relocated image directly and never
* relocated by efi_relocate_kernel. * return. On failure, it will exit to the firmware via efi_exit() instead of
* On failure, we exit to the firmware via efi_exit instead of returning. * returning.
*/ */
asmlinkage unsigned long efi_main(efi_handle_t handle, asmlinkage unsigned long efi_main(efi_handle_t handle,
efi_system_table_t *sys_table_arg, efi_system_table_t *sys_table_arg,
...@@ -950,7 +959,10 @@ asmlinkage unsigned long efi_main(efi_handle_t handle, ...@@ -950,7 +959,10 @@ asmlinkage unsigned long efi_main(efi_handle_t handle,
goto fail; goto fail;
} }
return bzimage_addr; if (IS_ENABLED(CONFIG_X86_64))
bzimage_addr += startup_64 - startup_32;
enter_kernel(bzimage_addr, boot_params);
fail: fail:
efi_err("efi_main() failed!\n"); efi_err("efi_main() failed!\n");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment