From: Ard Biesheuvel <ardb@kernel.org> To: Arvind Sankar <nivedita@alum.mit.edu> Cc: linux-efi <linux-efi@vger.kernel.org>, linux-arm-kernel <linux-arm-kernel@lists.infradead.org>, Laszlo Ersek <lersek@redhat.com>, Leif Lindholm <leif@nuviainc.com>, Peter Jones <pjones@redhat.com>, Matthew Garrett <mjg59@google.com>, Alexander Graf <agraf@csgraf.de>, Daniel Kiper <daniel.kiper@oracle.com>, Hans de Goede <hdegoede@redhat.com>, Michael Brown <mbrown@fensystems.co.uk>, Ingo Molnar <mingo@kernel.org> Subject: Re: [RFC PATCH 3/3] efi/x86: implement mixed mode boot without the handover protocol Date: Thu, 13 Feb 2020 17:42:22 +0000 [thread overview] Message-ID: <CAKv+Gu8KX4wFOx-GObTt2Z7k5v+BG=s35S-sqfrXg93xJ6mFjw@mail.gmail.com> (raw) In-Reply-To: <20200213172355.GB1400002@rani.riverdale.lan> On Thu, 13 Feb 2020 at 18:23, Arvind Sankar <nivedita@alum.mit.edu> wrote: > > On Thu, Feb 13, 2020 at 03:59:28PM +0100, Ard Biesheuvel wrote: > > Add support for booting 64-bit x86 kernels from 32-bit firmware running > > on 64-bit capable CPUs without requiring the bootloader to implement > > the EFI handover protocol, allocate the setup block etc etc, all of > > which can be done by the stub using code we have already implemented. > > > > Instead, create an ordinary EFI application entrypoint but implemented > > in 32-bit code, so that it can be invoked by 32-bit firmware, and stash > > the address of this 32-bit entrypoint in the .compat section where the > > bootloader can find it. > > > > Note that we use the setup block embedded in the binary to go through > > startup_32(), but it gets reallocated and copied in efi_pe_entry(), > > using the same code that runs when the x86 kernel is booted in EFI > > mode from native firmware. This requires the loaded image protocol to > > be installed on the kernel image's EFI handle, and point to the kernel > > image itself and not to its loader. This, in turn, requires the > > bootloader to use the LoadImage() boot services to load the 64-bit > > image from 32-bit firmware, which is in fact supported by firmware > > based on EDK2. (Only StartImage() will fail, and instead, the newly > > added entrypoint needs to be invoked) > > > > Signed-off-by: Ard Biesheuvel <ardb@kernel.org> > > --- > > arch/x86/boot/compressed/head_64.S | 61 +++++++++++++++++++- > > 1 file changed, 59 insertions(+), 2 deletions(-) > > > > diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S > > index a4f5561c1c0e..7baaf9c97f5a 100644 > > --- a/arch/x86/boot/compressed/head_64.S > > +++ b/arch/x86/boot/compressed/head_64.S > > @@ -207,8 +207,8 @@ SYM_FUNC_START(startup_32) > > cmp $0, %edi > > jz 1f > > leal efi64_stub_entry(%ebp), %eax > > - movl %esi, %edx > > movl efi32_boot_args+4(%ebp), %esi > > + movl efi32_boot_args+8(%ebp), %edx // saved bootparams pointer > > 1: > > #endif > > pushl %eax > > @@ -233,6 +233,8 @@ SYM_FUNC_START(efi32_stub_entry) > > 1: pop %ebp > > subl $1b, %ebp > > > > + movl %esi, efi32_boot_args+8(%ebp) > > +2: > > I think it would be easier to read if this were turned into a proper > SYM_INNER_LABEL. You could then also just put efi32_pe_entry into the > .text section instead of moving it to the end of .head.text with > .subsection. Another option is to use a separate flag in .data to > indicate that we entered via efi32_pe_entry, then you could just jump > to efi32_stub_entry. > Indeed. > > movl %ecx, efi32_boot_args(%ebp) > > movl %edx, efi32_boot_args+4(%ebp) > > movb $0, efi_is64(%ebp) > > @@ -249,6 +251,49 @@ SYM_FUNC_START(efi32_stub_entry) > > > > jmp startup_32 > > SYM_FUNC_END(efi32_stub_entry) > > + > > +#define ST32_boottime 60 // offsetof(efi_system_table_32_t, boottime) > > +#define BS32_handle_protocol 88 // offsetof(efi_boot_services_32_t, handle_protocol) > > +#define LI32_image_base 32 // offsetof(efi_loaded_image_32_t, image_base) > > + > > + .subsection 1 > > + .code32 > > +SYM_FUNC_START(efi32_pe_entry) > > + pushl %ebp > > + > > + call 3f > > +3: pop %ebp > > + subl $3b, %ebp > > + > > + /* Get the loaded image protocol pointer from the image handle */ > > + subl $12, %esp // space for the loaded image pointer > > + pushl %esp // pass its address > > + leal 5f(%ebp), %eax > > + pushl %eax // pass the GUID address > > + pushl 28(%esp) // pass the image handle > > + > > + movl 36(%esp), %eax // sys_table > > + movl ST32_boottime(%eax), %eax // sys_table->boottime > > + call *BS32_handle_protocol(%eax) // sys_table->boottime->handle_protocol > > + cmp $0, %eax > > + jnz 4f > > + > > + movl 32(%esp), %ecx // image_handle > > + movl 36(%esp), %edx // sys_table > > + movl 12(%esp), %esi // loaded_image > > + movl LI32_image_base(%esi), %esi // loaded_image->image_base > > + jmp 2b > > + > > +4: addl $24, %esp > > + popl %ebp > > + ret > > +SYM_FUNC_END(efi32_pe_entry) > > + > > + /* EFI loaded image protocol GUID */ > > +5: .long 0x5B1B31A1 > > + .word 0x9562, 0x11d2 > > + .byte 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B > > + .previous > > Any reason for this not to live in .data (or .rodata)? None other than laziness ... > > #endif > > > > .code64 > > @@ -465,11 +510,23 @@ SYM_CODE_END(startup_64) > > SYM_FUNC_START(efi64_stub_entry) > > SYM_FUNC_START_ALIAS(efi_stub_entry) > > and $~0xf, %rsp /* realign the stack */ > > +#ifdef CONFIG_EFI_MIXED > > + cmpl $0, %edx > > + jz 0f > > +#endif > > call efi_main > > movq %rax,%rsi > > movl BP_code32_start(%esi), %eax > > leaq startup_64(%rax), %rax > > jmp *%rax > > + > > +#ifdef CONFIG_EFI_MIXED > > +0: movl %edi, %ecx // MS calling convention > > + movl %esi, %edx > > + call efi_pe_entry > > +1: hlt > > + jmp 1b > > +#endif > > SYM_FUNC_END(efi64_stub_entry) > > SYM_FUNC_END_ALIAS(efi_stub_entry) > > #endif > > @@ -641,7 +698,7 @@ SYM_DATA_START_LOCAL(gdt) > > SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end) > > > > #ifdef CONFIG_EFI_MIXED > > -SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0) > > +SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0) > > SYM_DATA(efi_is64, .byte 1) > > #endif > > > > -- > > 2.17.1 > >
WARNING: multiple messages have this Message-ID (diff)
From: Ard Biesheuvel <ardb@kernel.org> To: Arvind Sankar <nivedita@alum.mit.edu> Cc: linux-efi <linux-efi@vger.kernel.org>, Alexander Graf <agraf@csgraf.de>, Daniel Kiper <daniel.kiper@oracle.com>, Matthew Garrett <mjg59@google.com>, Michael Brown <mbrown@fensystems.co.uk>, Hans de Goede <hdegoede@redhat.com>, Peter Jones <pjones@redhat.com>, Leif Lindholm <leif@nuviainc.com>, Laszlo Ersek <lersek@redhat.com>, Ingo Molnar <mingo@kernel.org>, linux-arm-kernel <linux-arm-kernel@lists.infradead.org> Subject: Re: [RFC PATCH 3/3] efi/x86: implement mixed mode boot without the handover protocol Date: Thu, 13 Feb 2020 17:42:22 +0000 [thread overview] Message-ID: <CAKv+Gu8KX4wFOx-GObTt2Z7k5v+BG=s35S-sqfrXg93xJ6mFjw@mail.gmail.com> (raw) In-Reply-To: <20200213172355.GB1400002@rani.riverdale.lan> On Thu, 13 Feb 2020 at 18:23, Arvind Sankar <nivedita@alum.mit.edu> wrote: > > On Thu, Feb 13, 2020 at 03:59:28PM +0100, Ard Biesheuvel wrote: > > Add support for booting 64-bit x86 kernels from 32-bit firmware running > > on 64-bit capable CPUs without requiring the bootloader to implement > > the EFI handover protocol, allocate the setup block etc etc, all of > > which can be done by the stub using code we have already implemented. > > > > Instead, create an ordinary EFI application entrypoint but implemented > > in 32-bit code, so that it can be invoked by 32-bit firmware, and stash > > the address of this 32-bit entrypoint in the .compat section where the > > bootloader can find it. > > > > Note that we use the setup block embedded in the binary to go through > > startup_32(), but it gets reallocated and copied in efi_pe_entry(), > > using the same code that runs when the x86 kernel is booted in EFI > > mode from native firmware. This requires the loaded image protocol to > > be installed on the kernel image's EFI handle, and point to the kernel > > image itself and not to its loader. This, in turn, requires the > > bootloader to use the LoadImage() boot services to load the 64-bit > > image from 32-bit firmware, which is in fact supported by firmware > > based on EDK2. (Only StartImage() will fail, and instead, the newly > > added entrypoint needs to be invoked) > > > > Signed-off-by: Ard Biesheuvel <ardb@kernel.org> > > --- > > arch/x86/boot/compressed/head_64.S | 61 +++++++++++++++++++- > > 1 file changed, 59 insertions(+), 2 deletions(-) > > > > diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S > > index a4f5561c1c0e..7baaf9c97f5a 100644 > > --- a/arch/x86/boot/compressed/head_64.S > > +++ b/arch/x86/boot/compressed/head_64.S > > @@ -207,8 +207,8 @@ SYM_FUNC_START(startup_32) > > cmp $0, %edi > > jz 1f > > leal efi64_stub_entry(%ebp), %eax > > - movl %esi, %edx > > movl efi32_boot_args+4(%ebp), %esi > > + movl efi32_boot_args+8(%ebp), %edx // saved bootparams pointer > > 1: > > #endif > > pushl %eax > > @@ -233,6 +233,8 @@ SYM_FUNC_START(efi32_stub_entry) > > 1: pop %ebp > > subl $1b, %ebp > > > > + movl %esi, efi32_boot_args+8(%ebp) > > +2: > > I think it would be easier to read if this were turned into a proper > SYM_INNER_LABEL. You could then also just put efi32_pe_entry into the > .text section instead of moving it to the end of .head.text with > .subsection. Another option is to use a separate flag in .data to > indicate that we entered via efi32_pe_entry, then you could just jump > to efi32_stub_entry. > Indeed. > > movl %ecx, efi32_boot_args(%ebp) > > movl %edx, efi32_boot_args+4(%ebp) > > movb $0, efi_is64(%ebp) > > @@ -249,6 +251,49 @@ SYM_FUNC_START(efi32_stub_entry) > > > > jmp startup_32 > > SYM_FUNC_END(efi32_stub_entry) > > + > > +#define ST32_boottime 60 // offsetof(efi_system_table_32_t, boottime) > > +#define BS32_handle_protocol 88 // offsetof(efi_boot_services_32_t, handle_protocol) > > +#define LI32_image_base 32 // offsetof(efi_loaded_image_32_t, image_base) > > + > > + .subsection 1 > > + .code32 > > +SYM_FUNC_START(efi32_pe_entry) > > + pushl %ebp > > + > > + call 3f > > +3: pop %ebp > > + subl $3b, %ebp > > + > > + /* Get the loaded image protocol pointer from the image handle */ > > + subl $12, %esp // space for the loaded image pointer > > + pushl %esp // pass its address > > + leal 5f(%ebp), %eax > > + pushl %eax // pass the GUID address > > + pushl 28(%esp) // pass the image handle > > + > > + movl 36(%esp), %eax // sys_table > > + movl ST32_boottime(%eax), %eax // sys_table->boottime > > + call *BS32_handle_protocol(%eax) // sys_table->boottime->handle_protocol > > + cmp $0, %eax > > + jnz 4f > > + > > + movl 32(%esp), %ecx // image_handle > > + movl 36(%esp), %edx // sys_table > > + movl 12(%esp), %esi // loaded_image > > + movl LI32_image_base(%esi), %esi // loaded_image->image_base > > + jmp 2b > > + > > +4: addl $24, %esp > > + popl %ebp > > + ret > > +SYM_FUNC_END(efi32_pe_entry) > > + > > + /* EFI loaded image protocol GUID */ > > +5: .long 0x5B1B31A1 > > + .word 0x9562, 0x11d2 > > + .byte 0x8E, 0x3F, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B > > + .previous > > Any reason for this not to live in .data (or .rodata)? None other than laziness ... > > #endif > > > > .code64 > > @@ -465,11 +510,23 @@ SYM_CODE_END(startup_64) > > SYM_FUNC_START(efi64_stub_entry) > > SYM_FUNC_START_ALIAS(efi_stub_entry) > > and $~0xf, %rsp /* realign the stack */ > > +#ifdef CONFIG_EFI_MIXED > > + cmpl $0, %edx > > + jz 0f > > +#endif > > call efi_main > > movq %rax,%rsi > > movl BP_code32_start(%esi), %eax > > leaq startup_64(%rax), %rax > > jmp *%rax > > + > > +#ifdef CONFIG_EFI_MIXED > > +0: movl %edi, %ecx // MS calling convention > > + movl %esi, %edx > > + call efi_pe_entry > > +1: hlt > > + jmp 1b > > +#endif > > SYM_FUNC_END(efi64_stub_entry) > > SYM_FUNC_END_ALIAS(efi_stub_entry) > > #endif > > @@ -641,7 +698,7 @@ SYM_DATA_START_LOCAL(gdt) > > SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end) > > > > #ifdef CONFIG_EFI_MIXED > > -SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0) > > +SYM_DATA_LOCAL(efi32_boot_args, .long 0, 0, 0) > > SYM_DATA(efi_is64, .byte 1) > > #endif > > > > -- > > 2.17.1 > > _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-02-13 17:42 UTC|newest] Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-02-13 14:59 [RFC PATCH 0/3] efi/x86: add support for generic EFI mixed mode boot Ard Biesheuvel 2020-02-13 14:59 ` Ard Biesheuvel 2020-02-13 14:59 ` [RFC PATCH 1/3] efi/x86: drop redundant .bss section Ard Biesheuvel 2020-02-13 14:59 ` Ard Biesheuvel 2020-02-13 14:59 ` [RFC PATCH 2/3] efi/x86: add true mixed mode entry point into .compat section Ard Biesheuvel 2020-02-13 14:59 ` Ard Biesheuvel 2020-02-13 16:59 ` Arvind Sankar 2020-02-13 16:59 ` Arvind Sankar 2020-02-13 17:13 ` Ard Biesheuvel 2020-02-13 17:13 ` Ard Biesheuvel 2020-02-13 14:59 ` [RFC PATCH 3/3] efi/x86: implement mixed mode boot without the handover protocol Ard Biesheuvel 2020-02-13 14:59 ` Ard Biesheuvel 2020-02-13 17:23 ` Arvind Sankar 2020-02-13 17:23 ` Arvind Sankar 2020-02-13 17:42 ` Ard Biesheuvel [this message] 2020-02-13 17:42 ` Ard Biesheuvel 2020-02-13 17:53 ` [RFC PATCH 0/3] efi/x86: add support for generic EFI mixed mode boot Arvind Sankar 2020-02-13 17:53 ` Arvind Sankar 2020-02-13 17:55 ` Ard Biesheuvel 2020-02-13 17:55 ` Ard Biesheuvel 2020-02-13 18:47 ` Arvind Sankar 2020-02-13 18:47 ` Arvind Sankar 2020-02-13 22:36 ` Ard Biesheuvel 2020-02-13 22:36 ` Ard Biesheuvel 2020-02-14 0:10 ` Arvind Sankar 2020-02-14 0:10 ` Arvind Sankar 2020-02-14 0:12 ` Arvind Sankar 2020-02-14 0:12 ` Arvind Sankar 2020-02-14 0:21 ` Ard Biesheuvel 2020-02-14 0:21 ` Ard Biesheuvel 2020-02-14 0:38 ` Arvind Sankar 2020-02-14 0:38 ` Arvind Sankar
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='CAKv+Gu8KX4wFOx-GObTt2Z7k5v+BG=s35S-sqfrXg93xJ6mFjw@mail.gmail.com' \ --to=ardb@kernel.org \ --cc=agraf@csgraf.de \ --cc=daniel.kiper@oracle.com \ --cc=hdegoede@redhat.com \ --cc=leif@nuviainc.com \ --cc=lersek@redhat.com \ --cc=linux-arm-kernel@lists.infradead.org \ --cc=linux-efi@vger.kernel.org \ --cc=mbrown@fensystems.co.uk \ --cc=mingo@kernel.org \ --cc=mjg59@google.com \ --cc=nivedita@alum.mit.edu \ --cc=pjones@redhat.com \ /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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.