aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Rutland <mark.rutland@arm.com>2014-11-18 07:16:30 -0500
committerMark Rutland <mark.rutland@arm.com>2015-01-15 07:24:22 -0500
commit60a1f02c9e91e0796b54e83b14fb8a07f7a568b6 (patch)
treee830e324106f707c0b51a048336e3cfea5cbc640
parentaed40e0144bdbdadb45f2b623e07aa3157eb74c9 (diff)
arm64: decode ESR_ELx.EC when reporting exceptions
To aid the developer when something triggers an unexpected exception, decode the ESR_ELx.EC field when logging an ESR_ELx value. This doesn't tell the developer the specifics of the exception encoded in the remaining IL and ISS bits, but it can be helpful to distinguish between exception classes (e.g. SError and a data abort) without having to manually decode the field, which can be tiresome. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Acked-by: Catalin Marinas <catalin.marinas@arm.com> Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Cc: Marc Zyngier <marc.zyngier@arm.com> Cc: Peter Maydell <peter.maydell@linaro.org> Cc: Will Deacon <will.deacon@arm.com>
-rw-r--r--arch/arm64/include/asm/esr.h6
-rw-r--r--arch/arm64/kernel/traps.c50
2 files changed, 54 insertions, 2 deletions
diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h
index 0fd1b0e15ea8..c315543d50f9 100644
--- a/arch/arm64/include/asm/esr.h
+++ b/arch/arm64/include/asm/esr.h
@@ -133,4 +133,10 @@
133#define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT) 133#define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT)
134#define ESR_ELx_WFx_ISS_WFE (UL(1) << 0) 134#define ESR_ELx_WFx_ISS_WFE (UL(1) << 0)
135 135
136#ifndef __ASSEMBLY__
137#include <asm/types.h>
138
139const char *esr_get_class_string(u32 esr);
140#endif /* __ASSEMBLY */
141
136#endif /* __ASM_ESR_H */ 142#endif /* __ASM_ESR_H */
diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c
index 0a801e3743d5..1ef2940df13c 100644
--- a/arch/arm64/kernel/traps.c
+++ b/arch/arm64/kernel/traps.c
@@ -33,6 +33,7 @@
33 33
34#include <asm/atomic.h> 34#include <asm/atomic.h>
35#include <asm/debug-monitors.h> 35#include <asm/debug-monitors.h>
36#include <asm/esr.h>
36#include <asm/traps.h> 37#include <asm/traps.h>
37#include <asm/stacktrace.h> 38#include <asm/stacktrace.h>
38#include <asm/exception.h> 39#include <asm/exception.h>
@@ -373,6 +374,51 @@ asmlinkage long do_ni_syscall(struct pt_regs *regs)
373 return sys_ni_syscall(); 374 return sys_ni_syscall();
374} 375}
375 376
377static const char *esr_class_str[] = {
378 [0 ... ESR_ELx_EC_MAX] = "UNRECOGNIZED EC",
379 [ESR_ELx_EC_UNKNOWN] = "Unknown/Uncategorized",
380 [ESR_ELx_EC_WFx] = "WFI/WFE",
381 [ESR_ELx_EC_CP15_32] = "CP15 MCR/MRC",
382 [ESR_ELx_EC_CP15_64] = "CP15 MCRR/MRRC",
383 [ESR_ELx_EC_CP14_MR] = "CP14 MCR/MRC",
384 [ESR_ELx_EC_CP14_LS] = "CP14 LDC/STC",
385 [ESR_ELx_EC_FP_ASIMD] = "ASIMD",
386 [ESR_ELx_EC_CP10_ID] = "CP10 MRC/VMRS",
387 [ESR_ELx_EC_CP14_64] = "CP14 MCRR/MRRC",
388 [ESR_ELx_EC_ILL] = "PSTATE.IL",
389 [ESR_ELx_EC_SVC32] = "SVC (AArch32)",
390 [ESR_ELx_EC_HVC32] = "HVC (AArch32)",
391 [ESR_ELx_EC_SMC32] = "SMC (AArch32)",
392 [ESR_ELx_EC_SVC64] = "SVC (AArch64)",
393 [ESR_ELx_EC_HVC64] = "HVC (AArch64)",
394 [ESR_ELx_EC_SMC64] = "SMC (AArch64)",
395 [ESR_ELx_EC_SYS64] = "MSR/MRS (AArch64)",
396 [ESR_ELx_EC_IMP_DEF] = "EL3 IMP DEF",
397 [ESR_ELx_EC_IABT_LOW] = "IABT (lower EL)",
398 [ESR_ELx_EC_IABT_CUR] = "IABT (current EL)",
399 [ESR_ELx_EC_PC_ALIGN] = "PC Alignment",
400 [ESR_ELx_EC_DABT_LOW] = "DABT (lower EL)",
401 [ESR_ELx_EC_DABT_CUR] = "DABT (current EL)",
402 [ESR_ELx_EC_SP_ALIGN] = "SP Alignment",
403 [ESR_ELx_EC_FP_EXC32] = "FP (AArch32)",
404 [ESR_ELx_EC_FP_EXC64] = "FP (AArch64)",
405 [ESR_ELx_EC_SERROR] = "SError",
406 [ESR_ELx_EC_BREAKPT_LOW] = "Breakpoint (lower EL)",
407 [ESR_ELx_EC_BREAKPT_CUR] = "Breakpoint (current EL)",
408 [ESR_ELx_EC_SOFTSTP_LOW] = "Software Step (lower EL)",
409 [ESR_ELx_EC_SOFTSTP_CUR] = "Software Step (current EL)",
410 [ESR_ELx_EC_WATCHPT_LOW] = "Watchpoint (lower EL)",
411 [ESR_ELx_EC_WATCHPT_CUR] = "Watchpoint (current EL)",
412 [ESR_ELx_EC_BKPT32] = "BKPT (AArch32)",
413 [ESR_ELx_EC_VECTOR32] = "Vector catch (AArch32)",
414 [ESR_ELx_EC_BRK64] = "BRK (AArch64)",
415};
416
417const char *esr_get_class_string(u32 esr)
418{
419 return esr_class_str[esr >> ESR_ELx_EC_SHIFT];
420}
421
376/* 422/*
377 * bad_mode handles the impossible case in the exception vector. 423 * bad_mode handles the impossible case in the exception vector.
378 */ 424 */
@@ -382,8 +428,8 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
382 void __user *pc = (void __user *)instruction_pointer(regs); 428 void __user *pc = (void __user *)instruction_pointer(regs);
383 console_verbose(); 429 console_verbose();
384 430
385 pr_crit("Bad mode in %s handler detected, code 0x%08x\n", 431 pr_crit("Bad mode in %s handler detected, code 0x%08x -- %s\n",
386 handler[reason], esr); 432 handler[reason], esr, esr_get_class_string(esr));
387 __show_regs(regs); 433 __show_regs(regs);
388 434
389 info.si_signo = SIGILL; 435 info.si_signo = SIGILL;