aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/traps.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/traps.c')
-rw-r--r--arch/powerpc/kernel/traps.c80
1 files changed, 58 insertions, 22 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 83efa2f7d926..a7a648f6b750 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -35,6 +35,7 @@
35#include <linux/kdebug.h> 35#include <linux/kdebug.h>
36#include <linux/debugfs.h> 36#include <linux/debugfs.h>
37#include <linux/ratelimit.h> 37#include <linux/ratelimit.h>
38#include <linux/context_tracking.h>
38 39
39#include <asm/emulated_ops.h> 40#include <asm/emulated_ops.h>
40#include <asm/pgtable.h> 41#include <asm/pgtable.h>
@@ -667,6 +668,7 @@ int machine_check_generic(struct pt_regs *regs)
667 668
668void machine_check_exception(struct pt_regs *regs) 669void machine_check_exception(struct pt_regs *regs)
669{ 670{
671 enum ctx_state prev_state = exception_enter();
670 int recover = 0; 672 int recover = 0;
671 673
672 __get_cpu_var(irq_stat).mce_exceptions++; 674 __get_cpu_var(irq_stat).mce_exceptions++;
@@ -683,7 +685,7 @@ void machine_check_exception(struct pt_regs *regs)
683 recover = cur_cpu_spec->machine_check(regs); 685 recover = cur_cpu_spec->machine_check(regs);
684 686
685 if (recover > 0) 687 if (recover > 0)
686 return; 688 goto bail;
687 689
688#if defined(CONFIG_8xx) && defined(CONFIG_PCI) 690#if defined(CONFIG_8xx) && defined(CONFIG_PCI)
689 /* the qspan pci read routines can cause machine checks -- Cort 691 /* the qspan pci read routines can cause machine checks -- Cort
@@ -693,20 +695,23 @@ void machine_check_exception(struct pt_regs *regs)
693 * -- BenH 695 * -- BenH
694 */ 696 */
695 bad_page_fault(regs, regs->dar, SIGBUS); 697 bad_page_fault(regs, regs->dar, SIGBUS);
696 return; 698 goto bail;
697#endif 699#endif
698 700
699 if (debugger_fault_handler(regs)) 701 if (debugger_fault_handler(regs))
700 return; 702 goto bail;
701 703
702 if (check_io_access(regs)) 704 if (check_io_access(regs))
703 return; 705 goto bail;
704 706
705 die("Machine check", regs, SIGBUS); 707 die("Machine check", regs, SIGBUS);
706 708
707 /* Must die if the interrupt is not recoverable */ 709 /* Must die if the interrupt is not recoverable */
708 if (!(regs->msr & MSR_RI)) 710 if (!(regs->msr & MSR_RI))
709 panic("Unrecoverable Machine check"); 711 panic("Unrecoverable Machine check");
712
713bail:
714 exception_exit(prev_state);
710} 715}
711 716
712void SMIException(struct pt_regs *regs) 717void SMIException(struct pt_regs *regs)
@@ -716,20 +721,29 @@ void SMIException(struct pt_regs *regs)
716 721
717void unknown_exception(struct pt_regs *regs) 722void unknown_exception(struct pt_regs *regs)
718{ 723{
724 enum ctx_state prev_state = exception_enter();
725
719 printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n", 726 printk("Bad trap at PC: %lx, SR: %lx, vector=%lx\n",
720 regs->nip, regs->msr, regs->trap); 727 regs->nip, regs->msr, regs->trap);
721 728
722 _exception(SIGTRAP, regs, 0, 0); 729 _exception(SIGTRAP, regs, 0, 0);
730
731 exception_exit(prev_state);
723} 732}
724 733
725void instruction_breakpoint_exception(struct pt_regs *regs) 734void instruction_breakpoint_exception(struct pt_regs *regs)
726{ 735{
736 enum ctx_state prev_state = exception_enter();
737
727 if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5, 738 if (notify_die(DIE_IABR_MATCH, "iabr_match", regs, 5,
728 5, SIGTRAP) == NOTIFY_STOP) 739 5, SIGTRAP) == NOTIFY_STOP)
729 return; 740 goto bail;
730 if (debugger_iabr_match(regs)) 741 if (debugger_iabr_match(regs))
731 return; 742 goto bail;
732 _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); 743 _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
744
745bail:
746 exception_exit(prev_state);
733} 747}
734 748
735void RunModeException(struct pt_regs *regs) 749void RunModeException(struct pt_regs *regs)
@@ -739,15 +753,20 @@ void RunModeException(struct pt_regs *regs)
739 753
740void __kprobes single_step_exception(struct pt_regs *regs) 754void __kprobes single_step_exception(struct pt_regs *regs)
741{ 755{
756 enum ctx_state prev_state = exception_enter();
757
742 clear_single_step(regs); 758 clear_single_step(regs);
743 759
744 if (notify_die(DIE_SSTEP, "single_step", regs, 5, 760 if (notify_die(DIE_SSTEP, "single_step", regs, 5,
745 5, SIGTRAP) == NOTIFY_STOP) 761 5, SIGTRAP) == NOTIFY_STOP)
746 return; 762 goto bail;
747 if (debugger_sstep(regs)) 763 if (debugger_sstep(regs))
748 return; 764 goto bail;
749 765
750 _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip); 766 _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
767
768bail:
769 exception_exit(prev_state);
751} 770}
752 771
753/* 772/*
@@ -1005,6 +1024,7 @@ int is_valid_bugaddr(unsigned long addr)
1005 1024
1006void __kprobes program_check_exception(struct pt_regs *regs) 1025void __kprobes program_check_exception(struct pt_regs *regs)
1007{ 1026{
1027 enum ctx_state prev_state = exception_enter();
1008 unsigned int reason = get_reason(regs); 1028 unsigned int reason = get_reason(regs);
1009 extern int do_mathemu(struct pt_regs *regs); 1029 extern int do_mathemu(struct pt_regs *regs);
1010 1030
@@ -1014,26 +1034,26 @@ void __kprobes program_check_exception(struct pt_regs *regs)
1014 if (reason & REASON_FP) { 1034 if (reason & REASON_FP) {
1015 /* IEEE FP exception */ 1035 /* IEEE FP exception */
1016 parse_fpe(regs); 1036 parse_fpe(regs);
1017 return; 1037 goto bail;
1018 } 1038 }
1019 if (reason & REASON_TRAP) { 1039 if (reason & REASON_TRAP) {
1020 /* Debugger is first in line to stop recursive faults in 1040 /* Debugger is first in line to stop recursive faults in
1021 * rcu_lock, notify_die, or atomic_notifier_call_chain */ 1041 * rcu_lock, notify_die, or atomic_notifier_call_chain */
1022 if (debugger_bpt(regs)) 1042 if (debugger_bpt(regs))
1023 return; 1043 goto bail;
1024 1044
1025 /* trap exception */ 1045 /* trap exception */
1026 if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP) 1046 if (notify_die(DIE_BPT, "breakpoint", regs, 5, 5, SIGTRAP)
1027 == NOTIFY_STOP) 1047 == NOTIFY_STOP)
1028 return; 1048 goto bail;
1029 1049
1030 if (!(regs->msr & MSR_PR) && /* not user-mode */ 1050 if (!(regs->msr & MSR_PR) && /* not user-mode */
1031 report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { 1051 report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) {
1032 regs->nip += 4; 1052 regs->nip += 4;
1033 return; 1053 goto bail;
1034 } 1054 }
1035 _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip); 1055 _exception(SIGTRAP, regs, TRAP_BRKPT, regs->nip);
1036 return; 1056 goto bail;
1037 } 1057 }
1038#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 1058#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
1039 if (reason & REASON_TM) { 1059 if (reason & REASON_TM) {
@@ -1049,7 +1069,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
1049 if (!user_mode(regs) && 1069 if (!user_mode(regs) &&
1050 report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) { 1070 report_bug(regs->nip, regs) == BUG_TRAP_TYPE_WARN) {
1051 regs->nip += 4; 1071 regs->nip += 4;
1052 return; 1072 goto bail;
1053 } 1073 }
1054 /* If usermode caused this, it's done something illegal and 1074 /* If usermode caused this, it's done something illegal and
1055 * gets a SIGILL slap on the wrist. We call it an illegal 1075 * gets a SIGILL slap on the wrist. We call it an illegal
@@ -1059,7 +1079,7 @@ void __kprobes program_check_exception(struct pt_regs *regs)
1059 */ 1079 */
1060 if (user_mode(regs)) { 1080 if (user_mode(regs)) {
1061 _exception(SIGILL, regs, ILL_ILLOPN, regs->nip); 1081 _exception(SIGILL, regs, ILL_ILLOPN, regs->nip);
1062 return; 1082 goto bail;
1063 } else { 1083 } else {
1064 printk(KERN_EMERG "Unexpected TM Bad Thing exception " 1084 printk(KERN_EMERG "Unexpected TM Bad Thing exception "
1065 "at %lx (msr 0x%x)\n", regs->nip, reason); 1085 "at %lx (msr 0x%x)\n", regs->nip, reason);
@@ -1083,16 +1103,16 @@ void __kprobes program_check_exception(struct pt_regs *regs)
1083 switch (do_mathemu(regs)) { 1103 switch (do_mathemu(regs)) {
1084 case 0: 1104 case 0:
1085 emulate_single_step(regs); 1105 emulate_single_step(regs);
1086 return; 1106 goto bail;
1087 case 1: { 1107 case 1: {
1088 int code = 0; 1108 int code = 0;
1089 code = __parse_fpscr(current->thread.fpscr.val); 1109 code = __parse_fpscr(current->thread.fpscr.val);
1090 _exception(SIGFPE, regs, code, regs->nip); 1110 _exception(SIGFPE, regs, code, regs->nip);
1091 return; 1111 goto bail;
1092 } 1112 }
1093 case -EFAULT: 1113 case -EFAULT:
1094 _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); 1114 _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
1095 return; 1115 goto bail;
1096 } 1116 }
1097 /* fall through on any other errors */ 1117 /* fall through on any other errors */
1098#endif /* CONFIG_MATH_EMULATION */ 1118#endif /* CONFIG_MATH_EMULATION */
@@ -1103,10 +1123,10 @@ void __kprobes program_check_exception(struct pt_regs *regs)
1103 case 0: 1123 case 0:
1104 regs->nip += 4; 1124 regs->nip += 4;
1105 emulate_single_step(regs); 1125 emulate_single_step(regs);
1106 return; 1126 goto bail;
1107 case -EFAULT: 1127 case -EFAULT:
1108 _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); 1128 _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip);
1109 return; 1129 goto bail;
1110 } 1130 }
1111 } 1131 }
1112 1132
@@ -1114,10 +1134,14 @@ void __kprobes program_check_exception(struct pt_regs *regs)
1114 _exception(SIGILL, regs, ILL_PRVOPC, regs->nip); 1134 _exception(SIGILL, regs, ILL_PRVOPC, regs->nip);
1115 else 1135 else
1116 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); 1136 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
1137
1138bail:
1139 exception_exit(prev_state);
1117} 1140}
1118 1141
1119void alignment_exception(struct pt_regs *regs) 1142void alignment_exception(struct pt_regs *regs)
1120{ 1143{
1144 enum ctx_state prev_state = exception_enter();
1121 int sig, code, fixed = 0; 1145 int sig, code, fixed = 0;
1122 1146
1123 /* We restore the interrupt state now */ 1147 /* We restore the interrupt state now */
@@ -1131,7 +1155,7 @@ void alignment_exception(struct pt_regs *regs)
1131 if (fixed == 1) { 1155 if (fixed == 1) {
1132 regs->nip += 4; /* skip over emulated instruction */ 1156 regs->nip += 4; /* skip over emulated instruction */
1133 emulate_single_step(regs); 1157 emulate_single_step(regs);
1134 return; 1158 goto bail;
1135 } 1159 }
1136 1160
1137 /* Operand address was bad */ 1161 /* Operand address was bad */
@@ -1146,6 +1170,9 @@ void alignment_exception(struct pt_regs *regs)
1146 _exception(sig, regs, code, regs->dar); 1170 _exception(sig, regs, code, regs->dar);
1147 else 1171 else
1148 bad_page_fault(regs, regs->dar, sig); 1172 bad_page_fault(regs, regs->dar, sig);
1173
1174bail:
1175 exception_exit(prev_state);
1149} 1176}
1150 1177
1151void StackOverflow(struct pt_regs *regs) 1178void StackOverflow(struct pt_regs *regs)
@@ -1174,23 +1201,32 @@ void trace_syscall(struct pt_regs *regs)
1174 1201
1175void kernel_fp_unavailable_exception(struct pt_regs *regs) 1202void kernel_fp_unavailable_exception(struct pt_regs *regs)
1176{ 1203{
1204 enum ctx_state prev_state = exception_enter();
1205
1177 printk(KERN_EMERG "Unrecoverable FP Unavailable Exception " 1206 printk(KERN_EMERG "Unrecoverable FP Unavailable Exception "
1178 "%lx at %lx\n", regs->trap, regs->nip); 1207 "%lx at %lx\n", regs->trap, regs->nip);
1179 die("Unrecoverable FP Unavailable Exception", regs, SIGABRT); 1208 die("Unrecoverable FP Unavailable Exception", regs, SIGABRT);
1209
1210 exception_exit(prev_state);
1180} 1211}
1181 1212
1182void altivec_unavailable_exception(struct pt_regs *regs) 1213void altivec_unavailable_exception(struct pt_regs *regs)
1183{ 1214{
1215 enum ctx_state prev_state = exception_enter();
1216
1184 if (user_mode(regs)) { 1217 if (user_mode(regs)) {
1185 /* A user program has executed an altivec instruction, 1218 /* A user program has executed an altivec instruction,
1186 but this kernel doesn't support altivec. */ 1219 but this kernel doesn't support altivec. */
1187 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); 1220 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip);
1188 return; 1221 goto bail;
1189 } 1222 }
1190 1223
1191 printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception " 1224 printk(KERN_EMERG "Unrecoverable VMX/Altivec Unavailable Exception "
1192 "%lx at %lx\n", regs->trap, regs->nip); 1225 "%lx at %lx\n", regs->trap, regs->nip);
1193 die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT); 1226 die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
1227
1228bail:
1229 exception_exit(prev_state);
1194} 1230}
1195 1231
1196void vsx_unavailable_exception(struct pt_regs *regs) 1232void vsx_unavailable_exception(struct pt_regs *regs)