Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[sfrench/cifs-2.6.git] / arch / x86 / kernel / machine_kexec_64.c
index cb0a30473c2310b76695c73ec6fad3cd1e7b051f..1f790cf9d38fe0e10e46eaf9b5bef945d25a9370 100644 (file)
@@ -87,7 +87,7 @@ static int init_transition_pgtable(struct kimage *image, pgd_t *pgd)
                set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE));
        }
        pte = pte_offset_kernel(pmd, vaddr);
-       set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC));
+       set_pte(pte, pfn_pte(paddr >> PAGE_SHIFT, PAGE_KERNEL_EXEC_NOENC));
        return 0;
 err:
        free_transition_pgtable(image);
@@ -115,6 +115,7 @@ static int init_pgtable(struct kimage *image, unsigned long start_pgtable)
                .alloc_pgt_page = alloc_pgt_page,
                .context        = image,
                .page_flag      = __PAGE_KERNEL_LARGE_EXEC,
+               .kernpg_flag    = _KERNPG_TABLE_NOENC,
        };
        unsigned long mstart, mend;
        pgd_t *level4p;
@@ -334,7 +335,8 @@ void machine_kexec(struct kimage *image)
        image->start = relocate_kernel((unsigned long)image->head,
                                       (unsigned long)page_list,
                                       image->start,
-                                      image->preserve_context);
+                                      image->preserve_context,
+                                      sme_active());
 
 #ifdef CONFIG_KEXEC_JUMP
        if (image->preserve_context)
@@ -602,3 +604,22 @@ void arch_kexec_unprotect_crashkres(void)
 {
        kexec_mark_crashkres(false);
 }
+
+int arch_kexec_post_alloc_pages(void *vaddr, unsigned int pages, gfp_t gfp)
+{
+       /*
+        * If SME is active we need to be sure that kexec pages are
+        * not encrypted because when we boot to the new kernel the
+        * pages won't be accessed encrypted (initially).
+        */
+       return set_memory_decrypted((unsigned long)vaddr, pages);
+}
+
+void arch_kexec_pre_free_pages(void *vaddr, unsigned int pages)
+{
+       /*
+        * If SME is active we need to reset the pages back to being
+        * an encrypted mapping before freeing them.
+        */
+       set_memory_encrypted((unsigned long)vaddr, pages);
+}