traps.c (6761ee3d7e139ec8728e1515bfc5fdcaf3be317e) | traps.c (3a3b5aa63fad4911e239055c2c0a89ce2dac62ce) |
---|---|
1/* 2 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright 2007-2010 Freescale Semiconductor, Inc. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 8 * 2 of the License, or (at your option) any later version. --- 1041 unchanged lines hidden (view full) --- 1050 return -EINVAL; 1051} 1052 1053int is_valid_bugaddr(unsigned long addr) 1054{ 1055 return is_kernel_addr(addr); 1056} 1057 | 1/* 2 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 3 * Copyright 2007-2010 Freescale Semiconductor, Inc. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 8 * 2 of the License, or (at your option) any later version. --- 1041 unchanged lines hidden (view full) --- 1050 return -EINVAL; 1051} 1052 1053int is_valid_bugaddr(unsigned long addr) 1054{ 1055 return is_kernel_addr(addr); 1056} 1057 |
1058#ifdef CONFIG_MATH_EMULATION 1059static int emulate_math(struct pt_regs *regs) 1060{ 1061 int ret; 1062 extern int do_mathemu(struct pt_regs *regs); 1063 1064 ret = do_mathemu(regs); 1065 if (ret >= 0) 1066 PPC_WARN_EMULATED(math, regs); 1067 1068 switch (ret) { 1069 case 0: 1070 emulate_single_step(regs); 1071 return 0; 1072 case 1: { 1073 int code = 0; 1074 code = __parse_fpscr(current->thread.fpscr.val); 1075 _exception(SIGFPE, regs, code, regs->nip); 1076 return 0; 1077 } 1078 case -EFAULT: 1079 _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); 1080 return 0; 1081 } 1082 1083 return -1; 1084} 1085#else 1086static inline int emulate_math(struct pt_regs *regs) { return -1; } 1087#endif 1088 |
|
1058void __kprobes program_check_exception(struct pt_regs *regs) 1059{ 1060 enum ctx_state prev_state = exception_enter(); 1061 unsigned int reason = get_reason(regs); | 1089void __kprobes program_check_exception(struct pt_regs *regs) 1090{ 1091 enum ctx_state prev_state = exception_enter(); 1092 unsigned int reason = get_reason(regs); |
1062 extern int do_mathemu(struct pt_regs *regs); | |
1063 1064 /* We can now get here via a FP Unavailable exception if the core 1065 * has no FPU, in that case the reason flags will be 0 */ 1066 1067 if (reason & REASON_FP) { 1068 /* IEEE FP exception */ 1069 parse_fpe(regs); 1070 goto bail; --- 49 unchanged lines hidden (view full) --- 1120 } 1121 } 1122#endif 1123 1124 /* We restore the interrupt state now */ 1125 if (!arch_irq_disabled_regs(regs)) 1126 local_irq_enable(); 1127 | 1093 1094 /* We can now get here via a FP Unavailable exception if the core 1095 * has no FPU, in that case the reason flags will be 0 */ 1096 1097 if (reason & REASON_FP) { 1098 /* IEEE FP exception */ 1099 parse_fpe(regs); 1100 goto bail; --- 49 unchanged lines hidden (view full) --- 1150 } 1151 } 1152#endif 1153 1154 /* We restore the interrupt state now */ 1155 if (!arch_irq_disabled_regs(regs)) 1156 local_irq_enable(); 1157 |
1128#ifdef CONFIG_MATH_EMULATION | |
1129 /* (reason & REASON_ILLEGAL) would be the obvious thing here, 1130 * but there seems to be a hardware bug on the 405GP (RevD) 1131 * that means ESR is sometimes set incorrectly - either to 1132 * ESR_DST (!?) or 0. In the process of chasing this with the 1133 * hardware people - not sure if it can happen on any illegal 1134 * instruction or only on FP instructions, whether there is a 1135 * pattern to occurrences etc. -dgibson 31/Mar/2003 1136 */ | 1158 /* (reason & REASON_ILLEGAL) would be the obvious thing here, 1159 * but there seems to be a hardware bug on the 405GP (RevD) 1160 * that means ESR is sometimes set incorrectly - either to 1161 * ESR_DST (!?) or 0. In the process of chasing this with the 1162 * hardware people - not sure if it can happen on any illegal 1163 * instruction or only on FP instructions, whether there is a 1164 * pattern to occurrences etc. -dgibson 31/Mar/2003 1165 */ |
1137 switch (do_mathemu(regs)) { 1138 case 0: 1139 emulate_single_step(regs); | 1166 if (!emulate_math(regs)) |
1140 goto bail; | 1167 goto bail; |
1141 case 1: { 1142 int code = 0; 1143 code = __parse_fpscr(current->thread.fpscr.val); 1144 _exception(SIGFPE, regs, code, regs->nip); 1145 goto bail; 1146 } 1147 case -EFAULT: 1148 _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); 1149 goto bail; 1150 } 1151 /* fall through on any other errors */ 1152#endif /* CONFIG_MATH_EMULATION */ | |
1153 1154 /* Try to emulate it if we should. */ 1155 if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { 1156 switch (emulate_instruction(regs)) { 1157 case 0: 1158 regs->nip += 4; 1159 emulate_single_step(regs); 1160 goto bail; --- 262 unchanged lines hidden (view full) --- 1423 __get_cpu_var(irq_stat).pmu_irqs++; 1424 1425 perf_irq(regs); 1426} 1427 1428#ifdef CONFIG_8xx 1429void SoftwareEmulation(struct pt_regs *regs) 1430{ | 1168 1169 /* Try to emulate it if we should. */ 1170 if (reason & (REASON_ILLEGAL | REASON_PRIVILEGED)) { 1171 switch (emulate_instruction(regs)) { 1172 case 0: 1173 regs->nip += 4; 1174 emulate_single_step(regs); 1175 goto bail; --- 262 unchanged lines hidden (view full) --- 1438 __get_cpu_var(irq_stat).pmu_irqs++; 1439 1440 perf_irq(regs); 1441} 1442 1443#ifdef CONFIG_8xx 1444void SoftwareEmulation(struct pt_regs *regs) 1445{ |
1431 extern int do_mathemu(struct pt_regs *); 1432#if defined(CONFIG_MATH_EMULATION) 1433 int errcode; 1434#endif 1435 | |
1436 CHECK_FULL_REGS(regs); 1437 1438 if (!user_mode(regs)) { 1439 debugger(regs); 1440 die("Kernel Mode Software FPU Emulation", regs, SIGFPE); 1441 } 1442 | 1446 CHECK_FULL_REGS(regs); 1447 1448 if (!user_mode(regs)) { 1449 debugger(regs); 1450 die("Kernel Mode Software FPU Emulation", regs, SIGFPE); 1451 } 1452 |
1443#ifdef CONFIG_MATH_EMULATION 1444 errcode = do_mathemu(regs); 1445 if (errcode >= 0) 1446 PPC_WARN_EMULATED(math, regs); 1447 1448 switch (errcode) { 1449 case 0: 1450 emulate_single_step(regs); | 1453 if (!emulate_math(regs)) |
1451 return; | 1454 return; |
1452 case 1: { 1453 int code = 0; 1454 code = __parse_fpscr(current->thread.fpscr.val); 1455 _exception(SIGFPE, regs, code, regs->nip); 1456 return; 1457 } 1458 case -EFAULT: 1459 _exception(SIGSEGV, regs, SEGV_MAPERR, regs->nip); 1460 return; 1461 default: 1462 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); 1463 return; 1464 } 1465#else | 1455 |
1466 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); | 1456 _exception(SIGILL, regs, ILL_ILLOPC, regs->nip); |
1467#endif | |
1468} 1469#endif /* CONFIG_8xx */ 1470 1471#ifdef CONFIG_PPC_ADV_DEBUG_REGS 1472static void handle_debug(struct pt_regs *regs, unsigned long debug_status) 1473{ 1474 int changed = 0; 1475 /* --- 392 unchanged lines hidden --- | 1457} 1458#endif /* CONFIG_8xx */ 1459 1460#ifdef CONFIG_PPC_ADV_DEBUG_REGS 1461static void handle_debug(struct pt_regs *regs, unsigned long debug_status) 1462{ 1463 int changed = 0; 1464 /* --- 392 unchanged lines hidden --- |