From: Corey Minyard Date: Mon, 8 May 2006 13:17:22 +0000 (+0200) Subject: [PATCH] x86_64: fix die_lock nesting X-Git-Tag: v2.6.17-rc4~18 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cdc60a4c8e71c4bcf67e83fac6c0cabd0ff19bfe;p=linux-2.6 [PATCH] x86_64: fix die_lock nesting I noticed this when poking around in this area. The oops_begin() function in x86_64 would only conditionally claim the die_lock if the call is nested, but oops_end() would always release the spinlock. This patch adds a nest count for the die lock so that the release of the lock is only done on the final oops_end(). Signed-off-by: Corey Minyard Signed-off-by: Andi Kleen Signed-off-by: Linus Torvalds --- diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 2700b1375c..0ebb281aa1 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -385,6 +385,7 @@ void out_of_line_bug(void) static DEFINE_SPINLOCK(die_lock); static int die_owner = -1; +static unsigned int die_nest_count; unsigned __kprobes long oops_begin(void) { @@ -399,6 +400,7 @@ unsigned __kprobes long oops_begin(void) else spin_lock(&die_lock); } + die_nest_count++; die_owner = cpu; console_verbose(); bust_spinlocks(1); @@ -409,7 +411,13 @@ void __kprobes oops_end(unsigned long flags) { die_owner = -1; bust_spinlocks(0); - spin_unlock_irqrestore(&die_lock, flags); + die_nest_count--; + if (die_nest_count) + /* We still own the lock */ + local_irq_restore(flags); + else + /* Nest count reaches zero, release the lock. */ + spin_unlock_irqrestore(&die_lock, flags); if (panic_on_oops) panic("Oops"); }