Skip to content

Commit 41d90b0

Browse files
nivedita76ardbiesheuvel
authored andcommitted
efi/x86: Setup stack correctly for efi_pe_entry
Commit 17054f4 ("efi/x86: Implement mixed mode boot without the handover protocol") introduced a new entry point for the EFI stub to be booted in mixed mode on 32-bit firmware. When entered via efi32_pe_entry, control is first transferred to startup_32 to setup for the switch to long mode, and then the EFI stub proper is entered via efi_pe_entry. efi_pe_entry is an MS ABI function, and the ABI requires 32 bytes of shadow stack space to be allocated by the caller, as well as the stack being aligned to 8 mod 16 on entry. Allocate 40 bytes on the stack before switching to 64-bit mode when calling efi_pe_entry to account for this. For robustness, explicitly align boot_stack_end to 16 bytes. It is currently implicitly aligned since .bss is cacheline-size aligned, head_64.o is the first object file with a .bss section, and the heap and boot sizes are aligned. Fixes: 17054f4 ("efi/x86: Implement mixed mode boot without the handover protocol") Signed-off-by: Arvind Sankar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Ard Biesheuvel <[email protected]>
1 parent 435d1a4 commit 41d90b0

File tree

1 file changed

+10
-1
lines changed

1 file changed

+10
-1
lines changed

arch/x86/boot/compressed/head_64.S

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,6 @@ SYM_FUNC_START(startup_32)
213213
* We place all of the values on our mini stack so lret can
214214
* used to perform that far jump.
215215
*/
216-
pushl $__KERNEL_CS
217216
leal startup_64(%ebp), %eax
218217
#ifdef CONFIG_EFI_MIXED
219218
movl efi32_boot_args(%ebp), %edi
@@ -224,11 +223,20 @@ SYM_FUNC_START(startup_32)
224223
movl efi32_boot_args+8(%ebp), %edx // saved bootparams pointer
225224
cmpl $0, %edx
226225
jnz 1f
226+
/*
227+
* efi_pe_entry uses MS calling convention, which requires 32 bytes of
228+
* shadow space on the stack even if all arguments are passed in
229+
* registers. We also need an additional 8 bytes for the space that
230+
* would be occupied by the return address, and this also results in
231+
* the correct stack alignment for entry.
232+
*/
233+
subl $40, %esp
227234
leal efi_pe_entry(%ebp), %eax
228235
movl %edi, %ecx // MS calling convention
229236
movl %esi, %edx
230237
1:
231238
#endif
239+
pushl $__KERNEL_CS
232240
pushl %eax
233241

234242
/* Enter paged protected Mode, activating Long Mode */
@@ -784,6 +792,7 @@ SYM_DATA_LOCAL(boot_heap, .fill BOOT_HEAP_SIZE, 1, 0)
784792

785793
SYM_DATA_START_LOCAL(boot_stack)
786794
.fill BOOT_STACK_SIZE, 1, 0
795+
.balign 16
787796
SYM_DATA_END_LABEL(boot_stack, SYM_L_LOCAL, boot_stack_end)
788797

789798
/*

0 commit comments

Comments
 (0)