[PATCH] linux-4.19.y/printk: Avoid logbuf_lock deadlock in oops_end()

From: Tony W Wang-oc
Date: Tue May 28 2024 - 06:30:42 EST


A CPU executing vprintk_emit might be interrupted by #PF exception,
this may leads to logbuf_lock deadlock:

CPU x: CPU x:
---- ----
vprintk_emit()
logbuf_lock_irqsave()
printk_safe_enter_irqsave()
A: raw_spin_lock(&logbuf_lock)
vprintk_store() #PF
do_page_fault
...
oops_end
bust_spinlocks(0)
console_unlock()
...
printk_safe_enter_irqsave()
B: raw_spin_lock(&logbuf_lock)

logbuf_lock is taken at A and the deadlock happends at B.

Pass 1 to bust_spinlocks() in the oops_end() to avoid this deadlock.

Signed-off-by: Tony W Wang-oc <TonyWWang-oc@xxxxxxxxxxx>
---
arch/x86/kernel/dumpstack.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/x86/kernel/dumpstack.c b/arch/x86/kernel/dumpstack.c
index 7e698c45760c..b4c145ee9536 100644
--- a/arch/x86/kernel/dumpstack.c
+++ b/arch/x86/kernel/dumpstack.c
@@ -336,7 +336,7 @@ void oops_end(unsigned long flags, struct pt_regs *regs, int signr)
if (regs && kexec_should_crash(current))
crash_kexec(regs);

- bust_spinlocks(0);
+ bust_spinlocks(1);
die_owner = -1;
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
die_nest_count--;
--
2.25.1