summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorvboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2023-05-08 06:49:25 +0000
committervboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f>2023-05-08 06:49:25 +0000
commitbc65d5eb1241ebd97441e5f32f93ca8620b0f022 (patch)
tree4630c08b512224a0c46ba5f1707d2d652d37d535 /src
parent026d014db4b2ffe3ca28a991b48d3dd2fc1f49d6 (diff)
downloadVirtualBox-svn-bc65d5eb1241ebd97441e5f32f93ca8620b0f022.tar.gz
VMM/IEM: Nested VMX: bugref:10318 Clear "NMI unblocked due to IRET" state on VM-exit. Minor optimization while injecting an event. Comments, assertions.
git-svn-id: https://www.virtualbox.org/svn/vbox/trunk@99650 cfe28804-0f27-0410-a406-dd0f0b0b656f
Diffstat (limited to 'src')
-rw-r--r--src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp39
1 files changed, 27 insertions, 12 deletions
diff --git a/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp b/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp
index ad3eedf6911..d8d2cded079 100644
--- a/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp
+++ b/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp
@@ -2577,9 +2577,15 @@ VBOXSTRICTRC iemVmxVmexit(PVMCPUCC pVCpu, uint32_t uExitReason, uint64_t u64Exit
Assert(uExitReason != VMX_EXIT_INT_WINDOW);
}
- /* For exception or NMI VM-exits the VM-exit interruption info. field must be valid. */
+ /* For exception or NMI VM-exits, the VM-exit interruption info. field must be valid. */
Assert(uExitReason != VMX_EXIT_XCPT_OR_NMI || VMX_EXIT_INT_INFO_IS_VALID(pVmcs->u32RoExitIntInfo));
+ /* For external interrupts that occur while "acknowledge interrupt on exit" VM-exit is set,
+ the VM-exit interruption info. field must be valid. */
+ Assert( uExitReason != VMX_EXIT_EXT_INT
+ || !(pVmcs->u32ExitCtls & VMX_EXIT_CTLS_ACK_EXT_INT)
+ || VMX_EXIT_INT_INFO_IS_VALID(pVmcs->u32RoExitIntInfo));
+
/*
* If we support storing EFER.LMA into IA32e-mode guest field on VM-exit, we need to do that now.
* See Intel spec. 27.2 "Recording VM-exit Information And Updating VM-entry Control".
@@ -2635,6 +2641,13 @@ VBOXSTRICTRC iemVmxVmexit(PVMCPUCC pVCpu, uint32_t uExitReason, uint64_t u64Exit
CPUMStopGuestVmxPremptTimer(pVCpu);
/*
+ * Clear the state of "NMI unblocked due to IRET" as otherwise we risk
+ * reporting a stale state on a subsequent VM-exit. This state will be
+ * re-established while emulating IRET in VMX non-root mode.
+ */
+ pVCpu->cpum.GstCtx.hwvirt.vmx.fNmiUnblockingIret = false;
+
+ /*
* Clear any pending VMX nested-guest force-flags.
* These force-flags have no effect on (outer) guest execution and will
* be re-evaluated and setup on the next nested-guest VM-entry.
@@ -7609,18 +7622,20 @@ static void iemVmxVmentryInjectTrpmEvent(PVMCPUCC pVCpu, const char *pszInstr, u
TRPMSetFaultAddress(pVCpu, GCPtrFaultAddress);
Log(("%s: Injecting: fault_addr=%RGp\n", pszInstr, GCPtrFaultAddress));
}
- else if ( uType == VMX_ENTRY_INT_INFO_TYPE_SW_INT
- || uType == VMX_ENTRY_INT_INFO_TYPE_SW_XCPT
- || uType == VMX_ENTRY_INT_INFO_TYPE_PRIV_SW_XCPT)
- {
- TRPMSetInstrLength(pVCpu, cbInstr);
- Log(("%s: Injecting: instr_len=%u\n", pszInstr, cbInstr));
- }
-
- if (VMX_ENTRY_INT_INFO_TYPE(uEntryIntInfo) == VMX_ENTRY_INT_INFO_TYPE_PRIV_SW_XCPT)
+ else
{
- TRPMSetTrapDueToIcebp(pVCpu);
- Log(("%s: Injecting: icebp\n", pszInstr));
+ switch (uType)
+ {
+ case VMX_ENTRY_INT_INFO_TYPE_PRIV_SW_XCPT:
+ TRPMSetTrapDueToIcebp(pVCpu);
+ Log(("%s: Injecting: icebp\n", pszInstr));
+ RT_FALL_THRU();
+ case VMX_ENTRY_INT_INFO_TYPE_SW_INT:
+ case VMX_ENTRY_INT_INFO_TYPE_SW_XCPT:
+ TRPMSetInstrLength(pVCpu, cbInstr);
+ Log(("%s: Injecting: instr_len=%u\n", pszInstr, cbInstr));
+ break;
+ }
}
NOREF(pszInstr);