]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - arch/x86/power/hibernate_64.c
x86/mm: Do not auto-massage page protections
[mirror_ubuntu-bionic-kernel.git] / arch / x86 / power / hibernate_64.c
index 0ef5e520496891eefe9e30269d6dd779027223fd..d42be25150ad27b1344a532d4fbecaa2347484c7 100644 (file)
@@ -51,6 +51,12 @@ static int set_up_temporary_text_mapping(pgd_t *pgd)
        pmd_t *pmd;
        pud_t *pud;
        p4d_t *p4d;
+       pgprot_t pgtable_prot = __pgprot(_KERNPG_TABLE);
+       pgprot_t pmd_text_prot = __pgprot(__PAGE_KERNEL_LARGE_EXEC);
+
+       /* Filter out unsupported __PAGE_KERNEL* bits: */
+       pgprot_val(pmd_text_prot) &= __default_kernel_pte_mask;
+       pgprot_val(pgtable_prot)  &= __default_kernel_pte_mask;
 
        /*
         * The new mapping only has to cover the page containing the image
@@ -81,15 +87,19 @@ static int set_up_temporary_text_mapping(pgd_t *pgd)
                return -ENOMEM;
 
        set_pmd(pmd + pmd_index(restore_jump_address),
-               __pmd((jump_address_phys & PMD_MASK) | __PAGE_KERNEL_LARGE_EXEC));
+               __pmd((jump_address_phys & PMD_MASK) | pgprot_val(pmd_text_prot)));
        set_pud(pud + pud_index(restore_jump_address),
-               __pud(__pa(pmd) | _KERNPG_TABLE));
+               __pud(__pa(pmd) | pgprot_val(pgtable_prot)));
        if (IS_ENABLED(CONFIG_X86_5LEVEL)) {
-               set_p4d(p4d + p4d_index(restore_jump_address), __p4d(__pa(pud) | _KERNPG_TABLE));
-               set_pgd(pgd + pgd_index(restore_jump_address), __pgd(__pa(p4d) | _KERNPG_TABLE));
+               p4d_t new_p4d = __p4d(__pa(pud) | pgprot_val(pgtable_prot));
+               pgd_t new_pgd = __pgd(__pa(p4d) | pgprot_val(pgtable_prot));
+
+               set_p4d(p4d + p4d_index(restore_jump_address), new_p4d);
+               set_pgd(pgd + pgd_index(restore_jump_address), new_pgd);
        } else {
                /* No p4d for 4-level paging: point the pgd to the pud page table */
-               set_pgd(pgd + pgd_index(restore_jump_address), __pgd(__pa(pud) | _KERNPG_TABLE));
+               pgd_t new_pgd = __pgd(__pa(p4d) | pgprot_val(pgtable_prot));
+               set_pgd(pgd + pgd_index(restore_jump_address), new_pgd);
        }
 
        return 0;