diff options
Diffstat (limited to 'arch/arm64/kernel/traps.c')
-rw-r--r-- | arch/arm64/kernel/traps.c | 50 |
1 files changed, 48 insertions, 2 deletions
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 | ||
377 | static 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 | |||
417 | const 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; |