[PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors

From: Xie Yuanbin

Date: Thu Jun 25 2026 - 03:35:50 EST


For lastest linux-next kernel, with default multi_v7_defconfig, and
setting CONFIG_PREEMPT_RT=y, CONFIG_DEBUG_ATOMIC_SLEEP=y, and
CONFIG_PERF_EVENTS=n. When the user program executes bkpt
instruction, the following WARN will be triggered:
```log
[ 3.677825] BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
[ 3.678002] in_atomic(): 0, irqs_disabled(): 128, non_block: 0, pid: 84, name: test
[ 3.678036] preempt_count: 0, expected: 0
[ 3.678078] RCU nest depth: 0, expected: 0
[ 3.678864] CPU: 0 UID: 0 PID: 84 Comm: test Tainted: G W 7.1.0-next-20260623 #45 PREEMPT_RT
[ 3.679067] Tainted: [W]=WARN
[ 3.679088] Hardware name: Generic DT based system
[ 3.679198] Call trace:
[ 3.679695] unwind_backtrace from show_stack+0x10/0x14
[ 3.680363] show_stack from dump_stack_lvl+0x50/0x5c
[ 3.680377] dump_stack_lvl from __might_resched+0x160/0x174
[ 3.680393] __might_resched from rt_spin_lock+0x38/0x138
[ 3.680425] rt_spin_lock from force_sig_info_to_task+0x1c/0x11c
[ 3.680438] force_sig_info_to_task from force_sig_fault+0x44/0x64
[ 3.680450] force_sig_fault from do_PrefetchAbort+0x94/0x9c
[ 3.680461] do_PrefetchAbort from ret_from_exception+0x0/0x20
[ 3.680513] Exception stack(0xf0ab5fb0 to 0xf0ab5ff8)
[ 3.680653] 5fa0: 00000000 bed32e94 bed32e9c 00037954
[ 3.680672] 5fc0: 00000002 00000001 bed32e94 0009d590 00000000 bed32e9c 00000002 00000000
[ 3.680682] 5fe0: bed32d48 bed32d38 00037a00 00037958 60000010 ffffffff
```

When PREEMPT_RT is enabled, force_sig_info() requires interrupts to be
enabled. Enable interrupts when arm_notify_die() is handling user mode
errors to fix the issue.

Fixes: c6e61c06d606 ("ARM: 9463/1: Allow to enable RT")

Cc: Sebastian Andrzej Siewior <bigeasy@xxxxxxxxxxxxx>
Cc: Russell King (Oracle) <rmk+kernel@xxxxxxxxxxxxxxx>
Signed-off-by: Xie Yuanbin <xieyuanbin1@xxxxxxxxxx>
---
arch/arm/kernel/traps.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index afbd2ebe5c39..6aa205a92920 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -375,6 +375,7 @@ void arm_notify_die(const char *str, struct pt_regs *regs,
unsigned long err, unsigned long trap)
{
if (user_mode(regs)) {
+ local_irq_enable();
current->thread.error_code = err;
current->thread.trap_no = trap;

--
2.53.0