diff options
Diffstat (limited to 'arch/x86_64/kernel/traps.c')
-rw-r--r-- | arch/x86_64/kernel/traps.c | 33 |
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) | |||
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 | /* |