Changeset 52653 in vbox
- Timestamp:
- Sep 9, 2014 1:40:20 PM (10 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 2 edited
-
HMSVMR0.cpp (modified) (8 diffs)
-
HMVMXR0.cpp (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r52396 r52653 218 218 /** Whether the #VMEXIT was caused by a page-fault during delivery of a 219 219 * contributary exception or a page-fault. */ 220 bool fVectoringDoublePF; 221 /** Whether the VM-exit was caused by a page-fault during delivery of an 222 * external interrupt or NMI. */ 220 223 bool fVectoringPF; 221 224 } SVMTRANSIENT, *PSVMTRANSIENT; … … 2209 2212 } 2210 2213 2214 /* If we're emulating an instruction, we shouldn't have any TRPM traps pending 2215 and if we're injecting an event we should have a TRPM trap pending. */ 2216 Assert(rcExit != VINF_EM_RAW_INJECT_TRPM_EVENT || TRPMHasTrap(pVCpu)); 2217 Assert(rcExit != VINF_EM_RAW_EMULATE_INSTR || !TRPMHasTrap(pVCpu)); 2218 2211 2219 /* Sync. the necessary state for going back to ring-3. */ 2212 2220 hmR0SvmLeaveSession(pVM, pVCpu, pCtx); … … 3220 3228 pSvmTransient->u64ExitCode = pVmcb->ctrl.u64ExitCode; /* Save the #VMEXIT reason. */ 3221 3229 HMCPU_EXIT_HISTORY_ADD(pVCpu, pVmcb->ctrl.u64ExitCode); /* Update the #VMEXIT history array. */ 3230 pSvmTransient->fVectoringDoublePF = false; /* Vectoring double page-fault needs to be determined later. */ 3222 3231 pSvmTransient->fVectoringPF = false; /* Vectoring page-fault needs to be determined later. */ 3223 3232 … … 4055 4064 && uIdtVector == X86_XCPT_PF) 4056 4065 { 4057 pSvmTransient->fVectoring PF = true;4058 Log4(("IDT: Vectoring #PF uCR2=%#RX64\n", pCtx->cr2));4066 pSvmTransient->fVectoringDoublePF = true; 4067 Log4(("IDT: Vectoring double #PF uCR2=%#RX64\n", pCtx->cr2)); 4059 4068 } 4060 4069 else if ( (pVmcb->ctrl.u32InterceptException & HMSVM_CONTRIBUTORY_XCPT_MASK) … … 4085 4094 } 4086 4095 } 4087 else if ( pVmcb->ctrl.ExitIntInfo.n.u3Type != SVM_EVENT_SOFTWARE_INT)4088 {4089 /* Ignore software interrupts (INT n) as they reoccur when restarting the instruction. */4096 else if ( pVmcb->ctrl.ExitIntInfo.n.u3Type == SVM_EVENT_EXTERNAL_IRQ 4097 || pVmcb->ctrl.ExitIntInfo.n.u3Type == SVM_EVENT_NMI) 4098 { 4090 4099 enmReflect = SVMREFLECTXCPT_XCPT; 4091 4100 fReflectingNmi = RT_BOOL(pVmcb->ctrl.ExitIntInfo.n.u3Type == SVM_EVENT_NMI); 4092 } 4101 4102 if (pSvmTransient->u64ExitCode - SVM_EXIT_EXCEPTION_0 <= SVM_EXIT_EXCEPTION_1F) 4103 { 4104 uint8_t uExitVector = (uint8_t)(pSvmTransient->u64ExitCode - SVM_EXIT_EXCEPTION_0); 4105 if (uExitVector == X86_XCPT_PF) 4106 { 4107 pSvmTransient->fVectoringPF = true; 4108 Log4(("IDT: Vectoring #PF due to Ext-Int/NMI. uCR2=%#RX64\n", pCtx->cr2)); 4109 } 4110 } 4111 } 4112 /* else: Ignore software interrupts (INT n) as they reoccur when restarting the instruction. */ 4093 4113 4094 4114 switch (enmReflect) … … 5044 5064 { 5045 5065 pVCpu->hm.s.Event.fPending = false; /* In case it's a contributory or vectoring #PF. */ 5046 if (!pSvmTransient->fVectoring PF)5066 if (!pSvmTransient->fVectoringDoublePF) 5047 5067 { 5048 5068 /* A genuine guest #PF, reflect it to the guest. */ … … 5094 5114 pCtx->rip, u32ErrCode, pCtx->cr3)); 5095 5115 5116 /* If it's a vectoring #PF, emulate injecting the original event injection as PGMTrap0eHandler() is incapable 5117 of differentiating between instruction emulation and event injection that caused a #PF. See @bugref{}. */ 5118 if (pSvmTransient->fVectoringPF) 5119 { 5120 Assert(pVCpu->hm.s.Event.fPending); 5121 return VINF_EM_RAW_INJECT_TRPM_EVENT; 5122 } 5123 5096 5124 TRPMAssertXcptPF(pVCpu, uFaultAddress, u32ErrCode); 5097 5125 int rc = PGMTrap0eHandler(pVCpu, u32ErrCode, CPUMCTX2CORE(pCtx), (RTGCPTR)uFaultAddress); … … 5111 5139 pVCpu->hm.s.Event.fPending = false; /* In case it's a contributory or vectoring #PF. */ 5112 5140 5113 if (!pSvmTransient->fVectoring PF)5141 if (!pSvmTransient->fVectoringDoublePF) 5114 5142 { 5115 5143 /* It's a guest page fault and needs to be reflected to the guest. */ -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r52611 r52653 279 279 /** Whether the VM-exit was caused by a page-fault during delivery of a 280 280 * contributory exception or a page-fault. */ 281 bool fVectoringDoublePF; 282 /** Whether the VM-exit was caused by a page-fault during delivery of an 283 * external interrupt or NMI. */ 281 284 bool fVectoringPF; 282 285 } VMXTRANSIENT; … … 5801 5804 && uIdtVector == X86_XCPT_PF) 5802 5805 { 5803 pVmxTransient->fVectoring PF = true;5804 Log4(("IDT: vcpu[%RU32] Vectoring #PF uCR2=%#RX64\n", pVCpu->idCpu, pMixedCtx->cr2));5806 pVmxTransient->fVectoringDoublePF = true; 5807 Log4(("IDT: vcpu[%RU32] Vectoring Double #PF uCR2=%#RX64\n", pVCpu->idCpu, pMixedCtx->cr2)); 5805 5808 } 5806 5809 else if ( (pVCpu->hm.s.vmx.u32XcptBitmap & HMVMX_CONTRIBUTORY_XCPT_MASK) … … 5814 5817 enmReflect = VMXREFLECTXCPT_TF; 5815 5818 } 5816 else if ( uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT 5817 || uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_EXT_INT 5819 else if ( uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_EXT_INT 5818 5820 || uIdtVectorType == VMX_IDT_VECTORING_INFO_TYPE_NMI) 5819 5821 { … … 5823 5825 */ 5824 5826 enmReflect = VMXREFLECTXCPT_XCPT; 5827 5828 if (uExitVector == X86_XCPT_PF) 5829 { 5830 pVmxTransient->fVectoringPF = true; 5831 Log4(("IDT: vcpu[%RU32] Vectoring #PF due to Ext-Int/NMI. uCR2=%#RX64\n", pVCpu->idCpu, pMixedCtx->cr2)); 5832 } 5825 5833 } 5826 5834 } … … 7187 7195 } 7188 7196 7197 /* If we're emulating an instruction, we shouldn't have any TRPM traps pending 7198 and if we're injecting an event we should have a TRPM trap pending. */ 7199 Assert(rcExit != VINF_EM_RAW_INJECT_TRPM_EVENT || TRPMHasTrap(pVCpu)); 7200 Assert(rcExit != VINF_EM_RAW_EMULATE_INSTR || !TRPMHasTrap(pVCpu)); 7201 7189 7202 /* Save guest state and restore host state bits. */ 7190 7203 int rc = hmR0VmxLeaveSession(pVM, pVCpu, pMixedCtx); 7191 7204 AssertRCReturn(rc, rc); 7192 7205 STAM_COUNTER_DEC(&pVCpu->hm.s.StatSwitchLongJmpToR3); 7206 /* Thread-context hooks are unregistered at this point!!! */ 7193 7207 7194 7208 /* Sync recompiler state. */ … … 8678 8692 pVmxTransient->fVmcsFieldsRead = 0; /* Transient fields need to be read from the VMCS. */ 8679 8693 pVmxTransient->fVectoringPF = false; /* Vectoring page-fault needs to be determined later. */ 8694 pVmxTransient->fVectoringDoublePF = false; /* Vectoring double page-fault needs to be determined later. */ 8680 8695 8681 8696 if (!(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT)) … … 11963 11978 { 11964 11979 pVCpu->hm.s.Event.fPending = false; /* In case it's a contributory or vectoring #PF. */ 11965 if (RT_LIKELY(!pVmxTransient->fVectoring PF))11980 if (RT_LIKELY(!pVmxTransient->fVectoringDoublePF)) 11966 11981 { 11967 11982 pMixedCtx->cr2 = pVmxTransient->uExitQualification; /* Update here in case we go back to ring-3 before injection. */ … … 11982 11997 NOREF(pVM); 11983 11998 #endif 11999 12000 /* If it's a vectoring #PF, emulate injecting the original event injection as PGMTrap0eHandler() is incapable 12001 of differentiating between instruction emulation and event injection that caused a #PF. See @bugref{}. */ 12002 if (pVmxTransient->fVectoringPF) 12003 { 12004 Assert(pVCpu->hm.s.Event.fPending); 12005 return VINF_EM_RAW_INJECT_TRPM_EVENT; 12006 } 11984 12007 11985 12008 rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx); … … 12009 12032 else if (rc == VINF_EM_RAW_GUEST_TRAP) 12010 12033 { 12011 if (!pVmxTransient->fVectoring PF)12034 if (!pVmxTransient->fVectoringDoublePF) 12012 12035 { 12013 12036 /* It's a guest page fault and needs to be reflected to the guest. */
Note:
See TracChangeset
for help on using the changeset viewer.

