target/riscv: add trace in riscv_raise_exception()

When using system mode we can get the CPU traps being taken via the
'riscv_trap' trace or the "-d int" qemu log. User mode does not a way of
logging/showing exceptions to users.

Add a trace in riscv_raise_exception() to allow qemu-riscv(32/64) users
to check all exceptions being thrown. This is particularly useful to
help identifying insns that are throwing SIGILLs.

As it is today we need to debug their binaries to identify where the
illegal insns are:

$ ~/work/qemu/build/qemu-riscv64 -cpu rv64 ./foo.out
Illegal instruction (core dumped)

After this change users can capture the trace and use EPC to pinpoint
the insn:

$ ~/work/qemu/build/qemu-riscv64 -cpu rv64 -trace riscv_exception ./foo.out
riscv_exception 8 (user_ecall) on epc 0x17cd2
riscv_exception 8 (user_ecall) on epc 0x17cda
riscv_exception 8 (user_ecall) on epc 0x17622
(...)
riscv_exception 2 (illegal_instruction) on epc 0x1053a
Illegal instruction (core dumped)

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20250106173734.412353-3-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Daniel Henrique Barboza 2025-01-06 14:37:34 -03:00 committed by Alistair Francis
parent e2dca2dc5a
commit 8f1a128942
2 changed files with 9 additions and 0 deletions

View File

@ -24,6 +24,7 @@
#include "exec/exec-all.h" #include "exec/exec-all.h"
#include "exec/cpu_ldst.h" #include "exec/cpu_ldst.h"
#include "exec/helper-proto.h" #include "exec/helper-proto.h"
#include "trace.h"
/* Exceptions processing helpers */ /* Exceptions processing helpers */
G_NORETURN void riscv_raise_exception(CPURISCVState *env, G_NORETURN void riscv_raise_exception(CPURISCVState *env,
@ -31,6 +32,11 @@ G_NORETURN void riscv_raise_exception(CPURISCVState *env,
uintptr_t pc) uintptr_t pc)
{ {
CPUState *cs = env_cpu(env); CPUState *cs = env_cpu(env);
trace_riscv_exception(exception,
riscv_cpu_get_trap_name(exception, false),
env->pc);
cs->exception_index = exception; cs->exception_index = exception;
cpu_loop_exit_restore(cs, pc); cpu_loop_exit_restore(cs, pc);
} }

View File

@ -9,3 +9,6 @@ pmpaddr_csr_write(uint64_t mhartid, uint32_t addr_index, uint64_t val) "hart %"
mseccfg_csr_read(uint64_t mhartid, uint64_t val) "hart %" PRIu64 ": read mseccfg, val: 0x%" PRIx64 mseccfg_csr_read(uint64_t mhartid, uint64_t val) "hart %" PRIu64 ": read mseccfg, val: 0x%" PRIx64
mseccfg_csr_write(uint64_t mhartid, uint64_t val) "hart %" PRIu64 ": write mseccfg, val: 0x%" PRIx64 mseccfg_csr_write(uint64_t mhartid, uint64_t val) "hart %" PRIu64 ": write mseccfg, val: 0x%" PRIx64
# op_helper.c
riscv_exception(uint32_t exception, const char *desc, uint64_t epc) "%u (%s) on epc 0x%"PRIx64""