We cannot proceed booting if the machine doesn't support the paging mode kernel was compiled for.
Getting error the usual way -- via validate_cpu() -- is not going to work. We need to enable appropriate paging mode before that, otherwise kernel would triple-fault during KASLR setup.
This code will go away once we get support for boot-time switching between paging modes.
Signed-off-by: Kirill A. Shutemov kirill.shutemov@linux.intel.com Cc: stable@vger.kernel.org [4.14+] --- arch/x86/boot/compressed/misc.c | 16 ++++++++++++++++ arch/x86/boot/compressed/pgtable_64.c | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index b50c42455e25..f7f8d9f76e15 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c @@ -169,6 +169,16 @@ void __puthex(unsigned long value) } }
+static int l5_supported(void) +{ + /* Check if leaf 7 is supported. */ + if (native_cpuid_eax(0) < 7) + return 0; + + /* Check if la57 is supported. */ + return native_cpuid_ecx(7) & (1 << (X86_FEATURE_LA57 & 31)); +} + #if CONFIG_X86_NEED_RELOCS static void handle_relocations(void *output, unsigned long output_len, unsigned long virt_addr) @@ -362,6 +372,12 @@ asmlinkage __visible void *extract_kernel(void *rmode, memptr heap, console_init(); debug_putstr("early console in extract_kernel\n");
+ if (IS_ENABLED(CONFIG_X86_5LEVEL) && !l5_supported()) { + error("This linux kernel as configured requires 5-level paging\n" + "This CPU does not support the required 'cr4.la57' feature\n" + "Unable to boot - please use a kernel appropriate for your CPU\n"); + } + free_mem_ptr = heap; /* Heap */ free_mem_end_ptr = heap + BOOT_HEAP_SIZE;
diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c index eed3a2c3b577..7bcf03b376da 100644 --- a/arch/x86/boot/compressed/pgtable_64.c +++ b/arch/x86/boot/compressed/pgtable_64.c @@ -2,7 +2,7 @@
int l5_paging_required(void) { - /* Check i leaf 7 is supported. */ + /* Check if leaf 7 is supported. */ if (native_cpuid_eax(0) < 7) return 0;