summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2023-05-08 10:19:01 +0000
committervboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2023-05-08 10:19:01 +0000
commitc207032d166390918e335901f0fd5715b35d646a (patch)
treed4861a35efc92de275e6b1a4e2a98bf51891f494 /src
parent57e1207920e13e63064088d9c8eb55285da0f5c2 (diff)
downloadVirtualBox-svn-c207032d166390918e335901f0fd5715b35d646a.tar.gz
VMM: Nested VMX: bugref:10318 Moved vmxHCGetGuestIntrStateAndUpdateFFs outside of vmxHCEvaluatePendingEvent[Nested] as it isn't used internally. Fix callers accordingly.
Fixed superfluous call to CPUMIsInInterruptShadowWithUpdate (called unconditionally), replaced subsequent calls with CPUMIsInInterruptShadow. Import RFLAGS explicitly when an interrupt is pending in the nested-guest case. git-svn-id: https://www.virtualbox.org/svn/vbox/trunk@99663 cfe28804-0f27-0410-a406-dd0f0b0b656f
Diffstat (limited to 'src')
-rw-r--r--src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h98
-rw-r--r--src/VBox/VMM/VMMR0/HMVMXR0.cpp11
-rw-r--r--src/VBox/VMM/VMMR3/NEMR3Native-darwin.cpp4
3 files changed, 49 insertions, 64 deletions
diff --git a/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h b/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h
index 9c04b5c0697..3f616d0b941 100644
--- a/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h
+++ b/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h
@@ -1696,14 +1696,15 @@ static void vmxHCExportGuestApicTpr(PVMCPUCC pVCpu, PCVMXTRANSIENT pVmxTransient
/**
- * Gets the guest interruptibility-state and updates related force-flags.
+ * Gets the guest interruptibility-state and updates related internal eflags
+ * inhibition state.
*
* @returns Guest's interruptibility-state.
- * @param pVCpu The cross context virtual CPU structure.
+ * @param pVCpu The cross context virtual CPU structure.
*
* @remarks No-long-jump zone!!!
*/
-static uint32_t vmxHCGetGuestIntrStateAndUpdateFFs(PVMCPUCC pVCpu)
+static uint32_t vmxHCGetGuestIntrStateWithUpdate(PVMCPUCC pVCpu)
{
uint32_t fIntrState;
@@ -4857,27 +4858,19 @@ static VBOXSTRICTRC vmxHCInjectEventVmcs(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcsInfo,
* NOT restore these force-flags.
*
* @returns Strict VBox status code (i.e. informational status codes too).
- * @param pVCpu The cross context virtual CPU structure.
- * @param pVmcsInfo The VMCS information structure.
- * @param pfIntrState Where to store the VT-x guest-interruptibility state.
+ * @param pVCpu The cross context virtual CPU structure.
+ * @param pVmcsInfo The VMCS information structure.
*/
-static VBOXSTRICTRC vmxHCEvaluatePendingEvent(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcsInfo, uint32_t *pfIntrState)
+static VBOXSTRICTRC vmxHCEvaluatePendingEvent(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcsInfo)
{
- Assert(pfIntrState);
Assert(!TRPMHasTrap(pVCpu));
/*
- * Compute/update guest-interruptibility state related FFs.
- * The FFs will be used below while evaluating events to be injected.
- */
- *pfIntrState = vmxHCGetGuestIntrStateAndUpdateFFs(pVCpu);
-
- /*
* Evaluate if a new event needs to be injected.
* An event that's already pending has already performed all necessary checks.
*/
if ( !VCPU_2_VMXSTATE(pVCpu).Event.fPending
- && !CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx))
+ && !CPUMIsInInterruptShadow(&pVCpu->cpum.GstCtx))
{
/** @todo SMI. SMIs take priority over NMIs. */
@@ -4990,28 +4983,19 @@ static VBOXSTRICTRC vmxHCEvaluatePendingEvent(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcs
* NOT restore these force-flags.
*
* @returns Strict VBox status code (i.e. informational status codes too).
- * @param pVCpu The cross context virtual CPU structure.
- * @param pVmcsInfo The VMCS information structure.
- * @param pfIntrState Where to store the VT-x guest-interruptibility state.
+ * @param pVCpu The cross context virtual CPU structure.
+ * @param pVmcsInfo The VMCS information structure.
*
* @remarks The guest must be in VMX non-root mode.
*/
-static VBOXSTRICTRC vmxHCEvaluatePendingEventNested(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcsInfo, uint32_t *pfIntrState)
+static VBOXSTRICTRC vmxHCEvaluatePendingEventNested(PVMCPUCC pVCpu, PVMXVMCSINFO pVmcsInfo)
{
- NOREF(pVmcsInfo);
PCCPUMCTX pCtx = &pVCpu->cpum.GstCtx;
- Assert(pfIntrState);
Assert(CPUMIsGuestInVmxNonRootMode(pCtx));
Assert(!TRPMHasTrap(pVCpu));
/*
- * Compute/update guest-interruptibility state related FFs.
- * The FFs will be used below while evaluating events to be injected.
- */
- *pfIntrState = vmxHCGetGuestIntrStateAndUpdateFFs(pVCpu);
-
- /*
* If we are injecting an event, we must not setup any interrupt/NMI-window
* exiting or we would get into an infinite VM-exit loop. An event that's
* already pending has already performed all necessary checks.
@@ -5037,7 +5021,7 @@ static VBOXSTRICTRC vmxHCEvaluatePendingEventNested(PVMCPUCC pVCpu, PVMXVMCSINFO
* See Intel spec. 24.4.2 "Guest Non-Register State".
* See Intel spec. 25.4.1 "Event Blocking".
*/
- if (!CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx))
+ if (!CPUMIsInInterruptShadow(&pVCpu->cpum.GstCtx))
{ /* likely */ }
else
return VINF_SUCCESS;
@@ -5107,48 +5091,50 @@ static VBOXSTRICTRC vmxHCEvaluatePendingEventNested(PVMCPUCC pVCpu, PVMXVMCSINFO
* This fixes a nasty SMP hang while executing nested-guest VCPUs on spinlocks which aren't rescued
* by other VM-exits (like a preemption timer), see @bugref{9562#c18}.
*
- * See Intel spec. 25.4.1 "Event Blocking".
- *
* NMIs block external interrupts as they are dispatched through the interrupt gate (vector 2)
* which automatically clears EFLAGS.IF. Also it's possible an NMI handler could enable interrupts
* and thus we should not check for NMI inhibition here.
*
+ * See Intel spec. 25.4.1 "Event Blocking".
* See Intel spec. 6.8.1 "Masking Maskable Hardware Interrupts".
*/
if ( VMCPU_FF_IS_ANY_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
- && !VCPU_2_VMXSTATE(pVCpu).fSingleInstruction
- && CPUMIsGuestVmxPhysIntrEnabled(pCtx))
+ && !VCPU_2_VMXSTATE(pVCpu).fSingleInstruction)
{
Assert(!DBGFIsStepping(pVCpu));
-
- /* Nested-guest external interrupt VM-exit. */
- if ( CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT)
- && !CPUMIsGuestVmxExitCtlsSet(pCtx, VMX_EXIT_CTLS_ACK_EXT_INT))
- {
- VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, 0 /* uVector */, true /* fIntPending */);
- Assert(rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE);
- return rcStrict;
- }
-
- /*
- * Fetch the external interrupt from the interrupt controller.
- * Once PDMGetInterrupt() returns an interrupt we -must- deliver it or pass it to
- * the nested-hypervisor. We cannot re-request the interrupt from the controller again.
- */
- uint8_t u8Interrupt;
- int rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
- if (RT_SUCCESS(rc))
+ int rc = vmxHCImportGuestStateEx(pVCpu, pVmcsInfo, CPUMCTX_EXTRN_RFLAGS);
+ AssertRC(rc);
+ if (CPUMIsGuestVmxPhysIntrEnabled(pCtx))
{
- /* Nested-guest external interrupt VM-exit when the "acknowledge interrupt on exit" is enabled. */
- if (CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT))
+ /* Nested-guest external interrupt VM-exit. */
+ if ( CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT)
+ && !CPUMIsGuestVmxExitCtlsSet(pCtx, VMX_EXIT_CTLS_ACK_EXT_INT))
{
- Assert(CPUMIsGuestVmxExitCtlsSet(pCtx, VMX_EXIT_CTLS_ACK_EXT_INT));
- VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, u8Interrupt, false /* fIntPending */);
+ VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, 0 /* uVector */, true /* fIntPending */);
Assert(rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE);
return rcStrict;
}
- vmxHCSetPendingExtInt(pVCpu, u8Interrupt);
- return VINF_SUCCESS;
+
+ /*
+ * Fetch the external interrupt from the interrupt controller.
+ * Once PDMGetInterrupt() returns an interrupt we -must- deliver it or pass it to
+ * the nested-hypervisor. We cannot re-request the interrupt from the controller again.
+ */
+ uint8_t u8Interrupt;
+ rc = PDMGetInterrupt(pVCpu, &u8Interrupt);
+ if (RT_SUCCESS(rc))
+ {
+ /* Nested-guest external interrupt VM-exit when the "acknowledge interrupt on exit" is enabled. */
+ if (CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_EXT_INT_EXIT))
+ {
+ Assert(CPUMIsGuestVmxExitCtlsSet(pCtx, VMX_EXIT_CTLS_ACK_EXT_INT));
+ VBOXSTRICTRC rcStrict = IEMExecVmxVmexitExtInt(pVCpu, u8Interrupt, false /* fIntPending */);
+ Assert(rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE);
+ return rcStrict;
+ }
+ vmxHCSetPendingExtInt(pVCpu, u8Interrupt);
+ return VINF_SUCCESS;
+ }
}
}
return VINF_SUCCESS;
diff --git a/src/VBox/VMM/VMMR0/HMVMXR0.cpp b/src/VBox/VMM/VMMR0/HMVMXR0.cpp
index 2a16c319997..12753f203ab 100644
--- a/src/VBox/VMM/VMMR0/HMVMXR0.cpp
+++ b/src/VBox/VMM/VMMR0/HMVMXR0.cpp
@@ -5922,12 +5922,12 @@ static VBOXSTRICTRC hmR0VmxPreRunGuest(PVMCPUCC pVCpu, PVMXTRANSIENT pVmxTransie
if (TRPMHasTrap(pVCpu))
vmxHCTrpmTrapToPendingEvent(pVCpu);
- uint32_t fIntrState;
+ uint32_t const fIntrState = vmxHCGetGuestIntrStateWithUpdate(pVCpu);
#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
if (!pVmxTransient->fIsNestedGuest)
- rcStrict = vmxHCEvaluatePendingEvent(pVCpu, pVmxTransient->pVmcsInfo, &fIntrState);
+ rcStrict = vmxHCEvaluatePendingEvent(pVCpu, pVmxTransient->pVmcsInfo);
else
- rcStrict = vmxHCEvaluatePendingEventNested(pVCpu, pVmxTransient->pVmcsInfo, &fIntrState);
+ rcStrict = vmxHCEvaluatePendingEventNested(pVCpu, pVmxTransient->pVmcsInfo);
/*
* While evaluating pending events if something failed (unlikely) or if we were
@@ -5942,7 +5942,7 @@ static VBOXSTRICTRC hmR0VmxPreRunGuest(PVMCPUCC pVCpu, PVMXTRANSIENT pVmxTransie
return VINF_VMX_VMEXIT;
}
#else
- rcStrict = vmxHCEvaluatePendingEvent(pVCpu, pVmxTransient->pVmcsInfo, &fIntrState);
+ rcStrict = vmxHCEvaluatePendingEvent(pVCpu, pVmxTransient->pVmcsInfo);
Assert(rcStrict == VINF_SUCCESS);
#endif
@@ -5954,8 +5954,7 @@ static VBOXSTRICTRC hmR0VmxPreRunGuest(PVMCPUCC pVCpu, PVMXTRANSIENT pVmxTransie
* With nested-guests, the above does not apply since unrestricted guest execution is a
* requirement. Regardless, we do this here to avoid duplicating code elsewhere.
*/
- rcStrict = vmxHCInjectPendingEvent(pVCpu, pVmxTransient->pVmcsInfo, pVmxTransient->fIsNestedGuest,
- fIntrState, fStepping);
+ rcStrict = vmxHCInjectPendingEvent(pVCpu, pVmxTransient->pVmcsInfo, pVmxTransient->fIsNestedGuest, fIntrState, fStepping);
if (RT_LIKELY(rcStrict == VINF_SUCCESS))
{ /* likely */ }
else
diff --git a/src/VBox/VMM/VMMR3/NEMR3Native-darwin.cpp b/src/VBox/VMM/VMMR3/NEMR3Native-darwin.cpp
index a4922ef081b..e5102151a72 100644
--- a/src/VBox/VMM/VMMR3/NEMR3Native-darwin.cpp
+++ b/src/VBox/VMM/VMMR3/NEMR3Native-darwin.cpp
@@ -3737,8 +3737,8 @@ static VBOXSTRICTRC nemR3DarwinPreRunGuest(PVM pVM, PVMCPU pVCpu, PVMXTRANSIENT
if (TRPMHasTrap(pVCpu))
vmxHCTrpmTrapToPendingEvent(pVCpu);
- uint32_t fIntrState;
- rcStrict = vmxHCEvaluatePendingEvent(pVCpu, &pVCpu->nem.s.VmcsInfo, &fIntrState);
+ uint32_t const fIntrState = vmxHCGetGuestIntrStateWithUpdate(pVCpu);
+ rcStrict = vmxHCEvaluatePendingEvent(pVCpu, &pVCpu->nem.s.VmcsInfo);
/*
* Event injection may take locks (currently the PGM lock for real-on-v86 case) and thus