Skip to content

Commit 5311599

Browse files
pm215philmd
authored andcommitted
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 <[email protected]> Fixes: 1697837 ("target/riscv: Add M-mode virtual interrupt and IRQ filtering support.") Fixes: 40336d5 ("target/riscv: Add HS-mode virtual interrupt and IRQ filtering support.") Reviewed-by: Daniel Henrique Barboza <[email protected]> Reviewed-by: Richard Henderson <[email protected]> Reviewed-by: Alistair Francis <[email protected]> Message-ID: <[email protected]> Signed-off-by: Philippe Mathieu-Daudé <[email protected]>
1 parent 235560b commit 5311599

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

target/riscv/cpu_helper.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -1802,10 +1802,10 @@ void riscv_cpu_do_interrupt(CPUState *cs)
18021802
bool async = !!(cs->exception_index & RISCV_EXCP_INT_FLAG);
18031803
target_ulong cause = cs->exception_index & RISCV_EXCP_INT_MASK;
18041804
uint64_t deleg = async ? env->mideleg : env->medeleg;
1805-
bool s_injected = env->mvip & (1 << cause) & env->mvien &&
1806-
!(env->mip & (1 << cause));
1807-
bool vs_injected = env->hvip & (1 << cause) & env->hvien &&
1808-
!(env->mip & (1 << cause));
1805+
bool s_injected = env->mvip & (1ULL << cause) & env->mvien &&
1806+
!(env->mip & (1ULL << cause));
1807+
bool vs_injected = env->hvip & (1ULL << cause) & env->hvien &&
1808+
!(env->mip & (1ULL << cause));
18091809
target_ulong tval = 0;
18101810
target_ulong tinst = 0;
18111811
target_ulong htval = 0;

0 commit comments

Comments
 (0)