Merge tag 'x86_seves_fixes_for_v5.10_rc1' of git://git.kernel.org/pub/scm/linux/kerne...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 24 Oct 2020 18:49:32 +0000 (11:49 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 24 Oct 2020 18:49:32 +0000 (11:49 -0700)
Pull x86 SEV-ES fixes from Borislav Petkov:
 "Three fixes to SEV-ES to correct setting up the new early pagetable on
  5-level paging machines, to always map boot_params and the kernel
  cmdline, and disable stack protector for ../compressed/head{32,64}.c.
  (Arvind Sankar)"

* tag 'x86_seves_fixes_for_v5.10_rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/boot/64: Explicitly map boot_params and command line
  x86/head/64: Disable stack protection for head$(BITS).o
  x86/boot/64: Initialize 5-level paging variables earlier

arch/x86/boot/compressed/head_64.S
arch/x86/boot/compressed/ident_map_64.c
arch/x86/boot/compressed/kaslr.c
arch/x86/boot/compressed/pgtable_64.c
arch/x86/kernel/Makefile

index 1c80f17..017de6c 100644 (file)
@@ -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
 
index 063a60e..a5e5db6 100644 (file)
 #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);
 }
 
index b59547c..b92fffb 100644 (file)
@@ -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))
index 7d0394f..5def167 100644 (file)
@@ -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
 }
index 04ceea8..68608bd 100644 (file)
@@ -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