Peter Maydell <[email protected]> writes:

> On Fri, 29 May 2026 at 09:29, Alex Bennée <[email protected]> wrote:
>>
>> This series fully models the behaviour of WFxT instructions. We
>> already had support for WFE for M-profile but we left off A-profile as
>> it has more potential sources of wake-ups. The main one is the event
>> stream which includes events from significant bits of the timer
>> ticking over.
>>
>> The refactoring from the previous iterations of the patch have now
>> been merged.
>>
>> I've dropped trying to fully model the global monitor in favour of
>> taking advantage of the architectural flexibility to have an IMPDEF
>> event wake up for any reason. We treat the setting of exclusive_addr
>> as such a reason because it indicates the current vCPU is in a ldstx
>> exclusive region and we don't want the guest to deadlock. This does mean
>> the system won't sleep on WFE enabled locks but people shouldn't be
>> relying on QEMU to model real world sleep patterns anyway given the
>> efficiency of emulation compared to real HW.
>>
>> I've written a test case using kvm-unit-tests:
>>
>>   Message-ID: <[email protected]>
>>   Date: Wed, 27 May 2026 12:18:21 +0100
>>   Subject: [kvm-unit-tests PATCH v2] arm: add wfx test case
>>   From: =?UTF-8?q?Alex=20Benn=C3=A9e?= <[email protected]>
>>
>> All patches are now reviewed.
>
>
>
> Applied to target-arm.next, thanks.

Is it too late to drop them? I've a fix for 2/8:

--8<---------------cut here---------------start------------->8---
modified    include/hw/core/sysemu-cpu-ops.h
@@ -18,6 +18,9 @@
 typedef struct SysemuCPUOps {
     /**
      * @has_work: Callback for checking if there is work to do.
+     *
+     * This function should be idempotent (i.e. not change state) as
+     * it will likely be queried multiple times before a CPU resumes.
      */
     bool (*has_work)(CPUState *cpu); /* MANDATORY NON-NULL */
     /**
modified    target/arm/cpu.c
@@ -158,7 +158,6 @@ static bool arm_cpu_has_work(CPUState *cs)
      * A wake-up event should only wake us if we are halted on a WFE
      */
     if (cpu->env.halt_reason == HALT_WFE && cpu->env.event_register) {
-        cpu->env.halt_reason = NOT_HALTED;
         return true;
     }
 
@@ -170,7 +169,6 @@ static bool arm_cpu_has_work(CPUState *cs)
                            | CPU_INTERRUPT_NMI | CPU_INTERRUPT_VINMI | 
CPU_INTERRUPT_VFNMI
                            | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ | 
CPU_INTERRUPT_VSERR
                            | CPU_INTERRUPT_EXITTB)) {
-        cpu->env.halt_reason = NOT_HALTED;
         return true;
     }
 
@@ -874,6 +872,8 @@ bool arm_cpu_exec_halt(CPUState *cs)
         if (cpu->wfxt_timer) {
             timer_del(cpu->wfxt_timer);
         }
+        /* clear the halt reason */
+        cpu->env.halt_reason = NOT_HALTED;
     }
     return leave_halt;
 }
--8<---------------cut here---------------end--------------->8---


>
> -- PMM

-- 
Alex Bennée
Virtualisation Tech Lead @ Linaro

Reply via email to