Make riscv_cpu_get_mip() read env->mip with qatomic_read() and riscv_cpu_update_mip() store it with qatomic_set(). This makes MIP reads and writes safe for riscv_cpu_has_work(), which may run without the BQL.
Reported-by: Paolo Bonzini <[email protected]> Signed-off-by: Philippe Mathieu-Daudé <[email protected]> Reviewed-by: Richard Henderson <[email protected]> --- target/riscv/cpu.c | 3 ++- target/riscv/tcg/cpu_helper.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index b8d6f992ba4..45e82fc30c5 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -22,6 +22,7 @@ #include "qemu/ctype.h" #include "qemu/log.h" #include "qemu/guest-random.h" +#include "qemu/atomic.h" #include "cpu.h" #include "cpu_vendorid.h" #include "target/riscv/tcg/csr.h" @@ -956,7 +957,7 @@ int riscv_cpu_vsirq_pending(CPURISCVState *env) uint64_t riscv_cpu_get_mip(const CPURISCVState *env) { - return env->mip; + return qatomic_read(&env->mip); } bool riscv_cpu_has_work(CPUState *cs) diff --git a/target/riscv/tcg/cpu_helper.c b/target/riscv/tcg/cpu_helper.c index f8f779a01d8..db7f2bd6de7 100644 --- a/target/riscv/tcg/cpu_helper.c +++ b/target/riscv/tcg/cpu_helper.c @@ -20,6 +20,7 @@ #include "qemu/osdep.h" #include "qemu/log.h" #include "qemu/main-loop.h" +#include "qemu/atomic.h" #include "cpu.h" #include "internals.h" #include "pmu.h" @@ -584,7 +585,7 @@ uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask, uint64_t value) BQL_LOCK_GUARD(); old = riscv_cpu_get_mip(env); - env->mip = (old & ~mask) | (value & mask); + qatomic_set(&env->mip, (old & ~mask) | (value & mask)); riscv_cpu_interrupt(env); -- 2.55.0
