linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] riscv: Enable interrupt during exception handling
@ 2025-06-25  8:56 Nam Cao
  2025-07-09  7:00 ` Alexandre Ghiti
  2025-07-16 20:00 ` patchwork-bot+linux-riscv
  0 siblings, 2 replies; 3+ messages in thread
From: Nam Cao @ 2025-06-25  8:56 UTC (permalink / raw)
  To: Paul Walmsley, Palmer Dabbelt, Albert Ou, Alexandre Ghiti,
	Peter Zijlstra, Sebastian Andrzej Siewior, Clark Williams,
	Steven Rostedt, linux-rt-devel, linux-riscv, linux-kernel
  Cc: Nam Cao

force_sig_fault() takes a spinlock, which is a sleeping lock with
CONFIG_PREEMPT_RT=y. However, exception handling calls force_sig_fault()
with interrupt disabled, causing a sleeping in atomic context warning.

This can be reproduced using userspace programs such as:
    int main() { asm ("ebreak"); }
or
    int main() { asm ("unimp"); }

There is no reason that interrupt must be disabled while handling
exceptions from userspace.

Enable interrupt while handling user exceptions. This also has the added
benefit of avoiding unnecessary delays in interrupt handling.

Fixes: f0bddf50586d ("riscv: entry: Convert to generic entry")
Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Nam Cao <namcao@linutronix.de>
---
v2: stop enabling interrupts for kernel exceptions. For exceptions treated
like NMI, it is wrong. For page faults, interrupts are already
(conditionally) enabled.
---
 arch/riscv/kernel/traps.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
index 9c83848797a78..80230de167def 100644
--- a/arch/riscv/kernel/traps.c
+++ b/arch/riscv/kernel/traps.c
@@ -6,6 +6,7 @@
 #include <linux/cpu.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/irqflags.h>
 #include <linux/randomize_kstack.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
@@ -151,7 +152,9 @@ asmlinkage __visible __trap_section void name(struct pt_regs *regs)		\
 {										\
 	if (user_mode(regs)) {							\
 		irqentry_enter_from_user_mode(regs);				\
+		local_irq_enable();						\
 		do_trap_error(regs, signo, code, regs->epc, "Oops - " str);	\
+		local_irq_disable();						\
 		irqentry_exit_to_user_mode(regs);				\
 	} else {								\
 		irqentry_state_t state = irqentry_nmi_enter(regs);		\
@@ -173,17 +176,14 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
 
 	if (user_mode(regs)) {
 		irqentry_enter_from_user_mode(regs);
-
 		local_irq_enable();
 
 		handled = riscv_v_first_use_handler(regs);
-
-		local_irq_disable();
-
 		if (!handled)
 			do_trap_error(regs, SIGILL, ILL_ILLOPC, regs->epc,
 				      "Oops - illegal instruction");
 
+		local_irq_disable();
 		irqentry_exit_to_user_mode(regs);
 	} else {
 		irqentry_state_t state = irqentry_nmi_enter(regs);
@@ -308,9 +308,11 @@ asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs)
 {
 	if (user_mode(regs)) {
 		irqentry_enter_from_user_mode(regs);
+		local_irq_enable();
 
 		handle_break(regs);
 
+		local_irq_disable();
 		irqentry_exit_to_user_mode(regs);
 	} else {
 		irqentry_state_t state = irqentry_nmi_enter(regs);
-- 
2.39.5


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

* Re: [PATCH v2] riscv: Enable interrupt during exception handling
  2025-06-25  8:56 [PATCH v2] riscv: Enable interrupt during exception handling Nam Cao
@ 2025-07-09  7:00 ` Alexandre Ghiti
  2025-07-16 20:00 ` patchwork-bot+linux-riscv
  1 sibling, 0 replies; 3+ messages in thread
From: Alexandre Ghiti @ 2025-07-09  7:00 UTC (permalink / raw)
  To: Nam Cao, Paul Walmsley, Palmer Dabbelt, Albert Ou, Peter Zijlstra,
	Sebastian Andrzej Siewior, Clark Williams, Steven Rostedt,
	linux-rt-devel, linux-riscv, linux-kernel

Hi Nam,

On 6/25/25 10:56, Nam Cao wrote:
> force_sig_fault() takes a spinlock, which is a sleeping lock with
> CONFIG_PREEMPT_RT=y. However, exception handling calls force_sig_fault()
> with interrupt disabled, causing a sleeping in atomic context warning.
>
> This can be reproduced using userspace programs such as:
>      int main() { asm ("ebreak"); }
> or
>      int main() { asm ("unimp"); }
>
> There is no reason that interrupt must be disabled while handling
> exceptions from userspace.
>
> Enable interrupt while handling user exceptions. This also has the added
> benefit of avoiding unnecessary delays in interrupt handling.
>
> Fixes: f0bddf50586d ("riscv: entry: Convert to generic entry")
> Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
> Signed-off-by: Nam Cao <namcao@linutronix.de>
> ---
> v2: stop enabling interrupts for kernel exceptions. For exceptions treated
> like NMI, it is wrong. For page faults, interrupts are already
> (conditionally) enabled.
> ---
>   arch/riscv/kernel/traps.c | 10 ++++++----
>   1 file changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c
> index 9c83848797a78..80230de167def 100644
> --- a/arch/riscv/kernel/traps.c
> +++ b/arch/riscv/kernel/traps.c
> @@ -6,6 +6,7 @@
>   #include <linux/cpu.h>
>   #include <linux/kernel.h>
>   #include <linux/init.h>
> +#include <linux/irqflags.h>
>   #include <linux/randomize_kstack.h>
>   #include <linux/sched.h>
>   #include <linux/sched/debug.h>
> @@ -151,7 +152,9 @@ asmlinkage __visible __trap_section void name(struct pt_regs *regs)		\
>   {										\
>   	if (user_mode(regs)) {							\
>   		irqentry_enter_from_user_mode(regs);				\
> +		local_irq_enable();						\
>   		do_trap_error(regs, signo, code, regs->epc, "Oops - " str);	\
> +		local_irq_disable();						\
>   		irqentry_exit_to_user_mode(regs);				\
>   	} else {								\
>   		irqentry_state_t state = irqentry_nmi_enter(regs);		\
> @@ -173,17 +176,14 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re
>   
>   	if (user_mode(regs)) {
>   		irqentry_enter_from_user_mode(regs);
> -
>   		local_irq_enable();
>   
>   		handled = riscv_v_first_use_handler(regs);
> -
> -		local_irq_disable();
> -
>   		if (!handled)
>   			do_trap_error(regs, SIGILL, ILL_ILLOPC, regs->epc,
>   				      "Oops - illegal instruction");
>   
> +		local_irq_disable();
>   		irqentry_exit_to_user_mode(regs);
>   	} else {
>   		irqentry_state_t state = irqentry_nmi_enter(regs);
> @@ -308,9 +308,11 @@ asmlinkage __visible __trap_section void do_trap_break(struct pt_regs *regs)
>   {
>   	if (user_mode(regs)) {
>   		irqentry_enter_from_user_mode(regs);
> +		local_irq_enable();
>   
>   		handle_break(regs);
>   
> +		local_irq_disable();
>   		irqentry_exit_to_user_mode(regs);
>   	} else {
>   		irqentry_state_t state = irqentry_nmi_enter(regs);


Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>

Let's also add:

Cc: stable@vger.kernel.org

I pick this up for next week fixes PR.

Thanks,

Alex



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

* Re: [PATCH v2] riscv: Enable interrupt during exception handling
  2025-06-25  8:56 [PATCH v2] riscv: Enable interrupt during exception handling Nam Cao
  2025-07-09  7:00 ` Alexandre Ghiti
@ 2025-07-16 20:00 ` patchwork-bot+linux-riscv
  1 sibling, 0 replies; 3+ messages in thread
From: patchwork-bot+linux-riscv @ 2025-07-16 20:00 UTC (permalink / raw)
  To: Nam Cao
  Cc: linux-riscv, paul.walmsley, palmer, aou, alex, peterz, bigeasy,
	clrkwllms, rostedt, linux-rt-devel, linux-kernel

Hello:

This patch was applied to riscv/linux.git (fixes)
by Palmer Dabbelt <palmer@dabbelt.com>:

On Wed, 25 Jun 2025 10:56:30 +0200 you wrote:
> force_sig_fault() takes a spinlock, which is a sleeping lock with
> CONFIG_PREEMPT_RT=y. However, exception handling calls force_sig_fault()
> with interrupt disabled, causing a sleeping in atomic context warning.
> 
> This can be reproduced using userspace programs such as:
>     int main() { asm ("ebreak"); }
> or
>     int main() { asm ("unimp"); }
> 
> [...]

Here is the summary with links:
  - [v2] riscv: Enable interrupt during exception handling
    https://git.kernel.org/riscv/c/969f028bf2c4

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

end of thread, other threads:[~2025-07-16 19:59 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-06-25  8:56 [PATCH v2] riscv: Enable interrupt during exception handling Nam Cao
2025-07-09  7:00 ` Alexandre Ghiti
2025-07-16 20:00 ` patchwork-bot+linux-riscv

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).