diff options
author | Chris Metcalf <cmetcalf@tilera.com> | 2012-03-30 16:31:08 -0400 |
---|---|---|
committer | Chris Metcalf <cmetcalf@tilera.com> | 2012-05-25 12:48:28 -0400 |
commit | c6f696f69ab352b17f5c97f721e646b53b91f643 (patch) | |
tree | e52ff4c19a69557f1c2b670a2a245f4425406501 /arch/tile | |
parent | 8703d6e0fcfdcc9323d5316a443882e790efc1a6 (diff) |
arch/tile: add descriptive text if the kernel reports a bad trap
If the kernel unexpectedly takes a bad trap, it's convenient to
have it report the type of trap as part of the error. This gives
customers a bit more context before they call up customer support.
Signed-off-by: Chris Metcalf <cmetcalf@tilera.com>
Diffstat (limited to 'arch/tile')
-rw-r--r-- | arch/tile/kernel/traps.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/arch/tile/kernel/traps.c b/arch/tile/kernel/traps.c index 73cff814ac57..5b19a23c8908 100644 --- a/arch/tile/kernel/traps.c +++ b/arch/tile/kernel/traps.c | |||
@@ -195,6 +195,25 @@ static int special_ill(bundle_bits bundle, int *sigp, int *codep) | |||
195 | return 1; | 195 | return 1; |
196 | } | 196 | } |
197 | 197 | ||
198 | static const char *const int_name[] = { | ||
199 | [INT_MEM_ERROR] = "Memory error", | ||
200 | [INT_ILL] = "Illegal instruction", | ||
201 | [INT_GPV] = "General protection violation", | ||
202 | [INT_UDN_ACCESS] = "UDN access", | ||
203 | [INT_IDN_ACCESS] = "IDN access", | ||
204 | #if CHIP_HAS_SN() | ||
205 | [INT_SN_ACCESS] = "SN access", | ||
206 | #endif | ||
207 | [INT_SWINT_3] = "Software interrupt 3", | ||
208 | [INT_SWINT_2] = "Software interrupt 2", | ||
209 | [INT_SWINT_0] = "Software interrupt 0", | ||
210 | [INT_UNALIGN_DATA] = "Unaligned data", | ||
211 | [INT_DOUBLE_FAULT] = "Double fault", | ||
212 | #ifdef __tilegx__ | ||
213 | [INT_ILL_TRANS] = "Illegal virtual address", | ||
214 | #endif | ||
215 | }; | ||
216 | |||
198 | void __kprobes do_trap(struct pt_regs *regs, int fault_num, | 217 | void __kprobes do_trap(struct pt_regs *regs, int fault_num, |
199 | unsigned long reason) | 218 | unsigned long reason) |
200 | { | 219 | { |
@@ -211,10 +230,17 @@ void __kprobes do_trap(struct pt_regs *regs, int fault_num, | |||
211 | * current process and hope for the best. | 230 | * current process and hope for the best. |
212 | */ | 231 | */ |
213 | if (!user_mode(regs)) { | 232 | if (!user_mode(regs)) { |
233 | const char *name; | ||
214 | if (fixup_exception(regs)) /* only UNALIGN_DATA in practice */ | 234 | if (fixup_exception(regs)) /* only UNALIGN_DATA in practice */ |
215 | return; | 235 | return; |
216 | pr_alert("Kernel took bad trap %d at PC %#lx\n", | 236 | if (fault_num >= 0 && |
217 | fault_num, regs->pc); | 237 | fault_num < sizeof(int_name)/sizeof(int_name[0]) && |
238 | int_name[fault_num] != NULL) | ||
239 | name = int_name[fault_num]; | ||
240 | else | ||
241 | name = "Unknown interrupt"; | ||
242 | pr_alert("Kernel took bad trap %d (%s) at PC %#lx\n", | ||
243 | fault_num, name, regs->pc); | ||
218 | if (fault_num == INT_GPV) | 244 | if (fault_num == INT_GPV) |
219 | pr_alert("GPV_REASON is %#lx\n", reason); | 245 | pr_alert("GPV_REASON is %#lx\n", reason); |
220 | show_regs(regs); | 246 | show_regs(regs); |