!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);
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};