Changeset 45685 in vbox for trunk/src/VBox/VMM/VMMR0
- Timestamp:
- Apr 23, 2013 5:27:33 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r45684 r45685 221 221 *******************************************************************************/ 222 222 static void hmR0VmxFlushVpid(PVM pVM, PVMCPU pVCpu, VMX_FLUSH_VPID enmFlush, RTGCPTR GCPtr); 223 static int hmR0VmxInjectEventVmcs(PVMCPU pVCpu, PCPUMCTX pMixedCtx, uint64_t u64IntrInfo, 224 uint32_t cbInstr, uint32_t u32ErrCode, uint32_t *puIntrState);223 static int hmR0VmxInjectEventVmcs(PVMCPU pVCpu, PCPUMCTX pMixedCtx, uint64_t u64IntrInfo, uint32_t cbInstr, 224 uint32_t u32ErrCode, RTGCUINTREG uCR2, uint32_t *puIntrState); 225 225 #if HC_ARCH_BITS == 32 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL) 226 226 static int hmR0VmxInitVmcsReadCache(PVM pVM, PVMCPU pVCpu); … … 5465 5465 /* Refer Intel spec. 24.8.3 "VM-entry Controls for Event Injection" for the format of u32IntrInfo. */ 5466 5466 uint32_t u32IntrInfo = uVector | (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT); 5467 uint32_t u32ErrCode = uErrCode;5468 5467 if (enmTrpmEvent == TRPM_TRAP) 5469 5468 { … … 5478 5477 5479 5478 case X86_XCPT_PF: 5480 pCtx->cr2 = GCPtrFaultAddress;5481 /* no break */5482 5479 case X86_XCPT_DF: 5483 5480 case X86_XCPT_TS: … … 5503 5500 } 5504 5501 else if (enmTrpmEvent == TRPM_SOFTWARE_INT) 5502 { 5505 5503 u32IntrInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_INT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT); 5504 } 5506 5505 else 5507 5506 AssertMsgFailed(("Invalid TRPM event type %d\n", enmTrpmEvent)); … … 5509 5508 rc = TRPMResetTrap(pVCpu); 5510 5509 AssertRC(rc); 5511 Log(("Converting TRPM trap: u32IntrInfo=%#RX32 enmTrpmEvent=%d cbInstr=%u u 32ErrCode=%#RX32 GCPtrFaultAddress=%#RGv\n",5512 u32IntrInfo, enmTrpmEvent, cbInstr, u 32ErrCode, GCPtrFaultAddress));5513 hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, cbInstr, u 32ErrCode, GCPtrFaultAddress);5510 Log(("Converting TRPM trap: u32IntrInfo=%#RX32 enmTrpmEvent=%d cbInstr=%u uErrCode=%#RX32 GCPtrFaultAddress=%#RGv\n", 5511 u32IntrInfo, enmTrpmEvent, cbInstr, uErrCode, GCPtrFaultAddress)); 5512 hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, cbInstr, uErrCode, GCPtrFaultAddress); 5514 5513 } 5515 5514 … … 5795 5794 Log(("Injecting pending event\n")); 5796 5795 rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, pVCpu->hm.s.Event.u64IntrInfo, pVCpu->hm.s.Event.cbInstr, 5797 pVCpu->hm.s.Event.u32ErrCode, &uIntrState);5796 pVCpu->hm.s.Event.u32ErrCode, pVCpu->hm.s.Event.GCPtrFaultAddress, &uIntrState); 5798 5797 AssertRCReturn(rc, rc); 5799 5798 pVCpu->hm.s.Event.fPending = false; … … 5812 5811 uIntrInfo = X86_XCPT_NMI | (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT); 5813 5812 uIntrInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT); 5814 rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, uIntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */, &uIntrState); 5813 rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, uIntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */, 5814 0 /* GCPtrFaultAddress */, &uIntrState); 5815 5815 AssertRCReturn(rc, rc); 5816 5816 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_NMI); … … 5836 5836 uint32_t u32IntrInfo = u8Interrupt | (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT); 5837 5837 u32IntrInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT_INT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT); 5838 rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */, &uIntrState); 5838 rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */, 5839 0 /* GCPtrFaultAddress */, &uIntrState); 5839 5840 } 5840 5841 else … … 5923 5924 u32IntrInfo |= VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID; 5924 5925 STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject); 5925 return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */, puIntrState); 5926 return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */, 0 /* GCPtrFaultAddress */, 5927 puIntrState); 5926 5928 } 5927 5929 … … 5981 5983 u32IntrInfo |= VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID; 5982 5984 STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject); 5983 return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, u32ErrorCode, puIntrState); 5985 return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, u32ErrorCode, 0 /* GCPtrFaultAddress */, 5986 puIntrState); 5984 5987 } 5985 5988 … … 6045 6048 * @retval VINF_EM_RESET if event injection resulted in a triple-fault. 6046 6049 * 6047 * @param pVCpu Pointer to the VMCPU. 6048 * @param pMixedCtx Pointer to the guest-CPU context. The data may be 6049 * out-of-sync. Make sure to update the required fields 6050 * before using them. 6051 * @param u64IntrInfo The VM-entry interruption-information field. 6052 * @param cbInstr The VM-entry instruction length in bytes (for software 6053 * interrupts, exceptions and privileged software 6054 * exceptions). 6055 * @param u32ErrCode The VM-entry exception error code. 6056 * @param puIntrState Pointer to the current guest interruptibility-state. 6057 * This interruptibility-state will be updated if 6058 * necessary. This cannot not be NULL. 6050 * @param pVCpu Pointer to the VMCPU. 6051 * @param pMixedCtx Pointer to the guest-CPU context. The data may 6052 * be out-of-sync. Make sure to update the required 6053 * fields before using them. 6054 * @param u64IntrInfo The VM-entry interruption-information field. 6055 * @param cbInstr The VM-entry instruction length in bytes (for 6056 * software interrupts, exceptions and privileged 6057 * software exceptions). 6058 * @param u32ErrCode The VM-entry exception error code. 6059 * @param GCPtrFaultAddress The page-fault address for #PF exceptions. 6060 * @param puIntrState Pointer to the current guest interruptibility-state. 6061 * This interruptibility-state will be updated if 6062 * necessary. This cannot not be NULL. 6059 6063 * 6060 6064 * @remarks No-long-jump zone!!! … … 6062 6066 */ 6063 6067 static int hmR0VmxInjectEventVmcs(PVMCPU pVCpu, PCPUMCTX pMixedCtx, uint64_t u64IntrInfo, uint32_t cbInstr, 6064 uint32_t u32ErrCode, uint32_t *puIntrState)6068 uint32_t u32ErrCode, RTGCUINTREG GCPtrFaultAddress, uint32_t *puIntrState) 6065 6069 { 6066 6070 /* Intel spec. 24.8.3 "VM-Entry Controls for Event Injection" specifies the interruption-information field to be 32-bits. */ … … 6151 6155 pMixedCtx->cs.Sel = selIdtEntry; 6152 6156 pMixedCtx->cs.u64Base = selIdtEntry << cbIdtEntry; 6157 if ( VMX_EXIT_INTERRUPTION_INFO_TYPE(u32IntrInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT 6158 && uVector == X86_XCPT_PF) 6159 { 6160 pMixedCtx->cr2 = GCPtrFaultAddress; 6161 } 6153 6162 pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_SEGMENT_REGS 6154 6163 | HM_CHANGED_GUEST_RIP … … 6164 6173 *puIntrState &= ~VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI; 6165 6174 } 6166 Log(("Injecting u32IntrInfo=%#x u32ErrCode=%#x instrlen=%#x\n", u32IntrInfo, u32ErrCode, cbInstr));6175 Log(("Injecting real-mode: u32IntrInfo=%#x u32ErrCode=%#x instrlen=%#x\n", u32IntrInfo, u32ErrCode, cbInstr)); 6167 6176 } 6168 6177 Assert(rc == VINF_SUCCESS || rc == VINF_EM_RESET); … … 6185 6194 6186 6195 /* Inject. */ 6187 Log(("Injecting u32IntrInfo=%#x u32ErrCode=%#x cbInstr=%#x uCR2=%#RGv\n", u32IntrInfo, u32ErrCode, cbInstr, pMixedCtx->cr2));6188 6196 rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO, u32IntrInfo); 6189 6197 if (VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(u32IntrInfo)) 6190 6198 rc |= VMXWriteVmcs32(VMX_VMCS32_CTRL_ENTRY_EXCEPTION_ERRCODE, u32ErrCode); 6191 6199 rc |= VMXWriteVmcs32(VMX_VMCS32_CTRL_ENTRY_INSTR_LENGTH, cbInstr); 6200 6201 if ( VMX_EXIT_INTERRUPTION_INFO_TYPE(u32IntrInfo) == VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT 6202 && uVector == X86_XCPT_PF) 6203 { 6204 pMixedCtx->cr2 = GCPtrFaultAddress; 6205 } 6206 Log(("Injecting u32IntrInfo=%#x u32ErrCode=%#x cbInstr=%#x uCR2=%#RGv\n", u32IntrInfo, u32ErrCode, cbInstr, pMixedCtx->cr2)); 6207 6192 6208 AssertRCReturn(rc, rc); 6193 6209 return rc; … … 8769 8785 if (RT_LIKELY(!pVmxTransient->fVectoringPF)) 8770 8786 { 8771 pMixedCtx->cr2 = pVmxTransient->uExitQualification;8772 8787 pVCpu->hm.s.Event.fPending = false; /* In case it's a contributory #PF. */ 8773 8788 hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8774 0 /* cbInstr */, pVmxTransient->uExitIntrErrorCode, p MixedCtx->cr2);8789 0 /* cbInstr */, pVmxTransient->uExitIntrErrorCode, pVmxTransient->uExitQualification); 8775 8790 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF); 8776 8791 } … … 8849 8864 uint32_t uGstErrorCode = TRPMGetErrorCode(pVCpu); 8850 8865 TRPMResetTrap(pVCpu); 8851 pMixedCtx->cr2 = pVmxTransient->uExitQualification;8852 8866 pVCpu->hm.s.Event.fPending = false; /* In case it's a contributory #PF. */ 8853 8867 hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8854 0 /* cbInstr */, uGstErrorCode, p MixedCtx->cr2);8868 0 /* cbInstr */, uGstErrorCode, pVmxTransient->uExitQualification); 8855 8869 } 8856 8870 else
Note:
See TracChangeset
for help on using the changeset viewer.