aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86_64/kernel/mce.c2
-rw-r--r--arch/x86_64/kernel/traps.c33
-rw-r--r--arch/x86_64/mm/fault.c8
-rw-r--r--include/asm-x86_64/kdebug.h13
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)
493asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, 494asmlinkage 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
696static int kernel_math_error(struct pt_regs *regs, char *str) 698static 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
38static inline int notify_die(enum die_val val,char *str,struct pt_regs *regs,long err,int trap, int sig) 38static 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