diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 1c80f1738fd9badde46226cf84a9db67eb3b01fd..017de6cc87dc6e5125f2d1ce236572ac56df1159 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S @@ -544,6 +544,9 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated) pushq %rsi call set_sev_encryption_mask call load_stage2_idt + + /* Pass boot_params to initialize_identity_maps() */ + movq (%rsp), %rdi call initialize_identity_maps popq %rsi diff --git a/arch/x86/boot/compressed/ident_map_64.c b/arch/x86/boot/compressed/ident_map_64.c index 063a60edcf9982437876766dd2db5c578393beb6..a5e5db6ada3c76c8132be74e420d77771c488e64 100644 --- a/arch/x86/boot/compressed/ident_map_64.c +++ b/arch/x86/boot/compressed/ident_map_64.c @@ -33,11 +33,11 @@ #define __PAGE_OFFSET __PAGE_OFFSET_BASE #include "../../mm/ident_map.c" -#ifdef CONFIG_X86_5LEVEL -unsigned int __pgtable_l5_enabled; -unsigned int pgdir_shift = 39; -unsigned int ptrs_per_p4d = 1; -#endif +#define _SETUP +#include <asm/setup.h> /* For COMMAND_LINE_SIZE */ +#undef _SETUP + +extern unsigned long get_cmd_line_ptr(void); /* Used by PAGE_KERN* macros: */ pteval_t __default_kernel_pte_mask __read_mostly = ~0; @@ -107,8 +107,10 @@ static void add_identity_map(unsigned long start, unsigned long end) } /* Locates and clears a region for a new top level page table. */ -void initialize_identity_maps(void) +void initialize_identity_maps(void *rmode) { + unsigned long cmdline; + /* Exclude the encryption mask from __PHYSICAL_MASK */ physical_mask &= ~sme_me_mask; @@ -149,10 +151,19 @@ void initialize_identity_maps(void) } /* - * New page-table is set up - map the kernel image and load it - * into cr3. + * New page-table is set up - map the kernel image, boot_params and the + * command line. The uncompressed kernel requires boot_params and the + * command line to be mapped in the identity mapping. Map them + * explicitly here in case the compressed kernel does not touch them, + * or does not touch all the pages covering them. */ add_identity_map((unsigned long)_head, (unsigned long)_end); + boot_params = rmode; + add_identity_map((unsigned long)boot_params, (unsigned long)(boot_params + 1)); + cmdline = get_cmd_line_ptr(); + add_identity_map(cmdline, cmdline + COMMAND_LINE_SIZE); + + /* Load the new page-table. */ write_cr3(top_level_pgt); } diff --git a/arch/x86/boot/compressed/kaslr.c b/arch/x86/boot/compressed/kaslr.c index b59547ce5b196039eea52f14838af84304c9ddb1..b92fffbe761fd5d38c86f68770bb71152c62d8c3 100644 --- a/arch/x86/boot/compressed/kaslr.c +++ b/arch/x86/boot/compressed/kaslr.c @@ -840,14 +840,6 @@ void choose_random_location(unsigned long input, return; } -#ifdef CONFIG_X86_5LEVEL - if (__read_cr4() & X86_CR4_LA57) { - __pgtable_l5_enabled = 1; - pgdir_shift = 48; - ptrs_per_p4d = 512; - } -#endif - boot_params->hdr.loadflags |= KASLR_FLAG; if (IS_ENABLED(CONFIG_X86_32)) diff --git a/arch/x86/boot/compressed/pgtable_64.c b/arch/x86/boot/compressed/pgtable_64.c index 7d0394f4ebf978cc1b0051eb6adae702231daa47..5def1674d6f1990dd9bded8c4cd1267349f002d0 100644 --- a/arch/x86/boot/compressed/pgtable_64.c +++ b/arch/x86/boot/compressed/pgtable_64.c @@ -8,6 +8,13 @@ #define BIOS_START_MIN 0x20000U /* 128K, less than this is insane */ #define BIOS_START_MAX 0x9f000U /* 640K, absolute maximum */ +#ifdef CONFIG_X86_5LEVEL +/* __pgtable_l5_enabled needs to be in .data to avoid being cleared along with .bss */ +unsigned int __section(.data) __pgtable_l5_enabled; +unsigned int __section(.data) pgdir_shift = 39; +unsigned int __section(.data) ptrs_per_p4d = 1; +#endif + struct paging_config { unsigned long trampoline_start; unsigned long l5_required; @@ -198,4 +205,13 @@ void cleanup_trampoline(void *pgtable) /* Restore trampoline memory */ memcpy(trampoline_32bit, trampoline_save, TRAMPOLINE_32BIT_SIZE); + + /* Initialize variables for 5-level paging */ +#ifdef CONFIG_X86_5LEVEL + if (__read_cr4() & X86_CR4_LA57) { + __pgtable_l5_enabled = 1; + pgdir_shift = 48; + ptrs_per_p4d = 512; + } +#endif } diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 04ceea8f4a8904a09460f846c8074589807d225b..68608bd892c0d56c6d9b257214268d0a7d519f23 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -47,6 +47,8 @@ endif # non-deterministic coverage. KCOV_INSTRUMENT := n +CFLAGS_head$(BITS).o += -fno-stack-protector + CFLAGS_irq.o := -I $(srctree)/$(src)/../include/asm/trace obj-y := process_$(BITS).o signal.o