diff options
-rw-r--r-- | arch/x86_64/kernel/mce.c | 2 | ||||
-rw-r--r-- | arch/x86_64/kernel/traps.c | 33 | ||||
-rw-r--r-- | arch/x86_64/mm/fault.c | 8 | ||||
-rw-r--r-- | include/asm-x86_64/kdebug.h | 13 |
4 files changed, 37 insertions, 19 deletions
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index ee5f65c44214..63777b8cb8c1 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -169,7 +169,7 @@ void do_machine_check(struct pt_regs * regs, long error_code) | |||
169 | int panicm_found = 0; | 169 | int panicm_found = 0; |
170 | 170 | ||
171 | if (regs) | 171 | if (regs) |
172 | notify_die(DIE_NMI, "machine check", regs, error_code, 255, SIGKILL); | 172 | notify_die(DIE_NMI, "machine check", regs, error_code, 18, SIGKILL); |
173 | if (!banks) | 173 | if (!banks) |
174 | return; | 174 | return; |
175 | 175 | ||
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 0fd17e01de06..0266b523e8d0 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -382,7 +382,7 @@ void __die(const char * str, struct pt_regs * regs, long err) | |||
382 | printk("DEBUG_PAGEALLOC"); | 382 | printk("DEBUG_PAGEALLOC"); |
383 | #endif | 383 | #endif |
384 | printk("\n"); | 384 | printk("\n"); |
385 | notify_die(DIE_OOPS, (char *)str, regs, err, 255, SIGSEGV); | 385 | notify_die(DIE_OOPS, str, regs, err, current->thread.trap_no, SIGSEGV); |
386 | show_registers(regs); | 386 | show_registers(regs); |
387 | /* Executive summary in case the oops scrolled away */ | 387 | /* Executive summary in case the oops scrolled away */ |
388 | printk(KERN_ALERT "RIP "); | 388 | printk(KERN_ALERT "RIP "); |
@@ -421,19 +421,20 @@ static void __kprobes do_trap(int trapnr, int signr, char *str, | |||
421 | struct pt_regs * regs, long error_code, | 421 | struct pt_regs * regs, long error_code, |
422 | siginfo_t *info) | 422 | siginfo_t *info) |
423 | { | 423 | { |
424 | struct task_struct *tsk = current; | ||
425 | |||
424 | conditional_sti(regs); | 426 | conditional_sti(regs); |
425 | 427 | ||
426 | if (user_mode(regs)) { | 428 | tsk->thread.error_code = error_code; |
427 | struct task_struct *tsk = current; | 429 | tsk->thread.trap_no = trapnr; |
428 | 430 | ||
431 | if (user_mode(regs)) { | ||
429 | if (exception_trace && unhandled_signal(tsk, signr)) | 432 | if (exception_trace && unhandled_signal(tsk, signr)) |
430 | printk(KERN_INFO | 433 | printk(KERN_INFO |
431 | "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n", | 434 | "%s[%d] trap %s rip:%lx rsp:%lx error:%lx\n", |
432 | tsk->comm, tsk->pid, str, | 435 | tsk->comm, tsk->pid, str, |
433 | regs->rip,regs->rsp,error_code); | 436 | regs->rip,regs->rsp,error_code); |
434 | 437 | ||
435 | tsk->thread.error_code = error_code; | ||
436 | tsk->thread.trap_no = trapnr; | ||
437 | if (info) | 438 | if (info) |
438 | force_sig_info(signr, info, tsk); | 439 | force_sig_info(signr, info, tsk); |
439 | else | 440 | else |
@@ -493,19 +494,20 @@ DO_ERROR( 8, SIGSEGV, "double fault", double_fault) | |||
493 | asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, | 494 | asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, |
494 | long error_code) | 495 | long error_code) |
495 | { | 496 | { |
497 | struct task_struct *tsk = current; | ||
498 | |||
496 | conditional_sti(regs); | 499 | conditional_sti(regs); |
497 | 500 | ||
498 | if (user_mode(regs)) { | 501 | tsk->thread.error_code = error_code; |
499 | struct task_struct *tsk = current; | 502 | tsk->thread.trap_no = 13; |
500 | 503 | ||
504 | if (user_mode(regs)) { | ||
501 | if (exception_trace && unhandled_signal(tsk, SIGSEGV)) | 505 | if (exception_trace && unhandled_signal(tsk, SIGSEGV)) |
502 | printk(KERN_INFO | 506 | printk(KERN_INFO |
503 | "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n", | 507 | "%s[%d] general protection rip:%lx rsp:%lx error:%lx\n", |
504 | tsk->comm, tsk->pid, | 508 | tsk->comm, tsk->pid, |
505 | regs->rip,regs->rsp,error_code); | 509 | regs->rip,regs->rsp,error_code); |
506 | 510 | ||
507 | tsk->thread.error_code = error_code; | ||
508 | tsk->thread.trap_no = 13; | ||
509 | force_sig(SIGSEGV, tsk); | 511 | force_sig(SIGSEGV, tsk); |
510 | return; | 512 | return; |
511 | } | 513 | } |
@@ -568,7 +570,7 @@ asmlinkage void default_do_nmi(struct pt_regs *regs) | |||
568 | reason = get_nmi_reason(); | 570 | reason = get_nmi_reason(); |
569 | 571 | ||
570 | if (!(reason & 0xc0)) { | 572 | if (!(reason & 0xc0)) { |
571 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 0, SIGINT) | 573 | if (notify_die(DIE_NMI_IPI, "nmi_ipi", regs, reason, 2, SIGINT) |
572 | == NOTIFY_STOP) | 574 | == NOTIFY_STOP) |
573 | return; | 575 | return; |
574 | #ifdef CONFIG_X86_LOCAL_APIC | 576 | #ifdef CONFIG_X86_LOCAL_APIC |
@@ -584,7 +586,7 @@ asmlinkage void default_do_nmi(struct pt_regs *regs) | |||
584 | unknown_nmi_error(reason, regs); | 586 | unknown_nmi_error(reason, regs); |
585 | return; | 587 | return; |
586 | } | 588 | } |
587 | if (notify_die(DIE_NMI, "nmi", regs, reason, 0, SIGINT) == NOTIFY_STOP) | 589 | if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) == NOTIFY_STOP) |
588 | return; | 590 | return; |
589 | 591 | ||
590 | /* AK: following checks seem to be broken on modern chipsets. FIXME */ | 592 | /* AK: following checks seem to be broken on modern chipsets. FIXME */ |
@@ -693,7 +695,7 @@ clear_TF_reenable: | |||
693 | regs->eflags &= ~TF_MASK; | 695 | regs->eflags &= ~TF_MASK; |
694 | } | 696 | } |
695 | 697 | ||
696 | static int kernel_math_error(struct pt_regs *regs, char *str) | 698 | static int kernel_math_error(struct pt_regs *regs, const char *str, int trapnr) |
697 | { | 699 | { |
698 | const struct exception_table_entry *fixup; | 700 | const struct exception_table_entry *fixup; |
699 | fixup = search_exception_tables(regs->rip); | 701 | fixup = search_exception_tables(regs->rip); |
@@ -701,8 +703,9 @@ static int kernel_math_error(struct pt_regs *regs, char *str) | |||
701 | regs->rip = fixup->fixup; | 703 | regs->rip = fixup->fixup; |
702 | return 1; | 704 | return 1; |
703 | } | 705 | } |
704 | notify_die(DIE_GPF, str, regs, 0, 16, SIGFPE); | 706 | notify_die(DIE_GPF, str, regs, 0, trapnr, SIGFPE); |
705 | /* Illegal floating point operation in the kernel */ | 707 | /* Illegal floating point operation in the kernel */ |
708 | current->thread.trap_no = trapnr; | ||
706 | die(str, regs, 0); | 709 | die(str, regs, 0); |
707 | return 0; | 710 | return 0; |
708 | } | 711 | } |
@@ -721,7 +724,7 @@ asmlinkage void do_coprocessor_error(struct pt_regs *regs) | |||
721 | 724 | ||
722 | conditional_sti(regs); | 725 | conditional_sti(regs); |
723 | if (!user_mode(regs) && | 726 | if (!user_mode(regs) && |
724 | kernel_math_error(regs, "kernel x87 math error")) | 727 | kernel_math_error(regs, "kernel x87 math error", 16)) |
725 | return; | 728 | return; |
726 | 729 | ||
727 | /* | 730 | /* |
@@ -790,7 +793,7 @@ asmlinkage void do_simd_coprocessor_error(struct pt_regs *regs) | |||
790 | 793 | ||
791 | conditional_sti(regs); | 794 | conditional_sti(regs); |
792 | if (!user_mode(regs) && | 795 | if (!user_mode(regs) && |
793 | kernel_math_error(regs, "kernel simd math error")) | 796 | kernel_math_error(regs, "kernel simd math error", 19)) |
794 | return; | 797 | return; |
795 | 798 | ||
796 | /* | 799 | /* |
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 3a63707a698b..21d1596946d6 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c | |||
@@ -222,10 +222,15 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs, | |||
222 | unsigned long error_code) | 222 | unsigned long error_code) |
223 | { | 223 | { |
224 | unsigned long flags = oops_begin(); | 224 | unsigned long flags = oops_begin(); |
225 | struct task_struct *tsk; | ||
225 | 226 | ||
226 | printk(KERN_ALERT "%s: Corrupted page table at address %lx\n", | 227 | printk(KERN_ALERT "%s: Corrupted page table at address %lx\n", |
227 | current->comm, address); | 228 | current->comm, address); |
228 | dump_pagetable(address); | 229 | dump_pagetable(address); |
230 | tsk = current; | ||
231 | tsk->thread.cr2 = address; | ||
232 | tsk->thread.trap_no = 14; | ||
233 | tsk->thread.error_code = error_code; | ||
229 | __die("Bad pagetable", regs, error_code); | 234 | __die("Bad pagetable", regs, error_code); |
230 | oops_end(flags); | 235 | oops_end(flags); |
231 | do_exit(SIGKILL); | 236 | do_exit(SIGKILL); |
@@ -521,6 +526,9 @@ no_context: | |||
521 | printk_address(regs->rip); | 526 | printk_address(regs->rip); |
522 | printk("\n"); | 527 | printk("\n"); |
523 | dump_pagetable(address); | 528 | dump_pagetable(address); |
529 | tsk->thread.cr2 = address; | ||
530 | tsk->thread.trap_no = 14; | ||
531 | tsk->thread.error_code = error_code; | ||
524 | __die("Oops", regs, error_code); | 532 | __die("Oops", regs, error_code); |
525 | /* Executive summary in case the body of the oops scrolled away */ | 533 | /* Executive summary in case the body of the oops scrolled away */ |
526 | printk(KERN_EMERG "CR2: %016lx\n", address); | 534 | printk(KERN_EMERG "CR2: %016lx\n", address); |
diff --git a/include/asm-x86_64/kdebug.h b/include/asm-x86_64/kdebug.h index f604e84c5303..b9ed4c0c8783 100644 --- a/include/asm-x86_64/kdebug.h +++ b/include/asm-x86_64/kdebug.h | |||
@@ -35,9 +35,16 @@ enum die_val { | |||
35 | DIE_PAGE_FAULT, | 35 | DIE_PAGE_FAULT, |
36 | }; | 36 | }; |
37 | 37 | ||
38 | static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig) | 38 | static inline int notify_die(enum die_val val, const char *str, |
39 | { | 39 | struct pt_regs *regs, long err, int trap, int sig) |
40 | struct die_args args = { .regs=regs, .str=str, .err=err, .trapnr=trap,.signr=sig }; | 40 | { |
41 | struct die_args args = { | ||
42 | .regs = regs, | ||
43 | .str = str, | ||
44 | .err = err, | ||
45 | .trapnr = trap, | ||
46 | .signr = sig | ||
47 | }; | ||
41 | return notifier_call_chain(&die_chain, val, &args); | 48 | return notifier_call_chain(&die_chain, val, &args); |
42 | } | 49 | } |
43 | 50 | ||