Changeset 52140 in vbox
- Timestamp:
- Jul 23, 2014 5:08:54 AM (11 years ago)
- svn:sync-xref-src-repo-rev:
- 95172
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r52125 r52140 5836 5836 } 5837 5837 } 5838 else 5838 else if ( uIntType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT 5839 || uIntType == VMX_IDT_VECTORING_INFO_TYPE_EXT_INT 5840 || uIntType == VMX_IDT_VECTORING_INFO_TYPE_NMI) 5839 5841 { 5840 5842 /* 5841 5843 * If event delivery caused an EPT violation/misconfig or APIC access VM-exit, then the VM-exit 5842 * interruption-information will not be valid a nd we end up here. In such cases, it is sufficient to reflect the5843 * original exception to the guest after handling the VM-exit.5844 * interruption-information will not be valid as it's not an exception and we end up here. In such cases, 5845 * it is sufficient to reflect the original exception to the guest after handling the VM-exit. 5844 5846 */ 5845 if ( uIntType == VMX_IDT_VECTORING_INFO_TYPE_NMI 5846 && (pVCpu->hm.s.vmx.u32PinCtls & VMX_VMCS_CTRL_PIN_EXEC_VIRTUAL_NMI)) 5847 { 5848 /* 5849 * On CPUs that support Virtual NMIs, if this exception occurred while delivering the NMI, we need to clear 5850 * the block-by-NMI field in the guest interruptibility-state before re-delivering the NMI, otherwise the 5851 * subsequent VM-entry would fail. 5852 * See Intel spec. 30.7.1.2 "Resuming Guest Software after Handling an Exception". See @bugref{7445}. 5853 */ 5854 Assert(VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_BLOCK_NMIS)); 5855 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_BLOCK_NMIS); 5856 enmReflect = VMXREFLECTXCPT_XCPT; 5857 } 5858 else if ( uIntType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT 5859 || uIntType == VMX_IDT_VECTORING_INFO_TYPE_EXT_INT 5860 || uIntType == VMX_IDT_VECTORING_INFO_TYPE_NMI) 5861 { 5862 enmReflect = VMXREFLECTXCPT_XCPT; 5863 } 5847 enmReflect = VMXREFLECTXCPT_XCPT; 5848 } 5849 5850 /* 5851 * On CPUs that support Virtual NMIs, if this VM-exit (be it an exception or EPT violation/misconfig etc.) occurred 5852 * while delivering the NMI, we need to clear the block-by-NMI field in the guest interruptibility-state before 5853 * re-delivering the NMI after handling the VM-exit. Otherwise the subsequent VM-entry would fail. 5854 * 5855 * See Intel spec. 30.7.1.2 "Resuming Guest Software after Handling an Exception". See @bugref{7445}. 5856 */ 5857 if ( uIntType == VMX_IDT_VECTORING_INFO_TYPE_NMI 5858 && enmReflect == VMXREFLECTXCPT_XCPT 5859 && (pVCpu->hm.s.vmx.u32PinCtls & VMX_VMCS_CTRL_PIN_EXEC_VIRTUAL_NMI) 5860 && VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_BLOCK_NMIS)) 5861 { 5862 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_BLOCK_NMIS); 5864 5863 } 5865 5864 … … 5919 5918 /* 5920 5919 * Execution of IRET caused this fault when NMI blocking was in effect (i.e we're in the guest NMI handler). 5921 * We need to reset the block-by-NMI field so that NMIs remain blocked until the IRET execution is completed.5920 * We need to set the block-by-NMI field so that NMIs remain blocked until the IRET execution is restarted. 5922 5921 * See Intel spec. 30.7.1.2 "Resuming guest software after handling an exception". 5923 5922 */ … … 7995 7994 /* Clear interrupt-window exiting control. */ 7996 7995 if (pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_INT_WINDOW_EXIT) 7996 { 7997 7997 hmR0VmxClearIntWindowExitVmcs(pVCpu); 7998 Assert(!pVCpu->hm.s.Event.fPending); 7999 } 8000 8001 /* Clear NMI-window exiting control. */ 8002 if (pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_NMI_WINDOW_EXIT) 8003 { 8004 hmR0VmxClearNmiWindowExitVmcs(pVCpu); 8005 Assert(!pVCpu->hm.s.Event.fPending); 8006 } 7998 8007 7999 8008 if (!pVCpu->hm.s.Event.fPending) … … 9951 9960 9952 9961 /* 9953 * Clear block-by-STI if it's active. The force-flag couldn't have been set by block-by-Mov SS in 9954 * hmR0VmxSaveGuestIntrState() when this VM-exit happened, as Intel CPUs are consistent with 9955 * block-by-Mov SS and NMIs. See @bugref{7445}. 9962 * If block-by-STI is set when we get this VM-exit, it means the CPU doesn't block NMIs following STI. 9963 * It is therefore safe to unblock STI and deliver the NMI ourselves. See @bugref{7445}. 9956 9964 */ 9957 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) 9965 uint32_t uIntrState = 0; 9966 int rc = VMXReadVmcs32(VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE, &uIntrState); 9967 AssertRCReturn(rc, rc); 9968 9969 bool const fBlockSti = RT_BOOL(uIntrState & VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI); 9970 if ( fBlockSti 9971 && VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)) 9972 { 9958 9973 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS); 9974 } 9959 9975 9960 9976 /* Indicate that we no longer need to VM-exit when the guest is ready to receive NMIs, it is now ready */
Note:
See TracChangeset
for help on using the changeset viewer.