]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - arch/x86/mm/mem_encrypt_identity.c
Merge branch 'x86-kdump-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / arch / x86 / mm / mem_encrypt_identity.c
index dddcd2a1afdb3b348bb624578b37303f26efdbd4..e2b0e2ac07bb6366a61c3f86cf3cb315ca092ccf 100644 (file)
@@ -70,6 +70,19 @@ struct sme_populate_pgd_data {
        unsigned long vaddr_end;
 };
 
+/*
+ * This work area lives in the .init.scratch section, which lives outside of
+ * the kernel proper. It is sized to hold the intermediate copy buffer and
+ * more than enough pagetable pages.
+ *
+ * By using this section, the kernel can be encrypted in place and it
+ * avoids any possibility of boot parameters or initramfs images being
+ * placed such that the in-place encryption logic overwrites them.  This
+ * section is 2MB aligned to allow for simple pagetable setup using only
+ * PMD entries (see vmlinux.lds.S).
+ */
+static char sme_workarea[2 * PMD_PAGE_SIZE] __section(.init.scratch);
+
 static char sme_cmdline_arg[] __initdata = "mem_encrypt";
 static char sme_cmdline_on[]  __initdata = "on";
 static char sme_cmdline_off[] __initdata = "off";
@@ -311,8 +324,13 @@ void __init sme_encrypt_kernel(struct boot_params *bp)
        }
 #endif
 
-       /* Set the encryption workarea to be immediately after the kernel */
-       workarea_start = kernel_end;
+       /*
+        * We're running identity mapped, so we must obtain the address to the
+        * SME encryption workarea using rip-relative addressing.
+        */
+       asm ("lea sme_workarea(%%rip), %0"
+            : "=r" (workarea_start)
+            : "p" (sme_workarea));
 
        /*
         * Calculate required number of workarea bytes needed: