mm/pgtable: Support for page table check on s390
Subsystems (8)
Alexander Gordeev
maintainerHi All,
In v7.0-rc1 page table check support for PPC was added, which conflicted with this series v1. Thus the only change in v2 is PPC headers update, which still is NOP for non-s390.
I only did compile test for PPC.
Thanks!
Alexander Gordeev (2):
s390/pgtable: Use set_pmd_bit() to invalidate PMD entry
s390: Enable page table check for debug_defconfig
Tobias Huschle (2):
mm/page_table_check: Pass mm_struct to pxx_user_accessible_page() s390/pgtable: Add s390 support for page table check
arch/arm64/include/asm/pgtable.h | 6 +- arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +- arch/powerpc/include/asm/book3s/64/pgtable.h | 10 ++-- arch/powerpc/include/asm/nohash/pgtable.h | 2 +- arch/powerpc/include/asm/pgtable.h | 4 +- arch/riscv/include/asm/pgtable.h | 6 +- arch/s390/Kconfig | 1 + arch/s390/configs/debug_defconfig | 2 + arch/s390/include/asm/pgtable.h | 60 +++++++++++++++++--- arch/x86/include/asm/pgtable.h | 6 +- mm/page_table_check.c | 15 ++--- 11 files changed, 80 insertions(+), 34 deletions(-)
Signature · 1 line
2.51.0
Alexander Gordeev
maintainerPATCH v2 1/4 mm/page_table_check: Pass mm_struct to pxx_user_accessible_page()
From: Tobias Huschle <[email protected]>
Unlike other architectures, s390 does not have means to distinguish kernel vs user page table entries - neither an entry itself, nor the address could be used for that. It is only the mm_struct that indicates whether an entry in question is mapped to a user space. So pass mm_struct to pxx_user_accessible_page() callbacks.
[[email protected]: rephrased commit message, removed braces]
--- arch/arm64/include/asm/pgtable.h | 6 +++--- arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +- arch/powerpc/include/asm/book3s/64/pgtable.h | 10 +++++----- arch/powerpc/include/asm/nohash/pgtable.h | 2 +- arch/powerpc/include/asm/pgtable.h | 4 ++-- arch/riscv/include/asm/pgtable.h | 6 +++--- arch/x86/include/asm/pgtable.h | 6 +++--- mm/page_table_check.c | 15 ++++++--------- 8 files changed, 24 insertions(+), 27 deletions(-)
arch/arm64/include/asm/pgtable.h +3 -3
@@ -1263,17 +1263,17 @@ static inline int pmdp_set_access_flags(struct vm_area_struct *vma,#endif #ifdef CONFIG_PAGE_TABLE_CHECK -static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte) {return pte_valid (pte) && (pte_user (pte) ||pte_user_exec (pte)); } -static inline bool pmd_user_accessible_page (pmd_t pmd,unsigned long addr) +static inline bool pmd_user_accessible_page (struct mm_struct *mm,unsigned long addr,pmd_t pmd) {return pmd_valid (pmd) && !pmd_table (pmd) && (pmd_user (pmd) ||pmd_user_exec (pmd)); } -static inline bool pud_user_accessible_page (pud_t pud,unsigned long addr) +static inline bool pud_user_accessible_page (struct mm_struct *mm,unsigned long addr,pud_t pud) {return pud_valid (pud) && !pud_table (pud) && (pud_user (pud) ||pud_user_exec (pud)); }
arch/powerpc/include/asm/book3s/32/pgtable.h +1 -1
@@ -438,7 +438,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)return true; } -static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte) {return pte_present (pte) && !is_kernel_addr (addr); }
arch/powerpc/include/asm/book3s/64/pgtable.h +5 -5
@@ -549,7 +549,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)return arch_pte_access_permitted (pte_val (pte), write,0 ); } -static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte) {return pte_present (pte) &&pte_user (pte); }
@@ -925,9 +925,9 @@ static inline bool pud_access_permitted(pud_t pud, bool write) }#define pud_user_accessible_page pud_user_accessible_page -static inline bool pud_user_accessible_page (pud_t pud,unsigned long addr) +static inline bool pud_user_accessible_page (struct mm_struct *mm,unsigned long addr,pud_t pud) { -return pud_leaf (pud) &&pte_user_accessible_page (pud_pte (pud), addr); +return pud_leaf (pud) &&pte_user_accessible_page (mm, addr,pud_pte (pud)); }#define __p4d_raw (x) ((p4d_t) { __pgd_raw(x) })
@@ -1096,9 +1096,9 @@ static inline bool pmd_access_permitted(pmd_t pmd, bool write) }#define pmd_user_accessible_page pmd_user_accessible_page -static inline bool pmd_user_accessible_page (pmd_t pmd,unsigned long addr) +static inline bool pmd_user_accessible_page (struct mm_struct *mm,unsigned long addr,pmd_t pmd) { -return pmd_leaf (pmd) &&pte_user_accessible_page (pmd_pte (pmd), addr); +return pmd_leaf (pmd) &&pte_user_accessible_page (mm, addr,pmd_pte (pmd)); }#ifdef CONFIG_TRANSPARENT_HUGEPAGE
arch/powerpc/include/asm/nohash/pgtable.h +1 -1
@@ -249,7 +249,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)return true; } -static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte) {return pte_present (pte) && !is_kernel_addr (addr); }
arch/powerpc/include/asm/pgtable.h +2 -2
@@ -205,11 +205,11 @@ static inline bool arch_supports_memmap_on_memory(unsigned long vmemmap_size)#endif /* CONFIG_PPC64 */ #ifndef pmd_user_accessible_page -#define pmd_user_accessible_page (pmd, addr) false +#define pmd_user_accessible_page (mm, addr, pmd) false#endif #ifndef pud_user_accessible_page -#define pud_user_accessible_page (pud, addr) false +#define pud_user_accessible_page (mm, addr, pud) false#endif #endif /* __ASSEMBLER__ */
arch/riscv/include/asm/pgtable.h +3 -3
@@ -984,17 +984,17 @@ static inline void set_pud_at(struct mm_struct *mm, unsigned long addr, }#ifdef CONFIG_PAGE_TABLE_CHECK -static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte) {return pte_present (pte) &&pte_user (pte); } -static inline bool pmd_user_accessible_page (pmd_t pmd,unsigned long addr) +static inline bool pmd_user_accessible_page (struct mm_struct *mm,unsigned long addr,pmd_t pmd) {return pmd_leaf (pmd) &&pmd_user (pmd); } -static inline bool pud_user_accessible_page (pud_t pud,unsigned long addr) +static inline bool pud_user_accessible_page (struct mm_struct *mm,unsigned long addr,pud_t pud) {return pud_leaf (pud) &&pud_user (pud); }
arch/x86/include/asm/pgtable.h +3 -3
@@ -1680,17 +1680,17 @@ static inline bool arch_has_hw_nonleaf_pmd_young(void)#endif #ifdef CONFIG_PAGE_TABLE_CHECK -static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte) {return (pte_val (pte) & _PAGE_PRESENT) && (pte_val (pte) & _PAGE_USER); } -static inline bool pmd_user_accessible_page (pmd_t pmd,unsigned long addr) +static inline bool pmd_user_accessible_page (struct mm_struct *mm,unsigned long addr,pmd_t pmd) {return pmd_leaf (pmd) && (pmd_val (pmd) & _PAGE_PRESENT) && (pmd_val (pmd) & _PAGE_USER); } -static inline bool pud_user_accessible_page (pud_t pud,unsigned long addr) +static inline bool pud_user_accessible_page (struct mm_struct *mm,unsigned long addr,pud_t pud) {return pud_leaf (pud) && (pud_val (pud) & _PAGE_PRESENT) && (pud_val (pud) & _PAGE_USER); }
mm/page_table_check.c +6 -9
@@ -151,9 +151,8 @@ void __page_table_check_pte_clear(struct mm_struct *mm, unsigned long addr,if (&init_mm == mm)return ; -if (pte_user_accessible_page (pte, addr)) { +if (pte_user_accessible_page (mm, addr, pte))page_table_check_clear (pte_pfn (pte),PAGE_SIZE >>PAGE_SHIFT ); - } }EXPORT_SYMBOL (__page_table_check_pte_clear);
@@ -163,9 +162,8 @@ void __page_table_check_pmd_clear(struct mm_struct *mm, unsigned long addr,if (&init_mm == mm)return ; -if (pmd_user_accessible_page (pmd, addr)) { +if (pmd_user_accessible_page (mm, addr, pmd))page_table_check_clear (pmd_pfn (pmd),PMD_SIZE >>PAGE_SHIFT ); - } }EXPORT_SYMBOL (__page_table_check_pmd_clear);
@@ -175,9 +173,8 @@ void __page_table_check_pud_clear(struct mm_struct *mm, unsigned long addr,if (&init_mm == mm)return ; -if (pud_user_accessible_page (pud, addr)) { +if (pud_user_accessible_page (mm, addr, pud))page_table_check_clear (pud_pfn (pud),PUD_SIZE >>PAGE_SHIFT ); - } }EXPORT_SYMBOL (__page_table_check_pud_clear);
@@ -211,7 +208,7 @@ void __page_table_check_ptes_set(struct mm_struct *mm, unsigned long addr,for (i =0 ; i < nr; i++)__page_table_check_pte_clear (mm, addr +PAGE_SIZE * i,ptep_get (ptep + i)); -if (pte_user_accessible_page (pte, addr)) +if (pte_user_accessible_page (mm, addr, pte))page_table_check_set (pte_pfn (pte), nr,pte_write (pte)); }EXPORT_SYMBOL (__page_table_check_ptes_set);
@@ -241,7 +238,7 @@ void __page_table_check_pmds_set(struct mm_struct *mm, unsigned long addr,for (i =0 ; i < nr; i++)__page_table_check_pmd_clear (mm, addr +PMD_SIZE * i, *(pmdp + i)); -if (pmd_user_accessible_page (pmd, addr)) +if (pmd_user_accessible_page (mm, addr, pmd))page_table_check_set (pmd_pfn (pmd), stride * nr,pmd_write (pmd)); }EXPORT_SYMBOL (__page_table_check_pmds_set);
@@ -257,7 +254,7 @@ void __page_table_check_puds_set(struct mm_struct *mm, unsigned long addr,for (i =0 ; i < nr; i++)__page_table_check_pud_clear (mm, addr +PUD_SIZE * i, *(pudp + i)); -if (pud_user_accessible_page (pud, addr)) +if (pud_user_accessible_page (mm, addr, pud))page_table_check_set (pud_pfn (pud), stride * nr,pud_write (pud)); }EXPORT_SYMBOL (__page_table_check_puds_set);
Signature · 1 line
2.51.0
Ritesh Harjani (IBM)
reviewerRe: [PATCH v2 1/4] mm/page_table_check: Pass mm_struct to pxx_user_accessible_page()
Quoted 15 lines · Alexander Gordeev
From: Tobias Huschle <[email protected]>
Unlike other architectures, s390 does not have means to distinguish kernel vs user page table entries - neither an entry itself, nor the address could be used for that. It is only the
mm_structthat indicates whether an entry in question is mapped to a user space. So passmm_structtopxx_user_accessible_page()callbacks.[[email protected]: rephrased commit message, removed braces]
Reviewed-by Gerald Schaefer <[email protected]>Reviewed-by Andrew Morton <[email protected]>Signed-off-by Tobias Huschle <[email protected]>Signed-off-by Alexander Gordeev <[email protected]>
Quoted 6 lines
--- arch/arm64/include/asm/pgtable.h | 6 +++--- arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +- arch/powerpc/include/asm/book3s/64/pgtable.h | 10 +++++----- arch/powerpc/include/asm/nohash/pgtable.h | 2 +- arch/powerpc/include/asm/pgtable.h | 4 ++--
straightforward change for adding mm struct param in the page table check calls. Also verified building different powerpc configs using ci.
The changes looks good to me. Please feel free to add:
Reviewed-by Ritesh Harjani (IBM) <[email protected]> #powerpc
Re: [PATCH v2 1/4] mm/page_table_check: Pass mm_struct to pxx_user_accessible_page()
In reply to Alexander GordeevQuoted 8 lines · Alexander Gordeev
From: Tobias Huschle <[email protected]>
Unlike other architectures, s390 does not have means to distinguish kernel vs user page table entries - neither an entry itself, nor the address could be used for that. It is only the
mm_structthat indicates whether an entry in question is mapped to a user space. So passmm_structtopxx_user_accessible_page()callbacks.
Changes looks fine to me
Quoted 237 lines
[[email protected]: rephrased commit message, removed braces]
Reviewed-by Gerald Schaefer <[email protected]>Reviewed-by Andrew Morton <[email protected]>Signed-off-by Tobias Huschle <[email protected]>Signed-off-by Alexander Gordeev <[email protected]>--- arch/arm64/include/asm/pgtable.h | 6 +++--- arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +- arch/powerpc/include/asm/book3s/64/pgtable.h | 10 +++++----- arch/powerpc/include/asm/nohash/pgtable.h | 2 +- arch/powerpc/include/asm/pgtable.h | 4 ++-- arch/riscv/include/asm/pgtable.h | 6 +++--- arch/x86/include/asm/pgtable.h | 6 +++--- mm/page_table_check.c | 15 ++++++--------- 8 files changed, 24 insertions(+), 27 deletions(-)arch/arm64/include/asm/pgtable.h +3
-3@@ -1263,17 +1263,17 @@ static inline int pmdp_set_access_flags(struct vm_area_struct *vma,#endif #ifdef CONFIG_PAGE_TABLE_CHECK -static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte) {return pte_valid (pte) && (pte_user (pte) ||pte_user_exec (pte)); } -static inline bool pmd_user_accessible_page (pmd_t pmd,unsigned long addr) +static inline bool pmd_user_accessible_page (struct mm_struct *mm,unsigned long addr,pmd_t pmd) {return pmd_valid (pmd) && !pmd_table (pmd) && (pmd_user (pmd) ||pmd_user_exec (pmd)); } -static inline bool pud_user_accessible_page (pud_t pud,unsigned long addr) +static inline bool pud_user_accessible_page (struct mm_struct *mm,unsigned long addr,pud_t pud) {return pud_valid (pud) && !pud_table (pud) && (pud_user (pud) ||pud_user_exec (pud)); }arch/powerpc/include/asm/book3s/32/pgtable.h +1
-1@@ -438,7 +438,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)return true; } -static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte) {return pte_present (pte) && !is_kernel_addr (addr); }arch/powerpc/include/asm/book3s/64/pgtable.h +5
-5@@ -549,7 +549,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)return arch_pte_access_permitted (pte_val (pte), write,0 ); } -static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte) {return pte_present (pte) &&pte_user (pte); }@@ -925,9 +925,9 @@ static inline bool pud_access_permitted(pud_t pud, bool write) }#define pud_user_accessible_page pud_user_accessible_page -static inline bool pud_user_accessible_page (pud_t pud,unsigned long addr) +static inline bool pud_user_accessible_page (struct mm_struct *mm,unsigned long addr,pud_t pud) { -return pud_leaf (pud) &&pte_user_accessible_page (pud_pte (pud), addr); +return pud_leaf (pud) &&pte_user_accessible_page (mm, addr,pud_pte (pud)); }#define __p4d_raw (x) ((p4d_t) { __pgd_raw(x) })@@ -1096,9 +1096,9 @@ static inline bool pmd_access_permitted(pmd_t pmd, bool write) }#define pmd_user_accessible_page pmd_user_accessible_page -static inline bool pmd_user_accessible_page (pmd_t pmd,unsigned long addr) +static inline bool pmd_user_accessible_page (struct mm_struct *mm,unsigned long addr,pmd_t pmd) { -return pmd_leaf (pmd) &&pte_user_accessible_page (pmd_pte (pmd), addr); +return pmd_leaf (pmd) &&pte_user_accessible_page (mm, addr,pmd_pte (pmd)); }#ifdef CONFIG_TRANSPARENT_HUGEPAGE arch/powerpc/include/asm/nohash/pgtable.h +1
-1@@ -249,7 +249,7 @@ static inline bool pte_access_permitted(pte_t pte, bool write)return true; } -static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte) {return pte_present (pte) && !is_kernel_addr (addr); }arch/powerpc/include/asm/pgtable.h +2
-2@@ -205,11 +205,11 @@ static inline bool arch_supports_memmap_on_memory(unsigned long vmemmap_size)#endif /* CONFIG_PPC64 */ #ifndef pmd_user_accessible_page -#define pmd_user_accessible_page (pmd, addr) false +#define pmd_user_accessible_page (mm, addr, pmd) false#endif #ifndef pud_user_accessible_page -#define pud_user_accessible_page (pud, addr) false +#define pud_user_accessible_page (mm, addr, pud) false#endif #endif /* __ASSEMBLER__ */ arch/riscv/include/asm/pgtable.h +3
-3@@ -984,17 +984,17 @@ static inline void set_pud_at(struct mm_struct *mm, unsigned long addr, }#ifdef CONFIG_PAGE_TABLE_CHECK -static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte) {return pte_present (pte) &&pte_user (pte); } -static inline bool pmd_user_accessible_page (pmd_t pmd,unsigned long addr) +static inline bool pmd_user_accessible_page (struct mm_struct *mm,unsigned long addr,pmd_t pmd) {return pmd_leaf (pmd) &&pmd_user (pmd); } -static inline bool pud_user_accessible_page (pud_t pud,unsigned long addr) +static inline bool pud_user_accessible_page (struct mm_struct *mm,unsigned long addr,pud_t pud) {return pud_leaf (pud) &&pud_user (pud); }arch/x86/include/asm/pgtable.h +3
-3@@ -1680,17 +1680,17 @@ static inline bool arch_has_hw_nonleaf_pmd_young(void)#endif #ifdef CONFIG_PAGE_TABLE_CHECK -static inline bool pte_user_accessible_page (pte_t pte,unsigned long addr) +static inline bool pte_user_accessible_page (struct mm_struct *mm,unsigned long addr,pte_t pte) {return (pte_val (pte) & _PAGE_PRESENT) && (pte_val (pte) & _PAGE_USER); } -static inline bool pmd_user_accessible_page (pmd_t pmd,unsigned long addr) +static inline bool pmd_user_accessible_page (struct mm_struct *mm,unsigned long addr,pmd_t pmd) {return pmd_leaf (pmd) && (pmd_val (pmd) & _PAGE_PRESENT) && (pmd_val (pmd) & _PAGE_USER); } -static inline bool pud_user_accessible_page (pud_t pud,unsigned long addr) +static inline bool pud_user_accessible_page (struct mm_struct *mm,unsigned long addr,pud_t pud) {return pud_leaf (pud) && (pud_val (pud) & _PAGE_PRESENT) && (pud_val (pud) & _PAGE_USER); }mm/page_table_check.c +6
-9@@ -151,9 +151,8 @@ void __page_table_check_pte_clear(struct mm_struct *mm, unsigned long addr,if (&init_mm == mm)return ; -if (pte_user_accessible_page (pte, addr)) { +if (pte_user_accessible_page (mm, addr, pte))page_table_check_clear (pte_pfn (pte),PAGE_SIZE >>PAGE_SHIFT ); - } }EXPORT_SYMBOL (__page_table_check_pte_clear);@@ -163,9 +162,8 @@ void __page_table_check_pmd_clear(struct mm_struct *mm, unsigned long addr,if (&init_mm == mm)return ; -if (pmd_user_accessible_page (pmd, addr)) { +if (pmd_user_accessible_page (mm, addr, pmd))page_table_check_clear (pmd_pfn (pmd),PMD_SIZE >>PAGE_SHIFT ); - } }EXPORT_SYMBOL (__page_table_check_pmd_clear);@@ -175,9 +173,8 @@ void __page_table_check_pud_clear(struct mm_struct *mm, unsigned long addr,if (&init_mm == mm)return ; -if (pud_user_accessible_page (pud, addr)) { +if (pud_user_accessible_page (mm, addr, pud))page_table_check_clear (pud_pfn (pud),PUD_SIZE >>PAGE_SHIFT ); - } }EXPORT_SYMBOL (__page_table_check_pud_clear);@@ -211,7 +208,7 @@ void __page_table_check_ptes_set(struct mm_struct *mm, unsigned long addr,for (i =0 ; i < nr; i++)__page_table_check_pte_clear (mm, addr +PAGE_SIZE * i,ptep_get (ptep + i)); -if (pte_user_accessible_page (pte, addr)) +if (pte_user_accessible_page (mm, addr, pte))page_table_check_set (pte_pfn (pte), nr,pte_write (pte)); }EXPORT_SYMBOL (__page_table_check_ptes_set);@@ -241,7 +238,7 @@ void __page_table_check_pmds_set(struct mm_struct *mm, unsigned long addr,for (i =0 ; i < nr; i++)__page_table_check_pmd_clear (mm, addr +PMD_SIZE * i, *(pmdp + i)); -if (pmd_user_accessible_page (pmd, addr)) +if (pmd_user_accessible_page (mm, addr, pmd))page_table_check_set (pmd_pfn (pmd), stride * nr,pmd_write (pmd)); }EXPORT_SYMBOL (__page_table_check_pmds_set);@@ -257,7 +254,7 @@ void __page_table_check_puds_set(struct mm_struct *mm, unsigned long addr,for (i =0 ; i < nr; i++)__page_table_check_pud_clear (mm, addr +PUD_SIZE * i, *(pudp + i)); -if (pud_user_accessible_page (pud, addr)) +if (pud_user_accessible_page (mm, addr, pud))page_table_check_set (pud_pfn (pud), stride * nr,pud_write (pud)); }EXPORT_SYMBOL (__page_table_check_puds_set);
Vasily Gorbik
maintainerRe: [PATCH v2 1/4] mm/page_table_check: Pass mm_struct to pxx_user_accessible_page()
In reply to Alexander GordeevQuoted 15 lines · Alexander Gordeev
From: Tobias Huschle <[email protected]>
Unlike other architectures, s390 does not have means to distinguish kernel vs user page table entries - neither an entry itself, nor the address could be used for that. It is only the
mm_structthat indicates whether an entry in question is mapped to a user space. So passmm_structtopxx_user_accessible_page()callbacks.[[email protected]: rephrased commit message, removed braces]
Reviewed-by Gerald Schaefer <[email protected]>Reviewed-by Andrew Morton <[email protected]>Signed-off-by Tobias Huschle <[email protected]>Signed-off-by Alexander Gordeev <[email protected]>
Quoted 10 lines
--- arch/arm64/include/asm/pgtable.h | 6 +++--- arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +- arch/powerpc/include/asm/book3s/64/pgtable.h | 10 +++++----- arch/powerpc/include/asm/nohash/pgtable.h | 2 +- arch/powerpc/include/asm/pgtable.h | 4 ++-- arch/riscv/include/asm/pgtable.h | 6 +++--- arch/x86/include/asm/pgtable.h | 6 +++--- mm/page_table_check.c | 15 ++++++--------- 8 files changed, 24 insertions(+), 27 deletions(-)
Andrew, may I get your Reviewed-by or Ack-by for v2 so I can take it via the s390 tree as well?
Thank you.
Re: [PATCH v2 1/4] mm/page_table_check: Pass mm_struct to pxx_user_accessible_page()
Quoted 27 lines · On Thu, 12 Mar 2026 16:02:40 +0100 Vasily Gorbik <[email protected]> wrote:
Quoted 15 lines · Alexander Gordeev
From: Tobias Huschle <[email protected]>
Unlike other architectures, s390 does not have means to distinguish kernel vs user page table entries - neither an entry itself, nor the address could be used for that. It is only the
mm_structthat indicates whether an entry in question is mapped to a user space. So passmm_structtopxx_user_accessible_page()callbacks.[[email protected]: rephrased commit message, removed braces]
Reviewed-by Gerald Schaefer <[email protected]>Reviewed-by Andrew Morton <[email protected]>Signed-off-by Tobias Huschle <[email protected]>Signed-off-by Alexander Gordeev <[email protected]>Quoted 10 lines
--- arch/arm64/include/asm/pgtable.h | 6 +++--- arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +- arch/powerpc/include/asm/book3s/64/pgtable.h | 10 +++++----- arch/powerpc/include/asm/nohash/pgtable.h | 2 +- arch/powerpc/include/asm/pgtable.h | 4 ++-- arch/riscv/include/asm/pgtable.h | 6 +++--- arch/x86/include/asm/pgtable.h | 6 +++--- mm/page_table_check.c | 15 ++++++--------- 8 files changed, 24 insertions(+), 27 deletions(-)
Quoted 2 lines
Andrew, may I get your Reviewed-by or Ack-by for v2 so I can take it via the s390 tree as well?
It doesn't look like [1/4] changed significanty since v1?
Vasily Gorbik
maintainerRe: [PATCH v2 1/4] mm/page_table_check: Pass mm_struct to pxx_user_accessible_page()
Quoted 12 lines · Andrew Morton
Quoted 10 lines · On Thu, 12 Mar 2026 16:02:40 +0100 Vasily Gorbik <[email protected]> wrote:
Quoted 9 lines · Alexander Gordeev
From: Tobias Huschle <[email protected]>
Unlike other architectures, s390 does not have means to distinguish kernel vs user page table entries - neither an entry itself, nor the address could be used for that. It is only the
mm_structthat indicates whether an entry in question is mapped to a user space. So passmm_structtopxx_user_accessible_page()callbacks.
...
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
--- arch/arm64/include/asm/pgtable.h | 6 +++--- arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +- arch/powerpc/include/asm/book3s/64/pgtable.h | 10 +++++----- arch/powerpc/include/asm/nohash/pgtable.h | 2 +- arch/powerpc/include/asm/pgtable.h | 4 ++-- arch/riscv/include/asm/pgtable.h | 6 +++--- arch/x86/include/asm/pgtable.h | 6 +++--- mm/page_table_check.c | 15 ++++++--------- 8 files changed, 24 insertions(+), 27 deletions(-)
Quoted 6 lines
Quoted 2 lines
Andrew, may I get your Reviewed-by or Ack-by for v2 so I can take it via the s390 tree as well?
Reviewed-by Andrew Morton <[email protected]>It doesn't look like [1/4] changed significanty since v1?
PowerPC page table check support landed at the same time v1 was sent, so v1 was missing PowerPC header changes, which was reported by the kernel test robot:
https://lore.kernel.org/all/[email protected]/
Hence, v2 to address that.
Alexander Gordeev
maintainerPATCH v2 2/4 s390/pgtable: Use set_pmd_bit() to invalidate PMD entry
In reply to Alexander GordeevCommit 3a5a8d343e1c ("mm: fix race between __split_huge_pmd_locked() and GUP-fast") failed to follow the convention and used direct PMD entry modification instead of set_pmd_bit().
--- arch/s390/include/asm/pgtable.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/s390/include/asm/pgtable.h +3 -3
@@ -1744,10 +1744,10 @@ static inline pmd_t pmdp_huge_clear_flush(struct vm_area_struct *vma,static inline pmd_t pmdp_invalidate (struct vm_area_struct *vma,unsigned long addr,pmd_t *pmdp) { -pmd_t pmd; +pmd_t pmd = *pmdp; -VM_WARN_ON_ONCE (!pmd_present (*pmdp)); - pmd =__pmd (pmd_val (*pmdp) | _SEGMENT_ENTRY_INVALID); +VM_WARN_ON_ONCE (!pmd_present (pmd)); + pmd =set_pmd_bit (pmd,__pgprot (_SEGMENT_ENTRY_INVALID));return pmdp_xchg_direct (vma->vm_mm, addr, pmdp, pmd); }
Signature · 1 line
2.51.0
Alexander Gordeev
maintainerPATCH v2 3/4 s390/pgtable: Add s390 support for page table check
In reply to Alexander GordeevFrom: Tobias Huschle <[email protected]>
Add page table check hooks into routines that modify user page tables.
Unlike other architectures s390 does not have means to distinguish between kernel and user page table entries. Rely on the fact the page table check infrastructure itself operates on non-init_mm memory spaces only.
Use the provided mm_struct to verify that the memory space is not init_mm (aka not the kernel memory space) indeed. That check is supposed to be succeeded already (on some code paths even twice).
If the passed memory space by contrast is init_mm that would be an unexpected semantical change in generic code, so do VM_BUG_ON() in such case.
Unset _SEGMENT_ENTRY_READ bit to indicate that pmdp_invalidate() was applied against a huge PMD and is going to be updated by set_pmd_at() shortly. The hook pmd_user_accessible_page() should skip such entries until that, otherwise the page table accounting falls apart and BUG_ON() gets hit as result.
The invalidated huge PMD entry should not be confused with a PROT_NONE entry as reported by pmd_protnone(), though the entry characteristics exactly match: _SEGMENT_ENTRY_LARGE is set while _SEGMENT_ENTRY_READ is unset. Since pmd_protnone() implementation depends on NUMA_BALANCING configuration option, it should not be used in pmd_user_accessible_page() check, which is expected to be CONFIG_NUMA_BALANCING-agnostic.
Nevertheless, an invalidated huge PMD is technically still pmd_protnone() entry and it should not break other code paths once _SEGMENT_ENTRY_READ is unset. As of now, all pmd_protnone() checks are done under page table locks or exercise GUP-fast and HMM code paths, which are expected to be safe against concurrent page table updates.
Alternative approach would be using the last remaining unused PMD entry bit 0x800 to indicate that pmdp_invalidate() was called on a PMD. That would allow avoiding collisions with pmd_protnone() handling code paths, but saving the bit is more preferable way to go.
--- arch/s390/Kconfig | 1 + arch/s390/include/asm/pgtable.h | 54 ++++++++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 4 deletions(-)
arch/s390/Kconfig +1 -0
@@ -154,6 +154,7 @@ config S390 select ARCH_SUPPORTS_INT128 if CC_HAS_INT128 && CC_IS_CLANG select ARCH_SUPPORTS_MSEAL_SYSTEM_MAPPINGS select ARCH_SUPPORTS_NUMA_BALANCING + select ARCH_SUPPORTS_PAGE_TABLE_CHECK select ARCH_SUPPORTS_PER_VMA_LOCK select ARCH_USE_BUILTIN_BSWAP select ARCH_USE_CMPXCHG_LOCKREF
arch/s390/include/asm/pgtable.h +50 -4
120 lines not on this page · raw message
Signature · 1 line
2.51.0
Alexander Gordeev
maintainerPATCH v2 4/4 s390: Enable page table check for debug_defconfig
In reply to Alexander Gordeev--- arch/s390/configs/debug_defconfig | 2 ++ 1 file changed, 2 insertions(+)
arch/s390/configs/debug_defconfig +2 -0
@@ -929,3 +929,5 @@ CONFIG_PERCPU_TEST=m CONFIG_ATOMIC64_SELFTEST=y CONFIG_TEST_BITOPS=m CONFIG_TEST_BPF=m +CONFIG_PAGE_TABLE_CHECK=y +CONFIG_PAGE_TABLE_CHECK_ENFORCED=y
Signature · 1 line
2.51.0
Quoted 18 lines · Alexander Gordeev
Hi All,
In v7.0-rc1 page table check support for PPC was added, which conflicted with this series v1. Thus the only change in v2 is PPC headers update, which still is NOP for non-s390.
I only did compile test for PPC.
Thanks!
Alexander Gordeev (2):
s390/pgtable: Useset_pmd_bit()to invalidate PMD entry
s390: Enable page table check fordebug_defconfigTobias Huschle (2):
mm/page_table_check: Passmm_structtopxx_user_accessible_page()s390/pgtable: Add s390 support for page table check
Quoted 12 lines
arch/arm64/include/asm/pgtable.h | 6 +- arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +- arch/powerpc/include/asm/book3s/64/pgtable.h | 10 ++-- arch/powerpc/include/asm/nohash/pgtable.h | 2 +- arch/powerpc/include/asm/pgtable.h | 4 +- arch/riscv/include/asm/pgtable.h | 6 +- arch/s390/Kconfig | 1 + arch/s390/configs/debug_defconfig | 2 + arch/s390/include/asm/pgtable.h | 60 +++++++++++++++++--- arch/x86/include/asm/pgtable.h | 6 +- mm/page_table_check.c | 15 ++--- 11 files changed, 80 insertions(+), 34 deletions(-)
Applied to the s390 tree, thank you!