From: Max Filippov Date: Sun, 7 May 2023 23:18:17 +0000 (-0700) Subject: xtensa: dump userspace code around the exception PC X-Git-Tag: v6.5-rc1~192^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f7667ca106df50ff8b776db54f85074dc9c52e1b;p=thirdparty%2Fkernel%2Flinux.git 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 --- diff --git a/arch/xtensa/Kconfig.debug b/arch/xtensa/Kconfig.debug index 83cc8d12fa0e1..e84172a7763c9 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 a2a9a460ec9e6..17eb180eff7c0 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); }