diff options
author | Harvey Harrison <harvey.harrison@gmail.com> | 2008-01-30 07:32:59 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-01-30 07:32:59 -0500 |
commit | a604b38036bee1483fb98a520c69895d5d6276a6 (patch) | |
tree | 0fe518585cdc6c3911bcdaa2bf66125a595ef34e /arch/x86 | |
parent | c68461b67d97739707b3fc57618f22091791f2af (diff) |
x86: introduce __die helper to X86_32
Small step towards unifying traps_32|64.c. No functional
changes. Pull out a small helper from an if() statement
in die().
Marked as __kprobes as eventually we will want to call this
from do_page_fault similar to how X86_64 does it.
Signed-off-by: Harvey Harrison <harvey.harrison@gmail.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/kernel/traps_32.c | 76 |
1 files changed, 42 insertions, 34 deletions
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index 2eb6ca0ef672..83df0f37ba75 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c | |||
@@ -352,6 +352,45 @@ int is_valid_bugaddr(unsigned long ip) | |||
352 | return ud2 == 0x0b0f; | 352 | return ud2 == 0x0b0f; |
353 | } | 353 | } |
354 | 354 | ||
355 | static int die_counter; | ||
356 | |||
357 | int __kprobes __die(const char * str, struct pt_regs * regs, long err) | ||
358 | { | ||
359 | unsigned long sp; | ||
360 | unsigned short ss; | ||
361 | |||
362 | printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, ++die_counter); | ||
363 | #ifdef CONFIG_PREEMPT | ||
364 | printk("PREEMPT "); | ||
365 | #endif | ||
366 | #ifdef CONFIG_SMP | ||
367 | printk("SMP "); | ||
368 | #endif | ||
369 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
370 | printk("DEBUG_PAGEALLOC"); | ||
371 | #endif | ||
372 | printk("\n"); | ||
373 | |||
374 | if (notify_die(DIE_OOPS, str, regs, err, | ||
375 | current->thread.trap_no, SIGSEGV) != | ||
376 | NOTIFY_STOP) { | ||
377 | show_registers(regs); | ||
378 | /* Executive summary in case the oops scrolled away */ | ||
379 | sp = (unsigned long) (®s->sp); | ||
380 | savesegment(ss, ss); | ||
381 | if (user_mode(regs)) { | ||
382 | sp = regs->sp; | ||
383 | ss = regs->ss & 0xffff; | ||
384 | } | ||
385 | printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip); | ||
386 | print_symbol("%s", regs->ip); | ||
387 | printk(" SS:ESP %04x:%08lx\n", ss, sp); | ||
388 | return 0; | ||
389 | } else { | ||
390 | return 1; | ||
391 | } | ||
392 | } | ||
393 | |||
355 | /* | 394 | /* |
356 | * This is gone through when something in the kernel has done something bad and | 395 | * This is gone through when something in the kernel has done something bad and |
357 | * is about to be terminated. | 396 | * is about to be terminated. |
@@ -367,7 +406,6 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
367 | .lock_owner = -1, | 406 | .lock_owner = -1, |
368 | .lock_owner_depth = 0 | 407 | .lock_owner_depth = 0 |
369 | }; | 408 | }; |
370 | static int die_counter; | ||
371 | unsigned long flags; | 409 | unsigned long flags; |
372 | 410 | ||
373 | oops_enter(); | 411 | oops_enter(); |
@@ -383,43 +421,13 @@ void die(const char * str, struct pt_regs * regs, long err) | |||
383 | raw_local_irq_save(flags); | 421 | raw_local_irq_save(flags); |
384 | 422 | ||
385 | if (++die.lock_owner_depth < 3) { | 423 | if (++die.lock_owner_depth < 3) { |
386 | unsigned long sp; | ||
387 | unsigned short ss; | ||
388 | |||
389 | report_bug(regs->ip, regs); | 424 | report_bug(regs->ip, regs); |
390 | 425 | ||
391 | printk(KERN_EMERG "%s: %04lx [#%d] ", str, err & 0xffff, | 426 | if (__die(str, regs, err)) |
392 | ++die_counter); | ||
393 | #ifdef CONFIG_PREEMPT | ||
394 | printk("PREEMPT "); | ||
395 | #endif | ||
396 | #ifdef CONFIG_SMP | ||
397 | printk("SMP "); | ||
398 | #endif | ||
399 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
400 | printk("DEBUG_PAGEALLOC"); | ||
401 | #endif | ||
402 | printk("\n"); | ||
403 | |||
404 | if (notify_die(DIE_OOPS, str, regs, err, | ||
405 | current->thread.trap_no, SIGSEGV) != | ||
406 | NOTIFY_STOP) { | ||
407 | show_registers(regs); | ||
408 | /* Executive summary in case the oops scrolled away */ | ||
409 | sp = (unsigned long) (®s->sp); | ||
410 | savesegment(ss, ss); | ||
411 | if (user_mode(regs)) { | ||
412 | sp = regs->sp; | ||
413 | ss = regs->ss & 0xffff; | ||
414 | } | ||
415 | printk(KERN_EMERG "EIP: [<%08lx>] ", regs->ip); | ||
416 | print_symbol("%s", regs->ip); | ||
417 | printk(" SS:ESP %04x:%08lx\n", ss, sp); | ||
418 | } | ||
419 | else | ||
420 | regs = NULL; | 427 | regs = NULL; |
421 | } else | 428 | } else { |
422 | printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); | 429 | printk(KERN_EMERG "Recursive die() failure, output suppressed\n"); |
430 | } | ||
423 | 431 | ||
424 | bust_spinlocks(0); | 432 | bust_spinlocks(0); |
425 | die.lock_owner = -1; | 433 | die.lock_owner = -1; |