Re: [RFC V1 09/16] arm64/mm: Route all pgtable reads via ptdesc_get()
From: Anshuman Khandual
Date: Sun Mar 01 2026 - 23:34:22 EST
On 28/02/26 4:47 PM, Mike Rapoport wrote:
> Hi Anshuman,
>
> On Tue, Feb 24, 2026 at 10:41:46AM +0530, Anshuman Khandual wrote:
>> Define arm64 platform specific implementations for new pXdp_get() helpers.
>> These resolve into READ_ONCE(), thus ensuring required single copy atomic
>> semantics for the page table entry reads.
>>
>> In future this infrastructure can be used for D128 to maintain single copy
>> atomicity semantics with inline asm blocks.
>>
>> Cc: Catalin Marinas <catalin.marinas@xxxxxxx>
>> Cc: Will Deacon <will@xxxxxxxxxx>
>> Cc: Ryan Roberts <ryan.roberts@xxxxxxx>
>> Cc: Mark Rutland <mark.rutland@xxxxxxx>
>> Cc: linux-arm-kernel@xxxxxxxxxxxxxxxxxxx
>> Cc: linux-kernel@xxxxxxxxxxxxxxx
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@xxxxxxx>
>> ---
>> arch/arm64/include/asm/pgtable.h | 28 +++++++++++++++++++++++++++-
>> 1 file changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
>> index 257af1c3015d..804ef49aea88 100644
>> --- a/arch/arm64/include/asm/pgtable.h
>> +++ b/arch/arm64/include/asm/pgtable.h
>> @@ -84,6 +84,32 @@ static inline void arch_leave_lazy_mmu_mode(void)
>> arch_flush_lazy_mmu_mode();
>> }
>>
>> +#define ptdesc_get(x) READ_ONCE(x)
>
> This will be confusing with 'struct ptdesc' APIs, maybe ptent_get()?
Created 'ptdesc_t' earlier on arm64 platform as an unified data type, which could
represent page table entries including their protection fields and masks for any
level.
typedef u64 ptdesc_t;
typedef ptdesc_t pteval_t;
typedef ptdesc_t pmdval_t;
typedef ptdesc_t pudval_t;
typedef ptdesc_t p4dval_t;
typedef ptdesc_t pgdval_t;
But now it conflicts with generic 'struct ptdesc'. Agreed that overall renaming is
required. Probably ptent_t along with ptent_get/set() could be an option. But that
is probably orthogonal to the series and can be done later in a separate patch.
>
>> +#define pmdp_get pmdp_get
>> +static inline pmd_t pmdp_get(pmd_t *pmdp)
>> +{
>> + return ptdesc_get(*pmdp);
>> +}
>> +
>> +#define pudp_get pudp_get
>> +static inline pud_t pudp_get(pud_t *pudp)
>> +{
>> + return ptdesc_get(*pudp);
>> +}
>> +
>> +#define p4dp_get p4dp_get
>> +static inline p4d_t p4dp_get(p4d_t *p4dp)
>> +{
>> + return ptdesc_get(*p4dp);
>> +}
>> +
>> +#define pgdp_get pgdp_get
>> +static inline pgd_t pgdp_get(pgd_t *pgdp)
>> +{
>> + return ptdesc_get(*pgdp);
>> +}
>> +
>> #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>> #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
>>
>> @@ -384,7 +410,7 @@ static inline void __set_pte(pte_t *ptep, pte_t pte)
>>
>> static inline pte_t __ptep_get(pte_t *ptep)
>> {
>> - return READ_ONCE(*ptep);
>> + return ptdesc_get(*ptep);
>> }
>>
>> extern void __sync_icache_dcache(pte_t pteval);
>> --
>> 2.43.0
>>
>