Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors
@ 2026-06-25  7:35 Xie Yuanbin
  2026-06-25  8:50 ` Sebastian Andrzej Siewior
  2026-06-25 10:00 ` Xie Yuanbin
  0 siblings, 2 replies; 9+ messages in thread
From: Xie Yuanbin @ 2026-06-25  7:35 UTC (permalink / raw)
  To: linux, bigeasy, clrkwllms, rostedt, rmk+kernel, linusw, arnd
  Cc: linux-arm-kernel, linux-kernel, linux-rt-devel, liaohua4,
	lilinjie8, Xie Yuanbin

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@linutronix.de>
Cc: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Xie Yuanbin <xieyuanbin1@huawei.com>
---
 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



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors
  2026-06-25  7:35 [PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors Xie Yuanbin
@ 2026-06-25  8:50 ` Sebastian Andrzej Siewior
  2026-06-25  9:05   ` Russell King
  2026-06-25 10:00 ` Xie Yuanbin
  1 sibling, 1 reply; 9+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-06-25  8:50 UTC (permalink / raw)
  To: Xie Yuanbin
  Cc: linux, clrkwllms, rostedt, rmk+kernel, linusw, arnd,
	linux-arm-kernel, linux-kernel, linux-rt-devel, liaohua4,
	lilinjie8

On 2026-06-25 15:35:22 [+0800], Xie Yuanbin wrote:
> 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
> ```

I don't think this required information as it is obvious. At the very
least you could trim it the needed parts if considered needed.

> 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@linutronix.de>
> Cc: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Xie Yuanbin <xieyuanbin1@huawei.com>

So I did test the 32bit case on arm64 while testing/ backporting the
breakpoint handling there but apparently did not try it on real
arm32.

For "asm("BKPT #0");" the SIGTRAP is not raised instead I get just
| 8<--- cut here ---
| Unhandled prefetch abort: debug event (0x222) at 0x00000000

on the kernel side and a "Bus error" on userland side.

So
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>

for this but actual breakpoint handling might be broken or is it just
me? But then your stack trace looks like mine so :/

Sebastian


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors
  2026-06-25  8:50 ` Sebastian Andrzej Siewior
@ 2026-06-25  9:05   ` Russell King
  2026-06-25  9:30     ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 9+ messages in thread
From: Russell King @ 2026-06-25  9:05 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: Xie Yuanbin, clrkwllms, rostedt, linusw, arnd, linux-arm-kernel,
	linux-kernel, linux-rt-devel, liaohua4, lilinjie8

On Thu, Jun 25, 2026 at 10:50:34AM +0200, Sebastian Andrzej Siewior wrote:
> On 2026-06-25 15:35:22 [+0800], Xie Yuanbin wrote:
> > 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
> > ```
> 
> I don't think this required information as it is obvious. At the very
> least you could trim it the needed parts if considered needed.
> 
> > 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@linutronix.de>
> > Cc: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
> > Signed-off-by: Xie Yuanbin <xieyuanbin1@huawei.com>
> 
> So I did test the 32bit case on arm64 while testing/ backporting the
> breakpoint handling there but apparently did not try it on real
> arm32.
> 
> For "asm("BKPT #0");" the SIGTRAP is not raised instead I get just
> | 8<--- cut here ---
> | Unhandled prefetch abort: debug event (0x222) at 0x00000000
> 
> on the kernel side and a "Bus error" on userland side.
> 
> So
> Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> 
> for this but actual breakpoint handling might be broken or is it just
> me? But then your stack trace looks like mine so :/

ARM Linux doesn't use BKPT. BKPT was an instruction introduced by Arm
Ltd in ARMv5TE. Prior to this, we use a UDF instruction instead (we
had to pick something!) and gdb and other tools use that as a
breapoint.

Moreover, BKPT isn't guaranteed to trap to the kernel, especially when
there is a hardware debugger connected. In that case, DDI0100E states
that use of BKPT must be according to the instructions provided with
the hardware debugger. This makes BKPT unsuitable for use.

Consequently, ARM Linux has not supported the use of BKPT - no code
was added to support this instruction, hence why the kernel prints an
Alert level message stating that the fault was unhandled.

In addition, when a hardware debugger is not being used, with the
addition of hw_breakpoint.c, what userland sees in response depends on
kernel configuration. If hw_breakpoint.c is not built (when PERF_EVENTS
is disabled), then a SIGBUS signal will be raised. If it is built, and
prior to a recent commit by LinusW, it will raise a SIGTRAP. After
LinusW's commit, it won't raise a signal, but userspace will spin on
the BKPT instruction.

The path we go through in the above case is very much an "oh damn,
we aren't handling this exception, let's try to do something that
might save the day".

Rather than throwing local_irq_enable() in random places, it would
be better to do it earlier, but I would want to review what x86 does
when it gets an exception that the kernel doesn't handle - not sure
when I'll get around to doing that though.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors
  2026-06-25  9:05   ` Russell King
@ 2026-06-25  9:30     ` Sebastian Andrzej Siewior
  2026-06-25 10:20       ` Russell King
  0 siblings, 1 reply; 9+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-06-25  9:30 UTC (permalink / raw)
  To: Russell King
  Cc: Xie Yuanbin, clrkwllms, rostedt, linusw, arnd, linux-arm-kernel,
	linux-kernel, linux-rt-devel, liaohua4, lilinjie8

On 2026-06-25 10:05:52 [+0100], Russell King wrote:
> > for this but actual breakpoint handling might be broken or is it just
> > me? But then your stack trace looks like mine so :/
> 
> ARM Linux doesn't use BKPT. BKPT was an instruction introduced by Arm
> Ltd in ARMv5TE. Prior to this, we use a UDF instruction instead (we
> had to pick something!) and gdb and other tools use that as a
> breapoint.
> 
> Moreover, BKPT isn't guaranteed to trap to the kernel, especially when
> there is a hardware debugger connected. In that case, DDI0100E states
> that use of BKPT must be according to the instructions provided with
> the hardware debugger. This makes BKPT unsuitable for use.

So you are saying this:

diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index e62cc4be5adf6..11ac69113eca2 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -595,6 +595,16 @@ do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
 	return 1;
 }
 
+static int do_debug_event(unsigned long addr, unsigned int fsr,
+			  struct pt_regs *regs)
+{
+	if (!user_mode(regs))
+		return 1;
+	local_irq_enable();
+	ptrace_break(regs);
+	return 0;
+}
+
 struct fsr_info {
 	int	(*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
 	int	sig;
diff --git a/arch/arm/mm/fsr-2level.c b/arch/arm/mm/fsr-2level.c
index f2be95197265d..bfd718f64020c 100644
--- a/arch/arm/mm/fsr-2level.c
+++ b/arch/arm/mm/fsr-2level.c
@@ -46,7 +46,7 @@ static struct fsr_info fsr_info[] = {
 static struct fsr_info ifsr_info[] = {
 	{ do_bad,		SIGBUS,  0,		"unknown 0"			   },
 	{ do_bad,		SIGBUS,  0,		"unknown 1"			   },
-	{ do_bad,		SIGBUS,  0,		"debug event"			   },
+	{ do_debug_event,	SIGBUS,  0,		"debug event"			   },
 	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"section access flag fault"	   },
 	{ do_bad,		SIGBUS,  0,		"unknown 4"			   },
 	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"section translation fault"	   },
diff --git a/arch/arm/mm/fsr-3level.c b/arch/arm/mm/fsr-3level.c
index d0ae2963656a6..96c1d45d20d9e 100644
--- a/arch/arm/mm/fsr-3level.c
+++ b/arch/arm/mm/fsr-3level.c
@@ -34,7 +34,7 @@ static struct fsr_info fsr_info[] = {
 	{ do_bad,		SIGBUS,  0,		"synchronous parity error (translation table walk" },
 	{ do_bad,		SIGBUS,  0,		"unknown 32"			},
 	{ do_bad,		SIGBUS,  BUS_ADRALN,	"alignment fault"		},
-	{ do_bad,		SIGBUS,  0,		"debug event"			},
+	{ do_debug_event,	SIGBUS,  0,		"debug event"			},
 	{ do_bad,		SIGBUS,  0,		"unknown 35"			},
 	{ do_bad,		SIGBUS,  0,		"unknown 36"			},
 	{ do_bad,		SIGBUS,  0,		"unknown 37"			},

is not worth doing it? With this I can my little testcase working.

> Consequently, ARM Linux has not supported the use of BKPT - no code
> was added to support this instruction, hence why the kernel prints an
> Alert level message stating that the fault was unhandled.
> 
> In addition, when a hardware debugger is not being used, with the
> addition of hw_breakpoint.c, what userland sees in response depends on
> kernel configuration. If hw_breakpoint.c is not built (when PERF_EVENTS
> is disabled), then a SIGBUS signal will be raised. If it is built, and
> prior to a recent commit by LinusW, it will raise a SIGTRAP. After
> LinusW's commit, it won't raise a signal, but userspace will spin on
> the BKPT instruction.
> 
> The path we go through in the above case is very much an "oh damn,
> we aren't handling this exception, let's try to do something that
> might save the day".

Okay.

> Rather than throwing local_irq_enable() in random places, it would
> be better to do it earlier, but I would want to review what x86 does
> when it gets an exception that the kernel doesn't handle - not sure
> when I'll get around to doing that though.

That would be exc_int3() from arch/x86/kernel/traps.c.
Besides doing "notify_die(DIE_INT3, "int3", regs, 0, X86_TRAP_BP, SIGTRAP);"

it does cond_local_irq_enable() which enables the interrupts if they
were enabled by the "caller", sends the signal (SIGTRAP).

Sebastian


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors
  2026-06-25  7:35 [PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors Xie Yuanbin
  2026-06-25  8:50 ` Sebastian Andrzej Siewior
@ 2026-06-25 10:00 ` Xie Yuanbin
  2026-06-25 10:23   ` Russell King
  1 sibling, 1 reply; 9+ messages in thread
From: Xie Yuanbin @ 2026-06-25 10:00 UTC (permalink / raw)
  To: linux, bigeasy, clrkwllms, rostedt, rmk+kernel, linusw, arnd
  Cc: linux-arm-kernel, linux-kernel, linux-rt-devel, liaohua4,
	lilinjie8, Xie Yuanbin

On 2026-06-25 10:05:52 [+0100], Russell King wrote:
> > for this but actual breakpoint handling might be broken or is it 
> > just me? But then your stack trace looks like mine so :/
> 
> ARM Linux doesn't use BKPT. BKPT was an instruction introduced by Arm 
> Ltd in ARMv5TE. Prior to this, we use a UDF instruction instead (we 
> had to pick something!) and gdb and other tools use that as a 
> breapoint.
> 
> Moreover, BKPT isn't guaranteed to trap to the kernel, especially when 
> there is a hardware debugger connected. In that case, DDI0100E states 
> that use of BKPT must be according to the instructions provided with 
> the hardware debugger. This makes BKPT unsuitable for use.

When do_DataAbort()/do_PrefetchAbort() run into `inf->fn()`, and the
hook function return != 0 with interrupts disabled, the WARN may be
triggered. From the code perspective, there are countless possible
places, and "bkpt #0" is just one of these.

For example:
bcm5301x_init_early()->hook_fault_code(bcm5301x_abort_handler).
if CONFIG_ARCH_BCM_5301X=y, then bcm5301x_abort_handler() may return 1
without enabling the interrupts.
if CONFIG_ARCH_BCM_5301X=n, then in the same scenario it will run into
do_bad(), also return 1 without enabling the interrupts.

So I think maybe:
1. enable interrupts in all hook functions, maybe
   multiple points for modification.
2. enable interrupts in do_DataAbort()/do_PrefetchAbort() before
   `inf->fn()`, but harden_branch_predictor() may be difficult.
3. enable interrupts in do_DataAbort()/do_PrefetchAbort() after
   `inf->fn()`, this may be ok.

From this perspective, arm_notify_die() also seems to be a good place?


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors
  2026-06-25  9:30     ` Sebastian Andrzej Siewior
@ 2026-06-25 10:20       ` Russell King
  2026-06-25 12:08         ` Sebastian Andrzej Siewior
  0 siblings, 1 reply; 9+ messages in thread
From: Russell King @ 2026-06-25 10:20 UTC (permalink / raw)
  To: Sebastian Andrzej Siewior
  Cc: Xie Yuanbin, clrkwllms, rostedt, linusw, arnd, linux-arm-kernel,
	linux-kernel, linux-rt-devel, liaohua4, lilinjie8

On Thu, Jun 25, 2026 at 11:30:08AM +0200, Sebastian Andrzej Siewior wrote:
> On 2026-06-25 10:05:52 [+0100], Russell King wrote:
> > > for this but actual breakpoint handling might be broken or is it just
> > > me? But then your stack trace looks like mine so :/
> > 
> > ARM Linux doesn't use BKPT. BKPT was an instruction introduced by Arm
> > Ltd in ARMv5TE. Prior to this, we use a UDF instruction instead (we
> > had to pick something!) and gdb and other tools use that as a
> > breapoint.
> > 
> > Moreover, BKPT isn't guaranteed to trap to the kernel, especially when
> > there is a hardware debugger connected. In that case, DDI0100E states
> > that use of BKPT must be according to the instructions provided with
> > the hardware debugger. This makes BKPT unsuitable for use.
> 
> So you are saying this:
> 
> diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
> index e62cc4be5adf6..11ac69113eca2 100644
> --- a/arch/arm/mm/fault.c
> +++ b/arch/arm/mm/fault.c
> @@ -595,6 +595,16 @@ do_bad(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
>  	return 1;
>  }
>  
> +static int do_debug_event(unsigned long addr, unsigned int fsr,
> +			  struct pt_regs *regs)
> +{
> +	if (!user_mode(regs))
> +		return 1;
> +	local_irq_enable();
> +	ptrace_break(regs);
> +	return 0;
> +}
> +
>  struct fsr_info {
>  	int	(*fn)(unsigned long addr, unsigned int fsr, struct pt_regs *regs);
>  	int	sig;
> diff --git a/arch/arm/mm/fsr-2level.c b/arch/arm/mm/fsr-2level.c
> index f2be95197265d..bfd718f64020c 100644
> --- a/arch/arm/mm/fsr-2level.c
> +++ b/arch/arm/mm/fsr-2level.c
> @@ -46,7 +46,7 @@ static struct fsr_info fsr_info[] = {
>  static struct fsr_info ifsr_info[] = {
>  	{ do_bad,		SIGBUS,  0,		"unknown 0"			   },
>  	{ do_bad,		SIGBUS,  0,		"unknown 1"			   },
> -	{ do_bad,		SIGBUS,  0,		"debug event"			   },
> +	{ do_debug_event,	SIGBUS,  0,		"debug event"			   },
>  	{ do_bad,		SIGSEGV, SEGV_ACCERR,	"section access flag fault"	   },
>  	{ do_bad,		SIGBUS,  0,		"unknown 4"			   },
>  	{ do_translation_fault,	SIGSEGV, SEGV_MAPERR,	"section translation fault"	   },
> diff --git a/arch/arm/mm/fsr-3level.c b/arch/arm/mm/fsr-3level.c
> index d0ae2963656a6..96c1d45d20d9e 100644
> --- a/arch/arm/mm/fsr-3level.c
> +++ b/arch/arm/mm/fsr-3level.c
> @@ -34,7 +34,7 @@ static struct fsr_info fsr_info[] = {
>  	{ do_bad,		SIGBUS,  0,		"synchronous parity error (translation table walk" },
>  	{ do_bad,		SIGBUS,  0,		"unknown 32"			},
>  	{ do_bad,		SIGBUS,  BUS_ADRALN,	"alignment fault"		},
> -	{ do_bad,		SIGBUS,  0,		"debug event"			},
> +	{ do_debug_event,	SIGBUS,  0,		"debug event"			},
>  	{ do_bad,		SIGBUS,  0,		"unknown 35"			},
>  	{ do_bad,		SIGBUS,  0,		"unknown 36"			},
>  	{ do_bad,		SIGBUS,  0,		"unknown 37"			},
> 
> is not worth doing it? With this I can my little testcase working.

No, it isn't, because if you enable PERF_EVENTS then BKPT breaks.
hw_breakpoint.c claims this vector.

Moreover, in older architectures, FSR=2 means "Terminal exception"
which is defined as "This indicates that an irrecoverable fault has
occurred. The circumstances under which this can happen (if at all)
are IMPLEMENTATION DEFINED." - from DDI0100E (which includes
ARMv5TE). In DDI0100F, this encoding was changed to "Debug exception".

Hence, the above can not be unconditional.

Then, we also have that FSR=2 is generated for a number of different
reasons (including hardware debug events) which may trigger.

Also a hardware debugger (e.g. connected via JTAG) could decide to
pass a BKPT exception on, and that could happen from the kernel. I
believe LLVM CFI uses BKPT (see LinusW's commit c3f89986fde7 ("ARM:
9391/2: hw_breakpoint: Handle CFI breakpoints")

BKPT is a total mess.

> That would be exc_int3() from arch/x86/kernel/traps.c.
> Besides doing "notify_die(DIE_INT3, "int3", regs, 0, X86_TRAP_BP, SIGTRAP);"
> 
> it does cond_local_irq_enable() which enables the interrupts if they
> were enabled by the "caller", sends the signal (SIGTRAP).

I'm happy with that approach as far as interrupts go, but we can't
change the behaviour for FSR=2 again, beyond fixing LinusW's
commit (which has recently been reported as a regression.)

Note that the change which makes this raise a SIGTRAP rather than
SIGBUS when PERF_EVENTS=y could _also_ be reported as a regression
that we would have to fix, and making FSR=2 raise a SIGTRAP now
could very well invite that regression to be reported.

Essentially, I don't think we can "fix" BKPT to always raise SIGTRAP.
The BKPT instruction is something the kernel has never _officially_
supported.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors
  2026-06-25 10:00 ` Xie Yuanbin
@ 2026-06-25 10:23   ` Russell King
  2026-06-25 12:26     ` Xie Yuanbin
  0 siblings, 1 reply; 9+ messages in thread
From: Russell King @ 2026-06-25 10:23 UTC (permalink / raw)
  To: Xie Yuanbin
  Cc: bigeasy, clrkwllms, rostedt, linusw, arnd, linux-arm-kernel,
	linux-kernel, linux-rt-devel, liaohua4, lilinjie8

On Thu, Jun 25, 2026 at 06:00:31PM +0800, Xie Yuanbin wrote:
> On 2026-06-25 10:05:52 [+0100], Russell King wrote:
> > > for this but actual breakpoint handling might be broken or is it 
> > > just me? But then your stack trace looks like mine so :/
> > 
> > ARM Linux doesn't use BKPT. BKPT was an instruction introduced by Arm 
> > Ltd in ARMv5TE. Prior to this, we use a UDF instruction instead (we 
> > had to pick something!) and gdb and other tools use that as a 
> > breapoint.
> > 
> > Moreover, BKPT isn't guaranteed to trap to the kernel, especially when 
> > there is a hardware debugger connected. In that case, DDI0100E states 
> > that use of BKPT must be according to the instructions provided with 
> > the hardware debugger. This makes BKPT unsuitable for use.
> 
> When do_DataAbort()/do_PrefetchAbort() run into `inf->fn()`, and the
> hook function return != 0 with interrupts disabled, the WARN may be
> triggered. From the code perspective, there are countless possible
> places, and "bkpt #0" is just one of these.
> 
> For example:
> bcm5301x_init_early()->hook_fault_code(bcm5301x_abort_handler).
> if CONFIG_ARCH_BCM_5301X=y, then bcm5301x_abort_handler() may return 1
> without enabling the interrupts.
> if CONFIG_ARCH_BCM_5301X=n, then in the same scenario it will run into
> do_bad(), also return 1 without enabling the interrupts.
> 
> So I think maybe:
> 1. enable interrupts in all hook functions, maybe
>    multiple points for modification.
> 2. enable interrupts in do_DataAbort()/do_PrefetchAbort() before
>    `inf->fn()`, but harden_branch_predictor() may be difficult.

Unfortunately, this breaks the Spectre/Meltdown mitigations. The
page fault handlers must be entered with interrupts disabled.

> 3. enable interrupts in do_DataAbort()/do_PrefetchAbort() after
>    `inf->fn()`, this may be ok.
> 
> From this perspective, arm_notify_die() also seems to be a good place?

If one is happy with higher latency for preempt cases, then it may
be, but if we want lower latency, then it ought to be earlier.
My preference is (3).

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors
  2026-06-25 10:20       ` Russell King
@ 2026-06-25 12:08         ` Sebastian Andrzej Siewior
  0 siblings, 0 replies; 9+ messages in thread
From: Sebastian Andrzej Siewior @ 2026-06-25 12:08 UTC (permalink / raw)
  To: Russell King
  Cc: Xie Yuanbin, clrkwllms, rostedt, linusw, arnd, linux-arm-kernel,
	linux-kernel, linux-rt-devel, liaohua4, lilinjie8

On 2026-06-25 11:20:13 [+0100], Russell King wrote:
> > is not worth doing it? With this I can my little testcase working.
> 
> No, it isn't, because if you enable PERF_EVENTS then BKPT breaks.
> hw_breakpoint.c claims this vector.

I see.

…
> BKPT is a total mess.

Understood.

> > it does cond_local_irq_enable() which enables the interrupts if they
> > were enabled by the "caller", sends the signal (SIGTRAP).
> 
> I'm happy with that approach as far as interrupts go, but we can't
> change the behaviour for FSR=2 again, beyond fixing LinusW's
> commit (which has recently been reported as a regression.)
> 
> Note that the change which makes this raise a SIGTRAP rather than
> SIGBUS when PERF_EVENTS=y could _also_ be reported as a regression
> that we would have to fix, and making FSR=2 raise a SIGTRAP now
> could very well invite that regression to be reported.
> 
> Essentially, I don't think we can "fix" BKPT to always raise SIGTRAP.
> The BKPT instruction is something the kernel has never _officially_
> supported.

It looked like an easy fix. You explained that it is a bigger mess with
"other features" and so on. Given that and the fact that it was never
supported, I would appreciate just to enable interrupts before the
(SIGBUS) signal is sent.

Sebastian


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors
  2026-06-25 10:23   ` Russell King
@ 2026-06-25 12:26     ` Xie Yuanbin
  0 siblings, 0 replies; 9+ messages in thread
From: Xie Yuanbin @ 2026-06-25 12:26 UTC (permalink / raw)
  To: linux, bigeasy, rmk+kernel
  Cc: clrkwllms, rostedt, linusw, arnd, linux-arm-kernel, linux-kernel,
	linux-rt-devel, liaohua4, lilinjie8, Xie Yuanbin

On Thu, 25 Jun 2026 11:23:34 +0100, Russell King wrote:
>> 3. enable interrupts in do_DataAbort()/do_PrefetchAbort() after
>>    `inf->fn()`, this may be ok.
>> 
>> From this perspective, arm_notify_die() also seems to be a good place?
>
> If one is happy with higher latency for preempt cases, then it may
> be, but if we want lower latency, then it ought to be earlier.
> My preference is (3).

```c
	if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
		return;

	if (likely(user_mode(regs)))
		local_irq_enable();

	pr_alert("8<--- cut here ---\n");
```
or
```c
	if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
		return;

	if (likely(interrupts_enabled(regs)))
		local_irq_enable();

	pr_alert("8<--- cut here ---\n");
```

Which one do you prefer? I prefer the first one, because for kernel
fault, kernel may have encountered a serious issue,
and enabling interrupts may be not appropriate.


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-06-25 13:07 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-25  7:35 [PATCH] ARM: enable interrupts when arm_notify_die() is handling user mode errors Xie Yuanbin
2026-06-25  8:50 ` Sebastian Andrzej Siewior
2026-06-25  9:05   ` Russell King
2026-06-25  9:30     ` Sebastian Andrzej Siewior
2026-06-25 10:20       ` Russell King
2026-06-25 12:08         ` Sebastian Andrzej Siewior
2026-06-25 10:00 ` Xie Yuanbin
2026-06-25 10:23   ` Russell King
2026-06-25 12:26     ` Xie Yuanbin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox