Merge branch 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 pti updates from Thomas Gleixner:
"Another series of PTI related changes:

- Remove the manual stack switch for user entries from the idtentry
code. This debloats entry by 5k+ bytes of text.

- Use the proper types for the asm/bootparam.h defines to prevent
user space compile errors.

- Use PAGE_GLOBAL for !PCID systems to gain back performance

- Prevent setting of huge PUD/PMD entries when the entries are not
leaf entries otherwise the entries to which the PUD/PMD points to
and are populated get lost"

* 'x86-pti-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/pgtable: Don't set huge PUD/PMD on non-leaf entries
x86/pti: Leave kernel text global for !PCID
x86/pti: Never implicitly clear _PAGE_GLOBAL for kernel image
x86/pti: Enable global pages for shared areas
x86/mm: Do not forbid _PAGE_RW before init for __ro_after_init
x86/mm: Comment _PAGE_GLOBAL mystery
x86/mm: Remove extra filtering in pageattr code
x86/mm: Do not auto-massage page protections
x86/espfix: Document use of _PAGE_GLOBAL
x86/mm: Introduce "default" kernel PTE mask
x86/mm: Undo double _PAGE_PSE clearing
x86/mm: Factor out pageattr _PAGE_GLOBAL setting
x86/entry/64: Drop idtentry's manual stack switch for user entries
x86/uapi: Fix asm/bootparam.h userspace compilation errors

+328 -104
+3
arch/x86/boot/compressed/kaslr.c
··· 54 55 extern unsigned long get_cmd_line_ptr(void); 56 57 /* Simplified build-specific string for starting entropy. */ 58 static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" 59 LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION;
··· 54 55 extern unsigned long get_cmd_line_ptr(void); 56 57 + /* Used by PAGE_KERN* macros: */ 58 + pteval_t __default_kernel_pte_mask __read_mostly = ~0; 59 + 60 /* Simplified build-specific string for starting entropy. */ 61 static const char build_str[] = UTS_RELEASE " (" LINUX_COMPILE_BY "@" 62 LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION;
+2 -2
arch/x86/entry/entry_64.S
··· 913 pushq $-1 /* ORIG_RAX: no syscall to restart */ 914 .endif 915 916 - .if \paranoid < 2 917 testb $3, CS-ORIG_RAX(%rsp) /* If coming from userspace, switch stacks */ 918 jnz .Lfrom_usermode_switch_stack_\@ 919 .endif ··· 960 jmp error_exit 961 .endif 962 963 - .if \paranoid < 2 964 /* 965 * Entry from userspace. Switch stacks and treat it 966 * as a normal entry. This means that paranoid handlers
··· 913 pushq $-1 /* ORIG_RAX: no syscall to restart */ 914 .endif 915 916 + .if \paranoid == 1 917 testb $3, CS-ORIG_RAX(%rsp) /* If coming from userspace, switch stacks */ 918 jnz .Lfrom_usermode_switch_stack_\@ 919 .endif ··· 960 jmp error_exit 961 .endif 962 963 + .if \paranoid == 1 964 /* 965 * Entry from userspace. Switch stacks and treat it 966 * as a normal entry. This means that paranoid handlers
+22 -5
arch/x86/include/asm/pgtable.h
··· 526 return protval; 527 } 528 529 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) 530 { 531 return __pte(((phys_addr_t)page_nr << PAGE_SHIFT) | 532 - massage_pgprot(pgprot)); 533 } 534 535 static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) 536 { 537 return __pmd(((phys_addr_t)page_nr << PAGE_SHIFT) | 538 - massage_pgprot(pgprot)); 539 } 540 541 static inline pud_t pfn_pud(unsigned long page_nr, pgprot_t pgprot) 542 { 543 return __pud(((phys_addr_t)page_nr << PAGE_SHIFT) | 544 - massage_pgprot(pgprot)); 545 } 546 547 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) ··· 570 * the newprot (if present): 571 */ 572 val &= _PAGE_CHG_MASK; 573 - val |= massage_pgprot(newprot) & ~_PAGE_CHG_MASK; 574 575 return __pte(val); 576 } ··· 580 pmdval_t val = pmd_val(pmd); 581 582 val &= _HPAGE_CHG_MASK; 583 - val |= massage_pgprot(newprot) & ~_HPAGE_CHG_MASK; 584 585 return __pmd(val); 586 }
··· 526 return protval; 527 } 528 529 + static inline pgprotval_t check_pgprot(pgprot_t pgprot) 530 + { 531 + pgprotval_t massaged_val = massage_pgprot(pgprot); 532 + 533 + /* mmdebug.h can not be included here because of dependencies */ 534 + #ifdef CONFIG_DEBUG_VM 535 + WARN_ONCE(pgprot_val(pgprot) != massaged_val, 536 + "attempted to set unsupported pgprot: %016llx " 537 + "bits: %016llx supported: %016llx\n", 538 + (u64)pgprot_val(pgprot), 539 + (u64)pgprot_val(pgprot) ^ massaged_val, 540 + (u64)__supported_pte_mask); 541 + #endif 542 + 543 + return massaged_val; 544 + } 545 + 546 static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) 547 { 548 return __pte(((phys_addr_t)page_nr << PAGE_SHIFT) | 549 + check_pgprot(pgprot)); 550 } 551 552 static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) 553 { 554 return __pmd(((phys_addr_t)page_nr << PAGE_SHIFT) | 555 + check_pgprot(pgprot)); 556 } 557 558 static inline pud_t pfn_pud(unsigned long page_nr, pgprot_t pgprot) 559 { 560 return __pud(((phys_addr_t)page_nr << PAGE_SHIFT) | 561 + check_pgprot(pgprot)); 562 } 563 564 static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) ··· 553 * the newprot (if present): 554 */ 555 val &= _PAGE_CHG_MASK; 556 + val |= check_pgprot(newprot) & ~_PAGE_CHG_MASK; 557 558 return __pte(val); 559 } ··· 563 pmdval_t val = pmd_val(pmd); 564 565 val &= _HPAGE_CHG_MASK; 566 + val |= check_pgprot(newprot) & ~_HPAGE_CHG_MASK; 567 568 return __pmd(val); 569 }
+15 -12
arch/x86/include/asm/pgtable_types.h
··· 196 #define __PAGE_KERNEL_NOENC (__PAGE_KERNEL) 197 #define __PAGE_KERNEL_NOENC_WP (__PAGE_KERNEL_WP) 198 199 - #define PAGE_KERNEL __pgprot(__PAGE_KERNEL | _PAGE_ENC) 200 - #define PAGE_KERNEL_NOENC __pgprot(__PAGE_KERNEL) 201 - #define PAGE_KERNEL_RO __pgprot(__PAGE_KERNEL_RO | _PAGE_ENC) 202 - #define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC | _PAGE_ENC) 203 - #define PAGE_KERNEL_EXEC_NOENC __pgprot(__PAGE_KERNEL_EXEC) 204 - #define PAGE_KERNEL_RX __pgprot(__PAGE_KERNEL_RX | _PAGE_ENC) 205 - #define PAGE_KERNEL_NOCACHE __pgprot(__PAGE_KERNEL_NOCACHE | _PAGE_ENC) 206 - #define PAGE_KERNEL_LARGE __pgprot(__PAGE_KERNEL_LARGE | _PAGE_ENC) 207 - #define PAGE_KERNEL_LARGE_EXEC __pgprot(__PAGE_KERNEL_LARGE_EXEC | _PAGE_ENC) 208 - #define PAGE_KERNEL_VVAR __pgprot(__PAGE_KERNEL_VVAR | _PAGE_ENC) 209 210 - #define PAGE_KERNEL_IO __pgprot(__PAGE_KERNEL_IO) 211 - #define PAGE_KERNEL_IO_NOCACHE __pgprot(__PAGE_KERNEL_IO_NOCACHE) 212 213 #endif /* __ASSEMBLY__ */ 214 ··· 485 typedef struct page *pgtable_t; 486 487 extern pteval_t __supported_pte_mask; 488 extern void set_nx(void); 489 extern int nx_enabled; 490
··· 196 #define __PAGE_KERNEL_NOENC (__PAGE_KERNEL) 197 #define __PAGE_KERNEL_NOENC_WP (__PAGE_KERNEL_WP) 198 199 + #define default_pgprot(x) __pgprot((x) & __default_kernel_pte_mask) 200 201 + #define PAGE_KERNEL default_pgprot(__PAGE_KERNEL | _PAGE_ENC) 202 + #define PAGE_KERNEL_NOENC default_pgprot(__PAGE_KERNEL) 203 + #define PAGE_KERNEL_RO default_pgprot(__PAGE_KERNEL_RO | _PAGE_ENC) 204 + #define PAGE_KERNEL_EXEC default_pgprot(__PAGE_KERNEL_EXEC | _PAGE_ENC) 205 + #define PAGE_KERNEL_EXEC_NOENC default_pgprot(__PAGE_KERNEL_EXEC) 206 + #define PAGE_KERNEL_RX default_pgprot(__PAGE_KERNEL_RX | _PAGE_ENC) 207 + #define PAGE_KERNEL_NOCACHE default_pgprot(__PAGE_KERNEL_NOCACHE | _PAGE_ENC) 208 + #define PAGE_KERNEL_LARGE default_pgprot(__PAGE_KERNEL_LARGE | _PAGE_ENC) 209 + #define PAGE_KERNEL_LARGE_EXEC default_pgprot(__PAGE_KERNEL_LARGE_EXEC | _PAGE_ENC) 210 + #define PAGE_KERNEL_VVAR default_pgprot(__PAGE_KERNEL_VVAR | _PAGE_ENC) 211 + 212 + #define PAGE_KERNEL_IO default_pgprot(__PAGE_KERNEL_IO) 213 + #define PAGE_KERNEL_IO_NOCACHE default_pgprot(__PAGE_KERNEL_IO_NOCACHE) 214 215 #endif /* __ASSEMBLY__ */ 216 ··· 483 typedef struct page *pgtable_t; 484 485 extern pteval_t __supported_pte_mask; 486 + extern pteval_t __default_kernel_pte_mask; 487 extern void set_nx(void); 488 extern int nx_enabled; 489
+2
arch/x86/include/asm/pti.h
··· 6 #ifdef CONFIG_PAGE_TABLE_ISOLATION 7 extern void pti_init(void); 8 extern void pti_check_boottime_disable(void); 9 #else 10 static inline void pti_check_boottime_disable(void) { } 11 #endif 12 13 #endif /* __ASSEMBLY__ */
··· 6 #ifdef CONFIG_PAGE_TABLE_ISOLATION 7 extern void pti_init(void); 8 extern void pti_check_boottime_disable(void); 9 + extern void pti_clone_kernel_text(void); 10 #else 11 static inline void pti_check_boottime_disable(void) { } 12 + static inline void pti_clone_kernel_text(void) { } 13 #endif 14 15 #endif /* __ASSEMBLY__ */
+9 -9
arch/x86/include/uapi/asm/bootparam.h
··· 137 * setup data structure. 138 */ 139 struct jailhouse_setup_data { 140 - u16 version; 141 - u16 compatible_version; 142 - u16 pm_timer_address; 143 - u16 num_cpus; 144 - u64 pci_mmconfig_base; 145 - u32 tsc_khz; 146 - u32 apic_khz; 147 - u8 standard_ioapic; 148 - u8 cpu_ids[255]; 149 } __attribute__((packed)); 150 151 /* The so-called "zeropage" */
··· 137 * setup data structure. 138 */ 139 struct jailhouse_setup_data { 140 + __u16 version; 141 + __u16 compatible_version; 142 + __u16 pm_timer_address; 143 + __u16 num_cpus; 144 + __u64 pci_mmconfig_base; 145 + __u32 tsc_khz; 146 + __u32 apic_khz; 147 + __u8 standard_ioapic; 148 + __u8 cpu_ids[255]; 149 } __attribute__((packed)); 150 151 /* The so-called "zeropage" */
+4
arch/x86/kernel/espfix_64.c
··· 195 196 pte_p = pte_offset_kernel(&pmd, addr); 197 stack_page = page_address(alloc_pages_node(node, GFP_KERNEL, 0)); 198 pte = __pte(__pa(stack_page) | ((__PAGE_KERNEL_RO | _PAGE_ENC) & ptemask)); 199 for (n = 0; n < ESPFIX_PTE_CLONES; n++) 200 set_pte(&pte_p[n*PTE_STRIDE], pte);
··· 195 196 pte_p = pte_offset_kernel(&pmd, addr); 197 stack_page = page_address(alloc_pages_node(node, GFP_KERNEL, 0)); 198 + /* 199 + * __PAGE_KERNEL_* includes _PAGE_GLOBAL, which we want since 200 + * this is mapped to userspace. 201 + */ 202 pte = __pte(__pa(stack_page) | ((__PAGE_KERNEL_RO | _PAGE_ENC) & ptemask)); 203 for (n = 0; n < ESPFIX_PTE_CLONES; n++) 204 set_pte(&pte_p[n*PTE_STRIDE], pte);
+2
arch/x86/kernel/head64.c
··· 195 pud[i + 1] = (pudval_t)pmd + pgtable_flags; 196 197 pmd_entry = __PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL; 198 pmd_entry += sme_get_me_mask(); 199 pmd_entry += physaddr; 200
··· 195 pud[i + 1] = (pudval_t)pmd + pgtable_flags; 196 197 pmd_entry = __PAGE_KERNEL_LARGE_EXEC & ~_PAGE_GLOBAL; 198 + /* Filter out unsupported __PAGE_KERNEL_* bits: */ 199 + pmd_entry &= __supported_pte_mask; 200 pmd_entry += sme_get_me_mask(); 201 pmd_entry += physaddr; 202
+10 -1
arch/x86/kernel/head_64.S
··· 399 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC 400 .fill 511, 8, 0 401 NEXT_PAGE(level2_ident_pgt) 402 - /* Since I easily can, map the first 1G. 403 * Don't set NX because code runs from these pages. 404 */ 405 PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD) 406 #else ··· 436 * (NOTE: at +512MB starts the module area, see MODULES_VADDR. 437 * If you want to increase this then increase MODULES_VADDR 438 * too.) 439 */ 440 PMDS(0, __PAGE_KERNEL_LARGE_EXEC, 441 KERNEL_IMAGE_SIZE/PMD_SIZE)
··· 399 .quad level2_ident_pgt - __START_KERNEL_map + _KERNPG_TABLE_NOENC 400 .fill 511, 8, 0 401 NEXT_PAGE(level2_ident_pgt) 402 + /* 403 + * Since I easily can, map the first 1G. 404 * Don't set NX because code runs from these pages. 405 + * 406 + * Note: This sets _PAGE_GLOBAL despite whether 407 + * the CPU supports it or it is enabled. But, 408 + * the CPU should ignore the bit. 409 */ 410 PMDS(0, __PAGE_KERNEL_IDENT_LARGE_EXEC, PTRS_PER_PMD) 411 #else ··· 431 * (NOTE: at +512MB starts the module area, see MODULES_VADDR. 432 * If you want to increase this then increase MODULES_VADDR 433 * too.) 434 + * 435 + * This table is eventually used by the kernel during normal 436 + * runtime. Care must be taken to clear out undesired bits 437 + * later, like _PAGE_RW or _PAGE_GLOBAL in some cases. 438 */ 439 PMDS(0, __PAGE_KERNEL_LARGE_EXEC, 440 KERNEL_IMAGE_SIZE/PMD_SIZE)
+5 -1
arch/x86/kernel/ldt.c
··· 145 unsigned long offset = i << PAGE_SHIFT; 146 const void *src = (char *)ldt->entries + offset; 147 unsigned long pfn; 148 pte_t pte, *ptep; 149 150 va = (unsigned long)ldt_slot_va(slot) + offset; ··· 164 * target via some kernel interface which misses a 165 * permission check. 166 */ 167 - pte = pfn_pte(pfn, __pgprot(__PAGE_KERNEL_RO & ~_PAGE_GLOBAL)); 168 set_pte_at(mm, va, ptep, pte); 169 pte_unmap_unlock(ptep, ptl); 170 }
··· 145 unsigned long offset = i << PAGE_SHIFT; 146 const void *src = (char *)ldt->entries + offset; 147 unsigned long pfn; 148 + pgprot_t pte_prot; 149 pte_t pte, *ptep; 150 151 va = (unsigned long)ldt_slot_va(slot) + offset; ··· 163 * target via some kernel interface which misses a 164 * permission check. 165 */ 166 + pte_prot = __pgprot(__PAGE_KERNEL_RO & ~_PAGE_GLOBAL); 167 + /* Filter out unsuppored __PAGE_KERNEL* bits: */ 168 + pgprot_val(pte_prot) |= __supported_pte_mask; 169 + pte = pfn_pte(pfn, pte_prot); 170 set_pte_at(mm, va, ptep, pte); 171 pte_unmap_unlock(ptep, ptl); 172 }
+13 -1
arch/x86/mm/cpu_entry_area.c
··· 27 void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags) 28 { 29 unsigned long va = (unsigned long) cea_vaddr; 30 31 - set_pte_vaddr(va, pfn_pte(pa >> PAGE_SHIFT, flags)); 32 } 33 34 static void __init
··· 27 void cea_set_pte(void *cea_vaddr, phys_addr_t pa, pgprot_t flags) 28 { 29 unsigned long va = (unsigned long) cea_vaddr; 30 + pte_t pte = pfn_pte(pa >> PAGE_SHIFT, flags); 31 32 + /* 33 + * The cpu_entry_area is shared between the user and kernel 34 + * page tables. All of its ptes can safely be global. 35 + * _PAGE_GLOBAL gets reused to help indicate PROT_NONE for 36 + * non-present PTEs, so be careful not to set it in that 37 + * case to avoid confusion. 38 + */ 39 + if (boot_cpu_has(X86_FEATURE_PGE) && 40 + (pgprot_val(flags) & _PAGE_PRESENT)) 41 + pte = pte_set_flags(pte, _PAGE_GLOBAL); 42 + 43 + set_pte_vaddr(va, pte); 44 } 45 46 static void __init
+3
arch/x86/mm/ident_map.c
··· 98 if (!info->kernpg_flag) 99 info->kernpg_flag = _KERNPG_TABLE; 100 101 for (; addr < end; addr = next) { 102 pgd_t *pgd = pgd_page + pgd_index(addr); 103 p4d_t *p4d;
··· 98 if (!info->kernpg_flag) 99 info->kernpg_flag = _KERNPG_TABLE; 100 101 + /* Filter out unsupported __PAGE_KERNEL_* bits: */ 102 + info->kernpg_flag &= __default_kernel_pte_mask; 103 + 104 for (; addr < end; addr = next) { 105 pgd_t *pgd = pgd_page + pgd_index(addr); 106 p4d_t *p4d;
+7 -7
arch/x86/mm/init.c
··· 161 162 static int page_size_mask; 163 164 - static void enable_global_pages(void) 165 - { 166 - if (!static_cpu_has(X86_FEATURE_PTI)) 167 - __supported_pte_mask |= _PAGE_GLOBAL; 168 - } 169 - 170 static void __init probe_page_size_mask(void) 171 { 172 /* ··· 181 __supported_pte_mask &= ~_PAGE_GLOBAL; 182 if (boot_cpu_has(X86_FEATURE_PGE)) { 183 cr4_set_bits_and_update_boot(X86_CR4_PGE); 184 - enable_global_pages(); 185 } 186 187 /* Enable 1 GB linear kernel mappings if available: */ 188 if (direct_gbpages && boot_cpu_has(X86_FEATURE_GBPAGES)) {
··· 161 162 static int page_size_mask; 163 164 static void __init probe_page_size_mask(void) 165 { 166 /* ··· 187 __supported_pte_mask &= ~_PAGE_GLOBAL; 188 if (boot_cpu_has(X86_FEATURE_PGE)) { 189 cr4_set_bits_and_update_boot(X86_CR4_PGE); 190 + __supported_pte_mask |= _PAGE_GLOBAL; 191 } 192 + 193 + /* By the default is everything supported: */ 194 + __default_kernel_pte_mask = __supported_pte_mask; 195 + /* Except when with PTI where the kernel is mostly non-Global: */ 196 + if (cpu_feature_enabled(X86_FEATURE_PTI)) 197 + __default_kernel_pte_mask &= ~_PAGE_GLOBAL; 198 199 /* Enable 1 GB linear kernel mappings if available: */ 200 if (direct_gbpages && boot_cpu_has(X86_FEATURE_GBPAGES)) {
+7 -1
arch/x86/mm/init_32.c
··· 558 permanent_kmaps_init(pgd_base); 559 } 560 561 - pteval_t __supported_pte_mask __read_mostly = ~(_PAGE_NX | _PAGE_GLOBAL); 562 EXPORT_SYMBOL_GPL(__supported_pte_mask); 563 564 /* user-defined highmem size */ 565 static unsigned int highmem_pages = -1;
··· 558 permanent_kmaps_init(pgd_base); 559 } 560 561 + #define DEFAULT_PTE_MASK ~(_PAGE_NX | _PAGE_GLOBAL) 562 + /* Bits supported by the hardware: */ 563 + pteval_t __supported_pte_mask __read_mostly = DEFAULT_PTE_MASK; 564 + /* Bits allowed in normal kernel mappings: */ 565 + pteval_t __default_kernel_pte_mask __read_mostly = DEFAULT_PTE_MASK; 566 EXPORT_SYMBOL_GPL(__supported_pte_mask); 567 + /* Used in PAGE_KERNEL_* macros which are reasonably used out-of-tree: */ 568 + EXPORT_SYMBOL(__default_kernel_pte_mask); 569 570 /* user-defined highmem size */ 571 static unsigned int highmem_pages = -1;
+11
arch/x86/mm/init_64.c
··· 65 * around without checking the pgd every time. 66 */ 67 68 pteval_t __supported_pte_mask __read_mostly = ~0; 69 EXPORT_SYMBOL_GPL(__supported_pte_mask); 70 71 int force_personality32; 72 ··· 1291 (unsigned long) __va(__pa_symbol(_sdata))); 1292 1293 debug_checkwx(); 1294 } 1295 1296 int kern_addr_valid(unsigned long addr)
··· 65 * around without checking the pgd every time. 66 */ 67 68 + /* Bits supported by the hardware: */ 69 pteval_t __supported_pte_mask __read_mostly = ~0; 70 + /* Bits allowed in normal kernel mappings: */ 71 + pteval_t __default_kernel_pte_mask __read_mostly = ~0; 72 EXPORT_SYMBOL_GPL(__supported_pte_mask); 73 + /* Used in PAGE_KERNEL_* macros which are reasonably used out-of-tree: */ 74 + EXPORT_SYMBOL(__default_kernel_pte_mask); 75 76 int force_personality32; 77 ··· 1286 (unsigned long) __va(__pa_symbol(_sdata))); 1287 1288 debug_checkwx(); 1289 + 1290 + /* 1291 + * Do this after all of the manipulation of the 1292 + * kernel text page tables are complete. 1293 + */ 1294 + pti_clone_kernel_text(); 1295 } 1296 1297 int kern_addr_valid(unsigned long addr)
+6
arch/x86/mm/iomap_32.c
··· 44 return ret; 45 46 *prot = __pgprot(__PAGE_KERNEL | cachemode2protval(pcm)); 47 return 0; 48 } 49 EXPORT_SYMBOL_GPL(iomap_create_wc); ··· 90 if (!pat_enabled() && pgprot2cachemode(prot) != _PAGE_CACHE_MODE_WB) 91 prot = __pgprot(__PAGE_KERNEL | 92 cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS)); 93 94 return (void __force __iomem *) kmap_atomic_prot_pfn(pfn, prot); 95 }
··· 44 return ret; 45 46 *prot = __pgprot(__PAGE_KERNEL | cachemode2protval(pcm)); 47 + /* Filter out unsupported __PAGE_KERNEL* bits: */ 48 + pgprot_val(*prot) &= __default_kernel_pte_mask; 49 + 50 return 0; 51 } 52 EXPORT_SYMBOL_GPL(iomap_create_wc); ··· 87 if (!pat_enabled() && pgprot2cachemode(prot) != _PAGE_CACHE_MODE_WB) 88 prot = __pgprot(__PAGE_KERNEL | 89 cachemode2protval(_PAGE_CACHE_MODE_UC_MINUS)); 90 + 91 + /* Filter out unsupported __PAGE_KERNEL* bits: */ 92 + pgprot_val(prot) &= __default_kernel_pte_mask; 93 94 return (void __force __iomem *) kmap_atomic_prot_pfn(pfn, prot); 95 }
+3
arch/x86/mm/ioremap.c
··· 816 } 817 pte = early_ioremap_pte(addr); 818 819 if (pgprot_val(flags)) 820 set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags)); 821 else
··· 816 } 817 pte = early_ioremap_pte(addr); 818 819 + /* Sanitize 'prot' against any unsupported bits: */ 820 + pgprot_val(flags) &= __default_kernel_pte_mask; 821 + 822 if (pgprot_val(flags)) 823 set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, flags)); 824 else
+13 -1
arch/x86/mm/kasan_init_64.c
··· 269 pudval_t pud_val = __pa_nodebug(kasan_zero_pmd) | _KERNPG_TABLE; 270 p4dval_t p4d_val = __pa_nodebug(kasan_zero_pud) | _KERNPG_TABLE; 271 272 for (i = 0; i < PTRS_PER_PTE; i++) 273 kasan_zero_pte[i] = __pte(pte_val); 274 ··· 377 */ 378 memset(kasan_zero_page, 0, PAGE_SIZE); 379 for (i = 0; i < PTRS_PER_PTE; i++) { 380 - pte_t pte = __pte(__pa(kasan_zero_page) | __PAGE_KERNEL_RO | _PAGE_ENC); 381 set_pte(&kasan_zero_pte[i], pte); 382 } 383 /* Flush TLBs again to be sure that write protection applied. */
··· 269 pudval_t pud_val = __pa_nodebug(kasan_zero_pmd) | _KERNPG_TABLE; 270 p4dval_t p4d_val = __pa_nodebug(kasan_zero_pud) | _KERNPG_TABLE; 271 272 + /* Mask out unsupported __PAGE_KERNEL bits: */ 273 + pte_val &= __default_kernel_pte_mask; 274 + pmd_val &= __default_kernel_pte_mask; 275 + pud_val &= __default_kernel_pte_mask; 276 + p4d_val &= __default_kernel_pte_mask; 277 + 278 for (i = 0; i < PTRS_PER_PTE; i++) 279 kasan_zero_pte[i] = __pte(pte_val); 280 ··· 371 */ 372 memset(kasan_zero_page, 0, PAGE_SIZE); 373 for (i = 0; i < PTRS_PER_PTE; i++) { 374 + pte_t pte; 375 + pgprot_t prot; 376 + 377 + prot = __pgprot(__PAGE_KERNEL_RO | _PAGE_ENC); 378 + pgprot_val(prot) &= __default_kernel_pte_mask; 379 + 380 + pte = __pte(__pa(kasan_zero_page) | pgprot_val(prot)); 381 set_pte(&kasan_zero_pte[i], pte); 382 } 383 /* Flush TLBs again to be sure that write protection applied. */
+43 -54
arch/x86/mm/pageattr.c
··· 298 299 /* 300 * The .rodata section needs to be read-only. Using the pfn 301 - * catches all aliases. 302 */ 303 - if (within(pfn, __pa_symbol(__start_rodata) >> PAGE_SHIFT, 304 __pa_symbol(__end_rodata) >> PAGE_SHIFT)) 305 pgprot_val(forbidden) |= _PAGE_RW; 306 ··· 514 #endif 515 } 516 517 static int 518 try_preserve_large_page(pte_t *kpte, unsigned long address, 519 struct cpa_data *cpa) ··· 585 * up accordingly. 586 */ 587 old_pte = *kpte; 588 req_prot = pgprot_large_2_4k(old_prot); 589 590 pgprot_val(req_prot) &= ~pgprot_val(cpa->mask_clr); ··· 597 * different bit positions in the two formats. 598 */ 599 req_prot = pgprot_4k_2_large(req_prot); 600 - 601 - /* 602 - * Set the PSE and GLOBAL flags only if the PRESENT flag is 603 - * set otherwise pmd_present/pmd_huge will return true even on 604 - * a non present pmd. The canon_pgprot will clear _PAGE_GLOBAL 605 - * for the ancient hardware that doesn't support it. 606 - */ 607 if (pgprot_val(req_prot) & _PAGE_PRESENT) 608 - pgprot_val(req_prot) |= _PAGE_PSE | _PAGE_GLOBAL; 609 - else 610 - pgprot_val(req_prot) &= ~(_PAGE_PSE | _PAGE_GLOBAL); 611 - 612 - req_prot = canon_pgprot(req_prot); 613 614 /* 615 * old_pfn points to the large page base pfn. So we need ··· 684 switch (level) { 685 case PG_LEVEL_2M: 686 ref_prot = pmd_pgprot(*(pmd_t *)kpte); 687 - /* clear PSE and promote PAT bit to correct position */ 688 ref_prot = pgprot_large_2_4k(ref_prot); 689 ref_pfn = pmd_pfn(*(pmd_t *)kpte); 690 break; 691 ··· 712 return 1; 713 } 714 715 - /* 716 - * Set the GLOBAL flags only if the PRESENT flag is set 717 - * otherwise pmd/pte_present will return true even on a non 718 - * present pmd/pte. The canon_pgprot will clear _PAGE_GLOBAL 719 - * for the ancient hardware that doesn't support it. 720 - */ 721 - if (pgprot_val(ref_prot) & _PAGE_PRESENT) 722 - pgprot_val(ref_prot) |= _PAGE_GLOBAL; 723 - else 724 - pgprot_val(ref_prot) &= ~_PAGE_GLOBAL; 725 726 /* 727 * Get the target pfn from the original entry: 728 */ 729 pfn = ref_pfn; 730 for (i = 0; i < PTRS_PER_PTE; i++, pfn += pfninc) 731 - set_pte(&pbase[i], pfn_pte(pfn, canon_pgprot(ref_prot))); 732 733 if (virt_addr_valid(address)) { 734 unsigned long pfn = PFN_DOWN(__pa(address)); ··· 935 936 pte = pte_offset_kernel(pmd, start); 937 938 - /* 939 - * Set the GLOBAL flags only if the PRESENT flag is 940 - * set otherwise pte_present will return true even on 941 - * a non present pte. The canon_pgprot will clear 942 - * _PAGE_GLOBAL for the ancient hardware that doesn't 943 - * support it. 944 - */ 945 - if (pgprot_val(pgprot) & _PAGE_PRESENT) 946 - pgprot_val(pgprot) |= _PAGE_GLOBAL; 947 - else 948 - pgprot_val(pgprot) &= ~_PAGE_GLOBAL; 949 - 950 - pgprot = canon_pgprot(pgprot); 951 952 while (num_pages-- && start < end) { 953 set_pte(pte, pfn_pte(cpa->pfn, pgprot)); ··· 1227 1228 new_prot = static_protections(new_prot, address, pfn); 1229 1230 - /* 1231 - * Set the GLOBAL flags only if the PRESENT flag is 1232 - * set otherwise pte_present will return true even on 1233 - * a non present pte. The canon_pgprot will clear 1234 - * _PAGE_GLOBAL for the ancient hardware that doesn't 1235 - * support it. 1236 - */ 1237 - if (pgprot_val(new_prot) & _PAGE_PRESENT) 1238 - pgprot_val(new_prot) |= _PAGE_GLOBAL; 1239 - else 1240 - pgprot_val(new_prot) &= ~_PAGE_GLOBAL; 1241 1242 /* 1243 * We need to keep the pfn from the existing PTE, 1244 * after all we're only going to change it's attributes 1245 * not the memory it points to 1246 */ 1247 - new_pte = pfn_pte(pfn, canon_pgprot(new_prot)); 1248 cpa->pfn = pfn; 1249 /* 1250 * Do we really change anything ? ··· 1411 memset(&cpa, 0, sizeof(cpa)); 1412 1413 /* 1414 - * Check, if we are requested to change a not supported 1415 - * feature: 1416 */ 1417 mask_set = canon_pgprot(mask_set); 1418 - mask_clr = canon_pgprot(mask_clr); 1419 if (!pgprot_val(mask_set) && !pgprot_val(mask_clr) && !force_split) 1420 return 0; 1421 ··· 1756 { 1757 return change_page_attr_set_clr(&addr, numpages, __pgprot(0), 1758 __pgprot(0), 1, 0, NULL); 1759 } 1760 1761 static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
··· 298 299 /* 300 * The .rodata section needs to be read-only. Using the pfn 301 + * catches all aliases. This also includes __ro_after_init, 302 + * so do not enforce until kernel_set_to_readonly is true. 303 */ 304 + if (kernel_set_to_readonly && 305 + within(pfn, __pa_symbol(__start_rodata) >> PAGE_SHIFT, 306 __pa_symbol(__end_rodata) >> PAGE_SHIFT)) 307 pgprot_val(forbidden) |= _PAGE_RW; 308 ··· 512 #endif 513 } 514 515 + static pgprot_t pgprot_clear_protnone_bits(pgprot_t prot) 516 + { 517 + /* 518 + * _PAGE_GLOBAL means "global page" for present PTEs. 519 + * But, it is also used to indicate _PAGE_PROTNONE 520 + * for non-present PTEs. 521 + * 522 + * This ensures that a _PAGE_GLOBAL PTE going from 523 + * present to non-present is not confused as 524 + * _PAGE_PROTNONE. 525 + */ 526 + if (!(pgprot_val(prot) & _PAGE_PRESENT)) 527 + pgprot_val(prot) &= ~_PAGE_GLOBAL; 528 + 529 + return prot; 530 + } 531 + 532 static int 533 try_preserve_large_page(pte_t *kpte, unsigned long address, 534 struct cpa_data *cpa) ··· 566 * up accordingly. 567 */ 568 old_pte = *kpte; 569 + /* Clear PSE (aka _PAGE_PAT) and move PAT bit to correct position */ 570 req_prot = pgprot_large_2_4k(old_prot); 571 572 pgprot_val(req_prot) &= ~pgprot_val(cpa->mask_clr); ··· 577 * different bit positions in the two formats. 578 */ 579 req_prot = pgprot_4k_2_large(req_prot); 580 + req_prot = pgprot_clear_protnone_bits(req_prot); 581 if (pgprot_val(req_prot) & _PAGE_PRESENT) 582 + pgprot_val(req_prot) |= _PAGE_PSE; 583 584 /* 585 * old_pfn points to the large page base pfn. So we need ··· 674 switch (level) { 675 case PG_LEVEL_2M: 676 ref_prot = pmd_pgprot(*(pmd_t *)kpte); 677 + /* 678 + * Clear PSE (aka _PAGE_PAT) and move 679 + * PAT bit to correct position. 680 + */ 681 ref_prot = pgprot_large_2_4k(ref_prot); 682 + 683 ref_pfn = pmd_pfn(*(pmd_t *)kpte); 684 break; 685 ··· 698 return 1; 699 } 700 701 + ref_prot = pgprot_clear_protnone_bits(ref_prot); 702 703 /* 704 * Get the target pfn from the original entry: 705 */ 706 pfn = ref_pfn; 707 for (i = 0; i < PTRS_PER_PTE; i++, pfn += pfninc) 708 + set_pte(&pbase[i], pfn_pte(pfn, ref_prot)); 709 710 if (virt_addr_valid(address)) { 711 unsigned long pfn = PFN_DOWN(__pa(address)); ··· 930 931 pte = pte_offset_kernel(pmd, start); 932 933 + pgprot = pgprot_clear_protnone_bits(pgprot); 934 935 while (num_pages-- && start < end) { 936 set_pte(pte, pfn_pte(cpa->pfn, pgprot)); ··· 1234 1235 new_prot = static_protections(new_prot, address, pfn); 1236 1237 + new_prot = pgprot_clear_protnone_bits(new_prot); 1238 1239 /* 1240 * We need to keep the pfn from the existing PTE, 1241 * after all we're only going to change it's attributes 1242 * not the memory it points to 1243 */ 1244 + new_pte = pfn_pte(pfn, new_prot); 1245 cpa->pfn = pfn; 1246 /* 1247 * Do we really change anything ? ··· 1428 memset(&cpa, 0, sizeof(cpa)); 1429 1430 /* 1431 + * Check, if we are requested to set a not supported 1432 + * feature. Clearing non-supported features is OK. 1433 */ 1434 mask_set = canon_pgprot(mask_set); 1435 + 1436 if (!pgprot_val(mask_set) && !pgprot_val(mask_clr) && !force_split) 1437 return 0; 1438 ··· 1773 { 1774 return change_page_attr_set_clr(&addr, numpages, __pgprot(0), 1775 __pgprot(0), 1, 0, NULL); 1776 + } 1777 + 1778 + int set_memory_nonglobal(unsigned long addr, int numpages) 1779 + { 1780 + return change_page_attr_clear(&addr, numpages, 1781 + __pgprot(_PAGE_GLOBAL), 0); 1782 } 1783 1784 static int __set_memory_enc_dec(unsigned long addr, int numpages, bool enc)
+12
arch/x86/mm/pgtable.c
··· 1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/mm.h> 3 #include <linux/gfp.h> 4 #include <asm/pgalloc.h> 5 #include <asm/pgtable.h> 6 #include <asm/tlb.h> ··· 584 void native_set_fixmap(enum fixed_addresses idx, phys_addr_t phys, 585 pgprot_t flags) 586 { 587 __native_set_fixmap(idx, pfn_pte(phys >> PAGE_SHIFT, flags)); 588 } 589 ··· 640 (mtrr != MTRR_TYPE_WRBACK)) 641 return 0; 642 643 prot = pgprot_4k_2_large(prot); 644 645 set_pte((pte_t *)pud, pfn_pte( ··· 671 __func__, addr, addr + PMD_SIZE); 672 return 0; 673 } 674 675 prot = pgprot_4k_2_large(prot); 676
··· 1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/mm.h> 3 #include <linux/gfp.h> 4 + #include <linux/hugetlb.h> 5 #include <asm/pgalloc.h> 6 #include <asm/pgtable.h> 7 #include <asm/tlb.h> ··· 583 void native_set_fixmap(enum fixed_addresses idx, phys_addr_t phys, 584 pgprot_t flags) 585 { 586 + /* Sanitize 'prot' against any unsupported bits: */ 587 + pgprot_val(flags) &= __default_kernel_pte_mask; 588 + 589 __native_set_fixmap(idx, pfn_pte(phys >> PAGE_SHIFT, flags)); 590 } 591 ··· 636 (mtrr != MTRR_TYPE_WRBACK)) 637 return 0; 638 639 + /* Bail out if we are we on a populated non-leaf entry: */ 640 + if (pud_present(*pud) && !pud_huge(*pud)) 641 + return 0; 642 + 643 prot = pgprot_4k_2_large(prot); 644 645 set_pte((pte_t *)pud, pfn_pte( ··· 663 __func__, addr, addr + PMD_SIZE); 664 return 0; 665 } 666 + 667 + /* Bail out if we are we on a populated non-leaf entry: */ 668 + if (pmd_present(*pmd) && !pmd_huge(*pmd)) 669 + return 0; 670 671 prot = pgprot_4k_2_large(prot); 672
+121 -5
arch/x86/mm/pti.c
··· 66 pr_info("%s\n", reason); 67 } 68 69 void __init pti_check_boottime_disable(void) 70 { 71 char arg[5]; 72 int ret; 73 74 if (hypervisor_is_type(X86_HYPER_XEN_PV)) { 75 pti_print_if_insecure("disabled on XEN PV."); 76 return; 77 } ··· 89 ret = cmdline_find_option(boot_command_line, "pti", arg, sizeof(arg)); 90 if (ret > 0) { 91 if (ret == 3 && !strncmp(arg, "off", 3)) { 92 pti_print_if_insecure("disabled on command line."); 93 return; 94 } 95 if (ret == 2 && !strncmp(arg, "on", 2)) { 96 pti_print_if_secure("force enabled on command line."); 97 goto enable; 98 } 99 - if (ret == 4 && !strncmp(arg, "auto", 4)) 100 goto autosel; 101 } 102 103 if (cmdline_find_option_bool(boot_command_line, "nopti")) { 104 pti_print_if_insecure("disabled on command line."); 105 return; 106 } ··· 164 * 165 * Returns a pointer to a P4D on success, or NULL on failure. 166 */ 167 - static __init p4d_t *pti_user_pagetable_walk_p4d(unsigned long address) 168 { 169 pgd_t *pgd = kernel_to_user_pgdp(pgd_offset_k(address)); 170 gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); ··· 192 * 193 * Returns a pointer to a PMD on success, or NULL on failure. 194 */ 195 - static __init pmd_t *pti_user_pagetable_walk_pmd(unsigned long address) 196 { 197 gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); 198 p4d_t *p4d = pti_user_pagetable_walk_p4d(address); ··· 282 static void __init pti_setup_vsyscall(void) { } 283 #endif 284 285 - static void __init 286 pti_clone_pmds(unsigned long start, unsigned long end, pmdval_t clear) 287 { 288 unsigned long addr; ··· 313 target_pmd = pti_user_pagetable_walk_pmd(addr); 314 if (WARN_ON(!target_pmd)) 315 return; 316 317 /* 318 * Copy the PMD. That is, the kernelmode and usermode ··· 384 { 385 pti_clone_pmds((unsigned long) __entry_text_start, 386 (unsigned long) __irqentry_text_end, 387 - _PAGE_RW | _PAGE_GLOBAL); 388 } 389 390 /* ··· 474 pr_info("enabled\n"); 475 476 pti_clone_user_shared(); 477 pti_clone_entry_text(); 478 pti_setup_espfix64(); 479 pti_setup_vsyscall();
··· 66 pr_info("%s\n", reason); 67 } 68 69 + enum pti_mode { 70 + PTI_AUTO = 0, 71 + PTI_FORCE_OFF, 72 + PTI_FORCE_ON 73 + } pti_mode; 74 + 75 void __init pti_check_boottime_disable(void) 76 { 77 char arg[5]; 78 int ret; 79 80 + /* Assume mode is auto unless overridden. */ 81 + pti_mode = PTI_AUTO; 82 + 83 if (hypervisor_is_type(X86_HYPER_XEN_PV)) { 84 + pti_mode = PTI_FORCE_OFF; 85 pti_print_if_insecure("disabled on XEN PV."); 86 return; 87 } ··· 79 ret = cmdline_find_option(boot_command_line, "pti", arg, sizeof(arg)); 80 if (ret > 0) { 81 if (ret == 3 && !strncmp(arg, "off", 3)) { 82 + pti_mode = PTI_FORCE_OFF; 83 pti_print_if_insecure("disabled on command line."); 84 return; 85 } 86 if (ret == 2 && !strncmp(arg, "on", 2)) { 87 + pti_mode = PTI_FORCE_ON; 88 pti_print_if_secure("force enabled on command line."); 89 goto enable; 90 } 91 + if (ret == 4 && !strncmp(arg, "auto", 4)) { 92 + pti_mode = PTI_AUTO; 93 goto autosel; 94 + } 95 } 96 97 if (cmdline_find_option_bool(boot_command_line, "nopti")) { 98 + pti_mode = PTI_FORCE_OFF; 99 pti_print_if_insecure("disabled on command line."); 100 return; 101 } ··· 149 * 150 * Returns a pointer to a P4D on success, or NULL on failure. 151 */ 152 + static p4d_t *pti_user_pagetable_walk_p4d(unsigned long address) 153 { 154 pgd_t *pgd = kernel_to_user_pgdp(pgd_offset_k(address)); 155 gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); ··· 177 * 178 * Returns a pointer to a PMD on success, or NULL on failure. 179 */ 180 + static pmd_t *pti_user_pagetable_walk_pmd(unsigned long address) 181 { 182 gfp_t gfp = (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO); 183 p4d_t *p4d = pti_user_pagetable_walk_p4d(address); ··· 267 static void __init pti_setup_vsyscall(void) { } 268 #endif 269 270 + static void 271 pti_clone_pmds(unsigned long start, unsigned long end, pmdval_t clear) 272 { 273 unsigned long addr; ··· 298 target_pmd = pti_user_pagetable_walk_pmd(addr); 299 if (WARN_ON(!target_pmd)) 300 return; 301 + 302 + /* 303 + * Only clone present PMDs. This ensures only setting 304 + * _PAGE_GLOBAL on present PMDs. This should only be 305 + * called on well-known addresses anyway, so a non- 306 + * present PMD would be a surprise. 307 + */ 308 + if (WARN_ON(!(pmd_flags(*pmd) & _PAGE_PRESENT))) 309 + return; 310 + 311 + /* 312 + * Setting 'target_pmd' below creates a mapping in both 313 + * the user and kernel page tables. It is effectively 314 + * global, so set it as global in both copies. Note: 315 + * the X86_FEATURE_PGE check is not _required_ because 316 + * the CPU ignores _PAGE_GLOBAL when PGE is not 317 + * supported. The check keeps consistentency with 318 + * code that only set this bit when supported. 319 + */ 320 + if (boot_cpu_has(X86_FEATURE_PGE)) 321 + *pmd = pmd_set_flags(*pmd, _PAGE_GLOBAL); 322 323 /* 324 * Copy the PMD. That is, the kernelmode and usermode ··· 348 { 349 pti_clone_pmds((unsigned long) __entry_text_start, 350 (unsigned long) __irqentry_text_end, 351 + _PAGE_RW); 352 + } 353 + 354 + /* 355 + * Global pages and PCIDs are both ways to make kernel TLB entries 356 + * live longer, reduce TLB misses and improve kernel performance. 357 + * But, leaving all kernel text Global makes it potentially accessible 358 + * to Meltdown-style attacks which make it trivial to find gadgets or 359 + * defeat KASLR. 360 + * 361 + * Only use global pages when it is really worth it. 362 + */ 363 + static inline bool pti_kernel_image_global_ok(void) 364 + { 365 + /* 366 + * Systems with PCIDs get litlle benefit from global 367 + * kernel text and are not worth the downsides. 368 + */ 369 + if (cpu_feature_enabled(X86_FEATURE_PCID)) 370 + return false; 371 + 372 + /* 373 + * Only do global kernel image for pti=auto. Do the most 374 + * secure thing (not global) if pti=on specified. 375 + */ 376 + if (pti_mode != PTI_AUTO) 377 + return false; 378 + 379 + /* 380 + * K8 may not tolerate the cleared _PAGE_RW on the userspace 381 + * global kernel image pages. Do the safe thing (disable 382 + * global kernel image). This is unlikely to ever be 383 + * noticed because PTI is disabled by default on AMD CPUs. 384 + */ 385 + if (boot_cpu_has(X86_FEATURE_K8)) 386 + return false; 387 + 388 + return true; 389 + } 390 + 391 + /* 392 + * For some configurations, map all of kernel text into the user page 393 + * tables. This reduces TLB misses, especially on non-PCID systems. 394 + */ 395 + void pti_clone_kernel_text(void) 396 + { 397 + unsigned long start = PFN_ALIGN(_text); 398 + unsigned long end = ALIGN((unsigned long)_end, PMD_PAGE_SIZE); 399 + 400 + if (!pti_kernel_image_global_ok()) 401 + return; 402 + 403 + pti_clone_pmds(start, end, _PAGE_RW); 404 + } 405 + 406 + /* 407 + * This is the only user for it and it is not arch-generic like 408 + * the other set_memory.h functions. Just extern it. 409 + */ 410 + extern int set_memory_nonglobal(unsigned long addr, int numpages); 411 + void pti_set_kernel_image_nonglobal(void) 412 + { 413 + /* 414 + * The identity map is created with PMDs, regardless of the 415 + * actual length of the kernel. We need to clear 416 + * _PAGE_GLOBAL up to a PMD boundary, not just to the end 417 + * of the image. 418 + */ 419 + unsigned long start = PFN_ALIGN(_text); 420 + unsigned long end = ALIGN((unsigned long)_end, PMD_PAGE_SIZE); 421 + 422 + if (pti_kernel_image_global_ok()) 423 + return; 424 + 425 + pr_debug("set kernel image non-global\n"); 426 + 427 + set_memory_nonglobal(start, (end - start) >> PAGE_SHIFT); 428 } 429 430 /* ··· 362 pr_info("enabled\n"); 363 364 pti_clone_user_shared(); 365 + 366 + /* Undo all global bits from the init pagetables in head_64.S: */ 367 + pti_set_kernel_image_nonglobal(); 368 + /* Replace some of the global bits just for shared entry text: */ 369 pti_clone_entry_text(); 370 pti_setup_espfix64(); 371 pti_setup_vsyscall();
+15 -5
arch/x86/power/hibernate_64.c
··· 51 pmd_t *pmd; 52 pud_t *pud; 53 p4d_t *p4d = NULL; 54 55 /* 56 * The new mapping only has to cover the page containing the image ··· 87 return -ENOMEM; 88 89 set_pmd(pmd + pmd_index(restore_jump_address), 90 - __pmd((jump_address_phys & PMD_MASK) | __PAGE_KERNEL_LARGE_EXEC)); 91 set_pud(pud + pud_index(restore_jump_address), 92 - __pud(__pa(pmd) | _KERNPG_TABLE)); 93 if (p4d) { 94 - set_p4d(p4d + p4d_index(restore_jump_address), __p4d(__pa(pud) | _KERNPG_TABLE)); 95 - set_pgd(pgd + pgd_index(restore_jump_address), __pgd(__pa(p4d) | _KERNPG_TABLE)); 96 } else { 97 /* No p4d for 4-level paging: point the pgd to the pud page table */ 98 - set_pgd(pgd + pgd_index(restore_jump_address), __pgd(__pa(pud) | _KERNPG_TABLE)); 99 } 100 101 return 0;
··· 51 pmd_t *pmd; 52 pud_t *pud; 53 p4d_t *p4d = NULL; 54 + pgprot_t pgtable_prot = __pgprot(_KERNPG_TABLE); 55 + pgprot_t pmd_text_prot = __pgprot(__PAGE_KERNEL_LARGE_EXEC); 56 + 57 + /* Filter out unsupported __PAGE_KERNEL* bits: */ 58 + pgprot_val(pmd_text_prot) &= __default_kernel_pte_mask; 59 + pgprot_val(pgtable_prot) &= __default_kernel_pte_mask; 60 61 /* 62 * The new mapping only has to cover the page containing the image ··· 81 return -ENOMEM; 82 83 set_pmd(pmd + pmd_index(restore_jump_address), 84 + __pmd((jump_address_phys & PMD_MASK) | pgprot_val(pmd_text_prot))); 85 set_pud(pud + pud_index(restore_jump_address), 86 + __pud(__pa(pmd) | pgprot_val(pgtable_prot))); 87 if (p4d) { 88 + p4d_t new_p4d = __p4d(__pa(pud) | pgprot_val(pgtable_prot)); 89 + pgd_t new_pgd = __pgd(__pa(p4d) | pgprot_val(pgtable_prot)); 90 + 91 + set_p4d(p4d + p4d_index(restore_jump_address), new_p4d); 92 + set_pgd(pgd + pgd_index(restore_jump_address), new_pgd); 93 } else { 94 /* No p4d for 4-level paging: point the pgd to the pud page table */ 95 + pgd_t new_pgd = __pgd(__pa(p4d) | pgprot_val(pgtable_prot)); 96 + set_pgd(pgd + pgd_index(restore_jump_address), new_pgd); 97 } 98 99 return 0;