- Timestamp:
- Sep 3, 2013 3:00:18 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r48248 r48250 316 316 static void hmR0VmxFlushEpt(PVMCPU pVCpu, VMX_FLUSH_EPT enmFlush); 317 317 static void hmR0VmxFlushVpid(PVM pVM, PVMCPU pVCpu, VMX_FLUSH_VPID enmFlush, RTGCPTR GCPtr); 318 static void hmR0VmxClearEventVmcs(PVMCPU pVCpu, PCPUMCTX pMixedCtx); 318 319 static int hmR0VmxInjectEventVmcs(PVMCPU pVCpu, PCPUMCTX pMixedCtx, uint64_t u64IntrInfo, uint32_t cbInstr, 319 320 uint32_t u32ErrCode, RTGCUINTREG GCPtrFaultAddress, uint32_t *puIntrState); … … 6475 6476 * out-of-sync. Make sure to update the required fields 6476 6477 * before using them. 6477 *6478 * @remarks No-long-jump zone!!!6479 6478 */ 6480 6479 static int hmR0VmxInjectPendingEvent(PVMCPU pVCpu, PCPUMCTX pMixedCtx) 6481 6480 { 6481 HMVMX_ASSERT_PREEMPT_SAFE(); 6482 Assert(VMMRZCallRing3IsEnabled(pVCpu)); 6483 6482 6484 /* Get the current interruptibility-state of the guest and then figure out what can be injected. */ 6483 6485 uint32_t uIntrState = hmR0VmxGetGuestIntrState(pVCpu, pMixedCtx); … … 6515 6517 pVCpu->hm.s.Event.u32ErrCode, pVCpu->hm.s.Event.GCPtrFaultAddress, &uIntrState); 6516 6518 AssertRCReturn(rc, rc); 6517 6518 pVCpu->hm.s.Event.fPending = false;6519 6519 6520 6520 /* Update the interruptibility-state as it could have been changed by … … 6733 6733 * necessary. This cannot not be NULL. 6734 6734 * 6735 * @remarks Requires CR0! 6735 6736 * @remarks No-long-jump zone!!! 6736 * @remarks Requires CR0!6737 6737 */ 6738 6738 static int hmR0VmxInjectEventVmcs(PVMCPU pVCpu, PCPUMCTX pMixedCtx, uint64_t u64IntrInfo, uint32_t cbInstr, … … 6872 6872 } 6873 6873 Log4(("Injecting real-mode: u32IntrInfo=%#x u32ErrCode=%#x instrlen=%#x\n", u32IntrInfo, u32ErrCode, cbInstr)); 6874 6875 /* The event has been truly dispatched. Mark it as no longer pending so we don't attempt to 'undo' 6876 it, if we are returning to ring-3 before executing guest code. */ 6877 pVCpu->hm.s.Event.fPending = false; 6874 6878 } 6875 6879 Assert(rc == VINF_SUCCESS || rc == VINF_EM_RESET); … … 6908 6912 AssertRCReturn(rc, rc); 6909 6913 return rc; 6914 } 6915 6916 6917 /** 6918 * Clears the current event in the VMCS. 6919 * 6920 * @returns VBox status code. 6921 * @param pVCpu Pointer to the VMCPU. 6922 * 6923 * @remarks Use this function only to clear events that have not yet been 6924 * delivered to the guest but are injected in the VMCS! 6925 * @remarks No-long-jump zone!!! 6926 */ 6927 static void hmR0VmxClearEventVmcs(PVMCPU pVCpu) 6928 { 6929 if (!pVCpu->hm.s.Event.fPending) 6930 return; 6931 6932 #ifdef VBOX_STRICT 6933 uint32_t u32EntryInfo; 6934 int rc2 = VMXReadVmcs32(VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO, &u32EntryInfo); 6935 AssertRC(rc2); 6936 Assert(VMX_ENTRY_INTERRUPTION_INFO_VALID(u32EntryInfo)); 6937 #endif 6938 6939 /* Clear the entry-interruption field (including the valid bit). */ 6940 int rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO, 0); 6941 AssertRC(rc); 6942 6943 /* Clear the pending debug exception field. */ 6944 rc = VMXWriteVmcs32(VMX_VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS, 0); 6945 AssertRC(rc); 6910 6946 } 6911 6947 … … 7350 7386 else if (!pVCpu->hm.s.Event.fPending) 7351 7387 hmR0VmxEvaluatePendingEvent(pVCpu, pMixedCtx); 7388 7389 /* 7390 * Event injection may take locks (currently the PGM lock for real-on-v86 case) and thus needs to be done with 7391 * longjmps or interrupts + preemption enabled. Event injection might also result in triple-faulting the VM. 7392 */ 7393 rc = hmR0VmxInjectPendingEvent(pVCpu, pMixedCtx); 7394 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 7395 { 7396 Assert(rc == VINF_EM_RESET); 7397 return rc; 7398 } 7352 7399 7353 7400 /* … … 7372 7419 || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_TO_R3_MASK)) 7373 7420 { 7421 hmR0VmxClearEventVmcs(pVCpu); 7374 7422 ASMSetFlags(pVmxTransient->uEflags); 7375 7423 VMMRZCallRing3Enable(pVCpu); … … 7379 7427 if (RTThreadPreemptIsPending(NIL_RTTHREAD)) 7380 7428 { 7429 hmR0VmxClearEventVmcs(pVCpu); 7381 7430 ASMSetFlags(pVmxTransient->uEflags); 7382 7431 VMMRZCallRing3Enable(pVCpu); … … 7385 7434 } 7386 7435 7387 /* 7388 * Event injection might result in triple-faulting the VM (real-on-v86 case), which is why it's 7389 * done here and not in hmR0VmxPreRunGuestCommitted() which doesn't expect failures. 7390 */ 7391 rc = hmR0VmxInjectPendingEvent(pVCpu, pMixedCtx); 7392 if (RT_UNLIKELY(rc != VINF_SUCCESS)) 7393 { 7394 ASMSetFlags(pVmxTransient->uEflags); 7395 VMMRZCallRing3Enable(pVCpu); 7396 return rc; 7397 } 7436 /* We've injected any pending events. This is really the point of no return (to ring-3). */ 7437 pVCpu->hm.s.Event.fPending = false; 7398 7438 7399 7439 return VINF_SUCCESS;
Note:
See TracChangeset
for help on using the changeset viewer.