aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorey Minyard <minyard@acm.org>2006-05-08 09:17:22 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-05-08 12:34:56 -0400
commitcdc60a4c8e71c4bcf67e83fac6c0cabd0ff19bfe (patch)
tree204e3ab2ccaa9828d0ea71b43891729b216db7bf
parent5192d84e4c32cd335fd572e5ff0712041f45f7e7 (diff)
[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 <minyard@acm.org> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/x86_64/kernel/traps.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c
index 2700b1375c1f..0ebb281aa178 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)
385 385
386static DEFINE_SPINLOCK(die_lock); 386static DEFINE_SPINLOCK(die_lock);
387static int die_owner = -1; 387static int die_owner = -1;
388static unsigned int die_nest_count;
388 389
389unsigned __kprobes long oops_begin(void) 390unsigned __kprobes long oops_begin(void)
390{ 391{
@@ -399,6 +400,7 @@ unsigned __kprobes long oops_begin(void)
399 else 400 else
400 spin_lock(&die_lock); 401 spin_lock(&die_lock);
401 } 402 }
403 die_nest_count++;
402 die_owner = cpu; 404 die_owner = cpu;
403 console_verbose(); 405 console_verbose();
404 bust_spinlocks(1); 406 bust_spinlocks(1);
@@ -409,7 +411,13 @@ void __kprobes oops_end(unsigned long flags)
409{ 411{
410 die_owner = -1; 412 die_owner = -1;
411 bust_spinlocks(0); 413 bust_spinlocks(0);
412 spin_unlock_irqrestore(&die_lock, flags); 414 die_nest_count--;
415 if (die_nest_count)
416 /* We still own the lock */
417 local_irq_restore(flags);
418 else
419 /* Nest count reaches zero, release the lock. */
420 spin_unlock_irqrestore(&die_lock, flags);
413 if (panic_on_oops) 421 if (panic_on_oops)
414 panic("Oops"); 422 panic("Oops");
415} 423}