]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.14-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Jan 2018 08:23:48 +0000 (09:23 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 20 Jan 2018 08:23:48 +0000 (09:23 +0100)
added patches:
x86-mm-encrypt-the-initrd-earlier-for-bsp-microcode-update.patch

queue-4.14/series
queue-4.14/x86-mm-encrypt-the-initrd-earlier-for-bsp-microcode-update.patch [new file with mode: 0644]

index a9c4211c6f8bdce17a1a447f31828af1c96cfa59..4030454e6e88e4440470ecdb2ba2d62c3707fea7 100644 (file)
@@ -46,3 +46,4 @@ x86-mm-use-a-struct-to-reduce-parameters-for-sme-pgd-mapping.patch
 x86-mm-centralize-pmd-flags-in-sme_encrypt_kernel.patch
 x86-mm-prepare-sme_encrypt_kernel-for-page-aligned-encryption.patch
 arm-omap3-hwmod_data-add-missing-module_offs-for-mmc3.patch
+x86-mm-encrypt-the-initrd-earlier-for-bsp-microcode-update.patch
diff --git a/queue-4.14/x86-mm-encrypt-the-initrd-earlier-for-bsp-microcode-update.patch b/queue-4.14/x86-mm-encrypt-the-initrd-earlier-for-bsp-microcode-update.patch
new file mode 100644 (file)
index 0000000..ce001a6
--- /dev/null
@@ -0,0 +1,332 @@
+From 107cd2532181b96c549e8f224cdcca8631c3076b Mon Sep 17 00:00:00 2001
+From: Tom Lendacky <thomas.lendacky@amd.com>
+Date: Wed, 10 Jan 2018 13:26:34 -0600
+Subject: x86/mm: Encrypt the initrd earlier for BSP microcode update
+
+From: Tom Lendacky <thomas.lendacky@amd.com>
+
+commit 107cd2532181b96c549e8f224cdcca8631c3076b upstream.
+
+Currently the BSP microcode update code examines the initrd very early
+in the boot process.  If SME is active, the initrd is treated as being
+encrypted but it has not been encrypted (in place) yet.  Update the
+early boot code that encrypts the kernel to also encrypt the initrd so
+that early BSP microcode updates work.
+
+Tested-by: Gabriel Craciunescu <nix.or.die@gmail.com>
+Signed-off-by: Tom Lendacky <thomas.lendacky@amd.com>
+Reviewed-by: Borislav Petkov <bp@suse.de>
+Cc: Borislav Petkov <bp@alien8.de>
+Cc: Brijesh Singh <brijesh.singh@amd.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+Link: http://lkml.kernel.org/r/20180110192634.6026.10452.stgit@tlendack-t1.amdoffice.net
+Signed-off-by: Ingo Molnar <mingo@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ arch/x86/include/asm/mem_encrypt.h |    4 +-
+ arch/x86/kernel/head64.c           |    4 +-
+ arch/x86/kernel/setup.c            |    8 ----
+ arch/x86/mm/mem_encrypt.c          |   66 ++++++++++++++++++++++++++++++++-----
+ arch/x86/mm/mem_encrypt_boot.S     |   46 ++++++++++++-------------
+ 5 files changed, 85 insertions(+), 43 deletions(-)
+
+--- a/arch/x86/include/asm/mem_encrypt.h
++++ b/arch/x86/include/asm/mem_encrypt.h
+@@ -39,7 +39,7 @@ void __init sme_unmap_bootdata(char *rea
+ void __init sme_early_init(void);
+-void __init sme_encrypt_kernel(void);
++void __init sme_encrypt_kernel(struct boot_params *bp);
+ void __init sme_enable(struct boot_params *bp);
+ /* Architecture __weak replacement functions */
+@@ -61,7 +61,7 @@ static inline void __init sme_unmap_boot
+ static inline void __init sme_early_init(void) { }
+-static inline void __init sme_encrypt_kernel(void) { }
++static inline void __init sme_encrypt_kernel(struct boot_params *bp) { }
+ static inline void __init sme_enable(struct boot_params *bp) { }
+ #endif        /* CONFIG_AMD_MEM_ENCRYPT */
+--- a/arch/x86/kernel/head64.c
++++ b/arch/x86/kernel/head64.c
+@@ -157,8 +157,8 @@ unsigned long __head __startup_64(unsign
+       p = fixup_pointer(&phys_base, physaddr);
+       *p += load_delta - sme_get_me_mask();
+-      /* Encrypt the kernel (if SME is active) */
+-      sme_encrypt_kernel();
++      /* Encrypt the kernel and related (if SME is active) */
++      sme_encrypt_kernel(bp);
+       /*
+        * Return the SME encryption mask (if SME is active) to be used as a
+--- a/arch/x86/kernel/setup.c
++++ b/arch/x86/kernel/setup.c
+@@ -376,14 +376,6 @@ static void __init reserve_initrd(void)
+           !ramdisk_image || !ramdisk_size)
+               return;         /* No initrd provided by bootloader */
+-      /*
+-       * If SME is active, this memory will be marked encrypted by the
+-       * kernel when it is accessed (including relocation). However, the
+-       * ramdisk image was loaded decrypted by the bootloader, so make
+-       * sure that it is encrypted before accessing it.
+-       */
+-      sme_early_encrypt(ramdisk_image, ramdisk_end - ramdisk_image);
+-
+       initrd_start = 0;
+       mapped_size = memblock_mem_size(max_pfn_mapped);
+--- a/arch/x86/mm/mem_encrypt.c
++++ b/arch/x86/mm/mem_encrypt.c
+@@ -487,11 +487,12 @@ static unsigned long __init sme_pgtable_
+       return total;
+ }
+-void __init sme_encrypt_kernel(void)
++void __init sme_encrypt_kernel(struct boot_params *bp)
+ {
+       unsigned long workarea_start, workarea_end, workarea_len;
+       unsigned long execute_start, execute_end, execute_len;
+       unsigned long kernel_start, kernel_end, kernel_len;
++      unsigned long initrd_start, initrd_end, initrd_len;
+       struct sme_populate_pgd_data ppd;
+       unsigned long pgtable_area_len;
+       unsigned long decrypted_base;
+@@ -500,14 +501,15 @@ void __init sme_encrypt_kernel(void)
+               return;
+       /*
+-       * Prepare for encrypting the kernel by building new pagetables with
+-       * the necessary attributes needed to encrypt the kernel in place.
++       * Prepare for encrypting the kernel and initrd by building new
++       * pagetables with the necessary attributes needed to encrypt the
++       * kernel in place.
+        *
+        *   One range of virtual addresses will map the memory occupied
+-       *   by the kernel as encrypted.
++       *   by the kernel and initrd as encrypted.
+        *
+        *   Another range of virtual addresses will map the memory occupied
+-       *   by the kernel as decrypted and write-protected.
++       *   by the kernel and initrd as decrypted and write-protected.
+        *
+        *     The use of write-protect attribute will prevent any of the
+        *     memory from being cached.
+@@ -518,6 +520,20 @@ void __init sme_encrypt_kernel(void)
+       kernel_end = ALIGN(__pa_symbol(_end), PMD_PAGE_SIZE);
+       kernel_len = kernel_end - kernel_start;
++      initrd_start = 0;
++      initrd_end = 0;
++      initrd_len = 0;
++#ifdef CONFIG_BLK_DEV_INITRD
++      initrd_len = (unsigned long)bp->hdr.ramdisk_size |
++                   ((unsigned long)bp->ext_ramdisk_size << 32);
++      if (initrd_len) {
++              initrd_start = (unsigned long)bp->hdr.ramdisk_image |
++                             ((unsigned long)bp->ext_ramdisk_image << 32);
++              initrd_end = PAGE_ALIGN(initrd_start + initrd_len);
++              initrd_len = initrd_end - initrd_start;
++      }
++#endif
++
+       /* Set the encryption workarea to be immediately after the kernel */
+       workarea_start = kernel_end;
+@@ -540,6 +556,8 @@ void __init sme_encrypt_kernel(void)
+        */
+       pgtable_area_len = sizeof(pgd_t) * PTRS_PER_PGD;
+       pgtable_area_len += sme_pgtable_calc(execute_end - kernel_start) * 2;
++      if (initrd_len)
++              pgtable_area_len += sme_pgtable_calc(initrd_len) * 2;
+       /* PUDs and PMDs needed in the current pagetables for the workarea */
+       pgtable_area_len += sme_pgtable_calc(execute_len + pgtable_area_len);
+@@ -578,9 +596,9 @@ void __init sme_encrypt_kernel(void)
+       /*
+        * A new pagetable structure is being built to allow for the kernel
+-       * to be encrypted. It starts with an empty PGD that will then be
+-       * populated with new PUDs and PMDs as the encrypted and decrypted
+-       * kernel mappings are created.
++       * and initrd to be encrypted. It starts with an empty PGD that will
++       * then be populated with new PUDs and PMDs as the encrypted and
++       * decrypted kernel mappings are created.
+        */
+       ppd.pgd = ppd.pgtable_area;
+       memset(ppd.pgd, 0, sizeof(pgd_t) * PTRS_PER_PGD);
+@@ -593,6 +611,12 @@ void __init sme_encrypt_kernel(void)
+        * the base of the mapping.
+        */
+       decrypted_base = (pgd_index(workarea_end) + 1) & (PTRS_PER_PGD - 1);
++      if (initrd_len) {
++              unsigned long check_base;
++
++              check_base = (pgd_index(initrd_end) + 1) & (PTRS_PER_PGD - 1);
++              decrypted_base = max(decrypted_base, check_base);
++      }
+       decrypted_base <<= PGDIR_SHIFT;
+       /* Add encrypted kernel (identity) mappings */
+@@ -607,6 +631,21 @@ void __init sme_encrypt_kernel(void)
+       ppd.vaddr_end = kernel_end + decrypted_base;
+       sme_map_range_decrypted_wp(&ppd);
++      if (initrd_len) {
++              /* Add encrypted initrd (identity) mappings */
++              ppd.paddr = initrd_start;
++              ppd.vaddr = initrd_start;
++              ppd.vaddr_end = initrd_end;
++              sme_map_range_encrypted(&ppd);
++              /*
++               * Add decrypted, write-protected initrd (non-identity) mappings
++               */
++              ppd.paddr = initrd_start;
++              ppd.vaddr = initrd_start + decrypted_base;
++              ppd.vaddr_end = initrd_end + decrypted_base;
++              sme_map_range_decrypted_wp(&ppd);
++      }
++
+       /* Add decrypted workarea mappings to both kernel mappings */
+       ppd.paddr = workarea_start;
+       ppd.vaddr = workarea_start;
+@@ -622,6 +661,11 @@ void __init sme_encrypt_kernel(void)
+       sme_encrypt_execute(kernel_start, kernel_start + decrypted_base,
+                           kernel_len, workarea_start, (unsigned long)ppd.pgd);
++      if (initrd_len)
++              sme_encrypt_execute(initrd_start, initrd_start + decrypted_base,
++                                  initrd_len, workarea_start,
++                                  (unsigned long)ppd.pgd);
++
+       /*
+        * At this point we are running encrypted.  Remove the mappings for
+        * the decrypted areas - all that is needed for this is to remove
+@@ -631,6 +675,12 @@ void __init sme_encrypt_kernel(void)
+       ppd.vaddr_end = kernel_end + decrypted_base;
+       sme_clear_pgd(&ppd);
++      if (initrd_len) {
++              ppd.vaddr = initrd_start + decrypted_base;
++              ppd.vaddr_end = initrd_end + decrypted_base;
++              sme_clear_pgd(&ppd);
++      }
++
+       ppd.vaddr = workarea_start + decrypted_base;
+       ppd.vaddr_end = workarea_end + decrypted_base;
+       sme_clear_pgd(&ppd);
+--- a/arch/x86/mm/mem_encrypt_boot.S
++++ b/arch/x86/mm/mem_encrypt_boot.S
+@@ -22,9 +22,9 @@ ENTRY(sme_encrypt_execute)
+       /*
+        * Entry parameters:
+-       *   RDI - virtual address for the encrypted kernel mapping
+-       *   RSI - virtual address for the decrypted kernel mapping
+-       *   RDX - length of kernel
++       *   RDI - virtual address for the encrypted mapping
++       *   RSI - virtual address for the decrypted mapping
++       *   RDX - length to encrypt
+        *   RCX - virtual address of the encryption workarea, including:
+        *     - stack page (PAGE_SIZE)
+        *     - encryption routine page (PAGE_SIZE)
+@@ -41,9 +41,9 @@ ENTRY(sme_encrypt_execute)
+       addq    $PAGE_SIZE, %rax        /* Workarea encryption routine */
+       push    %r12
+-      movq    %rdi, %r10              /* Encrypted kernel */
+-      movq    %rsi, %r11              /* Decrypted kernel */
+-      movq    %rdx, %r12              /* Kernel length */
++      movq    %rdi, %r10              /* Encrypted area */
++      movq    %rsi, %r11              /* Decrypted area */
++      movq    %rdx, %r12              /* Area length */
+       /* Copy encryption routine into the workarea */
+       movq    %rax, %rdi                              /* Workarea encryption routine */
+@@ -52,10 +52,10 @@ ENTRY(sme_encrypt_execute)
+       rep     movsb
+       /* Setup registers for call */
+-      movq    %r10, %rdi              /* Encrypted kernel */
+-      movq    %r11, %rsi              /* Decrypted kernel */
++      movq    %r10, %rdi              /* Encrypted area */
++      movq    %r11, %rsi              /* Decrypted area */
+       movq    %r8, %rdx               /* Pagetables used for encryption */
+-      movq    %r12, %rcx              /* Kernel length */
++      movq    %r12, %rcx              /* Area length */
+       movq    %rax, %r8               /* Workarea encryption routine */
+       addq    $PAGE_SIZE, %r8         /* Workarea intermediate copy buffer */
+@@ -71,7 +71,7 @@ ENDPROC(sme_encrypt_execute)
+ ENTRY(__enc_copy)
+ /*
+- * Routine used to encrypt kernel.
++ * Routine used to encrypt memory in place.
+  *   This routine must be run outside of the kernel proper since
+  *   the kernel will be encrypted during the process. So this
+  *   routine is defined here and then copied to an area outside
+@@ -79,19 +79,19 @@ ENTRY(__enc_copy)
+  *   during execution.
+  *
+  *   On entry the registers must be:
+- *     RDI - virtual address for the encrypted kernel mapping
+- *     RSI - virtual address for the decrypted kernel mapping
++ *     RDI - virtual address for the encrypted mapping
++ *     RSI - virtual address for the decrypted mapping
+  *     RDX - address of the pagetables to use for encryption
+- *     RCX - length of kernel
++ *     RCX - length of area
+  *      R8 - intermediate copy buffer
+  *
+  *     RAX - points to this routine
+  *
+- * The kernel will be encrypted by copying from the non-encrypted
+- * kernel space to an intermediate buffer and then copying from the
+- * intermediate buffer back to the encrypted kernel space. The physical
+- * addresses of the two kernel space mappings are the same which
+- * results in the kernel being encrypted "in place".
++ * The area will be encrypted by copying from the non-encrypted
++ * memory space to an intermediate buffer and then copying from the
++ * intermediate buffer back to the encrypted memory space. The physical
++ * addresses of the two mappings are the same which results in the area
++ * being encrypted "in place".
+  */
+       /* Enable the new page tables */
+       mov     %rdx, %cr3
+@@ -106,9 +106,9 @@ ENTRY(__enc_copy)
+       push    %r15
+       push    %r12
+-      movq    %rcx, %r9               /* Save kernel length */
+-      movq    %rdi, %r10              /* Save encrypted kernel address */
+-      movq    %rsi, %r11              /* Save decrypted kernel address */
++      movq    %rcx, %r9               /* Save area length */
++      movq    %rdi, %r10              /* Save encrypted area address */
++      movq    %rsi, %r11              /* Save decrypted area address */
+       /* Set the PAT register PA5 entry to write-protect */
+       movl    $MSR_IA32_CR_PAT, %ecx
+@@ -128,13 +128,13 @@ ENTRY(__enc_copy)
+       movq    %r9, %r12
+ 2:
+-      movq    %r11, %rsi              /* Source - decrypted kernel */
++      movq    %r11, %rsi              /* Source - decrypted area */
+       movq    %r8, %rdi               /* Dest   - intermediate copy buffer */
+       movq    %r12, %rcx
+       rep     movsb
+       movq    %r8, %rsi               /* Source - intermediate copy buffer */
+-      movq    %r10, %rdi              /* Dest   - encrypted kernel */
++      movq    %r10, %rdi              /* Dest   - encrypted area */
+       movq    %r12, %rcx
+       rep     movsb