[PATCH v4 1/2] ARM: mm: fault: Enable interrupts before invoking __do_user_fault()

Sebastian Andrzej Siewior bigeasy at linutronix.de
Fri Jan 16 09:00:40 PST 2026


From: "Yadi.hu" <yadi.hu at windriver.com>

A page fault from userland for a kernel address originates from from
do_sect_fault() (!LPAE) or do_page_fault() and ends in __do_user_fault()
by sending a signal.

Sending a signal requires to acquire sighand_struct::siglock which is a
spinlock_t. On PREEMPT_RT spinlock_t becomes a sleeping spin lock which
requires interrupts to be enabled. Since the calling context is user
land, interrupts must have been enabled so it is fine to enable them in
this case.

Enable interrupts in do_kernel_address_page_fault() unconditional in the
user_mode case().
Enable interrupts in do_sect_fault() if they were previously enabled.

[bigeasy: Initial patch/ report by Yadi. Maintained the patch and redid
          the patch description since]

Signed-off-by: Yadi.hu <yadi.hu at windriver.com>
Acked-by: Linus Walleij <linus.walleij at linaro.org>
Reviewed-by: Arnd Bergmann <arnd at arndb.de>
Acked-by: Bryan Brattlof <bb at ti.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy at linutronix.de>
---
 arch/arm/mm/fault.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index ed4330cc3f4e6..3f1c73269c126 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -270,6 +270,7 @@ do_kernel_address_page_fault(struct mm_struct *mm, unsigned long addr,
 		 * while interrupts are still disabled, then send a SIGSEGV.
 		 */
 		harden_branch_predictor();
+		local_irq_enable();
 		__do_user_fault(addr, fsr, SIGSEGV, SEGV_MAPERR, regs);
 	} else {
 		/*
@@ -592,6 +593,9 @@ do_sect_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 	if (addr >= TASK_SIZE && user_mode(regs))
 		harden_branch_predictor();
 
+	if (interrupts_enabled(regs))
+		local_irq_enable();
+
 	do_bad_area(addr, fsr, regs);
 
 	return 0;
-- 
2.51.0




More information about the linux-arm-kernel mailing list