mirror of
https://github.com/qemu/qemu.git
synced 2026-07-08 17:46:10 +00:00
Commitb5f8f77271("accel/hvf: Implement WFI without using pselect()") changed hvf_wfi() from blocking the vCPU thread with pselect() to returning EXCP_HLT, intending QEMU's main event loop to handle the idle wait. However, cpu->halted was never set, so cpu_thread_is_idle() always returns false and the vCPU thread spins at 100% CPU per core while the guest is idle. Fix this by: 1. Setting cpu->halted = 1 in hvf_wfi() so the vCPU thread sleeps on halt_cond in qemu_process_cpu_events(). 2. Arming a per-vCPU QEMU_CLOCK_VIRTUAL timer to fire when the guest's virtual timer (CNTV_CVAL_EL0) would expire. This is necessary because HVF only delivers HV_EXIT_REASON_VTIMER_ACTIVATED during hv_vcpu_run(), which is not called while the CPU is halted. The timer callback mirrors the VTIMER_ACTIVATED handler: it raises the vtimer IRQ through the GIC and marks vtimer_masked, causing the interrupt delivery chain to wake the vCPU via qemu_cpu_kick(). 3. Clearing cpu->halted in hvf_arch_vcpu_exec() when cpu_has_work() indicates a pending interrupt, and cancelling the WFI timer. 4. Re-arming the WFI timer from hvf_vm_state_change() on the resume transition for any halted vCPU, since the QEMUTimer is per-instance state and is not migrated. After cpu_synchronize_all_states() the migrated vtimer state is mirrored in env, so we can read CNTV_CTL and CNTV_CVAL from there. If the vtimer has already expired by the time the destination resumes, hvf_wfi_timer_cb() is invoked directly so the halted vCPU is woken up. All wfi_timer handling (allocation, arming, deletion, and the resume re-arm) is gated on !hvf_irqchip_in_kernel(): with the Apple in-kernel vGIC, HVF owns the vtimer and delivers wake-ups itself. Note for stable backports: this commit won't apply to 11.0 as it has changes to handle the hvf in-kernel irqchip support that landed after the 11.0 release. The v3 version of this commit: https://patchew.org/QEMU/20260427195516.46256-1-scottjgo@gmail.com/ should be suitable for 11.0 backporting (it is essentially identical except that it doesn't make the changes conditional on !hvf_irqchip_in_kernel()). Cc: qemu-stable@nongnu.org Fixes:b5f8f77271("accel/hvf: Implement WFI without using pselect()") Signed-off-by: Scott J. Goldman <scottjgo@gmail.com> Reviewed-by: Mohamed Mediouni <mohamed@unpredictable.fr> [PMM: added note about stable backports to commit message] Signed-off-by: Peter Maydell <peter.maydell@linaro.org>