This fixes the sti followed by hlt kvm_unit_tests.
Signed-off-by: Mohamed Mediouni <[email protected]>
---
target/i386/whpx/whpx-all.c | 49 ++++++++++++++++---------------------
1 file changed, 21 insertions(+), 28 deletions(-)
diff --git a/target/i386/whpx/whpx-all.c b/target/i386/whpx/whpx-all.c
index 6d2771a98a..90f51fc4dd 100644
--- a/target/i386/whpx/whpx-all.c
+++ b/target/i386/whpx/whpx-all.c
@@ -1308,6 +1308,16 @@ static int whpx_handle_halt(CPUState *cpu)
return ret;
}
+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_pre_run(CPUState *cpu)
{
HRESULT hr;
@@ -1391,6 +1401,17 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
.Vector = irq,
};
reg_count += 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.
+ */
+ if (whpx_irqchip_in_kernel()) {
+ whpx_vcpu_kick_out_of_hlt(cpu);
+ }
}
}
@@ -1453,15 +1474,6 @@ 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)
{
@@ -1770,25 +1782,6 @@ 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};
--
2.50.1 (Apple Git-155)