Skip to content

Commit

Permalink
riscv: Fix sleeping in invalid context in die()
Browse files Browse the repository at this point in the history
die() can be called in exception handler, and therefore cannot sleep.
However, die() takes spinlock_t which can sleep with PREEMPT_RT enabled.
That causes the following warning:

BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 285, name: mutex
preempt_count: 110001, expected: 0
RCU nest depth: 0, expected: 0
CPU: 0 UID: 0 PID: 285 Comm: mutex Not tainted 6.12.0-rc7-00022-ge19049cf7d56-dirty #234
Hardware name: riscv-virtio,qemu (DT)
Call Trace:
    dump_backtrace+0x1c/0x24
    show_stack+0x2c/0x38
    dump_stack_lvl+0x5a/0x72
    dump_stack+0x14/0x1c
    __might_resched+0x130/0x13a
    rt_spin_lock+0x2a/0x5c
    die+0x24/0x112
    do_trap_insn_illegal+0xa0/0xea
    _new_vmalloc_restore_context_a0+0xcc/0xd8
Oops - illegal instruction [#1]

Switch to use raw_spinlock_t, which does not sleep even with PREEMPT_RT
enabled.

Fixes: 76d2a04 ("RISC-V: Init and Halt Code")
Signed-off-by: Nam Cao <[email protected]>
Cc: [email protected]
Reviewed-by: Sebastian Andrzej Siewior <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Palmer Dabbelt <[email protected]>
  • Loading branch information
covanam authored and palmer-dabbelt committed Jan 8, 2025
1 parent 03f0b54 commit 6a97f41
Showing 1 changed file with 3 additions and 3 deletions.
6 changes: 3 additions & 3 deletions arch/riscv/kernel/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

int show_unhandled_signals = 1;

static DEFINE_SPINLOCK(die_lock);
static DEFINE_RAW_SPINLOCK(die_lock);

static int copy_code(struct pt_regs *regs, u16 *val, const u16 *insns)
{
Expand Down Expand Up @@ -81,7 +81,7 @@ void die(struct pt_regs *regs, const char *str)

oops_enter();

spin_lock_irqsave(&die_lock, flags);
raw_spin_lock_irqsave(&die_lock, flags);
console_verbose();
bust_spinlocks(1);

Expand All @@ -100,7 +100,7 @@ void die(struct pt_regs *regs, const char *str)

bust_spinlocks(0);
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
spin_unlock_irqrestore(&die_lock, flags);
raw_spin_unlock_irqrestore(&die_lock, flags);
oops_exit();

if (in_interrupt())
Expand Down

0 comments on commit 6a97f41

Please sign in to comment.