diff options
author | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2023-05-08 08:50:13 +0000 |
---|---|---|
committer | vboxsync <vboxsync@cfe28804-0f27-0410-a406-dd0f0b0b656f> | 2023-05-08 08:50:13 +0000 |
commit | 1b24a245aa8104db6bce7154ce549a2581e0736d (patch) | |
tree | 860feded4f1c4f30a5cd0c7a6765eb54a9049089 /src | |
parent | 4aec9a17c50466056c579ad5e4b9f1575b1f1706 (diff) | |
download | VirtualBox-svn-1b24a245aa8104db6bce7154ce549a2581e0736d.tar.gz |
VMM: Nested VMX: bugref:10318 NMI inhibition also blocks external interrupts. No scope of NMI-window exiting or delivering NMIs in such a case.
git-svn-id: https://www.virtualbox.org/svn/vbox/trunk@99656 cfe28804-0f27-0410-a406-dd0f0b0b656f
Diffstat (limited to 'src')
-rw-r--r-- | src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h | 69 |
1 files changed, 31 insertions, 38 deletions
diff --git a/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h b/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h index c15c7851ac4..927ed43209d 100644 --- a/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h +++ b/src/VBox/VMM/VMMAll/VMXAllTemplate.cpp.h @@ -5031,13 +5031,16 @@ static VBOXSTRICTRC vmxHCEvaluatePendingEventNested(PVMCPUCC pVCpu, PVMXVMCSINFO Assert(CPUMIsGuestVmxInterceptEvents(pCtx)); /* - * Interrupt shadows can also block NMIs. If we are in an interrupt shadow there's - * nothing more to do here. + * Interrupt shadows may block NMIs. + * Interrupt shadows may block external-interrupt VM-exits. + * NMI inhibition blocks NMIs in addition to external interrupts. * * See Intel spec. 24.4.2 "Guest Non-Register State". * See Intel spec. 25.4.1 "Event Blocking". + * See Intel spec. 6.7 "Nonmaskable Interrupt (NMI)". */ - if (!CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx)) + if ( CPUMIsInInterruptShadowWithUpdate(&pVCpu->cpum.GstCtx) + || CPUMAreInterruptsInhibitedByNmi(&pVCpu->cpum.GstCtx)) { /* likely */ } else return VINF_SUCCESS; @@ -5045,45 +5048,35 @@ static VBOXSTRICTRC vmxHCEvaluatePendingEventNested(PVMCPUCC pVCpu, PVMXVMCSINFO /** @todo SMI. SMIs take priority over NMIs. */ /* - * NMIs. - * NMIs take priority over external interrupts. + * Nested-guest NMI-window exiting. + * The NMI-window exit must happen regardless of whether an NMI is pending + * provided virtual-NMI blocking is not in effect. * - * NMI blocking is in effect after delivering an NMI until the execution of IRET. - * Only when there isn't any NMI blocking can an NMI-window VM-exit or delivery of an NMI happen. + * See Intel spec. 25.2 "Other Causes Of VM Exits". */ - if (!CPUMAreInterruptsInhibitedByNmi(&pVCpu->cpum.GstCtx)) + if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW) + && !CPUMIsGuestVmxVirtNmiBlocking(pCtx)) { - /* - * Nested-guest NMI-window exiting. - * The NMI-window exit must happen regardless of whether an NMI is pending - * provided virtual-NMI blocking is not in effect. - * - * See Intel spec. 25.2 "Other Causes Of VM Exits". - */ - if ( VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_VMX_NMI_WINDOW) - && !CPUMIsGuestVmxVirtNmiBlocking(pCtx)) - { - Assert(CPUMIsGuestVmxProcCtlsSet(&pVCpu->cpum.GstCtx, VMX_PROC_CTLS_NMI_WINDOW_EXIT)); - return IEMExecVmxVmexit(pVCpu, VMX_EXIT_NMI_WINDOW, 0 /* u64ExitQual */); - } + Assert(CPUMIsGuestVmxProcCtlsSet(&pVCpu->cpum.GstCtx, VMX_PROC_CTLS_NMI_WINDOW_EXIT)); + return IEMExecVmxVmexit(pVCpu, VMX_EXIT_NMI_WINDOW, 0 /* u64ExitQual */); + } - /* - * For a nested-guest, the FF always indicates the outer guest's ability to - * receive an NMI while the guest-interruptibility state bit depends on whether - * the nested-hypervisor is using virtual-NMIs. - * - * It is very important that we also clear the force-flag if we are causing - * an NMI VM-exit as it is the responsibility of the nested-hypervisor to deal - * with re-injecting or discarding the NMI. This fixes the bug that showed up - * with SMP Windows Server 2008 R2 with Hyper-V enabled, see @bugref{10318#c19}. - */ - if (VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI)) - { - if (CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_NMI_EXIT)) - return IEMExecVmxVmexitXcptNmi(pVCpu); - vmxHCSetPendingXcptNmi(pVCpu); - return VINF_SUCCESS; - } + /* + * For a nested-guest, the FF always indicates the outer guest's ability to + * receive an NMI while the guest-interruptibility state bit depends on whether + * the nested-hypervisor is using virtual-NMIs. + * + * It is very important that we also clear the force-flag if we are causing + * an NMI VM-exit as it is the responsibility of the nested-hypervisor to deal + * with re-injecting or discarding the NMI. This fixes the bug that showed up + * with SMP Windows Server 2008 R2 with Hyper-V enabled, see @bugref{10318#c19}. + */ + if (VMCPU_FF_TEST_AND_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI)) + { + if (CPUMIsGuestVmxPinCtlsSet(pCtx, VMX_PIN_CTLS_NMI_EXIT)) + return IEMExecVmxVmexitXcptNmi(pVCpu); + vmxHCSetPendingXcptNmi(pVCpu); + return VINF_SUCCESS; } /* |