diff options
| -rw-r--r-- | arch/x86/kernel/dumpstack_32.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c index a29b88ffa346..7c7d691b32be 100644 --- a/arch/x86/kernel/dumpstack_32.c +++ b/arch/x86/kernel/dumpstack_32.c | |||
| @@ -289,21 +289,24 @@ static unsigned int die_nest_count; | |||
| 289 | 289 | ||
| 290 | unsigned __kprobes long oops_begin(void) | 290 | unsigned __kprobes long oops_begin(void) |
| 291 | { | 291 | { |
| 292 | int cpu; | ||
| 292 | unsigned long flags; | 293 | unsigned long flags; |
| 293 | 294 | ||
| 294 | oops_enter(); | 295 | oops_enter(); |
| 295 | 296 | ||
| 296 | if (die_owner != raw_smp_processor_id()) { | 297 | /* racy, but better than risking deadlock. */ |
| 297 | console_verbose(); | 298 | raw_local_irq_save(flags); |
| 298 | raw_local_irq_save(flags); | 299 | cpu = smp_processor_id(); |
| 299 | __raw_spin_lock(&die_lock); | 300 | if (!__raw_spin_trylock(&die_lock)) { |
| 300 | die_owner = smp_processor_id(); | 301 | if (cpu == die_owner) |
| 301 | die_nest_count = 0; | 302 | /* nested oops. should stop eventually */; |
| 302 | bust_spinlocks(1); | 303 | else |
| 303 | } else { | 304 | __raw_spin_lock(&die_lock); |
| 304 | raw_local_irq_save(flags); | ||
| 305 | } | 305 | } |
| 306 | die_nest_count++; | 306 | die_nest_count++; |
| 307 | die_owner = cpu; | ||
| 308 | console_verbose(); | ||
| 309 | bust_spinlocks(1); | ||
| 307 | return flags; | 310 | return flags; |
| 308 | } | 311 | } |
| 309 | 312 | ||
| @@ -315,13 +318,15 @@ void __kprobes oops_end(unsigned long flags, struct pt_regs *regs, int signr) | |||
| 315 | bust_spinlocks(0); | 318 | bust_spinlocks(0); |
| 316 | die_owner = -1; | 319 | die_owner = -1; |
| 317 | add_taint(TAINT_DIE); | 320 | add_taint(TAINT_DIE); |
| 318 | __raw_spin_unlock(&die_lock); | 321 | die_nest_count--; |
| 322 | if (!die_nest_count) | ||
| 323 | /* Nest count reaches zero, release the lock. */ | ||
| 324 | __raw_spin_unlock(&die_lock); | ||
| 319 | raw_local_irq_restore(flags); | 325 | raw_local_irq_restore(flags); |
| 320 | |||
| 321 | oops_exit(); | 326 | oops_exit(); |
| 327 | |||
| 322 | if (!signr) | 328 | if (!signr) |
| 323 | return; | 329 | return; |
| 324 | |||
| 325 | if (in_interrupt()) | 330 | if (in_interrupt()) |
| 326 | panic("Fatal exception in interrupt"); | 331 | panic("Fatal exception in interrupt"); |
| 327 | if (panic_on_oops) | 332 | if (panic_on_oops) |
