From nobody Tue Sep 29 06:08:34 2026 Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) (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 95ACB43031F for ; Tue, 11 Aug 2026 16:45:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786466737; cv=none; b=OpnoXeBIUj7j11qvuymprFqGFIGxSyw86K6J/KoKFhEwGiP5CNBEuTLK2ER44vkp1lvt4T2Z6qRRSQPwMUxEcBgs+wwitLyAe4YH6MHBmQDl9kq15KnOI+OqIKjlJ/2+oUCbAlVP956WSFOR7OYLdvIgIHCUpx+Tl+PRupviMaE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786466737; c=relaxed/simple; bh=/dFtgpI6m2Kwt4mTbzBbOiTxtYRwhiPbVMJ5Uv07nHI=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=shDExIsz7OejKFvE6PlvYMaXaPWg7LnRqw591kv1VP9lFTVlNIRod54vrFn1yEF/xigIOuRqk4hRPbLYQAmvVmUC70T6hFfxBzdev3wNMsXcVKBf4DTUiTgNI28ETvvzwWP4gRhc8PPOFkosVzyj2EBjSHbaH99QU2ksJcG93NM= 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=f+p/0zUB; arc=none smtp.client-ip=209.85.221.43 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="f+p/0zUB" Received: by mail-wr1-f43.google.com with SMTP id ffacd0b85a97d-47de0093c42so2403004f8f.3 for ; Tue, 11 Aug 2026 09:45:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786466734; x=1787071534; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=hF7Kn6Oocs5orb8GcrxywBb2rOULTfC5b3zs7Me4nLc=; b=f+p/0zUBnFfZ08GGkE5rplZLUXNsCe3zxHOqKd7Ss8OYRZ1KKc+ueb+KLlxlhXEf0t XElyb+crL0nEfxFoGhuwJlzW7S1ZSe14xjr4sF+ZFp1KDS+7ssyaMbdS1q51/WTvdVXn +mTE8BaqSpY4/0N5SOxwMt9XNIj4Znensehp9+zglmZqwVWyJYgJ7vAsxhJ81mZeMxww Rrv8zStOO2YHXmlxCuOlXexS7cBAY4AZJSrT1HkMJUZ7Twjk96Y70q9qG8eqK/Q1Tlsa 1KBaCdudXREwNVQD8JLB64iZF0BsbEDOyldoBP40zSiGP0esMc/GkDe9z98RmVHG9wp9 8L7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786466734; x=1787071534; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=hF7Kn6Oocs5orb8GcrxywBb2rOULTfC5b3zs7Me4nLc=; b=fsMW+ZSj6hnPpNDqVoeopYWudOpsa47ynZFVAKLOVAXv0p5CJZccHeQ2PPRUp7GCtT 6YoIXND1wEari9h+vsE0JhJlFJL9cgKfleXpCv8PKkhrDb2k3Jh9kF0I8bHLKO13sfl1 cLHU+e97Y9vHZL/mgW9uhgz2RlByIiX1gxh9fNE1odymcXMxGj4iF+C48S1Bb8YKX1ms iQeRiTVjS12ByiNp04JGduHF22KahjtrCSi3aNli71D9ojL7DtEyvEA/UuJx4g/mMHFb KhZdnnBJLfrJnpL/Ud0tQW9dVLntB6GHLs7kethgeq7TSY7xWwMCasqrdczUsWd0XVyd OYnw== X-Forwarded-Encrypted: i=1; AHgh+Ro/KoK+RTSi7lQCNd63/bV0Jr0TETIcJc6mPGY6l+Ow3rldJBly+LJ6us25AqCJeaeOCgaZI/uEfhTREcM=@vger.kernel.org X-Gm-Message-State: AOJu0YxHQqs9yRiuJMOHEbthwwcuZ3tDVs4q1MqMC1LkAaKlNvTp1oLX 3xMP1eYJQyRM9Ub72csidUVPpFKQsgP+U1y7mc1la2tKCANJ2yOyikLZ X-Gm-Gg: AR+sD13jwjVQQNZFURRqOiJOgGUp1IF2PhedpnrXEmJxAdiyun2iJBNrdEr0rO2nHDN eYt30WAMYCr38ghT04rtfzHyR3dr4Xj6wd+fu8wDUUZqk4l7rW1sDOTshywMYRhzBQKw/EPDArF XoQM88S2nVxOk/B96axKcPQcvPBYu57vgUAztf355zYbpy7ofnzzdKkJK0/yDuvph7kdoyE5sgV jU20w4Ss5E8+/tiv0f2ehdRyk82GaUQEhheYsBDvkAfyFlGOevxiCfWmDsjQ2fkl9e4U7BGZ0xD grK4KCuu9JHmGGTduYkaYTnu5CeFlxRsUMe61rLthr7I7yzpT6ZjtmbYw/XB/5X62w1UlYPB4dz xaSLf11g752eXMt2DsYv9Gc//zLKG/IupKxPyGYyroe+6jAXsF9PzcDfzxKTJzJ0RDoSdr3CvWq hnayEPaIn+IY+Z+bkX46NXWrEpnxNCn3+vL9b5aYpZESAvjojpNAH44mLpCjeEsylcLlkQ3SHRe BJqm4bcJbIJ5om9U2I4oIOnlevrzVLG/0I6DfJA7lh7TYJTXgQSJ7rFkzofhfJlhzA59Zg7OFwb lCOycjb6COc6y5pbkgKHVP4jSqh3S12Mmke9bwKH3ZGcEpy7/s/ridsVOvae7seLvYee X-Received: by 2002:a5d:5888:0:b0:47f:d011:f644 with SMTP id ffacd0b85a97d-4814ad82de4mr7363109f8f.4.1786466733642; Tue, 11 Aug 2026 09:45:33 -0700 (PDT) Received: from localhost.localdomain (dynamic-2a02-3100-a133-e401-bc8e-d36c-2d08-c5e0.310.pool.telefonica.de. [2a02:3100:a133:e401:bc8e:d36c:2d08:c5e0]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4814a5ac691sm5949354f8f.3.2026.08.11.09.45.32 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Tue, 11 Aug 2026 09:45:33 -0700 (PDT) From: Karl Mehltretter To: Russell King Cc: Karl Mehltretter , Linus Walleij , Ard Biesheuvel , Florian Fainelli , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH RESEND] ARM: alignment: restore uaccess state on emulation fault Date: Tue, 11 Aug 2026 18:45:28 +0200 Message-Id: <20260811164528.65747-1-kmehltretter@gmail.com> X-Mailer: git-send-email 2.39.5 (Apple Git-154) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The alignment handlers enable access to user memory while emulating unaligned instructions. If a checked access faults, its exception table fixup jumps to the handler's fault label and bypasses uaccess_restore(). This leaves DOMAIN_USER as DOMAIN_CLIENT with SW domain PAN, or leaves TTBR0 page table walks enabled with TTBR0 PAN, while the fault is handled. An ARM926 QEMU test using LDMIA across an unmapped page boundary reports DOMAIN_USER=3D1 at TYPE_FAULT before this change and DOMAIN_USER=3D0 after = it. SW domain PAN is the default on ARMv5, ARMv6, and non-LPAE ARMv7 builds. Keep the saved uaccess state at function scope and track whether it was saved. Restore it at the fault label only when needed. Paths that did not enable user access continue to skip the restore. Fixes: 274e91b81ed2 ("ARM: alignment: fix alignment handling for uaccess ch= anges") Cc: stable@vger.kernel.org Assisted-by: Codex:gpt-5.6-sol Signed-off-by: Karl Mehltretter Reviewed-by: Linus Walleij --- Resending after two weeks without feedback; add ARM alignment/PAN reviewers to Cc. arch/arm/mm/alignment.c | 51 ++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 812380f30ae3..2b470a419dda 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c @@ -341,6 +341,8 @@ static int do_alignment_ldrhstrh(unsigned long addr, u32 instr, struct pt_regs *regs) { unsigned int rd =3D RD_BITS(instr); + unsigned int ua_flags; + bool ua_saved =3D false; =20 ai_half +=3D 1; =20 @@ -364,10 +366,11 @@ do_alignment_ldrhstrh(unsigned long addr, u32 instr, = struct pt_regs *regs) user: if (LDST_L_BIT(instr)) { unsigned long val; - unsigned int __ua_flags =3D uaccess_save_and_enable(); =20 + ua_flags =3D uaccess_save_and_enable(); + ua_saved =3D true; get16t_unaligned_check(val, addr); - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); =20 /* signed half-word? */ if (instr & 0x40) @@ -375,14 +378,17 @@ do_alignment_ldrhstrh(unsigned long addr, u32 instr, = struct pt_regs *regs) =20 regs->uregs[rd] =3D val; } else { - unsigned int __ua_flags =3D uaccess_save_and_enable(); + ua_flags =3D uaccess_save_and_enable(); + ua_saved =3D true; put16t_unaligned_check(regs->uregs[rd], addr); - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); } =20 return TYPE_LDST; =20 fault: + if (ua_saved) + uaccess_restore(ua_flags); return TYPE_FAULT; } =20 @@ -391,6 +397,8 @@ do_alignment_ldrdstrd(unsigned long addr, u32 instr, st= ruct pt_regs *regs) { unsigned int rd =3D RD_BITS(instr); unsigned int rd2; + unsigned int ua_flags; + bool ua_saved =3D false; int load; =20 if ((instr & 0xfe000000) =3D=3D 0xe8000000) { @@ -425,26 +433,30 @@ do_alignment_ldrdstrd(unsigned long addr, u32 instr, = struct pt_regs *regs) user: if (load) { unsigned long val, val2; - unsigned int __ua_flags =3D uaccess_save_and_enable(); =20 + ua_flags =3D uaccess_save_and_enable(); + ua_saved =3D true; get32t_unaligned_check(val, addr); get32t_unaligned_check(val2, addr + 4); =20 - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); =20 regs->uregs[rd] =3D val; regs->uregs[rd2] =3D val2; } else { - unsigned int __ua_flags =3D uaccess_save_and_enable(); + ua_flags =3D uaccess_save_and_enable(); + ua_saved =3D true; put32t_unaligned_check(regs->uregs[rd], addr); put32t_unaligned_check(regs->uregs[rd2], addr + 4); - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); } =20 return TYPE_LDST; bad: return TYPE_ERROR; fault: + if (ua_saved) + uaccess_restore(ua_flags); return TYPE_FAULT; } =20 @@ -452,6 +464,8 @@ static int do_alignment_ldrstr(unsigned long addr, u32 instr, struct pt_regs *regs) { unsigned int rd =3D RD_BITS(instr); + unsigned int ua_flags; + bool ua_saved =3D false; =20 ai_word +=3D 1; =20 @@ -469,18 +483,22 @@ do_alignment_ldrstr(unsigned long addr, u32 instr, st= ruct pt_regs *regs) trans: if (LDST_L_BIT(instr)) { unsigned int val; - unsigned int __ua_flags =3D uaccess_save_and_enable(); + ua_flags =3D uaccess_save_and_enable(); + ua_saved =3D true; get32t_unaligned_check(val, addr); - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); regs->uregs[rd] =3D val; } else { - unsigned int __ua_flags =3D uaccess_save_and_enable(); + ua_flags =3D uaccess_save_and_enable(); + ua_saved =3D true; put32t_unaligned_check(regs->uregs[rd], addr); - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); } return TYPE_LDST; =20 fault: + if (ua_saved) + uaccess_restore(ua_flags); return TYPE_FAULT; } =20 @@ -502,6 +520,8 @@ do_alignment_ldmstm(unsigned long addr, u32 instr, stru= ct pt_regs *regs) { unsigned int rd, rn, correction, nr_regs, regbits; unsigned long eaddr, newaddr; + unsigned int ua_flags; + bool ua_saved =3D false; =20 if (LDM_S_BIT(instr)) goto bad; @@ -547,7 +567,8 @@ do_alignment_ldmstm(unsigned long addr, u32 instr, stru= ct pt_regs *regs) #endif =20 if (user_mode(regs)) { - unsigned int __ua_flags =3D uaccess_save_and_enable(); + ua_flags =3D uaccess_save_and_enable(); + ua_saved =3D true; for (regbits =3D REGMASK_BITS(instr), rd =3D 0; regbits; regbits >>=3D 1, rd +=3D 1) if (regbits & 1) { @@ -559,7 +580,7 @@ do_alignment_ldmstm(unsigned long addr, u32 instr, stru= ct pt_regs *regs) put32t_unaligned_check(regs->uregs[rd], eaddr); eaddr +=3D 4; } - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); } else { for (regbits =3D REGMASK_BITS(instr), rd =3D 0; regbits; regbits >>=3D 1, rd +=3D 1) @@ -581,6 +602,8 @@ do_alignment_ldmstm(unsigned long addr, u32 instr, stru= ct pt_regs *regs) return TYPE_DONE; =20 fault: + if (ua_saved) + uaccess_restore(ua_flags); regs->ARM_pc -=3D correction; return TYPE_FAULT; =20 --=20 2.53.0