From: Ard Biesheuvel <ardb@kernel.org>
To: Arvind Sankar <nivedita@alum.mit.edu>
Cc: linux-efi <linux-efi@vger.kernel.org>
Subject: Re: [PATCH 1/1] efi/x86: Use firmware stack for mixed-mode EFI stub
Date: Mon, 15 Jun 2020 11:58:43 +0200 [thread overview]
Message-ID: <CAMj1kXFGubFssfb1K_KUGXHhwF1X-vsL+ENYHU4EtbEXCTsQXw@mail.gmail.com> (raw)
In-Reply-To: <20200526170226.2371024-2-nivedita@alum.mit.edu>
On Tue, 26 May 2020 at 19:02, Arvind Sankar <nivedita@alum.mit.edu> wrote:
>
> The UEFI specification requires a 128KiB stack during boot services. On
> a native mode boot, the EFI stub executes on the firmware stack.
> However, on a mixed-mode boot, startup_32 switches to the kernel's boot
> stack, which is only 16KiB, and the EFI stub is executed with this
> stack.
>
> To avoid any potential problems with running out of stack space, save
> and restore the UEFI stack pointer in the mixed-mode entry, so that the
> EFI stub can use the firmware stack in this case as well.
>
> Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu>
This does not apply onto v5.8-rc1, and I was going to take it as a fix.
However, are we sure this is safe? Do we have a ballpark figure of how
much stack we use in the stub?
This is one of those things I am reluctant to change, given that we
are not sure that firmware implementations conform to this, and IA32
firmware was not designed to boot a 64-bit image (which might use more
stack space?)
> ---
> arch/x86/boot/compressed/head_64.S | 46 ++++++++++++++++++++----------
> 1 file changed, 31 insertions(+), 15 deletions(-)
>
> diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
> index 4b7ad1dfbea6..923e5c381804 100644
> --- a/arch/x86/boot/compressed/head_64.S
> +++ b/arch/x86/boot/compressed/head_64.S
> @@ -237,21 +237,7 @@ SYM_FUNC_START(startup_32)
> * used to perform that far jump.
> */
> pushl $__KERNEL_CS
> - leal rva(startup_64)(%ebp), %eax
> -#ifdef CONFIG_EFI_MIXED
> - movl rva(efi32_boot_args)(%ebp), %edi
> - cmp $0, %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
> - cmpl $0, %edx
> - jnz 1f
> - leal rva(efi_pe_entry)(%ebp), %eax
> - movl %edi, %ecx // MS calling convention
> - movl %esi, %edx
> -1:
> -#endif
> + leal rva(.L64bit)(%ebp), %eax
> pushl %eax
>
> /* Enter paged protected Mode, activating Long Mode */
> @@ -260,6 +246,31 @@ SYM_FUNC_START(startup_32)
>
> /* Jump from 32bit compatibility mode into 64bit mode. */
> lret
> +
> + .code64
> +SYM_INNER_LABEL(.L64bit, SYM_L_LOCAL)
> +#ifndef CONFIG_EFI_MIXED
> + jmp startup_64
> +#else
> + movl efi32_boot_args(%rip), %edi
> + testl %edi, %edi
> + jz startup_64
> +
> + /* Restore firmware stack pointer */
> + movl efi32_boot_sp(%rip), %esp
> + /* and align it to 8 mod 16 */
> + andl $~0xf, %esp
> + subl $8, %esp
> +
> + movl efi32_boot_args+4(%rip), %esi
> + movl efi32_boot_args+8(%rip), %edx // saved bootparams pointer
> + testl %edx, %edx
> + jnz efi64_stub_entry
> + movl %edi, %ecx // MS calling convention
> + movl %esi, %edx
> + jmp efi_pe_entry
> +#endif
> + .code32
> SYM_FUNC_END(startup_32)
>
> #ifdef CONFIG_EFI_MIXED
> @@ -285,6 +296,9 @@ SYM_INNER_LABEL(efi32_pe_stub_entry, SYM_L_LOCAL)
> movw %cs, rva(efi32_boot_cs)(%ebp)
> movw %ds, rva(efi32_boot_ds)(%ebp)
>
> + /* Save firmware stack pointer */
> + movl %esp, rva(efi32_boot_sp)(%ebp)
> +
> /* Disable paging */
> movl %cr0, %eax
> btrl $X86_CR0_PG_BIT, %eax
> @@ -648,6 +662,7 @@ SYM_DATA(image_offset, .long 0)
>
> #ifdef CONFIG_EFI_MIXED
> SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0)
> +SYM_DATA_LOCAL(efi32_boot_sp, .long 0)
> SYM_DATA(efi_is64, .byte 1)
>
> #define ST32_boottime 60 // offsetof(efi_system_table_32_t, boottime)
> @@ -710,6 +725,7 @@ SYM_FUNC_START(efi32_pe_entry)
> movl 12(%ebp), %edx // sys_table
> movl -4(%ebp), %esi // loaded_image
> movl LI32_image_base(%esi), %esi // loaded_image->image_base
> + leave // clear stack frame
> movl %ebx, %ebp // startup_32 for efi32_pe_stub_entry
> /*
> * We need to set the image_offset variable here since startup_32() will
> --
> 2.26.2
>
next prev parent reply other threads:[~2020-06-15 9:58 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-05-26 17:02 [PATCH 0/1] efi/x86: Use firmware stack for mixed-mode EFI stub Arvind Sankar
2020-05-26 17:02 ` [PATCH 1/1] " Arvind Sankar
2020-06-15 9:58 ` Ard Biesheuvel [this message]
2020-06-15 15:56 ` Arvind Sankar
2020-06-16 18:48 ` Arvind Sankar
2020-06-16 18:50 ` Ard Biesheuvel
2020-06-16 19:48 ` [PATCH] efi/x86: Setup stack correctly for efi_pe_entry Arvind Sankar
2020-06-16 22:06 ` Ard Biesheuvel
2020-06-17 10:33 ` Ard Biesheuvel
2020-06-17 13:19 ` [PATCH v2] " Arvind Sankar
2020-06-17 13:26 ` Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAMj1kXFGubFssfb1K_KUGXHhwF1X-vsL+ENYHU4EtbEXCTsQXw@mail.gmail.com \
--to=ardb@kernel.org \
--cc=linux-efi@vger.kernel.org \
--cc=nivedita@alum.mit.edu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).