]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
riscv: Avoid enabling interrupts in die()
authorMattias Nissler <mnissler@rivosinc.com>
Wed, 15 Feb 2023 14:48:28 +0000 (14:48 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 10 Mar 2023 08:34:29 +0000 (09:34 +0100)
commit 130aee3fd9981297ff9354e5d5609cd59aafbbea upstream.

While working on something else, I noticed that the kernel would start
accepting interrupts again after crashing in an interrupt handler. Since
the kernel is already in inconsistent state, enabling interrupts is
dangerous and opens up risk of kernel state deteriorating further.
Interrupts do get enabled via what looks like an unintended side effect of
spin_unlock_irq, so switch to the more cautious
spin_lock_irqsave/spin_unlock_irqrestore instead.

Fixes: 76d2a0493a17 ("RISC-V: Init and Halt Code")
Signed-off-by: Mattias Nissler <mnissler@rivosinc.com>
Reviewed-by: Björn Töpel <bjorn@kernel.org>
Link: https://lore.kernel.org/r/20230215144828.3370316-1-mnissler@rivosinc.com
Cc: stable@vger.kernel.org
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
arch/riscv/kernel/traps.c

index f77cb8e42bd2ad1cfe3c2f1894e953907ce61375..5d07f6b3ca3273e1aef5c0039d5b90063e46925c 100644 (file)
@@ -34,10 +34,11 @@ void die(struct pt_regs *regs, const char *str)
        static int die_counter;
        int ret;
        long cause;
+       unsigned long flags;
 
        oops_enter();
 
-       spin_lock_irq(&die_lock);
+       spin_lock_irqsave(&die_lock, flags);
        console_verbose();
        bust_spinlocks(1);
 
@@ -54,7 +55,7 @@ void die(struct pt_regs *regs, const char *str)
 
        bust_spinlocks(0);
        add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
-       spin_unlock_irq(&die_lock);
+       spin_unlock_irqrestore(&die_lock, flags);
        oops_exit();
 
        if (in_interrupt())