@samitouri / QOSamiQemu / commits / ca7a6add3b

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 <mohamed@unpredictable.fr> Link: https://lore.kernel.org/r/20260226181930.53170-3-mohamed@unpredictable.fr Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Mohamed Mediouni committed Feb 26, 2026 at 19:19 UTC ca7a6add3bd20267f124ea8bed4391da8ee8e253
1 file changed +29
target/i386/whpx/whpx-all.c
+29
@@ -1468,6 +1468,16 @@ static void whpx_vcpu_post_run(CPUState *cpu)
1468 !vcpu->exit_ctx.VpContext.ExecutionState.InterruptShadow;
1469 }
1470
1471 +static void whpx_vcpu_kick_out_of_hlt(CPUState *cpu)
1472 +{
1473 + WHV_REGISTER_VALUE reg;
1474 + whpx_get_reg(cpu, WHvRegisterInternalActivityState, &reg);
1475 + if (reg.InternalActivity.HaltSuspend) {
1476 + reg.InternalActivity.HaltSuspend = 0;
1477 + whpx_set_reg(cpu, WHvRegisterInternalActivityState, reg);
1478 + }
1479 +}
1480 +
1481 static void whpx_vcpu_process_async_events(CPUState *cpu)
1482 {
1483 X86CPU *x86_cpu = X86_CPU(cpu);
@@ -1775,6 +1785,25 @@ int whpx_vcpu_run(CPUState *cpu)
1785 cpu->exception_index = EXCP_INTERRUPT;
1786 ret = 1;
1787 }
1788 + /*
1789 + * When the Hyper-V APIC is enabled, to get out of HLT we
1790 + * either have to request an interrupt or manually get it away
1791 + * from HLT.
1792 + *
1793 + * We also manually do inject some interrupts via WHvRegisterPendingEvent
1794 + * instead of WHVRequestInterrupt, which does not reset the HLT state.
1795 + *
1796 + * However, even with this done, if the guest does an HLT without
1797 + * interrupts enabled (which the test_sti_inhibit KVM unit test does)
1798 + * then the guest will stay in HLT forever.
1799 + *
1800 + * Keep it this way for now, with perhaps adding a heartbeat later
1801 + * so that we get the CPU time savings from having Hyper-V handle HLT
1802 + * instead of going away from it as soon as possible.
1803 + */
1804 + if (whpx_irqchip_in_kernel()) {
1805 + whpx_vcpu_kick_out_of_hlt(cpu);
1806 + }
1807 break;
1808 case WHvRunVpExitReasonX64MsrAccess: {
1809 WHV_REGISTER_VALUE reg_values[3] = {0};