summaryrefslogtreecommitdiff
path: root/user/grub/0009-linux-mixed-mode.patch
diff options
context:
space:
mode:
Diffstat (limited to 'user/grub/0009-linux-mixed-mode.patch')
-rw-r--r--user/grub/0009-linux-mixed-mode.patch79
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
+