* [PATCH v2 1/6] mm/arm64: constify pte_get*() and contpte get logic
2026-08-03 16:43 [PATCH v2 0/6] mm: add basic PTE const type-safety Pedro Falcato
@ 2026-08-03 16:43 ` Pedro Falcato
2026-08-04 10:55 ` Lorenzo Stoakes (ARM)
2026-08-03 16:43 ` [PATCH v2 2/6] parisc: Drop own implementations for ptep_get() and ptep_test_and_clear_young() Pedro Falcato
` (6 subsequent siblings)
7 siblings, 1 reply; 15+ messages in thread
From: Pedro Falcato @ 2026-08-03 16:43 UTC (permalink / raw)
To: David Hildenbrand, Andrew Morton
Cc: Pedro Falcato, Catalin Marinas, Will Deacon, James E.J. Bottomley,
Helge Deller, Madhavan Srinivasan, Michael Ellerman,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel
None of the contpte code needs write access to the PTEs.
Signed-off-by: Pedro Falcato <pfalcato@suse.de>
---
arch/arm64/include/asm/pgtable.h | 10 +++++-----
arch/arm64/mm/contpte.c | 11 ++++++++---
2 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index a2681d755358..043bc0649cee 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -378,7 +378,7 @@ static inline void __set_pte(pte_t *ptep, pte_t pte)
__set_pte_complete(pte);
}
-static inline pte_t __ptep_get(pte_t *ptep)
+static inline pte_t __ptep_get(const pte_t *ptep)
{
return READ_ONCE(*ptep);
}
@@ -1652,8 +1652,8 @@ extern void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte);
extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte);
-extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
-extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
+extern pte_t contpte_ptep_get(const pte_t *ptep, pte_t orig_pte);
+extern pte_t contpte_ptep_get_lockless(const pte_t *orig_ptep);
extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
pte_t *ptep, pte_t pte, unsigned int nr);
extern void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
@@ -1732,7 +1732,7 @@ static inline unsigned int pte_batch_hint(pte_t *ptep, pte_t pte)
*/
#define ptep_get ptep_get
-static inline pte_t ptep_get(pte_t *ptep)
+static inline pte_t ptep_get(const pte_t *ptep)
{
pte_t pte = __ptep_get(ptep);
@@ -1743,7 +1743,7 @@ static inline pte_t ptep_get(pte_t *ptep)
}
#define ptep_get_lockless ptep_get_lockless
-static inline pte_t ptep_get_lockless(pte_t *ptep)
+static inline pte_t ptep_get_lockless(const pte_t *ptep)
{
pte_t pte = __ptep_get(ptep);
diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
index 2de12656b4d8..3a5d6937fb51 100644
--- a/arch/arm64/mm/contpte.c
+++ b/arch/arm64/mm/contpte.c
@@ -26,6 +26,11 @@ static inline pte_t *contpte_align_down(pte_t *ptep)
return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
}
+#define contpte_align_down(ptep) \
+ _Generic((ptep), \
+ const pte_t *: (const pte_t *) contpte_align_down((pte_t *) (ptep)), \
+ pte_t *: contpte_align_down((pte_t *) ptep))
+
static inline pte_t *contpte_align_addr_ptep(unsigned long *start,
unsigned long *end, pte_t *ptep,
unsigned int nr)
@@ -310,7 +315,7 @@ void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
}
EXPORT_SYMBOL_GPL(__contpte_try_unfold);
-pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte)
+pte_t contpte_ptep_get(const pte_t *ptep, pte_t orig_pte)
{
/*
* Gather access/dirty bits, which may be populated in any of the ptes
@@ -367,7 +372,7 @@ static inline bool contpte_is_consistent(pte_t pte, unsigned long pfn,
pgprot_val(prot) == pgprot_val(orig_prot);
}
-pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
+pte_t contpte_ptep_get_lockless(const pte_t *orig_ptep)
{
/*
* The ptep_get_lockless() API requires us to read and return *orig_ptep
@@ -386,10 +391,10 @@ pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
* because it is not part of a contpte range.
*/
+ const pte_t *ptep;
pgprot_t orig_prot;
unsigned long pfn;
pte_t orig_pte;
- pte_t *ptep;
pte_t pte;
int i;
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 1/6] mm/arm64: constify pte_get*() and contpte get logic
2026-08-03 16:43 ` [PATCH v2 1/6] mm/arm64: constify pte_get*() and contpte get logic Pedro Falcato
@ 2026-08-04 10:55 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 15+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-08-04 10:55 UTC (permalink / raw)
To: Pedro Falcato
Cc: David Hildenbrand, Andrew Morton, Catalin Marinas, Will Deacon,
James E.J. Bottomley, Helge Deller, Madhavan Srinivasan,
Michael Ellerman, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel
On Mon, Aug 03, 2026 at 05:43:55PM +0100, Pedro Falcato wrote:
> None of the contpte code needs write access to the PTEs.
This seems like a very broad statement? Is that actually true? I see a bunch of
ptep's that aren't const-ified, so you should explain why those couldn't be
converted.
Also you add a new contpte_align_down() macro, you should mention that it the
commit message, explain why it was needed.
In general more needed here :) it'd be ok if it was a truly trivial change that
was all obvious but you're changing some pte_t *'s and not others so it's
clearly not.
>
> Signed-off-by: Pedro Falcato <pfalcato@suse.de>
> ---
> arch/arm64/include/asm/pgtable.h | 10 +++++-----
> arch/arm64/mm/contpte.c | 11 ++++++++---
> 2 files changed, 13 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
> index a2681d755358..043bc0649cee 100644
> --- a/arch/arm64/include/asm/pgtable.h
> +++ b/arch/arm64/include/asm/pgtable.h
> @@ -378,7 +378,7 @@ static inline void __set_pte(pte_t *ptep, pte_t pte)
> __set_pte_complete(pte);
> }
>
> -static inline pte_t __ptep_get(pte_t *ptep)
> +static inline pte_t __ptep_get(const pte_t *ptep)
> {
> return READ_ONCE(*ptep);
> }
> @@ -1652,8 +1652,8 @@ extern void __contpte_try_fold(struct mm_struct *mm, unsigned long addr,
> pte_t *ptep, pte_t pte);
> extern void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
> pte_t *ptep, pte_t pte);
> -extern pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte);
> -extern pte_t contpte_ptep_get_lockless(pte_t *orig_ptep);
> +extern pte_t contpte_ptep_get(const pte_t *ptep, pte_t orig_pte);
> +extern pte_t contpte_ptep_get_lockless(const pte_t *orig_ptep);
This is (very) nitty but - not sure on the policy on extern's (Will/Catalin?) -
but in mm we drop them when we touch the code since you don't need them these
days :)
> extern void contpte_set_ptes(struct mm_struct *mm, unsigned long addr,
> pte_t *ptep, pte_t pte, unsigned int nr);
> extern void contpte_clear_full_ptes(struct mm_struct *mm, unsigned long addr,
> @@ -1732,7 +1732,7 @@ static inline unsigned int pte_batch_hint(pte_t *ptep, pte_t pte)
> */
>
> #define ptep_get ptep_get
> -static inline pte_t ptep_get(pte_t *ptep)
> +static inline pte_t ptep_get(const pte_t *ptep)
> {
> pte_t pte = __ptep_get(ptep);
>
> @@ -1743,7 +1743,7 @@ static inline pte_t ptep_get(pte_t *ptep)
> }
>
> #define ptep_get_lockless ptep_get_lockless
> -static inline pte_t ptep_get_lockless(pte_t *ptep)
> +static inline pte_t ptep_get_lockless(const pte_t *ptep)
> {
> pte_t pte = __ptep_get(ptep);
>
> diff --git a/arch/arm64/mm/contpte.c b/arch/arm64/mm/contpte.c
> index 2de12656b4d8..3a5d6937fb51 100644
> --- a/arch/arm64/mm/contpte.c
> +++ b/arch/arm64/mm/contpte.c
> @@ -26,6 +26,11 @@ static inline pte_t *contpte_align_down(pte_t *ptep)
> return PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * CONT_PTES);
> }
>
> +#define contpte_align_down(ptep) \
> + _Generic((ptep), \
> + const pte_t *: (const pte_t *) contpte_align_down((pte_t *) (ptep)), \
> + pte_t *: contpte_align_down((pte_t *) ptep))
I really hate these _Generic() helper things. So ugly. And it's a pretty horrid
cast now :(
Was it not possible to const-ify further to just be able to constify
contpte_align_down itself?
It also seems to contradict the claim that contpte doesn't need write-access to
pte's since you're going to lengths to allow non-const pte_t * here.
You should cover off why this was necessary in the commit message as above.
Anyway PTR_ALIGN_DOWN() is already const-safe so couldn't you anyway just
collapse this to:
#define contpte_align_down(ptep) \
PTR_ALIGN_DOWN(ptep, sizeof(*(ptep)) * CONT_PTES)
Then describe in the commit message why you need to handle both cases?
> +
> static inline pte_t *contpte_align_addr_ptep(unsigned long *start,
> unsigned long *end, pte_t *ptep,
> unsigned int nr)
> @@ -310,7 +315,7 @@ void __contpte_try_unfold(struct mm_struct *mm, unsigned long addr,
> }
> EXPORT_SYMBOL_GPL(__contpte_try_unfold);
>
> -pte_t contpte_ptep_get(pte_t *ptep, pte_t orig_pte)
> +pte_t contpte_ptep_get(const pte_t *ptep, pte_t orig_pte)
> {
> /*
> * Gather access/dirty bits, which may be populated in any of the ptes
> @@ -367,7 +372,7 @@ static inline bool contpte_is_consistent(pte_t pte, unsigned long pfn,
> pgprot_val(prot) == pgprot_val(orig_prot);
> }
>
> -pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
> +pte_t contpte_ptep_get_lockless(const pte_t *orig_ptep)
> {
> /*
> * The ptep_get_lockless() API requires us to read and return *orig_ptep
> @@ -386,10 +391,10 @@ pte_t contpte_ptep_get_lockless(pte_t *orig_ptep)
> * because it is not part of a contpte range.
> */
>
> + const pte_t *ptep;
Nit but this is breaking the reverse xmas tree isn't it?
> pgprot_t orig_prot;
> unsigned long pfn;
> pte_t orig_pte;
> - pte_t *ptep;
> pte_t pte;
> int i;
>
> --
> 2.55.0
>
--
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 2/6] parisc: Drop own implementations for ptep_get() and ptep_test_and_clear_young()
2026-08-03 16:43 [PATCH v2 0/6] mm: add basic PTE const type-safety Pedro Falcato
2026-08-03 16:43 ` [PATCH v2 1/6] mm/arm64: constify pte_get*() and contpte get logic Pedro Falcato
@ 2026-08-03 16:43 ` Pedro Falcato
2026-08-04 11:11 ` Lorenzo Stoakes (ARM)
2026-08-03 16:43 ` [PATCH v2 3/6] mm/powerpc/8xx: constify ptep_get() argument Pedro Falcato
` (5 subsequent siblings)
7 siblings, 1 reply; 15+ messages in thread
From: Pedro Falcato @ 2026-08-03 16:43 UTC (permalink / raw)
To: David Hildenbrand, Andrew Morton
Cc: Pedro Falcato, Catalin Marinas, Will Deacon, James E.J. Bottomley,
Helge Deller, Madhavan Srinivasan, Michael Ellerman,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel,
John David Anglin
From: Helge Deller <deller@gmx.de>
Switch to the generic implementations, which are identical.
Suggested-by: Usama Arif <usama.arif@linux.dev>
Suggested-by: John David Anglin <dave.anglin@bell.net>
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Pedro Falcato <pfalcato@suse.de>
---
arch/parisc/include/asm/pgtable.h | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
index 467b8547ac8b..d92dee9fef3f 100644
--- a/arch/parisc/include/asm/pgtable.h
+++ b/arch/parisc/include/asm/pgtable.h
@@ -432,25 +432,6 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
return pte;
}
-static inline pte_t ptep_get(pte_t *ptep)
-{
- return READ_ONCE(*ptep);
-}
-#define ptep_get ptep_get
-
-static inline bool ptep_test_and_clear_young(struct vm_area_struct *vma,
- unsigned long addr, pte_t *ptep)
-{
- pte_t pte;
-
- pte = ptep_get(ptep);
- if (!pte_young(pte)) {
- return false;
- }
- set_pte_at(vma->vm_mm, addr, ptep, pte_mkold(pte));
- return true;
-}
-
bool ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep);
pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep);
@@ -491,7 +472,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
#define HAVE_ARCH_UNMAPPED_AREA
#define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
-#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
#define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
#define __HAVE_ARCH_PTEP_CLEAR_FLUSH
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 2/6] parisc: Drop own implementations for ptep_get() and ptep_test_and_clear_young()
2026-08-03 16:43 ` [PATCH v2 2/6] parisc: Drop own implementations for ptep_get() and ptep_test_and_clear_young() Pedro Falcato
@ 2026-08-04 11:11 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 15+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-08-04 11:11 UTC (permalink / raw)
To: Pedro Falcato
Cc: David Hildenbrand, Andrew Morton, Catalin Marinas, Will Deacon,
James E.J. Bottomley, Helge Deller, Madhavan Srinivasan,
Michael Ellerman, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel,
John David Anglin
On Mon, Aug 03, 2026 at 05:43:56PM +0100, Pedro Falcato wrote:
> From: Helge Deller <deller@gmx.de>
>
> Switch to the generic implementations, which are identical.
You sure do like succinct commit messages :)
Maybe worth saying by dropping the __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG and
ptep_get defines you get the generic versions from include/pgtable.h which are
functionally identical.
(Being pedantic, they're not quite strictly identical as the
ptep_test_and_clear_young() generic function does some weird unnecessary
indirection with a local variable and the single {} is dropped etc.)
>
> Suggested-by: Usama Arif <usama.arif@linux.dev>
> Suggested-by: John David Anglin <dave.anglin@bell.net>
> Signed-off-by: Helge Deller <deller@gmx.de>
> Signed-off-by: Pedro Falcato <pfalcato@suse.de>
Nits above notwithstanding, LGTM so:
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> arch/parisc/include/asm/pgtable.h | 20 --------------------
> 1 file changed, 20 deletions(-)
>
> diff --git a/arch/parisc/include/asm/pgtable.h b/arch/parisc/include/asm/pgtable.h
> index 467b8547ac8b..d92dee9fef3f 100644
> --- a/arch/parisc/include/asm/pgtable.h
> +++ b/arch/parisc/include/asm/pgtable.h
> @@ -432,25 +432,6 @@ static inline pte_t pte_swp_clear_exclusive(pte_t pte)
> return pte;
> }
>
> -static inline pte_t ptep_get(pte_t *ptep)
> -{
> - return READ_ONCE(*ptep);
> -}
> -#define ptep_get ptep_get
> -
> -static inline bool ptep_test_and_clear_young(struct vm_area_struct *vma,
> - unsigned long addr, pte_t *ptep)
> -{
> - pte_t pte;
> -
> - pte = ptep_get(ptep);
> - if (!pte_young(pte)) {
> - return false;
> - }
> - set_pte_at(vma->vm_mm, addr, ptep, pte_mkold(pte));
> - return true;
> -}
> -
> bool ptep_clear_flush_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep);
> pte_t ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep);
>
> @@ -491,7 +472,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
> #define HAVE_ARCH_UNMAPPED_AREA
> #define HAVE_ARCH_UNMAPPED_AREA_TOPDOWN
>
> -#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
> #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH
> #define __HAVE_ARCH_PTEP_CLEAR_FLUSH
> #define __HAVE_ARCH_PTEP_SET_WRPROTECT
> --
> 2.55.0
>
--
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 3/6] mm/powerpc/8xx: constify ptep_get() argument
2026-08-03 16:43 [PATCH v2 0/6] mm: add basic PTE const type-safety Pedro Falcato
2026-08-03 16:43 ` [PATCH v2 1/6] mm/arm64: constify pte_get*() and contpte get logic Pedro Falcato
2026-08-03 16:43 ` [PATCH v2 2/6] parisc: Drop own implementations for ptep_get() and ptep_test_and_clear_young() Pedro Falcato
@ 2026-08-03 16:43 ` Pedro Falcato
2026-08-04 11:13 ` Lorenzo Stoakes (ARM)
2026-08-03 16:43 ` [PATCH v2 4/6] mm/s390: " Pedro Falcato
` (4 subsequent siblings)
7 siblings, 1 reply; 15+ messages in thread
From: Pedro Falcato @ 2026-08-03 16:43 UTC (permalink / raw)
To: David Hildenbrand, Andrew Morton
Cc: Pedro Falcato, Catalin Marinas, Will Deacon, James E.J. Bottomley,
Helge Deller, Madhavan Srinivasan, Michael Ellerman,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel
There is no need for write access to the PTE.
Signed-off-by: Pedro Falcato <pfalcato@suse.de>
---
arch/powerpc/include/asm/nohash/32/pte-8xx.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
index e2ea8ba9f8ca..f2bab31040c7 100644
--- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h
+++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
@@ -226,7 +226,7 @@ static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, p
#ifdef CONFIG_PPC_16K_PAGES
#define ptep_get ptep_get
-static inline pte_t ptep_get(pte_t *ptep)
+static inline pte_t ptep_get(const pte_t *ptep)
{
pte_basic_t val = READ_ONCE(ptep->pte);
pte_t pte = {val, val, val, val};
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 3/6] mm/powerpc/8xx: constify ptep_get() argument
2026-08-03 16:43 ` [PATCH v2 3/6] mm/powerpc/8xx: constify ptep_get() argument Pedro Falcato
@ 2026-08-04 11:13 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 15+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-08-04 11:13 UTC (permalink / raw)
To: Pedro Falcato
Cc: David Hildenbrand, Andrew Morton, Catalin Marinas, Will Deacon,
James E.J. Bottomley, Helge Deller, Madhavan Srinivasan,
Michael Ellerman, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel
On Mon, Aug 03, 2026 at 05:43:57PM +0100, Pedro Falcato wrote:
> There is no need for write access to the PTE.
>
> Signed-off-by: Pedro Falcato <pfalcato@suse.de>
With below addressed LGTM so:
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> arch/powerpc/include/asm/nohash/32/pte-8xx.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/powerpc/include/asm/nohash/32/pte-8xx.h b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
> index e2ea8ba9f8ca..f2bab31040c7 100644
> --- a/arch/powerpc/include/asm/nohash/32/pte-8xx.h
> +++ b/arch/powerpc/include/asm/nohash/32/pte-8xx.h
> @@ -226,7 +226,7 @@ static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, p
>
> #ifdef CONFIG_PPC_16K_PAGES
> #define ptep_get ptep_get
> -static inline pte_t ptep_get(pte_t *ptep)
> +static inline pte_t ptep_get(const pte_t *ptep)
> {
> pte_basic_t val = READ_ONCE(ptep->pte);
> pte_t pte = {val, val, val, val};
Worth making these const too (that {val, val, val, val} horrifies me btw :)?
> --
> 2.55.0
>
--
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 4/6] mm/s390: constify ptep_get() argument
2026-08-03 16:43 [PATCH v2 0/6] mm: add basic PTE const type-safety Pedro Falcato
` (2 preceding siblings ...)
2026-08-03 16:43 ` [PATCH v2 3/6] mm/powerpc/8xx: constify ptep_get() argument Pedro Falcato
@ 2026-08-03 16:43 ` Pedro Falcato
2026-08-04 11:14 ` Lorenzo Stoakes (ARM)
2026-08-03 16:43 ` [PATCH v2 5/6] mm: constify generic pte_get*() Pedro Falcato
` (3 subsequent siblings)
7 siblings, 1 reply; 15+ messages in thread
From: Pedro Falcato @ 2026-08-03 16:43 UTC (permalink / raw)
To: David Hildenbrand, Andrew Morton
Cc: Pedro Falcato, Catalin Marinas, Will Deacon, James E.J. Bottomley,
Helge Deller, Madhavan Srinivasan, Michael Ellerman,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel
It's a simple READ_ONCE() dereference, therefore it can be const.
Signed-off-by: Pedro Falcato <pfalcato@suse.de>
---
arch/s390/include/asm/pgtable.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
index e882663a58e7..ec331ec92943 100644
--- a/arch/s390/include/asm/pgtable.h
+++ b/arch/s390/include/asm/pgtable.h
@@ -986,7 +986,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
}
#define ptep_get ptep_get
-static inline pte_t ptep_get(pte_t *ptep)
+static inline pte_t ptep_get(const pte_t *ptep)
{
return READ_ONCE(*ptep);
}
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 4/6] mm/s390: constify ptep_get() argument
2026-08-03 16:43 ` [PATCH v2 4/6] mm/s390: " Pedro Falcato
@ 2026-08-04 11:14 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 15+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-08-04 11:14 UTC (permalink / raw)
To: Pedro Falcato
Cc: David Hildenbrand, Andrew Morton, Catalin Marinas, Will Deacon,
James E.J. Bottomley, Helge Deller, Madhavan Srinivasan,
Michael Ellerman, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel
On Mon, Aug 03, 2026 at 05:43:58PM +0100, Pedro Falcato wrote:
> It's a simple READ_ONCE() dereference, therefore it can be const.
>
> Signed-off-by: Pedro Falcato <pfalcato@suse.de>
Even I can't be pedantic about this one... :) so:
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> arch/s390/include/asm/pgtable.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h
> index e882663a58e7..ec331ec92943 100644
> --- a/arch/s390/include/asm/pgtable.h
> +++ b/arch/s390/include/asm/pgtable.h
> @@ -986,7 +986,7 @@ static inline void set_pte(pte_t *ptep, pte_t pte)
> }
>
> #define ptep_get ptep_get
> -static inline pte_t ptep_get(pte_t *ptep)
> +static inline pte_t ptep_get(const pte_t *ptep)
> {
> return READ_ONCE(*ptep);
> }
> --
> 2.55.0
>
--
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 5/6] mm: constify generic pte_get*()
2026-08-03 16:43 [PATCH v2 0/6] mm: add basic PTE const type-safety Pedro Falcato
` (3 preceding siblings ...)
2026-08-03 16:43 ` [PATCH v2 4/6] mm/s390: " Pedro Falcato
@ 2026-08-03 16:43 ` Pedro Falcato
2026-08-04 11:15 ` Lorenzo Stoakes (ARM)
2026-08-03 16:44 ` [PATCH v2 6/6] mm: constify the pte_offset_map_ro_nolock() return value Pedro Falcato
` (2 subsequent siblings)
7 siblings, 1 reply; 15+ messages in thread
From: Pedro Falcato @ 2026-08-03 16:43 UTC (permalink / raw)
To: David Hildenbrand, Andrew Morton
Cc: Pedro Falcato, Catalin Marinas, Will Deacon, James E.J. Bottomley,
Helge Deller, Madhavan Srinivasan, Michael Ellerman,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel
None of the helpers need write access to the PTE. Constifying the param
allows for const typesafety.
Signed-off-by: Pedro Falcato <pfalcato@suse.de>
---
include/linux/pgtable.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index 8c093c119e5a..dc418553e57a 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -490,7 +490,7 @@ static inline int pudp_set_access_flags(struct vm_area_struct *vma,
#endif
#ifndef ptep_get
-static inline pte_t ptep_get(pte_t *ptep)
+static inline pte_t ptep_get(const pte_t *ptep)
{
return READ_ONCE(*ptep);
}
@@ -739,7 +739,7 @@ static inline void ptep_clear(struct mm_struct *mm, unsigned long addr,
* present bit set *unless* it is 'l'. Because get_user_pages_fast() only
* operates on present ptes we're safe.
*/
-static inline pte_t ptep_get_lockless(pte_t *ptep)
+static inline pte_t ptep_get_lockless(const pte_t *ptep)
{
pte_t pte;
@@ -777,7 +777,7 @@ static inline pmd_t pmdp_get_lockless(pmd_t *pmdp)
* We require that the PTE can be read atomically.
*/
#ifndef ptep_get_lockless
-static inline pte_t ptep_get_lockless(pte_t *ptep)
+static inline pte_t ptep_get_lockless(const pte_t *ptep)
{
return ptep_get(ptep);
}
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 5/6] mm: constify generic pte_get*()
2026-08-03 16:43 ` [PATCH v2 5/6] mm: constify generic pte_get*() Pedro Falcato
@ 2026-08-04 11:15 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 15+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-08-04 11:15 UTC (permalink / raw)
To: Pedro Falcato
Cc: David Hildenbrand, Andrew Morton, Catalin Marinas, Will Deacon,
James E.J. Bottomley, Helge Deller, Madhavan Srinivasan,
Michael Ellerman, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel
On Mon, Aug 03, 2026 at 05:43:59PM +0100, Pedro Falcato wrote:
> None of the helpers need write access to the PTE. Constifying the param
> allows for const typesafety.
constity?
>
> Signed-off-by: Pedro Falcato <pfalcato@suse.de>
LGTM, so:
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> include/linux/pgtable.h | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index 8c093c119e5a..dc418553e57a 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -490,7 +490,7 @@ static inline int pudp_set_access_flags(struct vm_area_struct *vma,
> #endif
>
> #ifndef ptep_get
> -static inline pte_t ptep_get(pte_t *ptep)
> +static inline pte_t ptep_get(const pte_t *ptep)
> {
> return READ_ONCE(*ptep);
> }
> @@ -739,7 +739,7 @@ static inline void ptep_clear(struct mm_struct *mm, unsigned long addr,
> * present bit set *unless* it is 'l'. Because get_user_pages_fast() only
> * operates on present ptes we're safe.
> */
> -static inline pte_t ptep_get_lockless(pte_t *ptep)
> +static inline pte_t ptep_get_lockless(const pte_t *ptep)
> {
> pte_t pte;
>
> @@ -777,7 +777,7 @@ static inline pmd_t pmdp_get_lockless(pmd_t *pmdp)
> * We require that the PTE can be read atomically.
> */
> #ifndef ptep_get_lockless
> -static inline pte_t ptep_get_lockless(pte_t *ptep)
> +static inline pte_t ptep_get_lockless(const pte_t *ptep)
> {
> return ptep_get(ptep);
> }
> --
> 2.55.0
>
--
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v2 6/6] mm: constify the pte_offset_map_ro_nolock() return value
2026-08-03 16:43 [PATCH v2 0/6] mm: add basic PTE const type-safety Pedro Falcato
` (4 preceding siblings ...)
2026-08-03 16:43 ` [PATCH v2 5/6] mm: constify generic pte_get*() Pedro Falcato
@ 2026-08-03 16:44 ` Pedro Falcato
2026-08-04 11:22 ` Lorenzo Stoakes (ARM)
2026-08-03 18:38 ` [PATCH v2 0/6] mm: add basic PTE const type-safety Muhammad Usama Anjum
2026-08-04 6:55 ` Christophe Leroy (CS GROUP)
7 siblings, 1 reply; 15+ messages in thread
From: Pedro Falcato @ 2026-08-03 16:44 UTC (permalink / raw)
To: David Hildenbrand, Andrew Morton
Cc: Pedro Falcato, Catalin Marinas, Will Deacon, James E.J. Bottomley,
Helge Deller, Madhavan Srinivasan, Michael Ellerman,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel
Constify the pte_t * retval from pte_offset_map_ro_nolock(), for which it is
already pledged that accesses must be read-only. With it, convert the three
treewide users to use const pte_t *.
khugepaged passes the result right down to fault code (do_swap_page()). This
leads to a complicated set of conditions that, in order to be correct, must
not install anything into *vmf->pte. This is not trivial to work around in
fault code, and as such just trivially cast to non-const pte_t* in the
meantime.
The other users are far more trivial and the conversion is equally
trivially simple.
Signed-off-by: Pedro Falcato <pfalcato@suse.de>
---
arch/powerpc/mm/pgtable.c | 2 +-
include/linux/mm.h | 4 ++--
include/linux/pgtable.h | 2 +-
mm/filemap.c | 2 +-
mm/khugepaged.c | 2 +-
mm/pgtable-generic.c | 4 ++--
6 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
index a9be337be3e4..e29db41b6043 100644
--- a/arch/powerpc/mm/pgtable.c
+++ b/arch/powerpc/mm/pgtable.c
@@ -390,7 +390,7 @@ void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
p4d_t *p4d;
pud_t *pud;
pmd_t *pmd;
- pte_t *pte;
+ const pte_t *pte;
spinlock_t *ptl;
if (mm == &init_mm)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7fabe6c66b4b..acf5a5e31d34 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -3885,8 +3885,8 @@ static inline pte_t *pte_offset_map(pmd_t *pmd, unsigned long addr)
pte_t *pte_offset_map_lock(struct mm_struct *mm, pmd_t *pmd,
unsigned long addr, spinlock_t **ptlp);
-pte_t *pte_offset_map_ro_nolock(struct mm_struct *mm, pmd_t *pmd,
- unsigned long addr, spinlock_t **ptlp);
+const pte_t *pte_offset_map_ro_nolock(struct mm_struct *mm, pmd_t *pmd,
+ unsigned long addr, spinlock_t **ptlp);
pte_t *pte_offset_map_rw_nolock(struct mm_struct *mm, pmd_t *pmd,
unsigned long addr, pmd_t *pmdvalp,
spinlock_t **ptlp);
diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
index dc418553e57a..dd51e722c535 100644
--- a/include/linux/pgtable.h
+++ b/include/linux/pgtable.h
@@ -112,7 +112,7 @@ static inline pte_t *__pte_map(pmd_t *pmd, unsigned long address)
{
return pte_offset_kernel(pmd, address);
}
-static inline void pte_unmap(pte_t *pte)
+static inline void pte_unmap(const pte_t *pte)
{
rcu_read_unlock();
}
diff --git a/mm/filemap.c b/mm/filemap.c
index 6afec636881f..af5d3fcd1b05 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -3490,7 +3490,7 @@ static vm_fault_t filemap_fault_recheck_pte_none(struct vm_fault *vmf)
{
struct vm_area_struct *vma = vmf->vma;
vm_fault_t ret = 0;
- pte_t *ptep;
+ const pte_t *ptep;
/*
* We might have COW'ed a pagecache folio and might now have an mlocked
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index b237f6e7662a..09efac93a8c6 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -1170,7 +1170,7 @@ static enum scan_result __collapse_huge_page_swapin(struct mm_struct *mm,
* Here the ptl is only used to check pte_same() in
* do_swap_page(), so readonly version is enough.
*/
- pte = pte_offset_map_ro_nolock(mm, pmd, addr, &ptl);
+ pte = (pte_t *) pte_offset_map_ro_nolock(mm, pmd, addr, &ptl);
if (!pte) {
mmap_read_unlock(mm);
result = SCAN_NO_PTE_TABLE;
diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
index b91b1a98029c..2cfc6e608ef4 100644
--- a/mm/pgtable-generic.c
+++ b/mm/pgtable-generic.c
@@ -308,8 +308,8 @@ pte_t *__pte_offset_map(pmd_t *pmd, unsigned long addr, pmd_t *pmdvalp)
return NULL;
}
-pte_t *pte_offset_map_ro_nolock(struct mm_struct *mm, pmd_t *pmd,
- unsigned long addr, spinlock_t **ptlp)
+const pte_t *pte_offset_map_ro_nolock(struct mm_struct *mm, pmd_t *pmd,
+ unsigned long addr, spinlock_t **ptlp)
{
pmd_t pmdval;
pte_t *pte;
--
2.55.0
^ permalink raw reply related [flat|nested] 15+ messages in thread* Re: [PATCH v2 6/6] mm: constify the pte_offset_map_ro_nolock() return value
2026-08-03 16:44 ` [PATCH v2 6/6] mm: constify the pte_offset_map_ro_nolock() return value Pedro Falcato
@ 2026-08-04 11:22 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 15+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-08-04 11:22 UTC (permalink / raw)
To: Pedro Falcato
Cc: David Hildenbrand, Andrew Morton, Catalin Marinas, Will Deacon,
James E.J. Bottomley, Helge Deller, Madhavan Srinivasan,
Michael Ellerman, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel
On Mon, Aug 03, 2026 at 05:44:00PM +0100, Pedro Falcato wrote:
> Constify the pte_t * retval from pte_offset_map_ro_nolock(), for which it is
> already pledged that accesses must be read-only. With it, convert the three
> treewide users to use const pte_t *.
>
> khugepaged passes the result right down to fault code (do_swap_page()). This
> leads to a complicated set of conditions that, in order to be correct, must
> not install anything into *vmf->pte. This is not trivial to work around in
> fault code, and as such just trivially cast to non-const pte_t* in the
> meantime.
>
> The other users are far more trivial and the conversion is equally
> trivially simple.
Ah finally more words! :)
>
> Signed-off-by: Pedro Falcato <pfalcato@suse.de>
With comment updated as below and nits addressed, LGTM so:
Reviewed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
> ---
> arch/powerpc/mm/pgtable.c | 2 +-
> include/linux/mm.h | 4 ++--
> include/linux/pgtable.h | 2 +-
> mm/filemap.c | 2 +-
> mm/khugepaged.c | 2 +-
> mm/pgtable-generic.c | 4 ++--
> 6 files changed, 8 insertions(+), 8 deletions(-)
>
> diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c
> index a9be337be3e4..e29db41b6043 100644
> --- a/arch/powerpc/mm/pgtable.c
> +++ b/arch/powerpc/mm/pgtable.c
> @@ -390,7 +390,7 @@ void assert_pte_locked(struct mm_struct *mm, unsigned long addr)
> p4d_t *p4d;
> pud_t *pud;
> pmd_t *pmd;
> - pte_t *pte;
> + const pte_t *pte;
> spinlock_t *ptl;
>
> if (mm == &init_mm)
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index 7fabe6c66b4b..acf5a5e31d34 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -3885,8 +3885,8 @@ static inline pte_t *pte_offset_map(pmd_t *pmd, unsigned long addr)
> pte_t *pte_offset_map_lock(struct mm_struct *mm, pmd_t *pmd,
> unsigned long addr, spinlock_t **ptlp);
>
> -pte_t *pte_offset_map_ro_nolock(struct mm_struct *mm, pmd_t *pmd,
> - unsigned long addr, spinlock_t **ptlp);
> +const pte_t *pte_offset_map_ro_nolock(struct mm_struct *mm, pmd_t *pmd,
> + unsigned long addr, spinlock_t **ptlp);
> pte_t *pte_offset_map_rw_nolock(struct mm_struct *mm, pmd_t *pmd,
> unsigned long addr, pmd_t *pmdvalp,
> spinlock_t **ptlp);
> diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h
> index dc418553e57a..dd51e722c535 100644
> --- a/include/linux/pgtable.h
> +++ b/include/linux/pgtable.h
> @@ -112,7 +112,7 @@ static inline pte_t *__pte_map(pmd_t *pmd, unsigned long address)
> {
> return pte_offset_kernel(pmd, address);
> }
> -static inline void pte_unmap(pte_t *pte)
> +static inline void pte_unmap(const pte_t *pte)
I was going to question this based on whether the contract holds for
CONFIG_HIGHPTE but actually:
#define pte_unmap(pte) do { \
kunmap_local((pte)); \
rcu_read_unlock(); \
} while (0)
#define kunmap_local(__addr) \
do { \
BUILD_BUG_ON(__same_type((__addr), struct page *)); \
__kunmap_local(__addr); \
} while (0)
static inline void __kunmap_local(const void *vaddr) <-- const!
{
kunmap_local_indexed(vaddr);
}
So nice (CONFIG_HIGHPTE is going to go away at some point though, right? I
hope... :)
> {
> rcu_read_unlock();
> }
> diff --git a/mm/filemap.c b/mm/filemap.c
> index 6afec636881f..af5d3fcd1b05 100644
> --- a/mm/filemap.c
> +++ b/mm/filemap.c
> @@ -3490,7 +3490,7 @@ static vm_fault_t filemap_fault_recheck_pte_none(struct vm_fault *vmf)
> {
> struct vm_area_struct *vma = vmf->vma;
> vm_fault_t ret = 0;
> - pte_t *ptep;
> + const pte_t *ptep;
>
> /*
> * We might have COW'ed a pagecache folio and might now have an mlocked
> diff --git a/mm/khugepaged.c b/mm/khugepaged.c
> index b237f6e7662a..09efac93a8c6 100644
> --- a/mm/khugepaged.c
> +++ b/mm/khugepaged.c
> @@ -1170,7 +1170,7 @@ static enum scan_result __collapse_huge_page_swapin(struct mm_struct *mm,
> * Here the ptl is only used to check pte_same() in
> * do_swap_page(), so readonly version is enough.
> */
> - pte = pte_offset_map_ro_nolock(mm, pmd, addr, &ptl);
> + pte = (pte_t *) pte_offset_map_ro_nolock(mm, pmd, addr, &ptl);
Hmm yeah this is nasty, but you explain why in the commit message. Could you
extend the comment to explain it?
> if (!pte) {
> mmap_read_unlock(mm);
> result = SCAN_NO_PTE_TABLE;
> diff --git a/mm/pgtable-generic.c b/mm/pgtable-generic.c
> index b91b1a98029c..2cfc6e608ef4 100644
> --- a/mm/pgtable-generic.c
> +++ b/mm/pgtable-generic.c
> @@ -308,8 +308,8 @@ pte_t *__pte_offset_map(pmd_t *pmd, unsigned long addr, pmd_t *pmdvalp)
> return NULL;
> }
>
> -pte_t *pte_offset_map_ro_nolock(struct mm_struct *mm, pmd_t *pmd,
> - unsigned long addr, spinlock_t **ptlp)
> +const pte_t *pte_offset_map_ro_nolock(struct mm_struct *mm, pmd_t *pmd,
Can pmd be const too?
> + unsigned long addr, spinlock_t **ptlp)
> {
> pmd_t pmdval;
> pte_t *pte;
> --
> 2.55.0
>
--
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [PATCH v2 0/6] mm: add basic PTE const type-safety
2026-08-03 16:43 [PATCH v2 0/6] mm: add basic PTE const type-safety Pedro Falcato
` (5 preceding siblings ...)
2026-08-03 16:44 ` [PATCH v2 6/6] mm: constify the pte_offset_map_ro_nolock() return value Pedro Falcato
@ 2026-08-03 18:38 ` Muhammad Usama Anjum
2026-08-04 6:55 ` Christophe Leroy (CS GROUP)
7 siblings, 0 replies; 15+ messages in thread
From: Muhammad Usama Anjum @ 2026-08-03 18:38 UTC (permalink / raw)
To: Pedro Falcato, David Hildenbrand, Andrew Morton
Cc: usama.anjum, Catalin Marinas, Will Deacon, James E.J. Bottomley,
Helge Deller, Madhavan Srinivasan, Michael Ellerman,
Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
linux-arm-kernel, linux-kernel, linux-parisc, linuxppc-dev,
linux-mm, linux-fsdevel
On 03/08/2026 5:43 pm, Pedro Falcato wrote:
> Since forever, MM code has thrown pte_t * around with no concern for const
> safety, or typesafety of any kind. This is confusing. Attempt to address it
> by:
> 1) Making sure pte_get*() helpers can cope with const pte_t * arguments
> 2) Constifying the pte_offset_map_ro_nolock() return type, which by definition
> already pledges that users will not write to it.
>
> These two simple steps were already able to uncover code smell from
> khugepaged + do_swap_page().
>
> Separate steps could include introducing pte_offset_map_ro_lock() for more
> widespread usage of this.
>
> Benefits of this include less confusion and better type-safety. It could also
> futurely aid in efforts such as [0] which may want semantic annotation of these
> accesses.
>
> Based on mm-unstable and compile-tested on a handful of architectures.
>
> No functional changes intended.
I've reviewed the entire series. Hence:
Reviewed-by: Muhammad Usama Anjum <usama.anjum@arm.com>
>
> [CC list editorially trimmed for brevity reasons; apologies if you're not on it]
>
> Link: https://lore.kernel.org/linux-mm/20260526-kpkeys-v8-0-eaaacdacc67c@arm.com/#t [0]
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> Cc: Helge Deller <deller@gmx.de>
> Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Lorenzo Stoakes <ljs@kernel.org>
> Cc: "Liam R. Howlett" <liam@infradead.org>
> Cc: Vlastimil Babka <vbabka@kernel.org>
> Cc: Mike Rapoport <rppt@kernel.org>
> Cc: Suren Baghdasaryan <surenb@google.com>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Zi Yan <ziy@nvidia.com>
> Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
> Cc: Nico Pache <npache@redhat.com>
> Cc: Ryan Roberts <ryan.roberts@arm.com>
> Cc: Dev Jain <dev.jain@arm.com>
> Cc: Barry Song <baohua@kernel.org>
> Cc: Lance Yang <lance.yang@linux.dev>
> Cc: Usama Arif <usama.arif@linux.dev>
> Cc: Kevin Brodsky <kevin.brodsky@arm.com>
> Cc: Muhammad Usama Anjum <usama.anjum@arm.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-parisc@vger.kernel.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: linux-mm@kvack.org
> Cc: linux-fsdevel@vger.kernel.org
>
> v2:
> - Small fixups on the arm64 side
> - Re-order patches in a way such that bisection is preserved
> - Pick up Helge's patch dropping parisc ptep_get()
> - Constify s390's ptep_get() as well
>
> Helge Deller (1):
> parisc: Drop own implementations for ptep_get() and
> ptep_test_and_clear_young()
>
> Pedro Falcato (5):
> mm/arm64: constify pte_get*() and contpte get logic
> mm/powerpc/8xx: constify ptep_get() argument
> mm/s390: constify ptep_get() argument
> mm: constify generic pte_get*()
> mm: constify the pte_offset_map_ro_nolock() return value
>
> arch/arm64/include/asm/pgtable.h | 10 +++++-----
> arch/arm64/mm/contpte.c | 11 ++++++++---
> arch/parisc/include/asm/pgtable.h | 20 --------------------
> arch/powerpc/include/asm/nohash/32/pte-8xx.h | 2 +-
> arch/powerpc/mm/pgtable.c | 2 +-
> arch/s390/include/asm/pgtable.h | 2 +-
> include/linux/mm.h | 4 ++--
> include/linux/pgtable.h | 8 ++++----
> mm/filemap.c | 2 +-
> mm/khugepaged.c | 2 +-
> mm/pgtable-generic.c | 4 ++--
> 11 files changed, 26 insertions(+), 41 deletions(-)
>
--
Thanks,
Usama
^ permalink raw reply [flat|nested] 15+ messages in thread* Re: [PATCH v2 0/6] mm: add basic PTE const type-safety
2026-08-03 16:43 [PATCH v2 0/6] mm: add basic PTE const type-safety Pedro Falcato
` (6 preceding siblings ...)
2026-08-03 18:38 ` [PATCH v2 0/6] mm: add basic PTE const type-safety Muhammad Usama Anjum
@ 2026-08-04 6:55 ` Christophe Leroy (CS GROUP)
7 siblings, 0 replies; 15+ messages in thread
From: Christophe Leroy (CS GROUP) @ 2026-08-04 6:55 UTC (permalink / raw)
To: Pedro Falcato, David Hildenbrand, Andrew Morton
Cc: Catalin Marinas, Will Deacon, James E.J. Bottomley, Helge Deller,
Madhavan Srinivasan, Michael Ellerman, Lorenzo Stoakes,
Liam R. Howlett, Vlastimil Babka, Mike Rapoport,
Suren Baghdasaryan, Michal Hocko, Matthew Wilcox (Oracle),
Jan Kara, Zi Yan, Baolin Wang, Nico Pache, Ryan Roberts, Dev Jain,
Barry Song, Lance Yang, Usama Arif, Kevin Brodsky,
Muhammad Usama Anjum, linux-arm-kernel, linux-kernel,
linux-parisc, linuxppc-dev, linux-mm, linux-fsdevel
Le 03/08/2026 à 18:43, Pedro Falcato a écrit :
> Since forever, MM code has thrown pte_t * around with no concern for const
> safety, or typesafety of any kind. This is confusing. Attempt to address it
> by:
What do you mean by "typesafety of any kind" ?
On powerpc64, pte_t is a struct so you can't play-up too much with it.
On powerpc32, pte_t is a long int because having it as a struct is
counter-performant, but we have it as a struct when __CHECKER__ is
defined, ie when doing a sparse check with 'make C=2'.
> 1) Making sure pte_get*() helpers can cope with const pte_t * arguments
> 2) Constifying the pte_offset_map_ro_nolock() return type, which by definition
> already pledges that users will not write to it.
>
> These two simple steps were already able to uncover code smell from
> khugepaged + do_swap_page().
>
> Separate steps could include introducing pte_offset_map_ro_lock() for more
> widespread usage of this.
>
> Benefits of this include less confusion and better type-safety. It could also
> futurely aid in efforts such as [0] which may want semantic annotation of these
> accesses.
>
> Based on mm-unstable and compile-tested on a handful of architectures.
>
> No functional changes intended.
>
For the series,
Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
> [CC list editorially trimmed for brevity reasons; apologies if you're not on it]
>
> Link: https://lore.kernel.org/linux-mm/20260526-kpkeys-v8-0-eaaacdacc67c@arm.com/#t [0]
> Cc: Catalin Marinas <catalin.marinas@arm.com>
> Cc: Will Deacon <will@kernel.org>
> Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
> Cc: Helge Deller <deller@gmx.de>
> Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Lorenzo Stoakes <ljs@kernel.org>
> Cc: "Liam R. Howlett" <liam@infradead.org>
> Cc: Vlastimil Babka <vbabka@kernel.org>
> Cc: Mike Rapoport <rppt@kernel.org>
> Cc: Suren Baghdasaryan <surenb@google.com>
> Cc: Michal Hocko <mhocko@suse.com>
> Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
> Cc: Jan Kara <jack@suse.cz>
> Cc: Zi Yan <ziy@nvidia.com>
> Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
> Cc: Nico Pache <npache@redhat.com>
> Cc: Ryan Roberts <ryan.roberts@arm.com>
> Cc: Dev Jain <dev.jain@arm.com>
> Cc: Barry Song <baohua@kernel.org>
> Cc: Lance Yang <lance.yang@linux.dev>
> Cc: Usama Arif <usama.arif@linux.dev>
> Cc: Kevin Brodsky <kevin.brodsky@arm.com>
> Cc: Muhammad Usama Anjum <usama.anjum@arm.com>
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-parisc@vger.kernel.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: linux-mm@kvack.org
> Cc: linux-fsdevel@vger.kernel.org
>
> v2:
> - Small fixups on the arm64 side
> - Re-order patches in a way such that bisection is preserved
> - Pick up Helge's patch dropping parisc ptep_get()
> - Constify s390's ptep_get() as well
>
> Helge Deller (1):
> parisc: Drop own implementations for ptep_get() and
> ptep_test_and_clear_young()
>
> Pedro Falcato (5):
> mm/arm64: constify pte_get*() and contpte get logic
> mm/powerpc/8xx: constify ptep_get() argument
> mm/s390: constify ptep_get() argument
> mm: constify generic pte_get*()
> mm: constify the pte_offset_map_ro_nolock() return value
>
> arch/arm64/include/asm/pgtable.h | 10 +++++-----
> arch/arm64/mm/contpte.c | 11 ++++++++---
> arch/parisc/include/asm/pgtable.h | 20 --------------------
> arch/powerpc/include/asm/nohash/32/pte-8xx.h | 2 +-
> arch/powerpc/mm/pgtable.c | 2 +-
> arch/s390/include/asm/pgtable.h | 2 +-
> include/linux/mm.h | 4 ++--
> include/linux/pgtable.h | 8 ++++----
> mm/filemap.c | 2 +-
> mm/khugepaged.c | 2 +-
> mm/pgtable-generic.c | 4 ++--
> 11 files changed, 26 insertions(+), 41 deletions(-)
>
^ permalink raw reply [flat|nested] 15+ messages in thread