Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

[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>

authored by

Corey Minyard and committed by
Linus Torvalds
cdc60a4c 5192d84e

+9 -1
+9 -1
arch/x86_64/kernel/traps.c
··· 385 385 386 386 static DEFINE_SPINLOCK(die_lock); 387 387 static int die_owner = -1; 388 + static unsigned int die_nest_count; 388 389 389 390 unsigned __kprobes long oops_begin(void) 390 391 { ··· 400 399 else 401 400 spin_lock(&die_lock); 402 401 } 402 + die_nest_count++; 403 403 die_owner = cpu; 404 404 console_verbose(); 405 405 bust_spinlocks(1); ··· 411 409 { 412 410 die_owner = -1; 413 411 bust_spinlocks(0); 414 - spin_unlock_irqrestore(&die_lock, flags); 412 + die_nest_count--; 413 + if (die_nest_count) 414 + /* We still own the lock */ 415 + local_irq_restore(flags); 416 + else 417 + /* Nest count reaches zero, release the lock. */ 418 + spin_unlock_irqrestore(&die_lock, flags); 415 419 if (panic_on_oops) 416 420 panic("Oops"); 417 421 }