From: Mohamed Mediouni Date: Thu, 26 Feb 2026 18:19:29 +0000 (+0100) Subject: whpx: x86: kick out of HLT manually when using the kernel-irqchip X-Git-Tag: v11.0.0-rc0~43^2~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ca7a6add3bd20267f124ea8bed4391da8ee8e253;p=thirdparty%2Fqemu.git whpx: x86: kick out of HLT manually when using the kernel-irqchip Otherwise, interrupts processed through the cancel vCPU and inject path will not cause the vCPU to go out of its halt state. Signed-off-by: Mohamed Mediouni Link: https://lore.kernel.org/r/20260226181930.53170-3-mohamed@unpredictable.fr Signed-off-by: Paolo Bonzini --- diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c index cfc63065807..51ecc9531fe 100644 --- a/target/i386/whpx/whpx-all.c +++ b/target/i386/whpx/whpx-all.c @@ -1468,6 +1468,16 @@ static void whpx_vcpu_post_run(CPUState *cpu) !vcpu->exit_ctx.VpContext.ExecutionState.InterruptShadow; } +static void whpx_vcpu_kick_out_of_hlt(CPUState *cpu) +{ + WHV_REGISTER_VALUE reg; + whpx_get_reg(cpu, WHvRegisterInternalActivityState, ®); + if (reg.InternalActivity.HaltSuspend) { + reg.InternalActivity.HaltSuspend = 0; + whpx_set_reg(cpu, WHvRegisterInternalActivityState, reg); + } +} + static void whpx_vcpu_process_async_events(CPUState *cpu) { X86CPU *x86_cpu = X86_CPU(cpu); @@ -1775,6 +1785,25 @@ int whpx_vcpu_run(CPUState *cpu) cpu->exception_index = EXCP_INTERRUPT; ret = 1; } + /* + * When the Hyper-V APIC is enabled, to get out of HLT we + * either have to request an interrupt or manually get it away + * from HLT. + * + * We also manually do inject some interrupts via WHvRegisterPendingEvent + * instead of WHVRequestInterrupt, which does not reset the HLT state. + * + * However, even with this done, if the guest does an HLT without + * interrupts enabled (which the test_sti_inhibit KVM unit test does) + * then the guest will stay in HLT forever. + * + * Keep it this way for now, with perhaps adding a heartbeat later + * so that we get the CPU time savings from having Hyper-V handle HLT + * instead of going away from it as soon as possible. + */ + if (whpx_irqchip_in_kernel()) { + whpx_vcpu_kick_out_of_hlt(cpu); + } break; case WHvRunVpExitReasonX64MsrAccess: { WHV_REGISTER_VALUE reg_values[3] = {0};