From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D2F33C53200 for ; Wed, 29 Jul 2026 12:25:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From: Reply-To:Content-Type:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=xRnJTTIxgyJhzAEBmZRsAl++8ZTYNjGGc69RgLSTkU4=; b=lv72JuODzeWML5IgTpnZHIDLEP dN3ScPdVkosW0drAWwszOtcG6h870TDd9ljk0zrjwH9sTpj/VH4oX+vhAx3ocMkHjTWDmXxIHGDy1 pkripsojtve9zLE0wFmiiWLWwob3lvGYj8xoDhwPA/9ftvTG8G5O5bQIIP6MTHU158gh8tKLgBD0B ZaGv5CDhnnIoVHAeezZkk56rnvzf81Cn/YdxwNC97RnwQ5j5dElbYeFcv4JTTN80fb2hfJD1ydXu5 TeJWEX5eVSLsAwiOKdSjPUIFJaWZR5i8wCtuaoxblVjwr4+Os2hGnjIAhAu2KJ7c7BzOATIwB4jVd 8UjJqHDA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wp3Lt-00000007tHi-35JA; Wed, 29 Jul 2026 12:25:37 +0000 Received: from foss.arm.com ([217.140.110.172]) by bombadil.infradead.org with esmtp (Exim 4.99.1 #2 (Red Hat Linux)) id 1wp3Lp-00000007tF4-3M3S for linux-arm-kernel@lists.infradead.org; Wed, 29 Jul 2026 12:25:35 +0000 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 CA570168F; Wed, 29 Jul 2026 05:25:25 -0700 (PDT) Received: from a085714.blr.arm.com (a085714.arm.com [10.164.19.28]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 1705F3F66F; Wed, 29 Jul 2026 05:25:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1785327929; bh=un+ELP9ikVFH4v2qEoGWM42r/ujHaHAs6bDRsgwiF8o=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jXDXd5cDeH2SWCOyZzNVoeIpfyIOczCOGisCQC0jApTdvP5v4wi+P+ceMm603tNWh 1O4FkdQxN4y8EcxaGr640ESUR2dQTqnxXOQS23PK+BK7gqfq+PFJ6nxfOGhc1MLC6K vIVJoIkFTlyqVDOSn6dJRodAYkDN8phU1N1qW/fA= From: Anshuman Khandual To: linux-mm@kvack.org, linux-arm-kernel@lists.infradead.org Cc: Anshuman Khandual , Catalin Marinas , Will Deacon , Ryan Roberts , Mark Rutland , Lorenzo Stoakes , Andrew Morton , David Hildenbrand , Mike Rapoport , Linu Cherian , linux-kernel@vger.kernel.org, kasan-dev@googlegroups.com Subject: [PATCH 05/17] arm64/mm: Convert READ_ONCE() as pgdp_get() while accessing PGD Date: Wed, 29 Jul 2026 17:54:40 +0530 Message-ID: <20260729122452.3797443-6-anshuman.khandual@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260729122452.3797443-1-anshuman.khandual@arm.com> References: <20260729122452.3797443-1-anshuman.khandual@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.9.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260729_052533_927911_90D2D7D4 X-CRM114-Status: GOOD ( 18.38 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Convert all READ_ONCE() based PGD accesses as pgdp_get() instead which will support both D64 and D128 translation regime going forward. That is because READ_ONCE() would need 128 bit single copy atomic guarantees, while reading 128 bit page table entries which is currently not supported on arm64. Build fails for READ_ONCE() while accessing beyond 64 bits. Load Pair/Store Pair (ldp/stp) are only single copy atomic if FEAT_LSE128 is supported (which is required when FEAT_D128 is supported). Currently 128 bit pgtables is a compile time decision - so we could have chosen to extend READ_ONCE()/WRITE_ONCE() to allow 128 bit for this configuration. But then it's a general purpose API and we were concerned that other users might eventually creep in that expect 128 and then fail to compile in the other configs. But worse, we are considering eventually making D128 a boot time option, at which point we'd have to make READ_ONCE() always allow 128 bit at compile time but then it might silently tear at runtime. So our preference is to standardize on these existing helpers, which we can override in arm64 to give the 128 bit single copy guarantee when required. 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 Cc: kasan-dev@googlegroups.com Signed-off-by: Anshuman Khandual --- arch/arm64/mm/fault.c | 2 +- arch/arm64/mm/hugetlbpage.c | 2 +- arch/arm64/mm/kasan_init.c | 6 +++--- arch/arm64/mm/mmu.c | 6 +++--- arch/arm64/mm/pageattr.c | 2 +- arch/arm64/mm/trans_pgd.c | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 6f3d30b689ff..fca716ed4513 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -155,7 +155,7 @@ static void show_pte(unsigned long addr) mm == &init_mm ? "swapper" : "user", PAGE_SIZE / SZ_1K, vabits_actual, mm_to_pgd_phys(mm)); pgdp = pgd_offset(mm, addr); - pgd = READ_ONCE(*pgdp); + pgd = pgdp_get(pgdp); pr_alert("[%016lx] pgd=%016llx", addr, pgd_val(pgd)); do { diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 5771bf49e1fe..e05e5b41ae50 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -284,7 +284,7 @@ pte_t *huge_pte_offset(struct mm_struct *mm, pmd_t *pmdp, pmd; pgdp = pgd_offset(mm, addr); - if (!pgd_present(READ_ONCE(*pgdp))) + if (!pgd_present(pgdp_get(pgdp))) return NULL; p4dp = p4d_offset(pgdp, addr); diff --git a/arch/arm64/mm/kasan_init.c b/arch/arm64/mm/kasan_init.c index 7e2bec43fd4a..41b65fd31f76 100644 --- a/arch/arm64/mm/kasan_init.c +++ b/arch/arm64/mm/kasan_init.c @@ -102,7 +102,7 @@ static pud_t *__init kasan_pud_offset(p4d_t *p4dp, unsigned long addr, int node, static p4d_t *__init kasan_p4d_offset(pgd_t *pgdp, unsigned long addr, int node, bool early) { - if (pgd_none(READ_ONCE(*pgdp))) { + if (pgd_none(pgdp_get(pgdp))) { phys_addr_t p4d_phys = early ? __pa_symbol(kasan_early_shadow_p4d) : kasan_alloc_zeroed_page(node); @@ -256,7 +256,7 @@ static int __init root_level_idx(u64 addr) static void __init clone_next_level(u64 addr, pgd_t *tmp_pg_dir, pud_t *pud) { int idx = root_level_idx(addr); - pgd_t pgd = READ_ONCE(swapper_pg_dir[idx]); + pgd_t pgd = pgdp_get(swapper_pg_dir + idx); pud_t *pudp = (pud_t *)__phys_to_kimg(__pgd_to_phys(pgd)); memcpy(pud, pudp, PAGE_SIZE); @@ -280,7 +280,7 @@ static int __init next_level_idx(u64 addr) */ static void __init clear_next_level(int pgd_idx, int start, int end) { - pgd_t pgd = READ_ONCE(swapper_pg_dir[pgd_idx]); + pgd_t pgd = pgdp_get(swapper_pg_dir + pgd_idx); pud_t *pudp = (pud_t *)__phys_to_kimg(__pgd_to_phys(pgd)); memset(&pudp[start], 0, (end - start) * sizeof(pud_t)); diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index aceb20e48251..d5b6eb544216 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -435,7 +435,7 @@ static int alloc_init_p4d(pgd_t *pgdp, unsigned long addr, unsigned long end, { int ret; unsigned long next; - pgd_t pgd = READ_ONCE(*pgdp); + pgd_t pgd = pgdp_get(pgdp); p4d_t *p4dp; if (pgd_none(pgd)) { @@ -1601,7 +1601,7 @@ static void unmap_hotplug_range(unsigned long addr, unsigned long end, do { next = pgd_addr_end(addr, end); pgdp = pgd_offset_k(addr); - pgd = READ_ONCE(*pgdp); + pgd = pgdp_get(pgdp); if (pgd_none(pgd)) continue; @@ -1779,7 +1779,7 @@ static void free_empty_tables(unsigned long addr, unsigned long end, do { next = pgd_addr_end(addr, end); pgdp = pgd_offset_k(addr); - pgd = READ_ONCE(*pgdp); + pgd = pgdp_get(pgdp); if (pgd_none(pgd)) continue; diff --git a/arch/arm64/mm/pageattr.c b/arch/arm64/mm/pageattr.c index 826856ef64a8..dfa1356daac2 100644 --- a/arch/arm64/mm/pageattr.c +++ b/arch/arm64/mm/pageattr.c @@ -399,7 +399,7 @@ bool kernel_page_present(struct page *page) unsigned long addr = (unsigned long)page_address(page); pgdp = pgd_offset_k(addr); - if (pgd_none(READ_ONCE(*pgdp))) + if (pgd_none(pgdp_get(pgdp))) return false; p4dp = p4d_offset(pgdp, addr); diff --git a/arch/arm64/mm/trans_pgd.c b/arch/arm64/mm/trans_pgd.c index 7afe2beca4ba..06470d690f9f 100644 --- a/arch/arm64/mm/trans_pgd.c +++ b/arch/arm64/mm/trans_pgd.c @@ -134,7 +134,7 @@ static int copy_p4d(struct trans_pgd_info *info, pgd_t *dst_pgdp, unsigned long next; unsigned long addr = start; - if (pgd_none(READ_ONCE(*dst_pgdp))) { + if (pgd_none(pgdp_get(dst_pgdp))) { dst_p4dp = trans_alloc(info); if (!dst_p4dp) return -ENOMEM; @@ -164,7 +164,7 @@ static int copy_page_tables(struct trans_pgd_info *info, pgd_t *dst_pgdp, dst_pgdp = pgd_offset_pgd(dst_pgdp, start); do { next = pgd_addr_end(addr, end); - if (pgd_none(READ_ONCE(*src_pgdp))) + if (pgd_none(pgdp_get(src_pgdp))) continue; if (copy_p4d(info, dst_pgdp, src_pgdp, addr, next)) return -ENOMEM; -- 2.43.0