aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/Kconfig14
-rw-r--r--arch/x86/boot/header.S15
-rw-r--r--arch/x86/include/asm/efi.h11
-rw-r--r--arch/x86/kernel/setup.c2
-rw-r--r--arch/x86/platform/efi/efi.c2
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
1588config 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
1588config SECCOMP 1602config 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
289realmode_swtch: .word 0, 0 # default_switch, SETUPSEG 289realmode_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
155static 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
155extern struct console early_efi_console; 166extern struct console early_efi_console;
156extern void parse_efi_setup(u64 phys_addr, u32 data_len); 167extern 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())