Skip to content

Commit d2d7a54

Browse files
ardbiesheuvelbp3tk0v
authored andcommitted
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: Ard Biesheuvel <[email protected]> Signed-off-by: Borislav Petkov (AMD) <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 2f69a81 commit d2d7a54

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

drivers/firmware/efi/libstub/x86-stub.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ adjust_memory_range_protection(unsigned long start, unsigned long size)
290290
#define TRAMPOLINE_PLACEMENT_BASE ((128 - 8)*1024)
291291
#define TRAMPOLINE_PLACEMENT_SIZE (640*1024 - (128 - 8)*1024)
292292

293-
void startup_32(struct boot_params *boot_params);
293+
extern const u8 startup_32[], startup_64[];
294294

295295
static void
296296
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)
803803
return EFI_SUCCESS;
804804
}
805805

806+
static void __noreturn enter_kernel(unsigned long kernel_addr,
807+
struct boot_params *boot_params)
808+
{
809+
/* enter decompressed kernel with boot_params pointer in RSI/ESI */
810+
asm("jmp *%0"::"r"(kernel_addr), "S"(boot_params));
811+
812+
unreachable();
813+
}
814+
806815
/*
807-
* On success, we return the address of startup_32, which has potentially been
808-
* relocated by efi_relocate_kernel.
809-
* On failure, we exit to the firmware via efi_exit instead of returning.
816+
* On success, this routine will jump to the relocated image directly and never
817+
* return. On failure, it will exit to the firmware via efi_exit() instead of
818+
* returning.
810819
*/
811820
asmlinkage unsigned long efi_main(efi_handle_t handle,
812821
efi_system_table_t *sys_table_arg,
@@ -950,7 +959,10 @@ asmlinkage unsigned long efi_main(efi_handle_t handle,
950959
goto fail;
951960
}
952961

953-
return bzimage_addr;
962+
if (IS_ENABLED(CONFIG_X86_64))
963+
bzimage_addr += startup_64 - startup_32;
964+
965+
enter_kernel(bzimage_addr, boot_params);
954966
fail:
955967
efi_err("efi_main() failed!\n");
956968

0 commit comments

Comments
 (0)