DORMANTno replies

[RFC PATCH] arm64: mm: recover from kernel-mode SEA via exception table

From: Nguyen Ngoc Thang <hidden>
Date: 2026-09-12 13:56:04
Also in: lkml
Subsystem: arm64 port (aarch64 architecture), the rest · Maintainers: Catalin Marinas, Will Deacon, Linus Torvalds

do_sea() unconditionally calls die() for a synchronous external
abort taken at EL1, without ever consulting the exception table.
This is inconsistent with __do_kernel_fault(), which does check
fixup_exception() before giving up.

A SEA at EL1 is reachable and recoverable: futex's LL/SC atomic ops
(__llsc_futex_cmpxchg/__llsc_futex_atomic_*) carry
_ASM_EXTABLE_UACCESS_ERR entries, but if the user address is mapped
to Device memory (e.g. a PCI BAR obtained via sysfs "resourceN" and
mmap'd MAP_FIXED), the LDXR/STLXR pair faults with a SEA instead of
a translation fault, and the extable fixup is never reached, so the
kernel oopses instead of returning -EFAULT to userspace.

Check fixup_exception() for kernel-mode SEAs before dying, mirroring
__do_kernel_fault(). No taint is added on the recovered path since
this is a userspace-triggerable condition, not a hardware failure;
a ratelimited warning keeps a trace of it.

Reported-by: syzbot+635d160c0d4133481520@syzkaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?extid=635d160c0d4133481520
Signed-off-by: Nguyen Ngoc Thang <redacted>
---
Sent as RFC: verified by code inspection (ESR/DFSC decode matches
the extable-carrying LL/SC futex path) but not yet reproduced under
QEMU on my end; would appreciate a look before I chase the aarch64
repro further.

 arch/arm64/mm/fault.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index 0b52557652be..fe5a5c5bbc27 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -878,6 +878,18 @@ static int do_sea(unsigned long far, unsigned long esr, struct pt_regs *regs)
 		return 0;
 	}
 
+	/*
+	 * A SEA at EL1 can happen from uaccess helpers (e.g. LDXR/STLXR
+	 * on a user page mapped as Device memory, as in the futex ops)
+	 * that carry an extable fixup. Let it return -EFAULT instead of
+	 * oopsing the kernel.
+	 */
+	if (!user_mode(regs) && fixup_exception(regs, esr)) {
+		pr_warn_ratelimited("Recovered SEA at kernel uaccess, addr=%#lx, esr=%#lx\n",
+				    far, esr);
+		return 0;
+	}
+
 	if (esr & ESR_ELx_FnV) {
 		siaddr = 0;
 	} else {
-- 
2.43.0

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help