From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 29F67322B74 for ; Thu, 26 Feb 2026 13:19:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772111959; cv=none; b=j87QRDwMpV8PO+Fd9hPLuvgFH1BE5XtGzSaY1stuWn0G28Wr38rwmeq+zWUf1sciFnktnn9xc2aIhrNypA8DA0yka1dIBtpdiA2l261XuDeKa9ITN249zjrZqo5QeuqZR80BpCo8pQTuQz/6xB424kDpYpM0wl6Tvmc7X3UcFAs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772111959; c=relaxed/simple; bh=2pdhdOeMDJPm5HoJI3x9uFH0rU4m4uzXJEGd/Pg/vz8=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=pJRYxU1grcHPoksIP9BjUjaGPyuK/YH20XVSIBHW8Q7nyPrlEl5LIOy4djBgwjH16kuVYxMOIJ9Ljf8OWZAW6tM7akB1Y/+ZWqi5A4CL1gWQZE1P0GzZl56fJvODtxRyVMAuX1E3MWSvv78UGhnUv+lJGmTdztphIs7b403pEGw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 4789E1516; Thu, 26 Feb 2026 05:19:11 -0800 (PST) Received: from [10.57.82.70] (unknown [10.57.82.70]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 49E263F62B; Thu, 26 Feb 2026 05:19:15 -0800 (PST) Message-ID: <917f3bc3-1f17-4712-836d-ac75fdef3d16@arm.com> Date: Thu, 26 Feb 2026 13:19:13 +0000 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [RFC V1 10/16] arm64/mm: Route all pgtable writes via ptdesc_set() Content-Language: en-GB To: Anshuman Khandual , Usama Arif Cc: linux-arm-kernel@lists.infradead.org, Catalin Marinas , Will Deacon , Mark Rutland , Lorenzo Stoakes , Andrew Morton , David Hildenbrand , Mike Rapoport , Linu Cherian , linux-kernel@vger.kernel.org, linux-mm@kvack.org References: <20260226123747.801496-1-usama.arif@linux.dev> <0ee7ff56-ac0c-458e-9772-b3c026389e65@arm.com> From: Ryan Roberts In-Reply-To: <0ee7ff56-ac0c-458e-9772-b3c026389e65@arm.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit On 26/02/2026 12:54, Anshuman Khandual wrote: > > > On 26/02/26 6:07 PM, Usama Arif wrote: >> On Tue, 24 Feb 2026 10:41:47 +0530 Anshuman Khandual wrote: >> >>> Currently ptdesc_set() is defined as WRITE_ONCE() but this will change for >>> D128 pgtable builds, for which WRITE_ONCE() is not sufficient for single >>> copy atomicity. >>> >>> In future this infrastructure can be used for D128 to maintain single copy >>> atomicity semantics with inline asm blocks. >>> >>> Cc: Catalin Marinas >>> Cc: Will Deacon >>> Cc: Ryan Roberts >>> Cc: Mark Rutland >>> Cc: linux-arm-kernel@lists.infradead.org >>> Cc: linux-kernel@vger.kernel.org >>> Signed-off-by: Anshuman Khandual >>> --- >>> arch/arm64/include/asm/pgtable.h | 11 ++++++----- >>> arch/arm64/mm/mmu.c | 4 ++-- >>> mm/debug_vm_pgtable.c | 4 ++-- >>> 3 files changed, 10 insertions(+), 9 deletions(-) >>> >>> diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h >>> index 804ef49aea88..42124d2f323d 100644 >>> --- a/arch/arm64/include/asm/pgtable.h >>> +++ b/arch/arm64/include/asm/pgtable.h >>> @@ -85,6 +85,7 @@ static inline void arch_leave_lazy_mmu_mode(void) >>> } >>> >>> #define ptdesc_get(x) READ_ONCE(x) >>> +#define ptdesc_set(x, val) WRITE_ONCE(x, val) >>> >>> #define pmdp_get pmdp_get >>> static inline pmd_t pmdp_get(pmd_t *pmdp) >>> @@ -389,7 +390,7 @@ static inline pte_t pte_clear_uffd_wp(pte_t pte) >>> >>> static inline void __set_pte_nosync(pte_t *ptep, pte_t pte) >>> { >>> - WRITE_ONCE(*ptep, pte); >>> + ptdesc_set(*ptep, pte); >>> } >>> >>> static inline void __set_pte_complete(pte_t pte) >>> @@ -856,7 +857,7 @@ static inline void set_pmd(pmd_t *pmdp, pmd_t pmd) >>> } >>> #endif /* __PAGETABLE_PMD_FOLDED */ >>> >>> - WRITE_ONCE(*pmdp, pmd); >>> + ptdesc_set(*pmdp, pmd); >>> >>> if (pmd_valid(pmd)) >>> queue_pte_barriers(); >>> @@ -917,7 +918,7 @@ static inline void set_pud(pud_t *pudp, pud_t pud) >>> return; >>> } >>> >>> - WRITE_ONCE(*pudp, pud); >>> + ptdesc_set(*pudp, pud); >>> >>> if (pud_valid(pud)) >>> queue_pte_barriers(); >>> @@ -999,7 +1000,7 @@ static inline void set_p4d(p4d_t *p4dp, p4d_t p4d) >>> return; >>> } >>> >>> - WRITE_ONCE(*p4dp, p4d); >>> + ptdesc_set(*p4dp, p4d); >>> queue_pte_barriers(); >>> } >>> >>> @@ -1120,7 +1121,7 @@ static inline void set_pgd(pgd_t *pgdp, pgd_t pgd) >>> return; >>> } >>> >>> - WRITE_ONCE(*pgdp, pgd); >>> + ptdesc_set(*pgdp, pgd); >>> queue_pte_barriers(); >>> } >>> >>> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c >>> index bcf32d1a92de..ffd307c546f5 100644 >>> --- a/arch/arm64/mm/mmu.c >>> +++ b/arch/arm64/mm/mmu.c >>> @@ -83,7 +83,7 @@ void noinstr set_swapper_pgd(pgd_t *pgdp, pgd_t pgd) >>> * writable in the kernel mapping. >>> */ >>> if (rodata_is_rw) { >>> - WRITE_ONCE(*pgdp, pgd); >>> + ptdesc_set(*pgdp, pgd); >>> dsb(ishst); >>> isb(); >>> return; >>> @@ -91,7 +91,7 @@ void noinstr set_swapper_pgd(pgd_t *pgdp, pgd_t pgd) >>> >>> spin_lock(&swapper_pgdir_lock); >>> fixmap_pgdp = pgd_set_fixmap(__pa_symbol(pgdp)); >>> - WRITE_ONCE(*fixmap_pgdp, pgd); >>> + ptdesc_set(*fixmap_pgdp, pgd); >>> /* >>> * We need dsb(ishst) here to ensure the page-table-walker sees >>> * our new entry before set_p?d() returns. The fixmap's >>> diff --git a/mm/debug_vm_pgtable.c b/mm/debug_vm_pgtable.c >>> index 83cf07269f13..faf6a19a89a1 100644 >>> --- a/mm/debug_vm_pgtable.c >>> +++ b/mm/debug_vm_pgtable.c >>> @@ -445,7 +445,7 @@ static void __init pmd_huge_tests(struct pgtable_debug_args *args) >>> * X86 defined pmd_set_huge() verifies that the given >>> * PMD is not a populated non-leaf entry. >>> */ >>> - WRITE_ONCE(*args->pmdp, __pmd(0)); >>> + ptdesc_set(*args->pmdp, __pmd(0)); >> >> The ptdesc_set() and ptdesc_get() macros are defined in >> arch/arm64/include/asm/pgtable.h and are arm64-specific. This change is >> in mm/debug_vm_pgtable.c which is generic code compiled for all >> architectures. Other architectures do not define ptdesc_set(), so this >> will would cause a build failure on other architectures.. > > Agreed. Probably will add a local fallback for ptdesc_set() which > defaults to WRITE_ONCE() for platforms not overriding. OR does it > require making ptdesc_get/set() much more generic construct ? > > Probably missed this problem while building on some other platforms > as DEBUG_VM_PGTABLE might not have been enabled in their defconfig. I don't think there is any need for WRITE_ONCE() in this file? (and I feel like this has come up before in some other context). Could you just change it to a plain C assignment? Or even better, pmd_clear()? > >> >>> WARN_ON(!pmd_set_huge(args->pmdp, __pfn_to_phys(args->fixed_pmd_pfn), args->page_prot)); >>> WARN_ON(!pmd_clear_huge(args->pmdp)); >>> pmd = pmdp_get(args->pmdp); >>> @@ -465,7 +465,7 @@ static void __init pud_huge_tests(struct pgtable_debug_args *args) >>> * X86 defined pud_set_huge() verifies that the given >>> * PUD is not a populated non-leaf entry. >>> */ >>> - WRITE_ONCE(*args->pudp, __pud(0)); >>> + ptdesc_set(*args->pudp, __pud(0)); >>> WARN_ON(!pud_set_huge(args->pudp, __pfn_to_phys(args->fixed_pud_pfn), args->page_prot)); >>> WARN_ON(!pud_clear_huge(args->pudp)); >>> pud = pudp_get(args->pudp); >>> -- >>> 2.43.0 >>> >>> >> >