aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86_64/kernel/traps.c')
-rw-r--r--arch/x86_64/kernel/traps.c33
1 files changed, 18 insertions, 15 deletions
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 /*