In preparation to moving core parts of change_page_attr() to common code, replace open coded checks for _PAGE_RW and _PAGE_NX bits in lookup_address_in_pgd_attr() with pXd_write() and pXd_exec() accessors. Add x86 implementation of pXd_write() and pXd_exec() accessors and provide generic stubs in include/linux/pgtable.h. The stubs follow the existing pattern and BUG() if they are called. No functional change intended. Assisted-by: Copilot:claude-opus-4.8 Signed-off-by: Mike Rapoport (Microsoft) --- arch/x86/include/asm/pgtable.h | 36 ++++++++++++++++++++++++++++++++++++ arch/x86/mm/pat/set_memory.c | 16 ++++++++-------- include/linux/pgtable.h | 40 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 8 deletions(-) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index ac295ca6c92f..497aaf08ad36 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -227,6 +227,42 @@ static inline int pud_write(pud_t pud) return pud_flags(pud) & _PAGE_RW; } +#define p4d_write p4d_write +static inline int p4d_write(p4d_t p4d) +{ + return p4d_flags(p4d) & _PAGE_RW; +} + +#define pgd_write pgd_write +static inline int pgd_write(pgd_t pgd) +{ + return pgd_flags(pgd) & _PAGE_RW; +} + +#define pmd_exec pmd_exec +static inline int pmd_exec(pmd_t pmd) +{ + return !(pmd_flags(pmd) & _PAGE_NX); +} + +#define pud_exec pud_exec +static inline int pud_exec(pud_t pud) +{ + return !(pud_flags(pud) & _PAGE_NX); +} + +#define p4d_exec p4d_exec +static inline int p4d_exec(p4d_t p4d) +{ + return !(p4d_flags(p4d) & _PAGE_NX); +} + +#define pgd_exec pgd_exec +static inline int pgd_exec(pgd_t pgd) +{ + return !(pgd_flags(pgd) & _PAGE_NX); +} + static inline int pte_huge(pte_t pte) { return pte_flags(pte) & _PAGE_PSE; diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c index 328805933d4d..8a1782f5de3e 100644 --- a/arch/x86/mm/pat/set_memory.c +++ b/arch/x86/mm/pat/set_memory.c @@ -729,8 +729,8 @@ pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address, return NULL; *level = PGTABLE_LEVEL_P4D; - *nx |= pgd_flags(*pgd) & _PAGE_NX; - *rw &= !!(pgd_flags(*pgd) & _PAGE_RW); + *nx |= !pgd_exec(*pgd); + *rw &= !!(pgd_write(*pgd)); p4d = p4d_offset(pgd, address); if (p4d_none(*p4d)) @@ -740,8 +740,8 @@ pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address, return (pte_t *)p4d; *level = PGTABLE_LEVEL_PUD; - *nx |= p4d_flags(*p4d) & _PAGE_NX; - *rw &= !!(p4d_flags(*p4d) & _PAGE_RW); + *nx |= !p4d_exec(*p4d); + *rw &= !!(p4d_write(*p4d)); pud = pud_offset(p4d, address); if (pud_none(*pud)) @@ -751,8 +751,8 @@ pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address, return (pte_t *)pud; *level = PGTABLE_LEVEL_PMD; - *nx |= pud_flags(*pud) & _PAGE_NX; - *rw &= !!(pud_flags(*pud) & _PAGE_RW); + *nx |= !pud_exec(*pud); + *rw &= !!(pud_write(*pud)); pmd = pmd_offset(pud, address); if (pmd_none(*pmd)) @@ -762,8 +762,8 @@ pte_t *lookup_address_in_pgd_attr(pgd_t *pgd, unsigned long address, return (pte_t *)pmd; *level = PGTABLE_LEVEL_PTE; - *nx |= pmd_flags(*pmd) & _PAGE_NX; - *rw &= !!(pmd_flags(*pmd) & _PAGE_RW); + *nx |= !pmd_exec(*pmd); + *rw &= !!(pmd_write(*pmd)); return pte_offset_kernel(pmd, address); } diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index 3889bc2a1f76..4b42ac5c27d9 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -2105,6 +2105,46 @@ static inline int pud_write(pud_t pud) } #endif /* pud_write */ +#ifndef p4d_write +static inline int p4d_write(p4d_t p4d) +{ + BUG(); + return 0; +} +#endif /* p4d_write */ + +#ifndef pmd_exec +static inline int pmd_exec(pmd_t pmd) +{ + BUG(); + return 0; +} +#endif /* pmd_exec */ + +#ifndef pud_exec +static inline int pud_exec(pud_t pud) +{ + BUG(); + return 0; +} +#endif /* pud_exec */ + +#ifndef p4d_exec +static inline int p4d_exec(p4d_t p4d) +{ + BUG(); + return 0; +} +#endif /* p4d_exec */ + +#ifndef pgd_exec +static inline int pgd_exec(pgd_t pgd) +{ + BUG(); + return 0; +} +#endif /* pgd_exec */ + #if !defined(CONFIG_TRANSPARENT_HUGEPAGE) || \ !defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD) static inline int pud_trans_huge(pud_t pud) -- 2.53.0