diff options
Diffstat (limited to 'user/grub/0009-linux-mixed-mode.patch')
-rw-r--r-- | user/grub/0009-linux-mixed-mode.patch | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/user/grub/0009-linux-mixed-mode.patch b/user/grub/0009-linux-mixed-mode.patch new file mode 100644 index 000000000..d3b2135f2 --- /dev/null +++ b/user/grub/0009-linux-mixed-mode.patch @@ -0,0 +1,79 @@ +From 1f5b180742ff2706bc3a696d115ddbc677ec75b9 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel <ardb@kernel.org> +Date: Mon, 7 Aug 2023 14:21:51 +0200 +Subject: loader/efi/linux: Implement x86 mixed mode using legacy boot + +Recent mixed-mode Linux kernels, i.e., v4.0 or newer, can access EFI +runtime services at OS runtime even when the OS was not entered via the +EFI stub. This is because, instead of reverting back to the firmware's +segment selectors, GDTs and IDTs, the 64-bit kernel simply calls 32-bit +runtime services using compatibility mode, i.e., the same mode used for +32-bit user space, without taking down all interrupt handling, exception +handling, etc. + +This means that GRUB's legacy x86 boot mode is sufficient to make use of +this: 32-bit i686 builds of GRUB can already boot 64-bit kernels in EFI +enlightened mode, but without going via the EFI stub, and provide all +the metadata that the OS needs to map the EFI runtime regions and call +EFI runtime services successfully. + +It does mean that GRUB should not attempt to invoke the firmware's +LoadImage()/StartImage() methods on kernel builds that it knows cannot +be started natively. So, add a check for this in the native EFI boot +path and fall back to legacy x86 mode in such cases. + +Note that in the general case, booting non-native images of the same +native word size, e.g., x64 EFI apps on arm64 firmware, might be +supported by means of emulation. So, let's only disallow images that use +a non-native word size. This will also permit booting i686 kernels on +x86_64 builds, although without access to runtime services, as this is +not supported by Linux. + +This change on top of 2.12-rc1 is sufficient to boot ordinary Linux +mixed mode builds and get full access to the EFI runtime services. + +Cc: Daniel Kiper <daniel.kiper@oracle.com> +Cc: Steve McIntyre <steve@einval.com> +Cc: Julian Andres Klode <julian.klode@canonical.com> +Signed-off-by: Ard Biesheuvel <ardb@kernel.org> +Acked-by: Dimitri John Ledkov <dimitri.ledkov@canonical.com> +Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> +--- + grub-core/loader/efi/linux.c | 3 +++ + include/grub/efi/pe32.h | 6 ++++++ + 2 files changed, 9 insertions(+) + +diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c +index ab8fb35..bfbd95a 100644 +--- a/grub-core/loader/efi/linux.c ++++ b/grub-core/loader/efi/linux.c +@@ -117,6 +117,9 @@ grub_arch_efi_linux_load_image_header (grub_file_t file, + return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header"); + } + ++ if (lh->pe_image_header.optional_header.magic != GRUB_PE32_NATIVE_MAGIC) ++ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, "non-native image not supported"); ++ + /* + * Linux kernels built for any architecture are guaranteed to support the + * LoadFile2 based initrd loading protocol if the image version is >= 1. +diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h +index 101859a..4e6e9d2 100644 +--- a/include/grub/efi/pe32.h ++++ b/include/grub/efi/pe32.h +@@ -267,6 +267,12 @@ struct grub_pe32_section_table + + #define GRUB_PE32_SIGNATURE_SIZE 4 + ++#if GRUB_TARGET_SIZEOF_VOID_P == 8 ++#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE64_MAGIC ++#else ++#define GRUB_PE32_NATIVE_MAGIC GRUB_PE32_PE32_MAGIC ++#endif ++ + struct grub_pe_image_header + { + /* This is always PE\0\0. */ +-- +cgit v1.1 + |