mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-05 10:31:46 +09:00
x86/efistub: Simplify and clean up handover entry code
From: Ard Biesheuvel <ardb@kernel.org>
[ Commit df9215f152 upstream ]
Now that the EFI entry code in assembler is only used by the optional
and deprecated EFI handover protocol, and given that the EFI stub C code
no longer returns to it, most of it can simply be dropped.
While at it, clarify the symbol naming, by merging efi_main() and
efi_stub_entry(), making the latter the shared entry point for all
different boot modes that enter via the EFI stub.
The efi32_stub_entry() and efi64_stub_entry() names are referenced
explicitly by the tooling that populates the setup header, so these must
be retained, but can be emitted as aliases of efi_stub_entry() where
appropriate.
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://lore.kernel.org/r/20230807162720.545787-5-ardb@kernel.org
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
33d064aecd
commit
f0acafd6f7
@@ -1416,7 +1416,7 @@ execution context provided by the EFI firmware.
|
||||
|
||||
The function prototype for the handover entry point looks like this::
|
||||
|
||||
efi_main(void *handle, efi_system_table_t *table, struct boot_params *bp)
|
||||
efi_stub_entry(void *handle, efi_system_table_t *table, struct boot_params *bp)
|
||||
|
||||
'handle' is the EFI image handle passed to the boot loader by the EFI
|
||||
firmware, 'table' is the EFI system table - these are the first two
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
* When booting in 64-bit mode on 32-bit EFI firmware, startup_64_mixed_mode()
|
||||
* is the first thing that runs after switching to long mode. Depending on
|
||||
* whether the EFI handover protocol or the compat entry point was used to
|
||||
* enter the kernel, it will either branch to the 64-bit EFI handover
|
||||
* entrypoint at offset 0x390 in the image, or to the 64-bit EFI PE/COFF
|
||||
* enter the kernel, it will either branch to the common 64-bit EFI stub
|
||||
* entrypoint efi_stub_entry() directly, or via the 64-bit EFI PE/COFF
|
||||
* entrypoint efi_pe_entry(). In the former case, the bootloader must provide a
|
||||
* struct bootparams pointer as the third argument, so the presence of such a
|
||||
* pointer is used to disambiguate.
|
||||
@@ -37,21 +37,23 @@
|
||||
* | efi32_pe_entry |---->| | | +-----------+--+
|
||||
* +------------------+ | | +------+----------------+ |
|
||||
* | startup_32 |---->| startup_64_mixed_mode | |
|
||||
* +------------------+ | | +------+----------------+ V
|
||||
* | efi32_stub_entry |---->| | | +------------------+
|
||||
* +------------------+ +------------+ +---->| efi64_stub_entry |
|
||||
* +-------------+----+
|
||||
* +------------+ +----------+ |
|
||||
* | startup_64 |<----| efi_main |<--------------+
|
||||
* +------------+ +----------+
|
||||
* +------------------+ | | +------+----------------+ |
|
||||
* | efi32_stub_entry |---->| | | |
|
||||
* +------------------+ +------------+ | |
|
||||
* V |
|
||||
* +------------+ +----------------+ |
|
||||
* | startup_64 |<----| efi_stub_entry |<--------+
|
||||
* +------------+ +----------------+
|
||||
*/
|
||||
SYM_FUNC_START(startup_64_mixed_mode)
|
||||
lea efi32_boot_args(%rip), %rdx
|
||||
mov 0(%rdx), %edi
|
||||
mov 4(%rdx), %esi
|
||||
#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
|
||||
mov 8(%rdx), %edx // saved bootparams pointer
|
||||
test %edx, %edx
|
||||
jnz efi64_stub_entry
|
||||
jnz efi_stub_entry
|
||||
#endif
|
||||
/*
|
||||
* efi_pe_entry uses MS calling convention, which requires 32 bytes of
|
||||
* shadow space on the stack even if all arguments are passed in
|
||||
|
||||
@@ -150,17 +150,6 @@ SYM_FUNC_START(startup_32)
|
||||
jmp *%eax
|
||||
SYM_FUNC_END(startup_32)
|
||||
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
SYM_FUNC_START(efi32_stub_entry)
|
||||
add $0x4, %esp
|
||||
movl 8(%esp), %esi /* save boot_params pointer */
|
||||
call efi_main
|
||||
/* efi_main returns the possibly relocated address of startup_32 */
|
||||
jmp *%eax
|
||||
SYM_FUNC_END(efi32_stub_entry)
|
||||
SYM_FUNC_ALIAS(efi_stub_entry, efi32_stub_entry)
|
||||
#endif
|
||||
|
||||
.text
|
||||
SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
|
||||
|
||||
|
||||
@@ -474,19 +474,11 @@ SYM_CODE_START(startup_64)
|
||||
jmp *%rax
|
||||
SYM_CODE_END(startup_64)
|
||||
|
||||
#ifdef CONFIG_EFI_STUB
|
||||
#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
|
||||
#if IS_ENABLED(CONFIG_EFI_MIXED) && IS_ENABLED(CONFIG_EFI_HANDOVER_PROTOCOL)
|
||||
.org 0x390
|
||||
#endif
|
||||
SYM_FUNC_START(efi64_stub_entry)
|
||||
and $~0xf, %rsp /* realign the stack */
|
||||
movq %rdx, %rbx /* save boot_params pointer */
|
||||
call efi_main
|
||||
movq %rbx,%rsi
|
||||
leaq rva(startup_64)(%rax), %rax
|
||||
jmp *%rax
|
||||
jmp efi_stub_entry
|
||||
SYM_FUNC_END(efi64_stub_entry)
|
||||
SYM_FUNC_ALIAS(efi_stub_entry, efi64_stub_entry)
|
||||
#endif
|
||||
|
||||
.text
|
||||
|
||||
@@ -774,9 +774,9 @@ static void __noreturn enter_kernel(unsigned long kernel_addr,
|
||||
* return. On failure, it will exit to the firmware via efi_exit() instead of
|
||||
* returning.
|
||||
*/
|
||||
asmlinkage unsigned long efi_main(efi_handle_t handle,
|
||||
efi_system_table_t *sys_table_arg,
|
||||
struct boot_params *boot_params)
|
||||
void __noreturn efi_stub_entry(efi_handle_t handle,
|
||||
efi_system_table_t *sys_table_arg,
|
||||
struct boot_params *boot_params)
|
||||
{
|
||||
unsigned long bzimage_addr = (unsigned long)startup_32;
|
||||
unsigned long buffer_start, buffer_end;
|
||||
@@ -919,7 +919,19 @@ asmlinkage unsigned long efi_main(efi_handle_t handle,
|
||||
|
||||
enter_kernel(bzimage_addr, boot_params);
|
||||
fail:
|
||||
efi_err("efi_main() failed!\n");
|
||||
efi_err("efi_stub_entry() failed!\n");
|
||||
|
||||
efi_exit(handle, status);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
|
||||
#ifndef CONFIG_EFI_MIXED
|
||||
extern __alias(efi_stub_entry)
|
||||
void efi32_stub_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg,
|
||||
struct boot_params *boot_params);
|
||||
|
||||
extern __alias(efi_stub_entry)
|
||||
void efi64_stub_entry(efi_handle_t handle, efi_system_table_t *sys_table_arg,
|
||||
struct boot_params *boot_params);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user