Changeset 45943 in vbox
- Timestamp:
- May 8, 2013 9:30:28 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r45937 r45943 5124 5124 { 5125 5125 CPUMSetGuestCR3(pVCpu, uVal); 5126 /* Set the force flag to inform PGM about it when necessary. It is cleared by PGMUpdateCR3().*/ 5127 VMCPU_FF_SET(pVCpu, VMCPU_FF_HM_UPDATE_CR3); 5126 if (VMMRZCallRing3IsEnabled(pVCpu)) 5127 PGMUpdateCR3(pVCpu, uVal); 5128 else 5129 { 5130 /* Set the force flag to inform PGM about it when necessary. It is cleared by PGMUpdateCR3().*/ 5131 VMCPU_FF_SET(pVCpu, VMCPU_FF_HM_UPDATE_CR3); 5132 } 5128 5133 } 5129 5134 … … 5135 5140 rc = VMXReadVmcs64(VMX_VMCS64_GUEST_PDPTE2_FULL, &pVCpu->hm.s.aPdpes[2].u); AssertRCReturn(rc, rc); 5136 5141 rc = VMXReadVmcs64(VMX_VMCS64_GUEST_PDPTE3_FULL, &pVCpu->hm.s.aPdpes[3].u); AssertRCReturn(rc, rc); 5137 /* Set the force flag to inform PGM about it when necessary. It is cleared by PGMGstUpdatePaePdpes(). */ 5138 VMCPU_FF_SET(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES); 5142 5143 if (VMMRZCallRing3IsEnabled(pVCpu)) 5144 PGMGstUpdatePaePdpes(pVCpu, &pVCpu->hm.s.aPdpes[0]); 5145 else 5146 { 5147 /* Set the force flag to inform PGM about it when necessary. It is cleared by PGMGstUpdatePaePdpes(). */ 5148 VMCPU_FF_SET(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES); 5149 } 5139 5150 } 5140 5151 } … … 5142 5153 pVCpu->hm.s.vmx.fUpdatedGuestState |= HMVMX_UPDATED_GUEST_CR3; 5143 5154 } 5155 5156 /* 5157 * Consider this scenario: VM-exit -> VMMRZCallRing3Enable() -> do stuff that causes a longjmp -> hmR0VmxCallRing3Callback() 5158 * -> VMMRZCallRing3Disable() -> hmR0VmxSaveGuestState() -> Set VMCPU_FF_HM_UPDATE_CR3 pending -> return from the longjmp 5159 * -> continue with VM-exit handling -> hmR0VmxSaveGuestControlRegs() and here we are. 5160 * 5161 * The longjmp exit path can't check these CR3 force-flags and call code that takes a lock again. 5162 * We cover for it here. 5163 */ 5164 if (VMMRZCallRing3IsEnabled(pVCpu)) 5165 { 5166 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_CR3)) 5167 PGMUpdateCR3(pVCpu, CPUMGetGuestCR3(pVCpu)); 5168 5169 if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES)) 5170 PGMGstUpdatePaePdpes(pVCpu, &pVCpu->hm.s.aPdpes[0]); 5171 5172 Assert(!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_CR3)); 5173 Assert(!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES)); 5174 } 5175 5144 5176 return rc; 5145 5177 } … … 5389 5421 return VINF_SUCCESS; 5390 5422 5391 VMMRZCallRing3Disable(pVCpu); 5392 Assert(VMMR0IsLogFlushDisabled(pVCpu)); 5423 /* Though we can longjmp to ring-3 due to log-flushes here and get recalled again on the ring-3 callback path, 5424 there is no real need to. */ 5425 if (VMMRZCallRing3IsEnabled(pVCpu)) 5426 VMMR0LogFlushDisable(pVCpu); 5427 else 5428 Assert(VMMR0IsLogFlushDisabled(pVCpu)); 5393 5429 LogFunc(("\n")); 5394 5430 … … 5429 5465 ("Missed guest state bits while saving state; residue %RX32\n", pVCpu->hm.s.vmx.fUpdatedGuestState)); 5430 5466 5431 VMMRZCallRing3Enable(pVCpu); 5467 if (VMMRZCallRing3IsEnabled(pVCpu)) 5468 VMMR0LogFlushEnable(pVCpu); 5469 5432 5470 return rc; 5433 5471 } … … 5474 5512 rc = PGMUpdateCR3(pVCpu, pMixedCtx->cr3); 5475 5513 Assert(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3); 5514 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_HM_UPDATE_CR3)); 5476 5515 } 5477 5516 if (VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES)) … … 5479 5518 rc = PGMGstUpdatePaePdpes(pVCpu, &pVCpu->hm.s.aPdpes[0]); 5480 5519 AssertRC(rc); 5520 Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES)); 5481 5521 } 5482 5522 … … 6762 6802 /* 6763 6803 * If the TPR was raised by the guest, it wouldn't cause a VM-exit immediately. Instead we sync the TPR lazily whenever 6764 * we eventually get a VM-exit for any reason. This maybe expensive as PDMApicSetTPR() can longjmp to ring-3; also why 6765 * we do it outside of hmR0VmxSaveGuestState() which must never cause longjmps. 6804 * we eventually get a VM-exit for any reason. This maybe expensive as PDMApicSetTPR() can longjmp to ring-3 and which is 6805 * why it's done here as it's easier and no less efficient to deal with it here than making hmR0VmxSaveGuestState() 6806 * cope with longjmps safely (see VMCPU_FF_HM_UPDATE_CR3 handling). 6766 6807 */ 6767 6808 if ( (pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW)
Note:
See TracChangeset
for help on using the changeset viewer.