x86/efi: Introduce EFI_BOOT_SERVICES_WARN
There may exist buggy implementations of UEFI firmaware that access the
EFI_BOOT_SERVICES_* memory regions after the call to ExitBootServices()
(e.g., when calling SetVirtualAddressMap()). This is in direct violation
of the UEFI specification.
If selected, this debug option will print a warning message if the UEFI
firmware tries to access the aforementioned memory regions. Along with
the warning, the EFI platform code will fixup the page fault so that the
firmware can proceed further.
If not selected, EFI_BOOT_SERVICES_CODE/DATA memory regions will be
mapped along with the runtime memory regions so that the buggy firmware
does not cause any page faults when trying to accessing such memory
regions. This is the approach from Matthew Garrett in commit 916f676f8dc0
("x86, efi: Retain boot service code until after switching to virtual
mode").
However, firmware developers are less likely to find and avoid such
illegal access as the kernel silently works around their bug.
Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 25d2c6f..b7c9d9e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1535,6 +1535,18 @@
If unsure, say N.
+config EFI_BOOT_SERVICES_WARN
+ bool "Warn about illegal accesses to BOOT_SERVICES memory"
+ depends on EFI
+ ---help---
+ Enable this debug feature to make the kernel issue a warning if
+ memory regions marked as EFI_BOOT_SERVICES_CODE/DATA are
+ accessed after the kernel calls ExitBootServices() on the
+ firmware. Please see the UEFI specification for details on
+ the expectations of memory usage.
+
+ If unsure, say N.
+
config SECCOMP
def_bool y
prompt "Enable seccomp to safely compute untrusted bytecode"
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index ff82bd7..dbaaa66 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -981,7 +981,7 @@
for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) {
md = p;
if (!(md->attribute & EFI_MEMORY_RUNTIME)) {
-#ifdef CONFIG_X86_64
+#if defined(CONFIG_X86_64) && !defined(CONFIG_EFI_BOOT_SERVICES_WARN)
if (md->type != EFI_BOOT_SERVICES_CODE &&
md->type != EFI_BOOT_SERVICES_DATA)
#endif