On 10/12/26 16:52, Alex Bennée wrote:
diff --git a/target/arm/tcg/op_helper.c b/target/arm/tcg/op_helper.c
index af56eff9f18..7c1fdab79d7 100644
--- a/target/arm/tcg/op_helper.c
+++ b/target/arm/tcg/op_helper.c
@@ -471,6 +471,9 @@ void HELPER(wfit)(CPUARMState *env, uint32_t rd)
  void HELPER(sev)(CPUARMState *env)
  {
      CPUState *cs = env_cpu(env);
+
+    BQL_LOCK_GUARD();
+
      CPU_FOREACH(cs) {
          ARMCPU *target_cpu = ARM_CPU(cs);
          target_cpu->env.event_register = true;
Reviewed-by: Paolo Bonzini <[email protected]>

The use of cmpxchg in wfxt_timer_cb is fishy though.

Clearing HALT_WFE should be the task of the target CPU, not the timer. The timer_mod() should be *after* halt_reason(*), and then you can just do a qatomic_read() instead of a cmpxchg(**) in wfxt_timer_cb().

However, I don't understand at all why wfxt_timer_cb needs to set event_register to true. It seems to me that a wfet + wfe sequence, where the first wfet times out, *should* halt again on the second wfe; but as the code is written it doesn't.

I think wfxt_timer_cb only needs to call cpu_interrupt().

Thanks,

Paolo

(*) always, even if the halt reason is not HALT_WFE, if only for consistency

(**) you don't need a lock or acquire/release here, because the timer callback always sees everything that happened before timer_mod(). In a sense, timer_mod() *is* the release operation and starting the callback is the acquire operation.


Reply via email to