linux/arch/x86/boot/compressed
Ard Biesheuvel d21f5a59ea x86/efistub: Add missing boot_params for mixed mode compat entry
The pure EFI stub entry point does not take a struct boot_params from
the boot loader, but creates it from scratch, and populates only the
fields that still have meaning in this context (command line, initrd
base and size, etc)

The original mixed mode implementation used the EFI handover protocol
instead, where the boot loader (i.e., GRUB) populates a boot_params
struct and passes it to a special Linux specific EFI entry point that
takes the boot_params pointer as its third argument.

When the new mixed mode implementation was introduced, using a special
32-bit PE entrypoint in the 64-bit kernel, it adopted the pure approach,
and relied on the EFI stub to create the struct boot_params.  This is
preferred because it makes the bootloader side much easier to implement,
as it does not need any x86-specific knowledge on how struct boot_params
and struct setup_header are put together. This mixed mode implementation
was adopted by systemd-boot version 252 and later.

When commit

  e2ab9eab32 ("x86/boot/compressed: Move 32-bit entrypoint code into .text section")

refactored this code and moved it out of head_64.S, the fact that ESI
was populated with the address of the base of the image was overlooked,
and to simplify the code flow, ESI is now zeroed and stored to memory
unconditionally in shared code, so that the NULL-ness of that variable
can still be used later to determine which mixed mode boot protocol is
in use.

With ESI pointing to the base of the image, it can serve as a struct
boot_params pointer for startup_32(), which only accesses the init_data
and kernel_alignment fields (and the scratch field as a temporary
stack). Zeroing ESI means that those accesses produce garbage now, even
though things appear to work if the first page of memory happens to be
zeroed, and the region right before LOAD_PHYSICAL_ADDR (== 16 MiB)
happens to be free.

The solution is to pass a special, temporary struct boot_params to
startup_32() via ESI, one that is sufficient for getting it to create
the page tables correctly and is discarded right after. This involves
setting a minimal alignment of 4k, only to get the statically allocated
page tables line up correctly, and setting init_size to the executable
image size (_end - startup_32). This ensures that the page tables are
covered by the static footprint of the PE image.

Given that EFI boot no longer calls the decompressor and no longer pads
the image to permit the decompressor to execute in place, the same
temporary struct boot_params should be used in the EFI handover protocol
based mixed mode implementation as well, to prevent the page tables from
being placed outside of allocated memory.

Fixes: e2ab9eab32 ("x86/boot/compressed: Move 32-bit entrypoint code into .text section")
Cc: <stable@kernel.org> # v6.1+
Closes: https://lore.kernel.org/all/20240321150510.GI8211@craftyguy.net/
Reported-by: Clayton Craft <clayton@craftyguy.net>
Tested-by: Clayton Craft <clayton@craftyguy.net>
Tested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
2024-03-26 08:45:27 +01:00
..
.gitignore
Makefile x86/efistub: Remap kernel text read-only before dropping NX attribute 2024-03-09 11:37:18 +01:00
acpi.c x86: Do not include <asm/bootparam.h> in several files 2024-01-30 15:17:24 +01:00
cmdline.c x86: Do not include <asm/bootparam.h> in several files 2024-01-30 15:17:24 +01:00
cpuflags.c
early_serial_console.c x86/boot: Put globals that are accessed early into the .data section 2022-04-20 20:10:54 +02:00
efi.c x86: Do not include <asm/bootparam.h> in several files 2024-01-30 15:17:24 +01:00
efi.h x86/setup: Move internal setup_data structures into setup_data.h 2024-01-30 15:17:12 +01:00
efi_mixed.S x86/efistub: Add missing boot_params for mixed mode compat entry 2024-03-26 08:45:27 +01:00
error.c x86/purgatory: Include header for warn() declaration 2023-08-03 16:37:18 +02:00
error.h x86/purgatory: Include header for warn() declaration 2023-08-03 16:37:18 +02:00
head_32.S x86/efistub: Avoid legacy decompressor when doing EFI boot 2023-08-07 21:07:43 +02:00
head_64.S x86/efistub: Avoid legacy decompressor when doing EFI boot 2023-08-07 21:07:43 +02:00
ident_map_64.c - Sumanth Korikkar has taught s390 to allocate hotplug-time page frames 2024-03-14 17:43:30 -07:00
idt_64.c x86/boot: Ignore NMIs during very early boot 2023-11-30 09:55:40 +01:00
idt_handlers_64.S x86/boot: Ignore NMIs during very early boot 2023-11-30 09:55:40 +01:00
kaslr.c x86/boot: Rename conflicting 'boot_params' pointer to 'boot_params_ptr' 2023-10-18 12:03:03 +02:00
kernel_info.S
mem.c arch/x86: Fix typos 2024-01-03 11:46:22 +01:00
mem_encrypt.S x86/boot/compressed: Only build mem_encrypt.S if AMD_MEM_ENCRYPT=y 2022-11-24 08:57:41 +01:00
misc.c EFI updates for v6.9: 2024-03-13 12:37:41 -07:00
misc.h x86/boot: Add a message about ignored early NMIs 2024-02-06 10:51:11 +01:00
mkpiggy.c
pgtable.h x86/decompressor: Pass pgtable address to trampoline directly 2023-08-07 20:49:26 +02:00
pgtable_64.c x86: Do not include <asm/bootparam.h> in several files 2024-01-30 15:17:24 +01:00
sev.c Merge branch 'linus' into x86/boot, to resolve conflict 2024-03-12 09:55:57 +01:00
sev.h x86/sev: Add SNP-specific unaccepted memory support 2023-06-06 18:31:37 +02:00
string.c
tdcall.S x86/boot: Port I/O: Add decompression-time support for TDX 2022-04-07 08:27:52 -07:00
tdx-shared.c x86/tdx: Add unaccepted memory support 2023-06-06 18:25:57 +02:00
tdx.c x86/tdx: Remove 'struct tdx_hypercall_args' 2023-09-12 16:30:14 -07:00
tdx.h x86/tdx: Detect TDX at early kernel decompression time 2022-04-07 08:27:51 -07:00
vmlinux.lds.S x86/boot: Increase section and file alignment to 4k/512 2023-09-17 19:48:44 +02:00