diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2024-11-28 10:38:31 +0000 |
---|---|---|
committer | Philippe Mathieu-Daudé <philmd@linaro.org> | 2024-12-03 12:26:24 +0100 |
commit | 5311599cdc48337f2f27b1b51a80d46d75b05ed0 (patch) | |
tree | 394dfc74114dab973711c36b012222b55720f326 /target | |
parent | 235560b3a771f4bc05cf3e1c267ba8e7451576ee (diff) | |
download | qemu-5311599cdc48337f2f27b1b51a80d46d75b05ed0.zip qemu-5311599cdc48337f2f27b1b51a80d46d75b05ed0.tar.gz qemu-5311599cdc48337f2f27b1b51a80d46d75b05ed0.tar.bz2 |
target/riscv: Avoid bad shift in riscv_cpu_do_interrupt()
In riscv_cpu_do_interrupt() we use the 'cause' value we got out of
cs->exception as a shift value. However this value can be larger
than 31, which means that "1 << cause" is undefined behaviour,
because we do the shift on an 'int' type.
This causes the undefined behaviour sanitizer to complain
on one of the check-tcg tests:
$ UBSAN_OPTIONS=print_stacktrace=1:abort_on_error=1:halt_on_error=1 ./build/clang/qemu-system-riscv64 -M virt -semihosting -display none -device loader,file=build/clang/tests/tcg/riscv64-softmmu/issue1060
../../target/riscv/cpu_helper.c:1805:38: runtime error: shift exponent 63 is too large for 32-bit type 'int'
#0 0x55f2dc026703 in riscv_cpu_do_interrupt /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/clang/../../target/riscv/cpu_helper.c:1805:38
#1 0x55f2dc3d170e in cpu_handle_exception /mnt/nvmedisk/linaro/qemu-from-laptop/qemu/build/clang/../../accel/tcg/cpu-exec.c:752:9
In this case cause is RISCV_EXCP_SEMIHOST, which is 0x3f.
Use 1ULL instead to ensure that the shift is in range.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Fixes: 1697837ed9 ("target/riscv: Add M-mode virtual interrupt and IRQ filtering support.")
Fixes: 40336d5b1d ("target/riscv: Add HS-mode virtual interrupt and IRQ filtering support.")
Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20241128103831.3452572-1-peter.maydell@linaro.org>
Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Diffstat (limited to 'target')
-rw-r--r-- | target/riscv/cpu_helper.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index 0a3ead6..45806f5 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -1802,10 +1802,10 @@ void riscv_cpu_do_interrupt(CPUState *cs) bool async = !!(cs->exception_index & RISCV_EXCP_INT_FLAG); target_ulong cause = cs->exception_index & RISCV_EXCP_INT_MASK; uint64_t deleg = async ? env->mideleg : env->medeleg; - bool s_injected = env->mvip & (1 << cause) & env->mvien && - !(env->mip & (1 << cause)); - bool vs_injected = env->hvip & (1 << cause) & env->hvien && - !(env->mip & (1 << cause)); + bool s_injected = env->mvip & (1ULL << cause) & env->mvien && + !(env->mip & (1ULL << cause)); + bool vs_injected = env->hvip & (1ULL << cause) & env->hvien && + !(env->mip & (1ULL << cause)); target_ulong tval = 0; target_ulong tinst = 0; target_ulong htval = 0; |