From: Frédéric Pétrot <[email protected]> UndefinedBehaviorSanitizer reports an undefined behavior when setting the Interrupt flag (msb) in the [ms]cause registers due to an out of bounds shift. We specifically correct these cases, leaving the ones depending on specific extensions untouched.
Reported-by: Peter Maydell <[email protected]> Signed-off-by: Frédéric Pétrot <[email protected]> --- target/riscv/cpu.h | 2 ++ target/riscv/tcg/cpu_helper.c | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index b65d631994..17bfcf38c0 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -354,10 +354,12 @@ struct CPUArchState { uint64_t stvec; uint64_t sepc; uint64_t scause; + uint64_t scauseh; uint64_t mtvec; uint64_t mepc; uint64_t mcause; + uint64_t mcauseh; uint64_t mtval; /* since: priv-1.10.0 */ uint64_t mctrctl; diff --git a/target/riscv/tcg/cpu_helper.c b/target/riscv/tcg/cpu_helper.c index 58e98e975c..b35b61dc01 100644 --- a/target/riscv/tcg/cpu_helper.c +++ b/target/riscv/tcg/cpu_helper.c @@ -2375,7 +2375,12 @@ void riscv_cpu_do_interrupt(CPUState *cs) } env->mstatus = s; sxlen = 16 << riscv_cpu_sxl(env); - env->scause = cause | ((target_ulong)async << (sxlen - 1)); + if (riscv_cpu_sxl(env) != MXL_RV128) { + env->scause = cause | ((target_ulong)async << (sxlen - 1)); + } else { + env->scause = cause; + env->scauseh = (target_ulong)async << 63; + } env->sepc = env->pc; env->stval = tval; env->htval = htval; @@ -2447,7 +2452,12 @@ void riscv_cpu_do_interrupt(CPUState *cs) s = set_field(s, MSTATUS_MDT, 1); } env->mstatus = s; - env->mcause = cause | ((target_ulong)async << (mxlen - 1)); + if (riscv_cpu_mxl(env) != MXL_RV128) { + env->mcause = cause | ((target_ulong)async << (mxlen - 1)); + } else { + env->mcause = cause; + env->mcauseh = (target_ulong)async << 63; + } if (smode_double_trap) { env->mtval2 = env->mcause; env->mcause = RISCV_EXCP_DOUBLE_TRAP; -- 2.43.0
