Changeset 45502 in vbox
- Timestamp:
- Apr 12, 2013 12:22:50 AM (12 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r45501 r45502 232 232 static DECLCALLBACK(int) hmR0VmxExitRdtsc(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 233 233 static DECLCALLBACK(int) hmR0VmxExitRsm(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 234 static DECLCALLBACK(int) hmR0VmxExit InjectXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);234 static DECLCALLBACK(int) hmR0VmxExitSetPendingXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 235 235 static DECLCALLBACK(int) hmR0VmxExitMovCRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); 236 236 static DECLCALLBACK(int) hmR0VmxExitMovDRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient); … … 304 304 /* 16 VMX_EXIT_RDTSC */ hmR0VmxExitRdtsc, 305 305 /* 17 VMX_EXIT_RSM */ hmR0VmxExitRsm, 306 /* 18 VMX_EXIT_VMCALL */ hmR0VmxExit InjectXcptUD,307 /* 19 VMX_EXIT_VMCLEAR */ hmR0VmxExit InjectXcptUD,308 /* 20 VMX_EXIT_VMLAUNCH */ hmR0VmxExit InjectXcptUD,309 /* 21 VMX_EXIT_VMPTRLD */ hmR0VmxExit InjectXcptUD,310 /* 22 VMX_EXIT_VMPTRST */ hmR0VmxExit InjectXcptUD,311 /* 23 VMX_EXIT_VMREAD */ hmR0VmxExit InjectXcptUD,312 /* 24 VMX_EXIT_VMRESUME */ hmR0VmxExit InjectXcptUD,313 /* 25 VMX_EXIT_VMWRITE */ hmR0VmxExit InjectXcptUD,314 /* 26 VMX_EXIT_VMXOFF */ hmR0VmxExit InjectXcptUD,315 /* 27 VMX_EXIT_VMXON */ hmR0VmxExit InjectXcptUD,306 /* 18 VMX_EXIT_VMCALL */ hmR0VmxExitSetPendingXcptUD, 307 /* 19 VMX_EXIT_VMCLEAR */ hmR0VmxExitSetPendingXcptUD, 308 /* 20 VMX_EXIT_VMLAUNCH */ hmR0VmxExitSetPendingXcptUD, 309 /* 21 VMX_EXIT_VMPTRLD */ hmR0VmxExitSetPendingXcptUD, 310 /* 22 VMX_EXIT_VMPTRST */ hmR0VmxExitSetPendingXcptUD, 311 /* 23 VMX_EXIT_VMREAD */ hmR0VmxExitSetPendingXcptUD, 312 /* 24 VMX_EXIT_VMRESUME */ hmR0VmxExitSetPendingXcptUD, 313 /* 25 VMX_EXIT_VMWRITE */ hmR0VmxExitSetPendingXcptUD, 314 /* 26 VMX_EXIT_VMXOFF */ hmR0VmxExitSetPendingXcptUD, 315 /* 27 VMX_EXIT_VMXON */ hmR0VmxExitSetPendingXcptUD, 316 316 /* 28 VMX_EXIT_MOV_CRX */ hmR0VmxExitMovCRx, 317 317 /* 29 VMX_EXIT_MOV_DRX */ hmR0VmxExitMovDRx, … … 336 336 /* 48 VMX_EXIT_EPT_VIOLATION */ hmR0VmxExitEptViolation, 337 337 /* 49 VMX_EXIT_EPT_MISCONFIG */ hmR0VmxExitEptMisconfig, 338 /* 50 VMX_EXIT_INVEPT */ hmR0VmxExit InjectXcptUD,338 /* 50 VMX_EXIT_INVEPT */ hmR0VmxExitSetPendingXcptUD, 339 339 /* 51 VMX_EXIT_RDTSCP */ hmR0VmxExitRdtscp, 340 340 /* 52 VMX_EXIT_PREEMPT_TIMER */ hmR0VmxExitPreemptTimer, 341 /* 53 VMX_EXIT_INVVPID */ hmR0VmxExit InjectXcptUD,341 /* 53 VMX_EXIT_INVVPID */ hmR0VmxExitSetPendingXcptUD, 342 342 /* 54 VMX_EXIT_WBINVD */ hmR0VmxExitWbinvd, 343 343 /* 55 VMX_EXIT_XSETBV */ hmR0VmxExitXsetbv, … … 345 345 /* 57 VMX_EXIT_RDRAND */ hmR0VmxExitRdrand, 346 346 /* 58 VMX_EXIT_INVPCID */ hmR0VmxExitInvpcid, 347 /* 59 VMX_EXIT_VMFUNC */ hmR0VmxExit InjectXcptUD347 /* 59 VMX_EXIT_VMFUNC */ hmR0VmxExitSetPendingXcptUD 348 348 }; 349 349 … … 4637 4637 4638 4638 /** 4639 * Sets an event as a pending event to be injected into the guest. 4640 * 4641 * @param pVCpu Pointer to the VMCPU. 4642 * @param u32IntrInfo The VM-entry interruption-information field. 4643 * @param cbInstr The VM-entry instruction length in bytes (for software 4644 * interrupts, exceptions and privileged software 4645 * exceptions). 4646 * @param u32ErrCode The VM-entry exception error code. 4647 */ 4648 DECLINLINE(void) hmR0VmxSetPendingEvent(PVMCPU pVCpu, uint32_t u32IntrInfo, uint32_t cbInstr, uint32_t u32ErrCode) 4649 { 4650 Assert(!pVCpu->hm.s.Event.fPending); 4651 pVCpu->hm.s.Event.fPending = true; 4652 pVCpu->hm.s.Event.u64IntrInfo = u32IntrInfo; 4653 pVCpu->hm.s.Event.u32ErrCode = u32ErrCode; 4654 pVCpu->hm.s.Event.u32InstrLen = cbInstr; 4655 } 4656 4657 4658 /** 4639 4659 * Handle a condition that occurred while delivering an event through the guest 4640 4660 * IDT. … … 4722 4742 case VMXREFLECTXCPT_XCPT: 4723 4743 { 4724 Assert(!pVCpu->hm.s.Event.fPending); 4725 pVCpu->hm.s.Event.fPending = true; 4726 pVCpu->hm.s.Event.u64IntrInfo = VMX_ENTRY_INTR_INFO_FROM_EXIT_IDT_INFO(pVmxTransient->uIdtVectoringInfo); 4744 uint32_t u32ErrCode = 0; 4727 4745 if (VMX_IDT_VECTORING_INFO_ERROR_CODE_IS_VALID(pVCpu->hm.s.Event.u64IntrInfo)) 4728 4746 { 4729 4747 rc = hmR0VmxReadIdtVectoringErrorCodeVmcs(pVmxTransient); 4730 4748 AssertRCReturn(rc, rc); 4731 pVCpu->hm.s.Event.u32ErrCode = pVmxTransient->uIdtVectoringErrorCode;4749 u32ErrCode = pVmxTransient->uIdtVectoringErrorCode; 4732 4750 } 4733 else 4734 pVCpu->hm.s.Event.u32ErrCode = 0; 4751 hmR0VmxSetPendingEvent(pVCpu, VMX_ENTRY_INTR_INFO_FROM_EXIT_IDT_INFO(pVmxTransient->uIdtVectoringInfo), 4752 0 /* cbInstr */, u32ErrCode); 4753 rc = VINF_SUCCESS; 4735 4754 Log(("Pending event %#RX64 Err=%#RX32\n", pVCpu->hm.s.Event.u64IntrInfo, pVCpu->hm.s.Event.u32ErrCode)); 4736 4755 break; … … 4743 4762 u32IntrInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT); 4744 4763 u32IntrInfo |= VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID; 4745 4746 Assert(!pVCpu->hm.s.Event.fPending); 4747 pVCpu->hm.s.Event.fPending = true; 4748 pVCpu->hm.s.Event.u64IntrInfo = u32IntrInfo; 4749 pVCpu->hm.s.Event.u32ErrCode = 0; 4764 hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */); 4750 4765 rc = VINF_VMX_DOUBLE_FAULT; 4751 4766 Log(("Pending #DF %#RX64 uIdt=%#x uExit=%#x\n", pVCpu->hm.s.Event.u64IntrInfo, uIdtVector, uExitVector)); … … 4764 4779 } 4765 4780 } 4766 Assert(rc == VINF_SUCCESS || rc == VINF_ EM_RESET || rc == VINF_VMX_DOUBLE_FAULT);4781 Assert(rc == VINF_SUCCESS || rc == VINF_VMX_DOUBLE_FAULT || rc == VINF_EM_RESET); 4767 4782 return rc; 4768 4783 } … … 5573 5588 pVCpu->hm.s.Event.fPending = false; 5574 5589 } 5575 5576 /* Clear the VT-x state bits to prevent any stale injection. This can happen when InjectEventVmcs() */5577 int rc2 = VMXWriteVmcs32(VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO, 0);5578 AssertRC(rc2);5579 5590 } 5580 5591 … … 5804 5815 if (pVCpu->hm.s.Event.fPending) 5805 5816 { 5806 Log((" Pending event\n"));5807 int rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, pVCpu->hm.s.Event.u64IntrInfo, 0 /* cbInstr */,5808 pVCpu->hm.s.Event.u32ErrCode);5817 Log(("Injecting pending event\n")); 5818 int rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, pVCpu->hm.s.Event.u64IntrInfo, pVCpu->hm.s.Event.u32InstrLen, 5819 pVCpu->hm.s.Event.u32ErrCode); 5809 5820 AssertRCReturn(rc, rc); 5810 5821 pVCpu->hm.s.Event.fPending = false; … … 5882 5893 Assert(!TRPMHasTrap(pVCpu)); 5883 5894 AssertRCReturn(rc, rc); 5884 } 5895 return rc; 5896 } 5897 5898 /* Clear the VM-entry interruption info. if we're not injecting anything; prevents any stale injection. */ 5899 rc = VMXWriteVmcs32(VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO, 0); 5900 AssertRCReturn(rc, rc); 5885 5901 return rc; 5886 5902 } 5887 5903 5888 5904 /** 5889 * Injects an invalid-opcode (#UD) exception into the VM.5905 * Sets an invalid-opcode (#UD) exception as pending-for-injection into the VM. 5890 5906 * 5891 5907 * @returns VBox status code (informational status code included). … … 5895 5911 * before using them. 5896 5912 */ 5897 DECLINLINE(int) hmR0Vmx InjectXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx)5913 DECLINLINE(int) hmR0VmxSetPendingXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx) 5898 5914 { 5899 5915 /* Refer Intel spec. 24.8.3 "VM-entry Controls for Event Injection" for the format of u32IntrInfo. */ 5900 5916 uint32_t u32IntrInfo = X86_XCPT_UD | (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT); 5901 5917 STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject); 5902 return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */); 5918 hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */); 5919 return VINF_SUCCESS; 5920 } 5921 5922 5923 /** 5924 * Sets a double-fault (#DF) exception as pending-for-injection into the VM. 5925 * 5926 * @param pVCpu Pointer to the VMCPU. 5927 * @param pMixedCtx Pointer to the guest-CPU context. The data may be 5928 * out-of-sync. Make sure to update the required fields 5929 * before using them. 5930 */ 5931 DECLINLINE(void) hmR0VmxSetPendingXcptDF(PVMCPU pVCpu, PCPUMCTX pMixedCtx) 5932 { 5933 /* Inject the double-fault. */ 5934 uint32_t u32IntrInfo = X86_XCPT_DF | (1 << VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT); 5935 u32IntrInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT); 5936 u32IntrInfo |= VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID; 5937 STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject); 5938 hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */); 5903 5939 } 5904 5940 … … 5920 5956 u32IntrInfo |= VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID; 5921 5957 STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject); 5922 return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */);5923 } 5924 5925 5926 /** 5927 * Injects a debug (#DB) exception into the VM.5958 return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */); 5959 } 5960 5961 5962 /** 5963 * Sets a debug (#DB) exception as pending-for-injection into the VM. 5928 5964 * 5929 5965 * @returns VBox status code (informational status code included). … … 5933 5969 * before using them. 5934 5970 */ 5935 DECLINLINE(int) hmR0Vmx InjectXcptDB(PVMCPU pVCpu, PCPUMCTX pMixedCtx)5971 DECLINLINE(int) hmR0VmxSetPendingXcptDB(PVMCPU pVCpu, PCPUMCTX pMixedCtx) 5936 5972 { 5937 5973 /* Inject the debug-exception. */ … … 5939 5975 u32IntrInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT); 5940 5976 STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject); 5941 return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */); 5942 } 5943 5944 5945 /** 5946 * Injects a overflow (#OF) exception into the VM. 5977 hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, 0 /* cbInstr */, 0 /* u32ErrCode */); 5978 return VINF_SUCCESS; 5979 } 5980 5981 5982 /** 5983 * Sets an overflow (#OF) exception as pending-for-injection into the VM. 5947 5984 * 5948 5985 * @returns VBox status code (informational status code included). … … 5954 5991 * stack. 5955 5992 */ 5956 DECLINLINE(int) hmR0Vmx InjectXcptOF(PVMCPU pVCpu, PCPUMCTX pMixedCtx, uint32_t cbInstr)5993 DECLINLINE(int) hmR0VmxSetPendingXcptOF(PVMCPU pVCpu, PCPUMCTX pMixedCtx, uint32_t cbInstr) 5957 5994 { 5958 5995 /* Inject the overflow exception. */ … … 5960 5997 u32IntrInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_INT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT); 5961 5998 STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject); 5962 return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, cbInstr, 0 /* u32ErrCode */); 5999 hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, cbInstr, 0 /* u32ErrCode */); 6000 return VINF_SUCCESS; 5963 6001 } 5964 6002 … … 6004 6042 u32IntrInfo |= (VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_INT << VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT); 6005 6043 STAM_COUNTER_INC(&pVCpu->hm.s.StatIntInject); 6006 return hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, u32IntrInfo, cbInstr, 0 /* u32ErrCode */); 6044 hmR0VmxSetPendingEvent(pVCpu, u32IntrInfo, cbInstr, 0 /* u32ErrCode */); 6045 return VINF_SUCCESS; 6007 6046 } 6008 6047 … … 6748 6787 case VMX_EXIT_INVVPID: 6749 6788 case VMX_EXIT_VMFUNC: 6750 rc = hmR0VmxExit InjectXcptUD(pVCpu, pMixedCtx, pVmxTransient);6789 rc = hmR0VmxExitSetPendingXcptUD(pVCpu, pMixedCtx, pVmxTransient); 6751 6790 break; 6752 6791 default: … … 6896 6935 rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVCpu, pVmxTransient); 6897 6936 AssertRCReturn(rc, rc); 6898 rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, 6899 VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(uExitIntrInfo), 6900 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 6937 hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(uExitIntrInfo), 6938 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 6901 6939 AssertRCReturn(rc, rc); 6902 6940 } … … 7301 7339 * VM-exit handler for instructions that result in a #UD exception delivered to the guest. 7302 7340 */ 7303 static DECLCALLBACK(int) hmR0VmxExit InjectXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient)7341 static DECLCALLBACK(int) hmR0VmxExitSetPendingXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient) 7304 7342 { 7305 7343 VMX_VALIDATE_EXIT_HANDLER_PARAMS(); 7306 return hmR0VmxInjectXcptUD(pVCpu, pMixedCtx); 7344 hmR0VmxSetPendingXcptUD(pVCpu, pMixedCtx); 7345 return VINF_SUCCESS; 7307 7346 } 7308 7347 … … 7884 7923 pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_DEBUG; 7885 7924 7886 /* Inject #DB and get on withguest execution. */7887 rc = hmR0Vmx InjectXcptDB(pVCpu, pMixedCtx);7925 /* Set #DB to be injected into the VM and continue guest execution. */ 7926 rc = hmR0VmxSetPendingXcptDB(pVCpu, pMixedCtx); 7888 7927 AssertRCReturn(rc, rc); 7889 7928 break; … … 8263 8302 return VERR_EM_INTERPRETER; 8264 8303 } 8265 rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, 8266 VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8267 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 8268 AssertRCReturn(rc, rc); 8304 hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8305 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 8269 8306 return rc; 8270 8307 } … … 8293 8330 AssertRCReturn(rc, rc); 8294 8331 8295 rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, 8296 VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8297 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 8298 AssertRCReturn(rc, rc); 8299 } 8300 8301 Assert(rc == VINF_SUCCESS || rc == VINF_EM_RESET || rc == VINF_EM_RAW_GUEST_TRAP || rc == VINF_EM_DBG_BREAKPOINT); 8332 hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8333 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 8334 } 8335 8336 Assert(rc == VINF_SUCCESS || rc == VINF_EM_RAW_GUEST_TRAP || rc == VINF_EM_DBG_BREAKPOINT); 8302 8337 return rc; 8303 8338 } … … 8345 8380 rc |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient); 8346 8381 rc |= hmR0VmxReadExitIntrErrorCodeVmcs(pVCpu, pVmxTransient); 8347 rc |= hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx,8348 VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo),8349 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode);8350 8382 AssertRCReturn(rc,rc); 8383 hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8384 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 8351 8385 return rc; 8352 8386 } … … 8387 8421 rc = hmR0VmxReadExitIntrInfoVmcs(pVCpu, pVmxTransient); 8388 8422 AssertRCReturn(rc, rc); 8389 rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, 8390 VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8391 pVmxTransient->cbInstr, 0 /* error code */); 8392 AssertRCReturn(rc, rc); 8423 hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8424 pVmxTransient->cbInstr, 0 /* error code */); 8393 8425 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestNM); 8394 8426 return rc; … … 8415 8447 rc |= hmR0VmxReadExitInstrLenVmcs(pVCpu, pVmxTransient); 8416 8448 rc |= hmR0VmxSaveGuestRip(pVCpu, pMixedCtx); 8449 AssertRCReturn(rc, rc); 8417 8450 Log(("#GP Gst: RIP %#RX64\n", pMixedCtx->rip)); 8418 rc |= hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, 8419 VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8420 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 8421 AssertRCReturn(rc, rc); 8451 hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8452 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 8422 8453 return rc; 8423 8454 #else … … 8608 8639 if (pMixedCtx->eflags.Bits.u1OF) 8609 8640 { 8610 rc = hmR0Vmx InjectXcptOF(pVCpu, pMixedCtx, pDis->cbInstr);8641 rc = hmR0VmxSetPendingXcptOF(pVCpu, pMixedCtx, pDis->cbInstr); 8611 8642 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitInt); 8612 8643 } … … 8628 8659 rc = VERR_EM_INTERPRETER; 8629 8660 8630 AssertMsg(rc == VINF_SUCCESS || rc == VERR_EM_INTERPRETER || rc == VINF_PGM_CHANGE_MODE || rc == VINF_EM_HALT 8631 || rc == VINF_EM_RESET /* injection caused triple fault */, 8661 AssertMsg(rc == VINF_SUCCESS || rc == VERR_EM_INTERPRETER || rc == VINF_PGM_CHANGE_MODE || rc == VINF_EM_HALT, 8632 8662 ("#GP Unexpected rc=%Rrc\n", rc)); 8633 8663 return rc; … … 8648 8678 /* Re-inject the exception into the guest. This cannot be a double-fault condition which would have been handled in 8649 8679 hmR0VmxCheckExitDueToEventDelivery(). */ 8650 int rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, 8651 VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8652 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 8653 AssertRCReturn(rc, rc); 8654 return rc; 8680 hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8681 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 8682 return VINF_SUCCESS; 8655 8683 } 8656 8684 … … 8675 8703 { 8676 8704 pMixedCtx->cr2 = pVmxTransient->uExitQualification; 8677 rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, 8678 VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8679 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 8680 AssertRCReturn(rc, rc); 8705 hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8706 pVmxTransient->cbInstr, pVmxTransient->uExitIntrErrorCode); 8681 8707 } 8682 8708 else 8683 8709 { 8684 8710 /* A guest page-fault occurred during delivery of a page-fault. Inject #DF. */ 8685 Assert(!pVCpu->hm.s.Event.fPending); 8686 rc = hmR0VmxInjectXcptDF(pVCpu, pMixedCtx); 8711 rc = hmR0VmxSetPendingXcptDF(pVCpu, pMixedCtx); 8687 8712 } 8688 8713 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF); … … 8757 8782 TRPMResetTrap(pVCpu); 8758 8783 pMixedCtx->cr2 = pVmxTransient->uExitQualification; 8759 rc = hmR0VmxInjectEventVmcs(pVCpu, pMixedCtx, 8760 VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8761 pVmxTransient->cbInstr, uGstErrorCode); 8762 AssertRCReturn(rc, rc); 8784 hmR0VmxSetPendingEvent(pVCpu, VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(pVmxTransient->uExitIntrInfo), 8785 pVmxTransient->cbInstr, uGstErrorCode); 8763 8786 } 8764 8787 else 8765 8788 { 8766 8789 /* A guest page-fault occurred during delivery of a page-fault. Inject #DF. */ 8767 Assert(!pVCpu->hm.s.Event.fPending);8768 8790 TRPMResetTrap(pVCpu); 8769 Log(("#PF: Injecting #DF\n"));8770 rc = hmR0VmxInjectXcptDF(pVCpu, pMixedCtx);8791 hmR0VmxSetPendingXcptDF(pVCpu, pMixedCtx); 8792 Log(("#PF: Pending #DF injection\n")); 8771 8793 } 8772 8794 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitGuestPF); 8773 Assert(rc == VINF_SUCCESS || rc == VINF_EM_RESET); 8774 return rc; 8795 return VINF_SUCCESS; 8775 8796 } 8776 8797 -
trunk/src/VBox/VMM/include/HMInternal.h
r45501 r45502 731 731 uint32_t fPending; 732 732 uint32_t u32ErrCode; 733 uint32_t u32InstrLen; 733 734 uint64_t u64IntrInfo; 734 735 } Event;
Note:
See TracChangeset
for help on using the changeset viewer.