riscv_cpu_update_mip() was called with a zero mask only to re-poll interrupts after updating env->vstime_irq, where the VS timer keeps VSTIP (see 14cb78bfaf4 "target/riscv: Don't clear mask in riscv_cpu_update_mip() for VSTIP"). Move that re-poll to riscv_accel_set_irq(), which now calls riscv_cpu_interrupt() directly for the zero-mask case, and keep the early return for the no-op VSTIP update.
No caller passes a zero mask anymore, so document @mask as non-zero and assert it. AI-used-for: code (prototype) Signed-off-by: Philippe Mathieu-Daudé <[email protected]> --- target/riscv/cpu.h | 2 +- target/riscv/tcg/cpu_helper.c | 6 +++++- target/riscv/time_helper.c | 11 ++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index ad731bf5d34..6173360e407 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -694,7 +694,7 @@ uint64_t riscv_cpu_get_mip(const CPURISCVState *env); /** * riscv_cpu_update_mip: * @env: CPURISCVState - * @mask: Mask of the MIP bits to update + * @mask: Mask of the MIP bits to update (must be non-zero) * @value: New values for the bits set in @mask. * Use BOOL_TO_MASK() for boolean values. * diff --git a/target/riscv/tcg/cpu_helper.c b/target/riscv/tcg/cpu_helper.c index db7f2bd6de7..16b2c486934 100644 --- a/target/riscv/tcg/cpu_helper.c +++ b/target/riscv/tcg/cpu_helper.c @@ -579,8 +579,12 @@ uint64_t riscv_cpu_update_mip(CPURISCVState *env, uint64_t mask, uint64_t value) { uint64_t old; + assert(mask); + /* No need to update mip for VSTIP */ - mask = ((mask == MIP_VSTIP) && env->vstime_irq) ? 0 : mask; + if (mask == MIP_VSTIP && env->vstime_irq) { + return riscv_cpu_get_mip(env); + } BQL_LOCK_GUARD(); diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c index 29bbebb96fc..6bd917383e3 100644 --- a/target/riscv/time_helper.c +++ b/target/riscv/time_helper.c @@ -39,7 +39,16 @@ static void riscv_accel_set_irq(RISCVCPU *cpu, uint64_t mask = irq_or_mask; uint64_t value = level_or_value; - riscv_cpu_update_mip(&cpu->env, mask, value); + if (!mask) { + /* + * The VS timer keeps VSTIP in env->vstime_irq rather than + * in mip, so callers pass a zero mask only to re-poll + * interrupts after updating it. + */ + riscv_cpu_interrupt(&cpu->env); + } else { + riscv_cpu_update_mip(&cpu->env, mask, value); + } } } -- 2.55.0
