@samitouri / QOSamiQemu / commits / 480681f916

whpx: i386: add HV_X64_MSR_GUEST_IDLE when !kernel-irqchip

Add support for an oddball HV_X64_MSR_GUEST_IDLE not-quite-an-HLT that wakes the vCPU even if EFLAGS.IF is set. Signed-off-by: Mohamed Mediouni <mohamed@unpredictable.fr> Link: https://lore.kernel.org/r/20260422214225.2242-23-mohamed@unpredictable.fr Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

Mohamed Mediouni committed Apr 22, 2026 at 23:42 UTC 480681f91608454ee1bdf925231335e4c7e3435c
1 file changed +26 -1
target/i386/whpx/whpx-all.c
+26 -1
@@ -52,6 +52,7 @@
52 /* for kernel-irqchip=off */
53 #define HV_X64_MSR_APIC_FREQUENCY 0x40000023
54 #define HV_X64_MSR_VP_ASSIST_PAGE 0x40000073
55 +#define HV_X64_MSR_GUEST_IDLE 0x400000f0
56
57 static bool is_modern_os = true;
58
@@ -1648,6 +1649,15 @@ static int whpx_handle_halt(CPUState *cpu)
1649 return ret;
1650 }
1651
1652 +static int whpx_handle_hyperv_guestidle(CPUState *cpu)
1653 +{
1654 + X86CPU *x86_cpu = X86_CPU(cpu);
1655 + CPUX86State *env = &x86_cpu->env;
1656 +
1657 + env->hflags2 |= HF2_HYPERV_HLT_MASK;
1658 + return whpx_handle_halt(cpu);
1659 +}
1660 +
1661 static void whpx_vcpu_kick_out_of_hlt(CPUState *cpu)
1662 {
1663 WHV_REGISTER_VALUE reg;
@@ -1851,9 +1861,10 @@ static void whpx_vcpu_process_async_events(CPUState *cpu)
1861 }
1862
1863 if ((cpu_test_interrupt(cpu, CPU_INTERRUPT_HARD) &&
1854 - (env->eflags & IF_MASK)) ||
1864 + ((env->eflags & IF_MASK) || (env->hflags2 & HF2_HYPERV_HLT_MASK))) ||
1865 cpu_test_interrupt(cpu, CPU_INTERRUPT_NMI)) {
1866 cpu->halted = false;
1867 + env->hflags2 &= ~HF2_HYPERV_HLT_MASK;
1868 }
1869
1870 if (cpu_test_interrupt(cpu, CPU_INTERRUPT_SIPI)) {
@@ -2128,6 +2139,20 @@ int whpx_vcpu_run(CPUState *cpu)
2139 }
2140 }
2141
2142 + /*
2143 + * Windows and Linux both use this MSR.
2144 + * Windows 11 25H2 uses it even when not advertised.
2145 + */
2146 + if (vcpu->exit_ctx.MsrAccess.MsrNumber == HV_X64_MSR_GUEST_IDLE
2147 + && !vcpu->exit_ctx.MsrAccess.AccessInfo.IsWrite
2148 + && !whpx_irqchip_in_kernel()
2149 + && whpx->hyperv_enlightenments_enabled) {
2150 + is_known_msr = 1;
2151 + whpx_bump_rip(cpu, &vcpu->exit_ctx);
2152 + ret = whpx_handle_hyperv_guestidle(cpu);
2153 + break;
2154 + }
2155 +
2156 /*
2157 * Linux tries to use it anyway even when not exposed.
2158 * Ignore the write as the VP assist page is not used.