diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kernel/traps_32.c | 36 | ||||
-rw-r--r-- | arch/x86/kernel/traps_64.c | 41 |
2 files changed, 42 insertions, 35 deletions
diff --git a/arch/x86/kernel/traps_32.c b/arch/x86/kernel/traps_32.c index 5afd94a01b98..c9a0120e510c 100644 --- a/arch/x86/kernel/traps_32.c +++ b/arch/x86/kernel/traps_32.c | |||
@@ -598,8 +598,10 @@ DO_ERROR(12, SIGBUS, "stack segment", stack_segment) | |||
598 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) | 598 | DO_ERROR_INFO(17, SIGBUS, "alignment check", alignment_check, BUS_ADRALN, 0, 0) |
599 | DO_ERROR_INFO(32, SIGILL, "iret exception", iret_error, ILL_BADSTK, 0, 1) | 599 | DO_ERROR_INFO(32, SIGILL, "iret exception", iret_error, ILL_BADSTK, 0, 1) |
600 | 600 | ||
601 | void __kprobes do_general_protection(struct pt_regs *regs, long error_code) | 601 | void __kprobes |
602 | do_general_protection(struct pt_regs *regs, long error_code) | ||
602 | { | 603 | { |
604 | struct task_struct *tsk; | ||
603 | struct thread_struct *thread; | 605 | struct thread_struct *thread; |
604 | struct tss_struct *tss; | 606 | struct tss_struct *tss; |
605 | int cpu; | 607 | int cpu; |
@@ -640,23 +642,24 @@ void __kprobes do_general_protection(struct pt_regs *regs, long error_code) | |||
640 | if (regs->flags & X86_VM_MASK) | 642 | if (regs->flags & X86_VM_MASK) |
641 | goto gp_in_vm86; | 643 | goto gp_in_vm86; |
642 | 644 | ||
645 | tsk = current; | ||
643 | if (!user_mode(regs)) | 646 | if (!user_mode(regs)) |
644 | goto gp_in_kernel; | 647 | goto gp_in_kernel; |
645 | 648 | ||
646 | current->thread.error_code = error_code; | 649 | tsk->thread.error_code = error_code; |
647 | current->thread.trap_no = 13; | 650 | tsk->thread.trap_no = 13; |
648 | 651 | ||
649 | if (show_unhandled_signals && unhandled_signal(current, SIGSEGV) && | 652 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && |
650 | printk_ratelimit()) { | 653 | printk_ratelimit()) { |
651 | printk(KERN_INFO | 654 | printk(KERN_INFO |
652 | "%s[%d] general protection ip:%lx sp:%lx error:%lx", | 655 | "%s[%d] general protection ip:%lx sp:%lx error:%lx", |
653 | current->comm, task_pid_nr(current), | 656 | tsk->comm, task_pid_nr(tsk), |
654 | regs->ip, regs->sp, error_code); | 657 | regs->ip, regs->sp, error_code); |
655 | print_vma_addr(" in ", regs->ip); | 658 | print_vma_addr(" in ", regs->ip); |
656 | printk("\n"); | 659 | printk("\n"); |
657 | } | 660 | } |
658 | 661 | ||
659 | force_sig(SIGSEGV, current); | 662 | force_sig(SIGSEGV, tsk); |
660 | return; | 663 | return; |
661 | 664 | ||
662 | gp_in_vm86: | 665 | gp_in_vm86: |
@@ -665,14 +668,15 @@ gp_in_vm86: | |||
665 | return; | 668 | return; |
666 | 669 | ||
667 | gp_in_kernel: | 670 | gp_in_kernel: |
668 | if (!fixup_exception(regs)) { | 671 | if (fixup_exception(regs)) |
669 | current->thread.error_code = error_code; | 672 | return; |
670 | current->thread.trap_no = 13; | 673 | |
671 | if (notify_die(DIE_GPF, "general protection fault", regs, | 674 | tsk->thread.error_code = error_code; |
675 | tsk->thread.trap_no = 13; | ||
676 | if (notify_die(DIE_GPF, "general protection fault", regs, | ||
672 | error_code, 13, SIGSEGV) == NOTIFY_STOP) | 677 | error_code, 13, SIGSEGV) == NOTIFY_STOP) |
673 | return; | 678 | return; |
674 | die("general protection fault", regs, error_code); | 679 | die("general protection fault", regs, error_code); |
675 | } | ||
676 | } | 680 | } |
677 | 681 | ||
678 | static notrace __kprobes void | 682 | static notrace __kprobes void |
diff --git a/arch/x86/kernel/traps_64.c b/arch/x86/kernel/traps_64.c index 1c2d533fe7ff..bc21ddc97a02 100644 --- a/arch/x86/kernel/traps_64.c +++ b/arch/x86/kernel/traps_64.c | |||
@@ -733,31 +733,34 @@ asmlinkage void do_double_fault(struct pt_regs * regs, long error_code) | |||
733 | die(str, regs, error_code); | 733 | die(str, regs, error_code); |
734 | } | 734 | } |
735 | 735 | ||
736 | asmlinkage void __kprobes do_general_protection(struct pt_regs * regs, | 736 | asmlinkage void __kprobes |
737 | long error_code) | 737 | do_general_protection(struct pt_regs *regs, long error_code) |
738 | { | 738 | { |
739 | struct task_struct *tsk = current; | 739 | struct task_struct *tsk; |
740 | 740 | ||
741 | conditional_sti(regs); | 741 | conditional_sti(regs); |
742 | 742 | ||
743 | if (user_mode(regs)) { | 743 | tsk = current; |
744 | tsk->thread.error_code = error_code; | 744 | if (!user_mode(regs)) |
745 | tsk->thread.trap_no = 13; | 745 | goto gp_in_kernel; |
746 | |||
747 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && | ||
748 | printk_ratelimit()) { | ||
749 | printk(KERN_INFO | ||
750 | "%s[%d] general protection ip:%lx sp:%lx error:%lx", | ||
751 | tsk->comm, tsk->pid, | ||
752 | regs->ip, regs->sp, error_code); | ||
753 | print_vma_addr(" in ", regs->ip); | ||
754 | printk("\n"); | ||
755 | } | ||
756 | 746 | ||
757 | force_sig(SIGSEGV, tsk); | 747 | tsk->thread.error_code = error_code; |
758 | return; | 748 | tsk->thread.trap_no = 13; |
759 | } | 749 | |
750 | if (show_unhandled_signals && unhandled_signal(tsk, SIGSEGV) && | ||
751 | printk_ratelimit()) { | ||
752 | printk(KERN_INFO | ||
753 | "%s[%d] general protection ip:%lx sp:%lx error:%lx", | ||
754 | tsk->comm, tsk->pid, | ||
755 | regs->ip, regs->sp, error_code); | ||
756 | print_vma_addr(" in ", regs->ip); | ||
757 | printk("\n"); | ||
758 | } | ||
759 | |||
760 | force_sig(SIGSEGV, tsk); | ||
761 | return; | ||
760 | 762 | ||
763 | gp_in_kernel: | ||
761 | if (fixup_exception(regs)) | 764 | if (fixup_exception(regs)) |
762 | return; | 765 | return; |
763 | 766 | ||