mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-15 08:14:15 +08:00
x86/boot/compressed: Move bootargs parsing out of 32-bit startup code
Move the logic that chooses between the different EFI entrypoints out of the 32-bit boot path, and into a 64-bit helper that can perform the same task much more cleanly. While at it, document the mixed mode boot flow in a code comment. Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Borislav Petkov <bp@suse.de> Link: https://lore.kernel.org/r/20221122161017.2426828-4-ardb@kernel.org
This commit is contained in:
parent
e2ab9eab32
commit
5c3a85f35b
@ -22,6 +22,49 @@
|
||||
|
||||
.code64
|
||||
.text
|
||||
/*
|
||||
* 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
|
||||
* 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.
|
||||
*
|
||||
* +--------------+
|
||||
* +------------------+ +------------+ +------>| efi_pe_entry |
|
||||
* | efi32_pe_entry |---->| | | +-----------+--+
|
||||
* +------------------+ | | +------+----------------+ |
|
||||
* | startup_32 |---->| startup_64_mixed_mode | |
|
||||
* +------------------+ | | +------+----------------+ V
|
||||
* | efi32_stub_entry |---->| | | +------------------+
|
||||
* +------------------+ +------------+ +---->| efi64_stub_entry |
|
||||
* +-------------+----+
|
||||
* +------------+ +----------+ |
|
||||
* | startup_64 |<----| efi_main |<--------------+
|
||||
* +------------+ +----------+
|
||||
*/
|
||||
SYM_FUNC_START(startup_64_mixed_mode)
|
||||
lea efi32_boot_args(%rip), %rdx
|
||||
mov 0(%rdx), %edi
|
||||
mov 4(%rdx), %esi
|
||||
mov 8(%rdx), %edx // saved bootparams pointer
|
||||
test %edx, %edx
|
||||
jnz efi64_stub_entry
|
||||
/*
|
||||
* efi_pe_entry uses MS calling convention, which requires 32 bytes of
|
||||
* shadow space on the stack even if all arguments are passed in
|
||||
* registers. We also need an additional 8 bytes for the space that
|
||||
* would be occupied by the return address, and this also results in
|
||||
* the correct stack alignment for entry.
|
||||
*/
|
||||
sub $40, %rsp
|
||||
mov %rdi, %rcx // MS calling convention
|
||||
mov %rsi, %rdx
|
||||
jmp efi_pe_entry
|
||||
SYM_FUNC_END(startup_64_mixed_mode)
|
||||
|
||||
SYM_FUNC_START(__efi64_thunk)
|
||||
push %rbp
|
||||
push %rbx
|
||||
|
@ -261,25 +261,9 @@ SYM_FUNC_START(startup_32)
|
||||
*/
|
||||
leal rva(startup_64)(%ebp), %eax
|
||||
#ifdef CONFIG_EFI_MIXED
|
||||
movl rva(efi32_boot_args)(%ebp), %edi
|
||||
testl %edi, %edi
|
||||
jz 1f
|
||||
leal rva(efi64_stub_entry)(%ebp), %eax
|
||||
movl rva(efi32_boot_args+4)(%ebp), %esi
|
||||
movl rva(efi32_boot_args+8)(%ebp), %edx // saved bootparams pointer
|
||||
testl %edx, %edx
|
||||
jnz 1f
|
||||
/*
|
||||
* efi_pe_entry uses MS calling convention, which requires 32 bytes of
|
||||
* shadow space on the stack even if all arguments are passed in
|
||||
* registers. We also need an additional 8 bytes for the space that
|
||||
* would be occupied by the return address, and this also results in
|
||||
* the correct stack alignment for entry.
|
||||
*/
|
||||
subl $40, %esp
|
||||
leal rva(efi_pe_entry)(%ebp), %eax
|
||||
movl %edi, %ecx // MS calling convention
|
||||
movl %esi, %edx
|
||||
cmpb $1, rva(efi_is64)(%ebp)
|
||||
je 1f
|
||||
leal rva(startup_64_mixed_mode)(%ebp), %eax
|
||||
1:
|
||||
#endif
|
||||
/* Check if the C-bit position is correct when SEV is active */
|
||||
@ -779,7 +763,7 @@ SYM_DATA_END_LABEL(boot32_idt, SYM_L_GLOBAL, boot32_idt_end)
|
||||
SYM_DATA(image_offset, .long 0)
|
||||
#endif
|
||||
#ifdef CONFIG_EFI_MIXED
|
||||
SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0)
|
||||
SYM_DATA(efi32_boot_args, .long 0, 0, 0)
|
||||
SYM_DATA(efi_is64, .byte 1)
|
||||
|
||||
#define ST32_boottime 60 // offsetof(efi_system_table_32_t, boottime)
|
||||
|
Loading…
Reference in New Issue
Block a user