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.c178
1 files changed, 113 insertions, 65 deletions
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 6f0ae1a9bfae..29d128eb6c43 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -21,7 +21,6 @@
21#include <linux/stddef.h> 21#include <linux/stddef.h>
22#include <linux/unistd.h> 22#include <linux/unistd.h>
23#include <linux/ptrace.h> 23#include <linux/ptrace.h>
24#include <linux/slab.h>
25#include <linux/user.h> 24#include <linux/user.h>
26#include <linux/interrupt.h> 25#include <linux/interrupt.h>
27#include <linux/init.h> 26#include <linux/init.h>
@@ -60,13 +59,13 @@
60#endif 59#endif
61 60
62#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC) 61#if defined(CONFIG_DEBUGGER) || defined(CONFIG_KEXEC)
63int (*__debugger)(struct pt_regs *regs); 62int (*__debugger)(struct pt_regs *regs) __read_mostly;
64int (*__debugger_ipi)(struct pt_regs *regs); 63int (*__debugger_ipi)(struct pt_regs *regs) __read_mostly;
65int (*__debugger_bpt)(struct pt_regs *regs); 64int (*__debugger_bpt)(struct pt_regs *regs) __read_mostly;
66int (*__debugger_sstep)(struct pt_regs *regs); 65int (*__debugger_sstep)(struct pt_regs *regs) __read_mostly;
67int (*__debugger_iabr_match)(struct pt_regs *regs); 66int (*__debugger_iabr_match)(struct pt_regs *regs) __read_mostly;
68int (*__debugger_dabr_match)(struct pt_regs *regs); 67int (*__debugger_dabr_match)(struct pt_regs *regs) __read_mostly;
69int (*__debugger_fault_handler)(struct pt_regs *regs); 68int (*__debugger_fault_handler)(struct pt_regs *regs) __read_mostly;
70 69
71EXPORT_SYMBOL(__debugger); 70EXPORT_SYMBOL(__debugger);
72EXPORT_SYMBOL(__debugger_ipi); 71EXPORT_SYMBOL(__debugger_ipi);
@@ -102,11 +101,11 @@ static inline void pmac_backlight_unblank(void) { }
102int die(const char *str, struct pt_regs *regs, long err) 101int die(const char *str, struct pt_regs *regs, long err)
103{ 102{
104 static struct { 103 static struct {
105 spinlock_t lock; 104 raw_spinlock_t lock;
106 u32 lock_owner; 105 u32 lock_owner;
107 int lock_owner_depth; 106 int lock_owner_depth;
108 } die = { 107 } die = {
109 .lock = __SPIN_LOCK_UNLOCKED(die.lock), 108 .lock = __RAW_SPIN_LOCK_UNLOCKED(die.lock),
110 .lock_owner = -1, 109 .lock_owner = -1,
111 .lock_owner_depth = 0 110 .lock_owner_depth = 0
112 }; 111 };
@@ -120,7 +119,7 @@ int die(const char *str, struct pt_regs *regs, long err)
120 119
121 if (die.lock_owner != raw_smp_processor_id()) { 120 if (die.lock_owner != raw_smp_processor_id()) {
122 console_verbose(); 121 console_verbose();
123 spin_lock_irqsave(&die.lock, flags); 122 raw_spin_lock_irqsave(&die.lock, flags);
124 die.lock_owner = smp_processor_id(); 123 die.lock_owner = smp_processor_id();
125 die.lock_owner_depth = 0; 124 die.lock_owner_depth = 0;
126 bust_spinlocks(1); 125 bust_spinlocks(1);
@@ -146,6 +145,11 @@ int die(const char *str, struct pt_regs *regs, long err)
146#endif 145#endif
147 printk("%s\n", ppc_md.name ? ppc_md.name : ""); 146 printk("%s\n", ppc_md.name ? ppc_md.name : "");
148 147
148 sysfs_printk_last_file();
149 if (notify_die(DIE_OOPS, str, regs, err, 255,
150 SIGSEGV) == NOTIFY_STOP)
151 return 1;
152
149 print_modules(); 153 print_modules();
150 show_regs(regs); 154 show_regs(regs);
151 } else { 155 } else {
@@ -155,7 +159,7 @@ int die(const char *str, struct pt_regs *regs, long err)
155 bust_spinlocks(0); 159 bust_spinlocks(0);
156 die.lock_owner = -1; 160 die.lock_owner = -1;
157 add_taint(TAINT_DIE); 161 add_taint(TAINT_DIE);
158 spin_unlock_irqrestore(&die.lock, flags); 162 raw_spin_unlock_irqrestore(&die.lock, flags);
159 163
160 if (kexec_should_crash(current) || 164 if (kexec_should_crash(current) ||
161 kexec_sr_activated(smp_processor_id())) 165 kexec_sr_activated(smp_processor_id()))
@@ -174,6 +178,15 @@ int die(const char *str, struct pt_regs *regs, long err)
174 return 0; 178 return 0;
175} 179}
176 180
181void user_single_step_siginfo(struct task_struct *tsk,
182 struct pt_regs *regs, siginfo_t *info)
183{
184 memset(info, 0, sizeof(*info));
185 info->si_signo = SIGTRAP;
186 info->si_code = TRAP_TRACE;
187 info->si_addr = (void __user *)regs->nip;
188}
189
177void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr) 190void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
178{ 191{
179 siginfo_t info; 192 siginfo_t info;
@@ -198,28 +211,6 @@ void _exception(int signr, struct pt_regs *regs, int code, unsigned long addr)
198 info.si_code = code; 211 info.si_code = code;
199 info.si_addr = (void __user *) addr; 212 info.si_addr = (void __user *) addr;
200 force_sig_info(signr, &info, current); 213 force_sig_info(signr, &info, current);
201
202 /*
203 * Init gets no signals that it doesn't have a handler for.
204 * That's all very well, but if it has caused a synchronous
205 * exception and we ignore the resulting signal, it will just
206 * generate the same exception over and over again and we get
207 * nowhere. Better to kill it and let the kernel panic.
208 */
209 if (is_global_init(current)) {
210 __sighandler_t handler;
211
212 spin_lock_irq(&current->sighand->siglock);
213 handler = current->sighand->action[signr-1].sa.sa_handler;
214 spin_unlock_irq(&current->sighand->siglock);
215 if (handler == SIG_DFL) {
216 /* init has generated a synchronous exception
217 and it doesn't have a handler for the signal */
218 printk(KERN_CRIT "init has generated signal %d "
219 "but has no handler for it\n", signr);
220 do_exit(signr);
221 }
222 }
223} 214}
224 215
225#ifdef CONFIG_PPC64 216#ifdef CONFIG_PPC64
@@ -307,7 +298,7 @@ static inline int check_io_access(struct pt_regs *regs)
307 return 0; 298 return 0;
308} 299}
309 300
310#if defined(CONFIG_4xx) || defined(CONFIG_BOOKE) 301#ifdef CONFIG_PPC_ADV_DEBUG_REGS
311/* On 4xx, the reason for the machine check or program exception 302/* On 4xx, the reason for the machine check or program exception
312 is in the ESR. */ 303 is in the ESR. */
313#define get_reason(regs) ((regs)->dsisr) 304#define get_reason(regs) ((regs)->dsisr)
@@ -491,6 +482,8 @@ void machine_check_exception(struct pt_regs *regs)
491{ 482{
492 int recover = 0; 483 int recover = 0;
493 484
485 __get_cpu_var(irq_stat).mce_exceptions++;
486
494 /* See if any machine dependent calls. In theory, we would want 487 /* See if any machine dependent calls. In theory, we would want
495 * to call the CPU first, and call the ppc_md. one if the CPU 488 * to call the CPU first, and call the ppc_md. one if the CPU
496 * one returns a positive number. However there is existing code 489 * one returns a positive number. However there is existing code
@@ -759,7 +752,7 @@ static int emulate_instruction(struct pt_regs *regs)
759 752
760 /* Emulate the mfspr rD, PVR. */ 753 /* Emulate the mfspr rD, PVR. */
761 if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) { 754 if ((instword & PPC_INST_MFSPR_PVR_MASK) == PPC_INST_MFSPR_PVR) {
762 PPC_WARN_EMULATED(mfpvr); 755 PPC_WARN_EMULATED(mfpvr, regs);
763 rd = (instword >> 21) & 0x1f; 756 rd = (instword >> 21) & 0x1f;
764 regs->gpr[rd] = mfspr(SPRN_PVR); 757 regs->gpr[rd] = mfspr(SPRN_PVR);
765 return 0; 758 return 0;
@@ -767,7 +760,7 @@ static int emulate_instruction(struct pt_regs *regs)
767 760
768 /* Emulating the dcba insn is just a no-op. */ 761 /* Emulating the dcba insn is just a no-op. */
769 if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) { 762 if ((instword & PPC_INST_DCBA_MASK) == PPC_INST_DCBA) {
770 PPC_WARN_EMULATED(dcba); 763 PPC_WARN_EMULATED(dcba, regs);
771 return 0; 764 return 0;
772 } 765 }
773 766
@@ -776,7 +769,7 @@ static int emulate_instruction(struct pt_regs *regs)
776 int shift = (instword >> 21) & 0x1c; 769 int shift = (instword >> 21) & 0x1c;
777 unsigned long msk = 0xf0000000UL >> shift; 770 unsigned long msk = 0xf0000000UL >> shift;
778 771
779 PPC_WARN_EMULATED(mcrxr); 772 PPC_WARN_EMULATED(mcrxr, regs);
780 regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk); 773 regs->ccr = (regs->ccr & ~msk) | ((regs->xer >> shift) & msk);
781 regs->xer &= ~0xf0000000UL; 774 regs->xer &= ~0xf0000000UL;
782 return 0; 775 return 0;
@@ -784,19 +777,19 @@ static int emulate_instruction(struct pt_regs *regs)
784 777
785 /* Emulate load/store string insn. */ 778 /* Emulate load/store string insn. */
786 if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) { 779 if ((instword & PPC_INST_STRING_GEN_MASK) == PPC_INST_STRING) {
787 PPC_WARN_EMULATED(string); 780 PPC_WARN_EMULATED(string, regs);
788 return emulate_string_inst(regs, instword); 781 return emulate_string_inst(regs, instword);
789 } 782 }
790 783
791 /* Emulate the popcntb (Population Count Bytes) instruction. */ 784 /* Emulate the popcntb (Population Count Bytes) instruction. */
792 if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) { 785 if ((instword & PPC_INST_POPCNTB_MASK) == PPC_INST_POPCNTB) {
793 PPC_WARN_EMULATED(popcntb); 786 PPC_WARN_EMULATED(popcntb, regs);
794 return emulate_popcntb_inst(regs, instword); 787 return emulate_popcntb_inst(regs, instword);
795 } 788 }
796 789
797 /* Emulate isel (Integer Select) instruction */ 790 /* Emulate isel (Integer Select) instruction */
798 if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) { 791 if ((instword & PPC_INST_ISEL_MASK) == PPC_INST_ISEL) {
799 PPC_WARN_EMULATED(isel); 792 PPC_WARN_EMULATED(isel, regs);
800 return emulate_isel(regs, instword); 793 return emulate_isel(regs, instword);
801 } 794 }
802 795
@@ -973,6 +966,8 @@ void vsx_unavailable_exception(struct pt_regs *regs)
973 966
974void performance_monitor_exception(struct pt_regs *regs) 967void performance_monitor_exception(struct pt_regs *regs)
975{ 968{
969 __get_cpu_var(irq_stat).pmu_irqs++;
970
976 perf_irq(regs); 971 perf_irq(regs);
977} 972}
978 973
@@ -995,7 +990,7 @@ void SoftwareEmulation(struct pt_regs *regs)
995#ifdef CONFIG_MATH_EMULATION 990#ifdef CONFIG_MATH_EMULATION
996 errcode = do_mathemu(regs); 991 errcode = do_mathemu(regs);
997 if (errcode >= 0) 992 if (errcode >= 0)
998 PPC_WARN_EMULATED(math); 993 PPC_WARN_EMULATED(math, regs);
999 994
1000 switch (errcode) { 995 switch (errcode) {
1001 case 0: 996 case 0:
@@ -1018,7 +1013,7 @@ void SoftwareEmulation(struct pt_regs *regs)
1018#elif defined(CONFIG_8XX_MINIMAL_FPEMU) 1013#elif defined(CONFIG_8XX_MINIMAL_FPEMU)
1019 errcode = Soft_emulate_8xx(regs); 1014 errcode = Soft_emulate_8xx(regs);
1020 if (errcode >= 0) 1015 if (errcode >= 0)
1021 PPC_WARN_EMULATED(8xx); 1016 PPC_WARN_EMULATED(8xx, regs);
1022 1017
1023 switch (errcode) { 1018 switch (errcode) {
1024 case 0: 1019 case 0:
@@ -1037,10 +1032,69 @@ void SoftwareEmulation(struct pt_regs *regs)
1037} 1032}
1038#endif /* CONFIG_8xx */ 1033#endif /* CONFIG_8xx */
1039 1034
1040#if defined(CONFIG_40x) || defined(CONFIG_BOOKE) 1035#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1036static void handle_debug(struct pt_regs *regs, unsigned long debug_status)
1037{
1038 int changed = 0;
1039 /*
1040 * Determine the cause of the debug event, clear the
1041 * event flags and send a trap to the handler. Torez
1042 */
1043 if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
1044 dbcr_dac(current) &= ~(DBCR_DAC1R | DBCR_DAC1W);
1045#ifdef CONFIG_PPC_ADV_DEBUG_DAC_RANGE
1046 current->thread.dbcr2 &= ~DBCR2_DAC12MODE;
1047#endif
1048 do_send_trap(regs, mfspr(SPRN_DAC1), debug_status, TRAP_HWBKPT,
1049 5);
1050 changed |= 0x01;
1051 } else if (debug_status & (DBSR_DAC2R | DBSR_DAC2W)) {
1052 dbcr_dac(current) &= ~(DBCR_DAC2R | DBCR_DAC2W);
1053 do_send_trap(regs, mfspr(SPRN_DAC2), debug_status, TRAP_HWBKPT,
1054 6);
1055 changed |= 0x01;
1056 } else if (debug_status & DBSR_IAC1) {
1057 current->thread.dbcr0 &= ~DBCR0_IAC1;
1058 dbcr_iac_range(current) &= ~DBCR_IAC12MODE;
1059 do_send_trap(regs, mfspr(SPRN_IAC1), debug_status, TRAP_HWBKPT,
1060 1);
1061 changed |= 0x01;
1062 } else if (debug_status & DBSR_IAC2) {
1063 current->thread.dbcr0 &= ~DBCR0_IAC2;
1064 do_send_trap(regs, mfspr(SPRN_IAC2), debug_status, TRAP_HWBKPT,
1065 2);
1066 changed |= 0x01;
1067 } else if (debug_status & DBSR_IAC3) {
1068 current->thread.dbcr0 &= ~DBCR0_IAC3;
1069 dbcr_iac_range(current) &= ~DBCR_IAC34MODE;
1070 do_send_trap(regs, mfspr(SPRN_IAC3), debug_status, TRAP_HWBKPT,
1071 3);
1072 changed |= 0x01;
1073 } else if (debug_status & DBSR_IAC4) {
1074 current->thread.dbcr0 &= ~DBCR0_IAC4;
1075 do_send_trap(regs, mfspr(SPRN_IAC4), debug_status, TRAP_HWBKPT,
1076 4);
1077 changed |= 0x01;
1078 }
1079 /*
1080 * At the point this routine was called, the MSR(DE) was turned off.
1081 * Check all other debug flags and see if that bit needs to be turned
1082 * back on or not.
1083 */
1084 if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0, current->thread.dbcr1))
1085 regs->msr |= MSR_DE;
1086 else
1087 /* Make sure the IDM flag is off */
1088 current->thread.dbcr0 &= ~DBCR0_IDM;
1089
1090 if (changed & 0x01)
1091 mtspr(SPRN_DBCR0, current->thread.dbcr0);
1092}
1041 1093
1042void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status) 1094void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
1043{ 1095{
1096 current->thread.dbsr = debug_status;
1097
1044 /* Hack alert: On BookE, Branch Taken stops on the branch itself, while 1098 /* Hack alert: On BookE, Branch Taken stops on the branch itself, while
1045 * on server, it stops on the target of the branch. In order to simulate 1099 * on server, it stops on the target of the branch. In order to simulate
1046 * the server behaviour, we thus restart right away with a single step 1100 * the server behaviour, we thus restart right away with a single step
@@ -1084,29 +1138,23 @@ void __kprobes DebugException(struct pt_regs *regs, unsigned long debug_status)
1084 if (debugger_sstep(regs)) 1138 if (debugger_sstep(regs))
1085 return; 1139 return;
1086 1140
1087 if (user_mode(regs))
1088 current->thread.dbcr0 &= ~(DBCR0_IC);
1089
1090 _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
1091 } else if (debug_status & (DBSR_DAC1R | DBSR_DAC1W)) {
1092 regs->msr &= ~MSR_DE;
1093
1094 if (user_mode(regs)) { 1141 if (user_mode(regs)) {
1095 current->thread.dbcr0 &= ~(DBSR_DAC1R | DBSR_DAC1W | 1142 current->thread.dbcr0 &= ~DBCR0_IC;
1096 DBCR0_IDM); 1143#ifdef CONFIG_PPC_ADV_DEBUG_REGS
1097 } else { 1144 if (DBCR_ACTIVE_EVENTS(current->thread.dbcr0,
1098 /* Disable DAC interupts */ 1145 current->thread.dbcr1))
1099 mtspr(SPRN_DBCR0, mfspr(SPRN_DBCR0) & ~(DBSR_DAC1R | 1146 regs->msr |= MSR_DE;
1100 DBSR_DAC1W | DBCR0_IDM)); 1147 else
1101 1148 /* Make sure the IDM bit is off */
1102 /* Clear the DAC event */ 1149 current->thread.dbcr0 &= ~DBCR0_IDM;
1103 mtspr(SPRN_DBSR, (DBSR_DAC1R | DBSR_DAC1W)); 1150#endif
1104 } 1151 }
1105 /* Setup and send the trap to the handler */ 1152
1106 do_dabr(regs, mfspr(SPRN_DAC1), debug_status); 1153 _exception(SIGTRAP, regs, TRAP_TRACE, regs->nip);
1107 } 1154 } else
1155 handle_debug(regs, debug_status);
1108} 1156}
1109#endif /* CONFIG_4xx || CONFIG_BOOKE */ 1157#endif /* CONFIG_PPC_ADV_DEBUG_REGS */
1110 1158
1111#if !defined(CONFIG_TAU_INT) 1159#if !defined(CONFIG_TAU_INT)
1112void TAUException(struct pt_regs *regs) 1160void TAUException(struct pt_regs *regs)
@@ -1129,7 +1177,7 @@ void altivec_assist_exception(struct pt_regs *regs)
1129 1177
1130 flush_altivec_to_thread(current); 1178 flush_altivec_to_thread(current);
1131 1179
1132 PPC_WARN_EMULATED(altivec); 1180 PPC_WARN_EMULATED(altivec, regs);
1133 err = emulate_altivec(regs); 1181 err = emulate_altivec(regs);
1134 if (err == 0) { 1182 if (err == 0) {
1135 regs->nip += 4; /* skip emulated instruction */ 1183 regs->nip += 4; /* skip emulated instruction */