diff options
author | Palmer Dabbelt <palmer@rivosinc.com> | 2023-02-21 16:53:58 -0800 |
---|---|---|
committer | Palmer Dabbelt <palmer@rivosinc.com> | 2023-02-21 17:21:51 -0800 |
commit | b19aa282c50344bbac8e50592b21bac624c51d5d (patch) | |
tree | f9a60e4f136450a521d25ce02be92dd7fdf5c653 /arch | |
parent | 91612cfb173619b38087449cd3811f9cb4420d94 (diff) | |
parent | 00b242509c8f2b9041c4c16d67d51eae3c9ab1d9 (diff) |
Merge patch series "riscv: Dump faulting instructions in oops handler"
Björn Töpel <bjorn@kernel.org> says:
From: Björn Töpel <bjorn@rivosinc.com>
RISC-V does not dump faulting instructions in the oops handler. This
series adds "Code:" dumps to the oops output together with
scripts/decodecode support.
* b4-shazam-merge:
scripts/decodecode: Add support for RISC-V
riscv: Add instruction dump to RISC-V splats
Link: https://lore.kernel.org/r/20230119074738.708301-1-bjorn@kernel.org
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/riscv/kernel/traps.c | 25 |
1 files changed, 24 insertions, 1 deletions
diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index 70c98ce23be2..f6fda94e8e59 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -29,6 +29,27 @@ int show_unhandled_signals = 1; static DEFINE_SPINLOCK(die_lock); +static void dump_kernel_instr(const char *loglvl, struct pt_regs *regs) +{ + char str[sizeof("0000 ") * 12 + 2 + 1], *p = str; + const u16 *insns = (u16 *)instruction_pointer(regs); + long bad; + u16 val; + int i; + + for (i = -10; i < 2; i++) { + bad = get_kernel_nofault(val, &insns[i]); + if (!bad) { + p += sprintf(p, i == 0 ? "(%04hx) " : "%04hx ", val); + } else { + printk("%sCode: Unable to access instruction at 0x%px.\n", + loglvl, &insns[i]); + return; + } + } + printk("%sCode: %s\n", loglvl, str); +} + void die(struct pt_regs *regs, const char *str) { static int die_counter; @@ -44,8 +65,10 @@ void die(struct pt_regs *regs, const char *str) pr_emerg("%s [#%d]\n", str, ++die_counter); print_modules(); - if (regs) + if (regs) { show_regs(regs); + dump_kernel_instr(KERN_EMERG, regs); + } cause = regs ? regs->cause : -1; ret = notify_die(DIE_OOPS, str, regs, 0, cause, SIGSEGV); |