diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2023-05-07 16:18:17 -0700 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2023-06-24 06:34:27 -0700 |
commit | f7667ca106df50ff8b776db54f85074dc9c52e1b (patch) | |
tree | 9bee827b7df376837359c2591bd8499b2008fe14 /arch/xtensa | |
parent | cc34f2909d2fbc8f52d24b20f6cbedcdf477e049 (diff) |
xtensa: dump userspace code around the exception PC
In the absence of other debug facilities dumping user code around the
unhandled exception address may help debugging the issue.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'arch/xtensa')
-rw-r--r-- | arch/xtensa/Kconfig.debug | 8 | ||||
-rw-r--r-- | arch/xtensa/kernel/traps.c | 18 |
2 files changed, 26 insertions, 0 deletions
diff --git a/arch/xtensa/Kconfig.debug b/arch/xtensa/Kconfig.debug index 83cc8d12fa0e..e84172a7763c 100644 --- a/arch/xtensa/Kconfig.debug +++ b/arch/xtensa/Kconfig.debug @@ -38,3 +38,11 @@ config PRINT_STACK_DEPTH help This option allows you to set the stack depth that the kernel prints in stack traces. + +config PRINT_USER_CODE_ON_UNHANDLED_EXCEPTION + bool "Dump user code around unhandled exception address" + help + Enable this option to display user code around PC of the unhandled + exception (starting at address aligned on 16 byte boundary). + This may simplify finding faulting code in the absence of other + debug facilities. diff --git a/arch/xtensa/kernel/traps.c b/arch/xtensa/kernel/traps.c index a2a9a460ec9e..17eb180eff7c 100644 --- a/arch/xtensa/kernel/traps.c +++ b/arch/xtensa/kernel/traps.c @@ -175,6 +175,23 @@ __die_if_kernel(const char *str, struct pt_regs *regs, long err) die(str, regs, err); } +#ifdef CONFIG_PRINT_USER_CODE_ON_UNHANDLED_EXCEPTION +static inline void dump_user_code(struct pt_regs *regs) +{ + char buf[32]; + + if (copy_from_user(buf, (void __user *)(regs->pc & -16), sizeof(buf)) == 0) { + print_hex_dump(KERN_INFO, " ", DUMP_PREFIX_NONE, + 32, 1, buf, sizeof(buf), false); + + } +} +#else +static inline void dump_user_code(struct pt_regs *regs) +{ +} +#endif + /* * Unhandled Exceptions. Kill user task or panic if in kernel space. */ @@ -190,6 +207,7 @@ void do_unhandled(struct pt_regs *regs) "\tEXCCAUSE is %ld\n", current->comm, task_pid_nr(current), regs->pc, regs->exccause); + dump_user_code(regs); force_sig(SIGILL); } |