Skip to content

Commit cc3fdda

Browse files
ardbiesheuvelsuryasaimadhu
authored andcommitted
x86/efi: Make the deprecated EFI handover protocol optional
The EFI handover protocol permits a bootloader to invoke the kernel as a EFI PE/COFF application, while passing a bootparams struct as a third argument to the entrypoint function call. This has no basis in the UEFI specification, and there are better ways to pass additional data to a UEFI application (UEFI configuration tables, UEFI variables, UEFI protocols) than going around the StartImage() boot service and jumping to a fixed offset in the loaded image, just to call a different function that takes a third parameter. The reason for handling struct bootparams in the bootloader was that the EFI stub could only load initrd images from the EFI system partition, and so passing it via struct bootparams was needed for loaders like GRUB, which pass the initrd in memory, and may load it from anywhere, including from the network. Another motivation was EFI mixed mode, which could not use the initrd loader in the EFI stub at all due to 32/64 bit incompatibilities (which will be fixed shortly [0]), and could not invoke the ordinary PE/COFF entry point either, for the same reasons. Given that loaders such as GRUB already carried the bootparams handling in order to implement non-EFI boot, retaining that code and just passing bootparams to the EFI stub was a reasonable choice (although defining an alternate entrypoint could have been avoided.) However, the GRUB side changes never made it upstream, and are only shipped by some of the distros in their downstream versions. In the meantime, EFI support has been added to other Linux architecture ports, as well as to U-boot and systemd, including arch-agnostic methods for passing initrd images in memory [1], and for doing mixed mode boot [2], none of them requiring anything like the EFI handover protocol. So given that only out-of-tree distro GRUB relies on this, let's permit it to be omitted from the build, in preparation for retiring it completely at a later date. (Note that systemd-boot does have an implementation as well, but only uses it as a fallback for booting images that do not implement the LoadFile2 based initrd loading method, i.e., v5.8 or older) [0] https://lore.kernel.org/all/[email protected]/ [1] ec93fc3 ("efi/libstub: Add support for loading the initrd from a device path") [2] 97aa276 ("efi/x86: Add true mixed mode entry point into .compat section") Signed-off-by: Ard Biesheuvel <[email protected]> Signed-off-by: Borislav Petkov <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent 61de13d commit cc3fdda

File tree

4 files changed

+23
-2
lines changed

4 files changed

+23
-2
lines changed

arch/x86/Kconfig

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,6 +1980,23 @@ config EFI_STUB
19801980

19811981
See Documentation/admin-guide/efi-stub.rst for more information.
19821982

1983+
config EFI_HANDOVER_PROTOCOL
1984+
bool "EFI handover protocol (DEPRECATED)"
1985+
depends on EFI_STUB
1986+
default y
1987+
help
1988+
Select this in order to include support for the deprecated EFI
1989+
handover protocol, which defines alternative entry points into the
1990+
EFI stub. This is a practice that has no basis in the UEFI
1991+
specification, and requires a priori knowledge on the part of the
1992+
bootloader about Linux/x86 specific ways of passing the command line
1993+
and initrd, and where in memory those assets may be loaded.
1994+
1995+
If in doubt, say Y. Even though the corresponding support is not
1996+
present in upstream GRUB or other bootloaders, most distros build
1997+
GRUB with numerous downstream patches applied, and may rely on the
1998+
handover protocol as as result.
1999+
19832000
config EFI_MIXED
19842001
bool "EFI mixed-mode support"
19852002
depends on EFI_STUB && X86_64

arch/x86/boot/compressed/head_64.S

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ SYM_FUNC_START(startup_32)
286286
lret
287287
SYM_FUNC_END(startup_32)
288288

289-
#ifdef CONFIG_EFI_MIXED
289+
#if IS_ENABLED(CONFIG_EFI_MIXED) && IS_ENABLED(CONFIG_EFI_HANDOVER_PROTOCOL)
290290
.org 0x190
291291
SYM_FUNC_START(efi32_stub_entry)
292292
add $0x4, %esp /* Discard return address */
@@ -516,7 +516,9 @@ trampoline_return:
516516
SYM_CODE_END(startup_64)
517517

518518
#ifdef CONFIG_EFI_STUB
519+
#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
519520
.org 0x390
521+
#endif
520522
SYM_FUNC_START(efi64_stub_entry)
521523
and $~0xf, %rsp /* realign the stack */
522524
movq %rdx, %rbx /* save boot_params pointer */

arch/x86/boot/header.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ xloadflags:
406406
# define XLF1 0
407407
#endif
408408

409-
#ifdef CONFIG_EFI_STUB
409+
#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
410410
# ifdef CONFIG_EFI_MIXED
411411
# define XLF23 (XLF_EFI_HANDOVER_32|XLF_EFI_HANDOVER_64)
412412
# else

arch/x86/boot/tools/build.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ static void efi_stub_entry_update(void)
290290
{
291291
unsigned long addr = efi32_stub_entry;
292292

293+
#ifdef CONFIG_EFI_HANDOVER_PROTOCOL
293294
#ifdef CONFIG_X86_64
294295
/* Yes, this is really how we defined it :( */
295296
addr = efi64_stub_entry - 0x200;
@@ -298,6 +299,7 @@ static void efi_stub_entry_update(void)
298299
#ifdef CONFIG_EFI_MIXED
299300
if (efi32_stub_entry != addr)
300301
die("32-bit and 64-bit EFI entry points do not match\n");
302+
#endif
301303
#endif
302304
put_unaligned_le32(addr, &buf[0x264]);
303305
}

0 commit comments

Comments
 (0)