diff options
-rw-r--r-- | arch/x86/Kconfig | 14 | ||||
-rw-r--r-- | arch/x86/boot/header.S | 15 | ||||
-rw-r--r-- | arch/x86/include/asm/efi.h | 11 | ||||
-rw-r--r-- | arch/x86/kernel/setup.c | 2 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi.c | 2 |
5 files changed, 37 insertions, 7 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 0af5250d914f..8453fe1342ea 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -1585,6 +1585,20 @@ config EFI_STUB | |||
1585 | 1585 | ||
1586 | See Documentation/efi-stub.txt for more information. | 1586 | See Documentation/efi-stub.txt for more information. |
1587 | 1587 | ||
1588 | config EFI_MIXED | ||
1589 | bool "EFI mixed-mode support" | ||
1590 | depends on EFI_STUB && X86_64 | ||
1591 | ---help--- | ||
1592 | Enabling this feature allows a 64-bit kernel to be booted | ||
1593 | on a 32-bit firmware, provided that your CPU supports 64-bit | ||
1594 | mode. | ||
1595 | |||
1596 | Note that it is not possible to boot a mixed-mode enabled | ||
1597 | kernel via the EFI boot stub - a bootloader that supports | ||
1598 | the EFI handover protocol must be used. | ||
1599 | |||
1600 | If unsure, say N. | ||
1601 | |||
1588 | config SECCOMP | 1602 | config SECCOMP |
1589 | def_bool y | 1603 | def_bool y |
1590 | prompt "Enable seccomp to safely compute untrusted bytecode" | 1604 | prompt "Enable seccomp to safely compute untrusted bytecode" |
diff --git a/arch/x86/boot/header.S b/arch/x86/boot/header.S index d69d96653325..256388260c88 100644 --- a/arch/x86/boot/header.S +++ b/arch/x86/boot/header.S | |||
@@ -283,7 +283,7 @@ _start: | |||
283 | # Part 2 of the header, from the old setup.S | 283 | # Part 2 of the header, from the old setup.S |
284 | 284 | ||
285 | .ascii "HdrS" # header signature | 285 | .ascii "HdrS" # header signature |
286 | .word 0x020c # header version number (>= 0x0105) | 286 | .word 0x020d # header version number (>= 0x0105) |
287 | # or else old loadlin-1.5 will fail) | 287 | # or else old loadlin-1.5 will fail) |
288 | .globl realmode_swtch | 288 | .globl realmode_swtch |
289 | realmode_swtch: .word 0, 0 # default_switch, SETUPSEG | 289 | realmode_swtch: .word 0, 0 # default_switch, SETUPSEG |
@@ -375,7 +375,8 @@ xloadflags: | |||
375 | # define XLF0 0 | 375 | # define XLF0 0 |
376 | #endif | 376 | #endif |
377 | 377 | ||
378 | #if defined(CONFIG_RELOCATABLE) && defined(CONFIG_X86_64) | 378 | #if defined(CONFIG_RELOCATABLE) && defined(CONFIG_X86_64) && \ |
379 | !defined(CONFIG_EFI_MIXED) | ||
379 | /* kernel/boot_param/ramdisk could be loaded above 4g */ | 380 | /* kernel/boot_param/ramdisk could be loaded above 4g */ |
380 | # define XLF1 XLF_CAN_BE_LOADED_ABOVE_4G | 381 | # define XLF1 XLF_CAN_BE_LOADED_ABOVE_4G |
381 | #else | 382 | #else |
@@ -383,10 +384,14 @@ xloadflags: | |||
383 | #endif | 384 | #endif |
384 | 385 | ||
385 | #ifdef CONFIG_EFI_STUB | 386 | #ifdef CONFIG_EFI_STUB |
386 | # ifdef CONFIG_X86_64 | 387 | # ifdef CONFIG_EFI_MIXED |
387 | # define XLF23 XLF_EFI_HANDOVER_64 /* 64-bit EFI handover ok */ | 388 | # define XLF23 (XLF_EFI_HANDOVER_32|XLF_EFI_HANDOVER_64) |
388 | # else | 389 | # else |
389 | # define XLF23 XLF_EFI_HANDOVER_32 /* 32-bit EFI handover ok */ | 390 | # ifdef CONFIG_X86_64 |
391 | # define XLF23 XLF_EFI_HANDOVER_64 /* 64-bit EFI handover ok */ | ||
392 | # else | ||
393 | # define XLF23 XLF_EFI_HANDOVER_32 /* 32-bit EFI handover ok */ | ||
394 | # endif | ||
390 | # endif | 395 | # endif |
391 | #else | 396 | #else |
392 | # define XLF23 0 | 397 | # define XLF23 0 |
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 85935e6f69f3..a3837254e320 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h | |||
@@ -152,6 +152,17 @@ static inline bool efi_is_native(void) | |||
152 | return IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT); | 152 | return IS_ENABLED(CONFIG_X86_64) == efi_enabled(EFI_64BIT); |
153 | } | 153 | } |
154 | 154 | ||
155 | static inline bool efi_runtime_supported(void) | ||
156 | { | ||
157 | if (efi_is_native()) | ||
158 | return true; | ||
159 | |||
160 | if (IS_ENABLED(CONFIG_EFI_MIXED) && !efi_enabled(EFI_OLD_MEMMAP)) | ||
161 | return true; | ||
162 | |||
163 | return false; | ||
164 | } | ||
165 | |||
155 | extern struct console early_efi_console; | 166 | extern struct console early_efi_console; |
156 | extern void parse_efi_setup(u64 phys_addr, u32 data_len); | 167 | extern void parse_efi_setup(u64 phys_addr, u32 data_len); |
157 | 168 | ||
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c index 06853e670354..ff9b3a62a05c 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c | |||
@@ -1243,7 +1243,7 @@ void __init setup_arch(char **cmdline_p) | |||
1243 | * mismatched firmware/kernel archtectures since there is no | 1243 | * mismatched firmware/kernel archtectures since there is no |
1244 | * support for runtime services. | 1244 | * support for runtime services. |
1245 | */ | 1245 | */ |
1246 | if (efi_enabled(EFI_BOOT) && !efi_is_native()) { | 1246 | if (efi_enabled(EFI_BOOT) && !efi_runtime_supported()) { |
1247 | pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); | 1247 | pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); |
1248 | efi_unmap_memmap(); | 1248 | efi_unmap_memmap(); |
1249 | } | 1249 | } |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 39f5b7bba695..395decedfa2b 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -802,7 +802,7 @@ void __init efi_init(void) | |||
802 | * that doesn't match the kernel 32/64-bit mode. | 802 | * that doesn't match the kernel 32/64-bit mode. |
803 | */ | 803 | */ |
804 | 804 | ||
805 | if (!efi_is_native()) | 805 | if (!efi_runtime_supported()) |
806 | pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); | 806 | pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); |
807 | else { | 807 | else { |
808 | if (disable_runtime || efi_runtime_init()) | 808 | if (disable_runtime || efi_runtime_init()) |