mbox series

[v2,0/7] x86/efi/mixed: Decouple from legacy decompressor

Message ID 20250210174941.3251435-9-ardb+git@google.com
Headers show
Series x86/efi/mixed: Decouple from legacy decompressor | expand

Message

Ard Biesheuvel Feb. 10, 2025, 5:49 p.m. UTC
From: Ard Biesheuvel <ardb@kernel.org>

Since commit

  a1b87d54f4e4 ("x86/efistub: Avoid legacy decompressor when doing EFI boot")

booting via the EFI stub no longer relies on the legacy decompressor,
and instead, the kernel proper is decompressed by code executing in the
context of the EFI boot services, and subsequently invoked directly.

The only remaining dependency is the EFI mixed mode startup code, which
makes a detour via the legacy decompressor's 32-bit entrypoint, in order
to obtain a 1:1 mapping of memory, which is a prerequisite for 64-bit
execution on x86.

This detour requires some fiddly setup on the part of the mixed mode
startup code, which has to stash the firmware stack pointer and boot
arguments in memory, and create a fake struct boot_params to trick the
code in startup_32 to behave as intended.

This dependency also impedes reuse of the EFI stub code in other
contexts, such as generic EFI zboot, which will reuse the EFI stub but
not the legacy decompressor.

So remove this dependency, by replacing this detour with a minimal
reimplementation of the 1:1 mapping code. With some further cleanup
applied on top, the line count drops substantially, but without loss of
functionality. The resulting code can operate independently from the
legacy decompressor, and is therefore moved out of arch/x86/boot/ and
into the EFI libstub/ directory.

Changes since v1 [0]:
- Create new long mode GDT that extends the firmware's 32-bit only GDT
  so that preserving/restoring data segment selectors or swapping out
  GDTs and IDTs is no longer needed at all.
- Rebase onto v6.14-rc1

[0] https://lore.kernel.org/all/20250108182218.1453754-8-ardb+git@google.com/

Ard Biesheuvel (7):
  x86/efistub: Merge PE and handover entrypoints
  x86/efi/mixed: Check CPU compatibility without relying on verify_cpu()
  x86/efi/mixed: Factor out and clean up long mode entry
  x86/efi/mixed: Set up 1:1 mapping of lower 4GiB in the stub
  x86/efi/mixed: Remove dependency on legacy startup_32 code
  x86/efi/mixed: Simplify and document thunking logic
  x86/efi/mixed: Move mixed mode startup code into libstub

 arch/x86/boot/compressed/Makefile        |   1 -
 arch/x86/boot/compressed/efi_mixed.S     | 341 --------------------
 arch/x86/boot/compressed/head_64.S       |   7 -
 drivers/firmware/efi/libstub/Makefile    |   3 +
 drivers/firmware/efi/libstub/x86-mixed.S | 253 +++++++++++++++
 drivers/firmware/efi/libstub/x86-stub.c  |  52 +--
 6 files changed, 285 insertions(+), 372 deletions(-)
 delete mode 100644 arch/x86/boot/compressed/efi_mixed.S
 create mode 100644 drivers/firmware/efi/libstub/x86-mixed.S

Comments

Ard Biesheuvel Feb. 20, 2025, 11:29 a.m. UTC | #1
On Mon, 10 Feb 2025 at 18:50, Ard Biesheuvel <ardb+git@google.com> wrote:
>
> From: Ard Biesheuvel <ardb@kernel.org>
>
> Since commit
>
>   a1b87d54f4e4 ("x86/efistub: Avoid legacy decompressor when doing EFI boot")
>
> booting via the EFI stub no longer relies on the legacy decompressor,
> and instead, the kernel proper is decompressed by code executing in the
> context of the EFI boot services, and subsequently invoked directly.
>
> The only remaining dependency is the EFI mixed mode startup code, which
> makes a detour via the legacy decompressor's 32-bit entrypoint, in order
> to obtain a 1:1 mapping of memory, which is a prerequisite for 64-bit
> execution on x86.
>
> This detour requires some fiddly setup on the part of the mixed mode
> startup code, which has to stash the firmware stack pointer and boot
> arguments in memory, and create a fake struct boot_params to trick the
> code in startup_32 to behave as intended.
>
> This dependency also impedes reuse of the EFI stub code in other
> contexts, such as generic EFI zboot, which will reuse the EFI stub but
> not the legacy decompressor.
>
> So remove this dependency, by replacing this detour with a minimal
> reimplementation of the 1:1 mapping code. With some further cleanup
> applied on top, the line count drops substantially, but without loss of
> functionality. The resulting code can operate independently from the
> legacy decompressor, and is therefore moved out of arch/x86/boot/ and
> into the EFI libstub/ directory.
>
> Changes since v1 [0]:
> - Create new long mode GDT that extends the firmware's 32-bit only GDT
>   so that preserving/restoring data segment selectors or swapping out
>   GDTs and IDTs is no longer needed at all.
> - Rebase onto v6.14-rc1
>
> [0] https://lore.kernel.org/all/20250108182218.1453754-8-ardb+git@google.com/
>
> Ard Biesheuvel (7):
>   x86/efistub: Merge PE and handover entrypoints
>   x86/efi/mixed: Check CPU compatibility without relying on verify_cpu()
>   x86/efi/mixed: Factor out and clean up long mode entry
>   x86/efi/mixed: Set up 1:1 mapping of lower 4GiB in the stub
>   x86/efi/mixed: Remove dependency on legacy startup_32 code
>   x86/efi/mixed: Simplify and document thunking logic
>   x86/efi/mixed: Move mixed mode startup code into libstub
>

Unless anyone minds, I'd like to queue this up in the EFI tree.

Boris, Ingo?
Borislav Petkov Feb. 20, 2025, 12:48 p.m. UTC | #2
On Thu, Feb 20, 2025 at 12:29:30PM +0100, Ard Biesheuvel wrote:
> Unless anyone minds, I'd like to queue this up in the EFI tree.
> 
> Boris, Ingo?

FWIW, it looks like a nice cleanup to me and it boots in my 64-bit OVMF guest
but that doesn't mean a whole lot.

Thx.
Ard Biesheuvel Feb. 20, 2025, 12:54 p.m. UTC | #3
On Thu, 20 Feb 2025 at 13:48, Borislav Petkov <bp@alien8.de> wrote:
>
> On Thu, Feb 20, 2025 at 12:29:30PM +0100, Ard Biesheuvel wrote:
> > Unless anyone minds, I'd like to queue this up in the EFI tree.
> >
> > Boris, Ingo?
>
> FWIW, it looks like a nice cleanup to me and it boots in my 64-bit OVMF guest
> but that doesn't mean a whole lot.
>

Thanks. For the record, I tested this both on 32-bit OVMF and on a
mixed mode tablet (with 32-bit AMI firmware) that I keep for testing
purposes. Notably, 32-bit OVMF boots with paging (and PAE) enabled
whereas the AMI firmware doesn't.

Not sure how many users of mixed mode remain and how invested they are
in upgrading to newer kernels, but decoupling it from the legacy
decompressor does help the cleanup work I am doing in that area.
Hans de Goede Feb. 20, 2025, 1:38 p.m. UTC | #4
Hi Ard,

On 20-Feb-25 1:54 PM, Ard Biesheuvel wrote:
> On Thu, 20 Feb 2025 at 13:48, Borislav Petkov <bp@alien8.de> wrote:
>>
>> On Thu, Feb 20, 2025 at 12:29:30PM +0100, Ard Biesheuvel wrote:
>>> Unless anyone minds, I'd like to queue this up in the EFI tree.
>>>
>>> Boris, Ingo?
>>
>> FWIW, it looks like a nice cleanup to me and it boots in my 64-bit OVMF guest
>> but that doesn't mean a whole lot.
>>
> 
> Thanks. For the record, I tested this both on 32-bit OVMF and on a
> mixed mode tablet (with 32-bit AMI firmware) that I keep for testing
> purposes. Notably, 32-bit OVMF boots with paging (and PAE) enabled
> whereas the AMI firmware doesn't.

Ah good to know that you're still using the mixed-mode tablet
for testing.

I've just added this series to my personal kernel testing-tree which
I regularly boot on various models of these kinda tablets. I'll let
you know if I hit any problems.

> Not sure how many users of mixed mode remain

I think the 32 bit mixed-mode Intel Bay Trail tablets are still
somewhat popular I still get occasional inquiries about when we will
finally have the cameras working on them :)

Regards,

Hans
Ingo Molnar Feb. 21, 2025, 3:42 p.m. UTC | #5
* Ard Biesheuvel <ardb@kernel.org> wrote:

> On Mon, 10 Feb 2025 at 18:50, Ard Biesheuvel <ardb+git@google.com> wrote:
> >
> > From: Ard Biesheuvel <ardb@kernel.org>
> >
> > Since commit
> >
> >   a1b87d54f4e4 ("x86/efistub: Avoid legacy decompressor when doing EFI boot")
> >
> > booting via the EFI stub no longer relies on the legacy decompressor,
> > and instead, the kernel proper is decompressed by code executing in the
> > context of the EFI boot services, and subsequently invoked directly.
> >
> > The only remaining dependency is the EFI mixed mode startup code, which
> > makes a detour via the legacy decompressor's 32-bit entrypoint, in order
> > to obtain a 1:1 mapping of memory, which is a prerequisite for 64-bit
> > execution on x86.
> >
> > This detour requires some fiddly setup on the part of the mixed mode
> > startup code, which has to stash the firmware stack pointer and boot
> > arguments in memory, and create a fake struct boot_params to trick the
> > code in startup_32 to behave as intended.
> >
> > This dependency also impedes reuse of the EFI stub code in other
> > contexts, such as generic EFI zboot, which will reuse the EFI stub but
> > not the legacy decompressor.
> >
> > So remove this dependency, by replacing this detour with a minimal
> > reimplementation of the 1:1 mapping code. With some further cleanup
> > applied on top, the line count drops substantially, but without loss of
> > functionality. The resulting code can operate independently from the
> > legacy decompressor, and is therefore moved out of arch/x86/boot/ and
> > into the EFI libstub/ directory.
> >
> > Changes since v1 [0]:
> > - Create new long mode GDT that extends the firmware's 32-bit only GDT
> >   so that preserving/restoring data segment selectors or swapping out
> >   GDTs and IDTs is no longer needed at all.
> > - Rebase onto v6.14-rc1
> >
> > [0] https://lore.kernel.org/all/20250108182218.1453754-8-ardb+git@google.com/
> >
> > Ard Biesheuvel (7):
> >   x86/efistub: Merge PE and handover entrypoints
> >   x86/efi/mixed: Check CPU compatibility without relying on verify_cpu()
> >   x86/efi/mixed: Factor out and clean up long mode entry
> >   x86/efi/mixed: Set up 1:1 mapping of lower 4GiB in the stub
> >   x86/efi/mixed: Remove dependency on legacy startup_32 code
> >   x86/efi/mixed: Simplify and document thunking logic
> >   x86/efi/mixed: Move mixed mode startup code into libstub
> >
> 
> Unless anyone minds, I'd like to queue this up in the EFI tree.
> 
> Boris, Ingo?

Sure!

Acked-by: Ingo Molnar <mingo@kernel.org>

Thanks,

	Ingo
Ard Biesheuvel Feb. 27, 2025, 10:57 a.m. UTC | #6
On Thu, 20 Feb 2025 at 14:38, Hans de Goede <hdegoede@redhat.com> wrote:
>
> Hi Ard,
>
> On 20-Feb-25 1:54 PM, Ard Biesheuvel wrote:
> > On Thu, 20 Feb 2025 at 13:48, Borislav Petkov <bp@alien8.de> wrote:
> >>
> >> On Thu, Feb 20, 2025 at 12:29:30PM +0100, Ard Biesheuvel wrote:
> >>> Unless anyone minds, I'd like to queue this up in the EFI tree.
> >>>
> >>> Boris, Ingo?
> >>
> >> FWIW, it looks like a nice cleanup to me and it boots in my 64-bit OVMF guest
> >> but that doesn't mean a whole lot.
> >>
> >
> > Thanks. For the record, I tested this both on 32-bit OVMF and on a
> > mixed mode tablet (with 32-bit AMI firmware) that I keep for testing
> > purposes. Notably, 32-bit OVMF boots with paging (and PAE) enabled
> > whereas the AMI firmware doesn't.
>
> Ah good to know that you're still using the mixed-mode tablet
> for testing.
>

Yes, thanks again for sending me that thing - it has been quite
useful. I bricked my mixed mode iMac24, but that thing is just too old
now anyway.

> I've just added this series to my personal kernel testing-tree which
> I regularly boot on various models of these kinda tablets. I'll let
> you know if I hit any problems.
>

Thanks. These changes are in -next now, so that give some more
coverage until the next merge window.