From nobody Tue Apr 7 07:30:44 2026 Received: from mail-pj1-f49.google.com (mail-pj1-f49.google.com [209.85.216.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7566C3126D7 for ; Sat, 14 Mar 2026 19:11:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773515501; cv=none; b=Jn91+4/c0UGHqh+ar0gVtaQEhYB93cplcwc+RFD2J2DxQl6Wy261ncxBXS6+Db+Nj8en48NVpF1qd/e299Urt66Eq9DTw7SAQhkc30JjQguZfzLsdErW//8TS2sJZTQtpAto0Kt0+qDRlePGrCjuI0swhimS4JHWs82yE+wM+V0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773515501; c=relaxed/simple; bh=O5Vz2SHUyEAmQVFLJfmscCu8zHMJVKJaSHDHtMjdC6w=; h=Date:From:To:Cc:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition; b=iLpE2fsifLLfXVh3eix7RgH+x+tL/063ux8Yrx31z3LrVahFv68rxKDFtJsrwoO8epBDccA3oqedutmrWWlJob5m4OCqx0bD6gYGUDLUcw5OOPZd3in1TLUuVLCMoIFiZBgLdj8a9VN7+PDFXPly/96P/0h9bL2JweDLMEjtCiM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=A91o3nPZ; arc=none smtp.client-ip=209.85.216.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="A91o3nPZ" Received: by mail-pj1-f49.google.com with SMTP id 98e67ed59e1d1-35a1cc6e478so1593968a91.0 for ; Sat, 14 Mar 2026 12:11:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1773515500; x=1774120300; darn=vger.kernel.org; h=user-agent:content-disposition:mime-version:mail-followup-to :message-id:subject:cc:to:from:date:from:to:cc:subject:date :message-id:reply-to; bh=G1Rwy1rCypsS5rvd/5BlfnntkzTDDi7zIl48jCy+BOQ=; b=A91o3nPZGu76CbZ5HsBNqDcQdbJ0jQzQszw8FSC0RTAeR88Zb+CtNQ2qde470SKnU7 G49h9uUjFBw4kKDiE6zXY6v7+a6q92bCvoO0bnJ5r3CN/WsHlcgh214XQuFirlbZqA2C V6KDrXrfZIoF+A6uKiGKHjHwzaKTY9R/QUT2Yf/g0zW/wOwgwsQFnuE7WIDUxMwwOhCq B46d0hISrochNfQZbSAXnWZ6kCgBdplsmIjAOVuu64nDI4ktoue9EBPKv8tT8A+aSUWT pkUdzwb0ZbUn8TkcwF5pTrm2BLYJ+Qtw1pQCekp3QAb8XLPwEjjIPLQV1LygxnmkUvC6 G25w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1773515500; x=1774120300; h=user-agent:content-disposition:mime-version:mail-followup-to :message-id:subject:cc:to:from:date:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=G1Rwy1rCypsS5rvd/5BlfnntkzTDDi7zIl48jCy+BOQ=; b=E0IyMKPdfLoz7w/lzIBePukU6Pu2wRujF+ooTVZFgzThnaPaWjVxXpUTNYkAgW8kG4 gp5pl6I3vWJr5XTX7oCsDZOk8lWmcq2ifP45/3/zCdYHoR8jPIlPbA33Wdj/lq6YuYHI ezLeMgPK1k48LDy5bnDHj/U/Ikgl4bdrI2zjuarqxZH6jTXK6F1Af3hwm+/jlxNztecp vR6he20kEg3rG0TAsAMNmMF8H+KW3YpJOgUBpzM5zhfslcr/u5yk4lc24EE+/nMJxqip SJObzkz/nx+nVRso5GRWInbTDT9JozYiaOd3DG4VG/vUJe7MwjBVR/bex2CzrMYyLkXb i2zw== X-Forwarded-Encrypted: i=1; AJvYcCUn3YYkiP8h+vpw0mbIqPRe9pYEQomcYM02boKXxS3wwx2LlIlrdBRhJe4RwKDiKGSoTp1nefZ94bA4ENI=@vger.kernel.org X-Gm-Message-State: AOJu0YzTgRJUeS30XFLTDQBrzGrrLHjnukPGnLUAS8JTszEgZlxBIkC5 DzC8l0XGDjcghLdy4DM/UPobhFFZIk6PhCVHgBaDPPiwZTUN8UZixchI X-Gm-Gg: ATEYQzzmj+X72Yr2RphBWtZ5OUUY4+XpgTqjrK/N8T0M+6BpW6O+LnsbH21mkypYVls Sq+RwBDTKW3K9we3tqCaolKchu1721but+21VuyoUbxQt6ttN9G9UAEseAe3GWVMppBFE85EQ3c SRq+G9gY0BlFhcBS7awLdohW3W4dB663p28ah0rm4B9c14fKZ27+x9XREFBD2ewopMs9eesbJgO eti99M+qe1MSDcwzR/Jp/5H/mRylPXmZFrjKFm4QPM7NE4SoPGTJVNOtCJnZ10HJTsy7juwoDtW VOi8l9xmNkN7quiMDR+uYHK697V/a0BqMeSHzkJAUqfzHIDD0V2G+IX9qyuwDCdefXRVJZ89ore hCppiEDnCpVp8vAZhXmaBOJDzmbWxXjjZRn24ZKAD3iYODNU7ipP+8vW/kutWxLdxnm69XvtieF BCUQV/lIuY/nBQbPg6BuApj2+wQYbCUBzWnSu5Du4g X-Received: by 2002:a17:90b:5345:b0:35b:93d8:6aaf with SMTP id 98e67ed59e1d1-35b93d86c76mr586837a91.19.1773515499736; Sat, 14 Mar 2026 12:11:39 -0700 (PDT) Received: from udknight.localhost ([120.36.202.188]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-35a2450ffd9sm2593217a91.6.2026.03.14.12.11.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 14 Mar 2026 12:11:38 -0700 (PDT) Received: from udknight.localhost (localhost [127.0.0.1]) by udknight.localhost (8.14.9/8.14.4) with ESMTP id 62EI04la008004; Sun, 15 Mar 2026 02:00:04 +0800 Received: (from root@localhost) by udknight.localhost (8.14.9/8.14.9/Submit) id 62EHxw2u008000; Sun, 15 Mar 2026 01:59:58 +0800 Date: Sun, 15 Mar 2026 01:59:58 +0800 From: Wang YanQing To: linux@armlinux.org.uk, akpm@linux-foundation.org Cc: willy@infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH] arm: lpae: fix non-atomic page table entry update issue Message-ID: <20260314175958.GA7956@udknight> Mail-Followup-To: Wang YanQing , linux@armlinux.org.uk, akpm@linux-foundation.org, willy@infradead.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.7.1 (2016-10-04) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The ARM Architecture Reference Manual explicitly dictates that writes of 64= -bit translation table descriptors must be single-copy atomic, to archieve this = 64-bit atomicity on a 32-bit architecture, the linux kernel relies on the STRD (St= ore Register Dual) instruction, but the copy_pmd() in pgtable-3level.h is C cod= e, then compiler could do very crazy optimization for it and generate code that bre= ak the atomicity, for example, we get below copy_pmd() assembly code with gcc 12.4= .0 (Using CC_OPTIMIZE_FOR_PERFORMANCE, it is the default compile option): " gdb vmlinux gdb disassemble do_translation_fault gdb ... gdb 0xc020e544 <+136>: ldr.w r4, [r0, r1, lsl #3] @load low 32-bit of= pmdps gdb 0xc020e548 <+140>: ldr r0, [r6, #4] @load high 32-bit o= f pmdps gdb 0xc020e54a <+142>: orrs.w r6, r4, r0 @ pmd_none(pmd_k[in= dex]) gdb 0xc020e54e <+146>: beq.n 0xc020e586 gdb ... gdb 0xc020e562 <+166>: str.w r4, [r5, r1, lsl #3] @store low 32-bit t= o pmdpd gdb 0xc020e566 <+170>: str r0, [r2, #4] @store hight 32-bit= to pmdpd The code breaks the atomicity and valid bit is in the low 32-bit, page tabl= e walker could see and cache the partial write entry, this will cause very strange translation-related issues when next page table (level3 PTE table) physical= address is larger than 32-bits. So let's use WRITE_ONCE() to protect the page table entry update functions = from crazy optimization. Signed-off-by: Wang YanQing --- arch/arm/include/asm/pgtable-3level.h | 28 +++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/p= gtable-3level.h index 7b71a3d414b7..b077174a4231 100644 --- a/arch/arm/include/asm/pgtable-3level.h +++ b/arch/arm/include/asm/pgtable-3level.h @@ -120,15 +120,15 @@ PMD_TYPE_SECT) #define pmd_leaf(pmd) pmd_sect(pmd) =20 -#define pud_clear(pudp) \ - do { \ - *pudp =3D __pud(0); \ - clean_pmd_entry(pudp); \ +#define pud_clear(pudp) \ + do { \ + WRITE_ONCE(*pudp, __pud(0)); \ + clean_pmd_entry(pudp); \ } while (0) =20 #define set_pud(pudp, pud) \ do { \ - *pudp =3D pud; \ + WRITE_ONCE(*pudp, pud); \ flush_pmd_entry(pudp); \ } while (0) =20 @@ -139,16 +139,16 @@ static inline pmd_t *pud_pgtable(pud_t pud) =20 #define pmd_bad(pmd) (!(pmd_val(pmd) & PMD_TABLE_BIT)) =20 -#define copy_pmd(pmdpd,pmdps) \ - do { \ - *pmdpd =3D *pmdps; \ - flush_pmd_entry(pmdpd); \ +#define copy_pmd(pmdpd, pmdps) \ + do { \ + WRITE_ONCE(*pmdpd, READ_ONCE(*pmdps)); \ + flush_pmd_entry(pmdpd); \ } while (0) =20 -#define pmd_clear(pmdp) \ - do { \ - *pmdp =3D __pmd(0); \ - clean_pmd_entry(pmdp); \ +#define pmd_clear(pmdp) \ + do { \ + WRITE_ONCE(*pmdp, __pmd(0)); \ + clean_pmd_entry(pmdp); \ } while (0) =20 /* @@ -241,7 +241,7 @@ static inline void set_pmd_at(struct mm_struct *mm, uns= igned long addr, else pmd_val(pmd) |=3D PMD_SECT_AP2; =20 - *pmdp =3D __pmd(pmd_val(pmd) | PMD_SECT_nG); + WRITE_ONCE(*pmdp, __pmd(pmd_val(pmd) | PMD_SECT_nG)); flush_pmd_entry(pmdp); } =20 --=20 2.34.1