aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm/pgtable.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/include/asm/pgtable.h')
-rw-r--r--arch/x86/include/asm/pgtable.h26
1 files changed, 20 insertions, 6 deletions
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 06bbcbd66e9c..4f5af8447d54 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -302,16 +302,30 @@ static inline pte_t pte_mkspecial(pte_t pte)
302 302
303extern pteval_t __supported_pte_mask; 303extern pteval_t __supported_pte_mask;
304 304
305/*
306 * Mask out unsupported bits in a present pgprot. Non-present pgprots
307 * can use those bits for other purposes, so leave them be.
308 */
309static inline pgprotval_t massage_pgprot(pgprot_t pgprot)
310{
311 pgprotval_t protval = pgprot_val(pgprot);
312
313 if (protval & _PAGE_PRESENT)
314 protval &= __supported_pte_mask;
315
316 return protval;
317}
318
305static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot) 319static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
306{ 320{
307 return __pte((((phys_addr_t)page_nr << PAGE_SHIFT) | 321 return __pte(((phys_addr_t)page_nr << PAGE_SHIFT) |
308 pgprot_val(pgprot)) & __supported_pte_mask); 322 massage_pgprot(pgprot));
309} 323}
310 324
311static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot) 325static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
312{ 326{
313 return __pmd((((phys_addr_t)page_nr << PAGE_SHIFT) | 327 return __pmd(((phys_addr_t)page_nr << PAGE_SHIFT) |
314 pgprot_val(pgprot)) & __supported_pte_mask); 328 massage_pgprot(pgprot));
315} 329}
316 330
317static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) 331static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
@@ -323,7 +337,7 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
323 * the newprot (if present): 337 * the newprot (if present):
324 */ 338 */
325 val &= _PAGE_CHG_MASK; 339 val &= _PAGE_CHG_MASK;
326 val |= pgprot_val(newprot) & (~_PAGE_CHG_MASK) & __supported_pte_mask; 340 val |= massage_pgprot(newprot) & ~_PAGE_CHG_MASK;
327 341
328 return __pte(val); 342 return __pte(val);
329} 343}
@@ -339,7 +353,7 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
339 353
340#define pte_pgprot(x) __pgprot(pte_flags(x) & PTE_FLAGS_MASK) 354#define pte_pgprot(x) __pgprot(pte_flags(x) & PTE_FLAGS_MASK)
341 355
342#define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask) 356#define canon_pgprot(p) __pgprot(massage_pgprot(p))
343 357
344static inline int is_new_memtype_allowed(unsigned long flags, 358static inline int is_new_memtype_allowed(unsigned long flags,
345 unsigned long new_flags) 359 unsigned long new_flags)