efi/x86: Implement mixed mode boot without the handover protocol
authorArd Biesheuvel <ardb@kernel.org>
Wed, 12 Feb 2020 22:20:54 +0000 (23:20 +0100)
committerArd Biesheuvel <ardb@kernel.org>
Sun, 23 Feb 2020 20:59:42 +0000 (21:59 +0100)
commit17054f492dfd4d91e093ebb87013807812ec42a4
tree76a0f59fe30fed885de6c1962e49d5c1e0a67340
parent3b8f44fc0810d51b58837cf7fdba3f72f8cffcdc
efi/x86: Implement mixed mode boot without the handover protocol

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 or allocate the setup block, etc etc, all of
which can be done by the stub itself, using code that already exists.

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 service 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
drivers/firmware/efi/libstub/x86-stub.c