Commit cdc60a4c authored by Corey Minyard's avatar Corey Minyard Committed by Linus Torvalds

[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: default avatarCorey Minyard <minyard@acm.org>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 5192d84e
...@@ -385,6 +385,7 @@ void out_of_line_bug(void) ...@@ -385,6 +385,7 @@ void out_of_line_bug(void)
static DEFINE_SPINLOCK(die_lock); static DEFINE_SPINLOCK(die_lock);
static int die_owner = -1; static int die_owner = -1;
static unsigned int die_nest_count;
unsigned __kprobes long oops_begin(void) unsigned __kprobes long oops_begin(void)
{ {
...@@ -399,6 +400,7 @@ unsigned __kprobes long oops_begin(void) ...@@ -399,6 +400,7 @@ unsigned __kprobes long oops_begin(void)
else else
spin_lock(&die_lock); spin_lock(&die_lock);
} }
die_nest_count++;
die_owner = cpu; die_owner = cpu;
console_verbose(); console_verbose();
bust_spinlocks(1); bust_spinlocks(1);
...@@ -409,7 +411,13 @@ void __kprobes oops_end(unsigned long flags) ...@@ -409,7 +411,13 @@ void __kprobes oops_end(unsigned long flags)
{ {
die_owner = -1; die_owner = -1;
bust_spinlocks(0); 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) if (panic_on_oops)
panic("Oops"); panic("Oops");
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment