- Timestamp:
- May 4, 2017 12:27:56 PM (7 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r66756 r66790 5900 5900 uint32_t const uIdtVector = VMX_IDT_VECTORING_INFO_VECTOR(pVmxTransient->uIdtVectoringInfo); 5901 5901 #ifdef HMVMX_USE_IEM_EVENT_REFLECTION 5902 /* See Intel spec. 30.7.1.1 "Reflecting Exceptions to Guest Software". */ 5902 /* 5903 * If the event was a software interrupt (generated with INT n) or a software exception (generated 5904 * by INT3/INTO) or a privileged software exception (generated by INT1), we can handle the VM-exit 5905 * and continue guest execution which will re-execute the instruction rather than re-injecting the 5906 * exception, as that can cause premature trips to ring-3 before injection and involve TRPM which 5907 * currently has no way of storing that these exceptions were caused by these instructions 5908 * (ICEBP's #DB poses the problem). 5909 */ 5903 5910 IEMXCPTRAISE enmRaise; 5904 5911 IEMXCPTRAISEINFO fRaiseInfo; 5905 if (VMX_EXIT_INTERRUPTION_INFO_IS_VALID(pVmxTransient->uExitIntInfo)) 5912 if ( uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_SW_INT 5913 || uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT 5914 || uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT) 5915 { 5916 enmRaise = IEMXCPTRAISE_REEXEC_INSTR; 5917 fRaiseInfo = IEMXCPTRAISEINFO_NONE; 5918 } 5919 else if (VMX_EXIT_INTERRUPTION_INFO_IS_VALID(pVmxTransient->uExitIntInfo)) 5906 5920 { 5907 5921 uint32_t const uExitVectorType = VMX_IDT_VECTORING_INFO_TYPE(pVmxTransient->uExitIntInfo); 5908 5922 uint32_t const fIdtVectorFlags = hmR0VmxGetIemXcptFlags(uIdtVector, uIdtVectorType); 5909 5923 uint32_t const fExitVectorFlags = hmR0VmxGetIemXcptFlags(uExitVector, uExitVectorType); 5910 AssertMsg( uExitVectorType == VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT 5911 || uExitVectorType == VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI, 5912 ("hmR0VmxCheckExitDueToEventDelivery: Unexpected VM-exit interruption info. type %#x!\n", uExitVectorType)); 5913 enmRaise = IEMEvaluateRecursiveXcpt(pVCpu, fIdtVectorFlags, uIdtVector, fExitVectorFlags, uExitVector, 5914 &fRaiseInfo); 5915 5916 if (fRaiseInfo & (IEMXCPTRAISEINFO_EXT_INT_XCPT | IEMXCPTRAISEINFO_NMI_XCPT)) 5917 { 5918 /* 5919 * For some reason we go back to the interpreter if delivery of an external interrupt or 5920 * NMI causes an exception, see hmR0VmxExitXcptOrNmi. As long as we go back to the interpret 5921 * we need to keep the previous (first) event pending, hence this hack. 5922 */ 5923 enmRaise = IEMXCPTRAISE_PREV_EVENT; 5924 5925 /* Determine a vectoring #PF condition, see comment in hmR0VmxExitXcptPF(). */ 5926 if (fRaiseInfo & (IEMXCPTRAISEINFO_EXT_INT_PF | IEMXCPTRAISEINFO_NMI_PF)) 5927 pVmxTransient->fVectoringPF = true; 5928 } 5924 /** @todo Make AssertMsgReturn as just AssertMsg later. */ 5925 AssertMsgReturn(uExitVectorType == VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT, 5926 ("hmR0VmxCheckExitDueToEventDelivery: Unexpected VM-exit interruption info. %#x!\n", 5927 uExitVectorType), VERR_VMX_IPE_5); 5928 enmRaise = IEMEvaluateRecursiveXcpt(pVCpu, fIdtVectorFlags, uIdtVector, fExitVectorFlags, uExitVector, &fRaiseInfo); 5929 5929 } 5930 5930 else 5931 5931 { 5932 5932 /* 5933 * If event delivery caused an EPT violation/misconfig or APIC access VM-exit, then the VM-exit 5934 * interruption-information will not be valid as it's not an exception and we end up here. 5935 * 5936 * If the event was an external interrupt or hardare exception (incl. NMI) it is sufficient to 5937 * reflect this event to the guest after handling the VM-exit. 5938 * 5939 * If the event was a software interrupt (generated with INT n) or a software exception (generated 5940 * by INT3/INTO) or a privileged software exception (generated by INT1), we can handle the VM-exit 5941 * and continue guest execution which will re-execute the instruction rather than re-injecting the 5942 * event, as that can cause premature trips to ring-3 before injection and involve TRPM which 5943 * currently has no way of storing that the exceptions were caused by these special instructions. 5933 * If an exception or hardware interrupt delivery caused an EPT violation/misconfig or APIC access 5934 * VM-exit, then the VM-exit interruption-information will not be valid and we end up here. 5935 * It is sufficient to reflect the original event to the guest after handling the VM-exit. 5944 5936 */ 5945 if ( uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT 5946 || uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_NMI 5947 || uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_EXT_INT) 5948 enmRaise = IEMXCPTRAISE_PREV_EVENT; 5949 else 5950 enmRaise = IEMXCPTRAISE_REEXEC_INSTR; 5937 Assert( uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT 5938 || uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_NMI 5939 || uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_EXT_INT); 5940 enmRaise = IEMXCPTRAISE_PREV_EVENT; 5951 5941 fRaiseInfo = IEMXCPTRAISEINFO_NONE; 5952 5942 } … … 5972 5962 { 5973 5963 case IEMXCPTRAISE_CURRENT_XCPT: 5974 case IEMXCPTRAISE_REEXEC_INSTR:5975 Assert(rcStrict == VINF_SUCCESS);5976 break;5977 5978 5964 case IEMXCPTRAISE_PREV_EVENT: 5979 5965 { 5980 /* 5981 * Re-raise the previous (first) exception/interrupt as delivery caused a premature VM-exit. 5982 */ 5983 Assert( uIdtVectorType != VMX_IDT_VECTORING_INFO_TYPE_SW_INT 5984 && uIdtVectorType != VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT 5985 && uIdtVectorType != VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT); 5966 /* Determine a vectoring #PF condition, see comment in hmR0VmxExitXcptPF(). */ 5967 if (fRaiseInfo & (IEMXCPTRAISEINFO_EXT_INT_PF | IEMXCPTRAISEINFO_NMI_PF)) 5968 pVmxTransient->fVectoringPF = true; 5986 5969 5987 5970 uint32_t u32ErrCode; … … 6005 5988 break; 6006 5989 } 5990 5991 case IEMXCPTRAISE_REEXEC_INSTR: 5992 Assert(rcStrict == VINF_SUCCESS); 5993 break; 6007 5994 6008 5995 case IEMXCPTRAISE_DOUBLE_FAULT:
Note:
See TracChangeset
for help on using the changeset viewer.

