Changeset 73015 in vbox for trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
- Timestamp:
- Jul 10, 2018 4:38:01 AM (7 years ago)
- svn:sync-xref-src-repo-rev:
- 123567
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp
r72988 r73015 3204 3204 3205 3205 Assert(pVCpu); 3206 Assert(pvUser);3207 3206 Assert(VMMRZCallRing3IsEnabled(pVCpu)); 3208 3207 HMSVM_ASSERT_PREEMPT_SAFE(pVCpu); … … 6061 6060 6062 6061 /** 6063 * Gets the length of the current instruction if the CPU supports the NRIP_SAVE 6064 * feature. Otherwise, returns the value in @a cbLikely. 6065 * 6062 * Gets the length of the current instruction when the CPU supports the NRIP_SAVE 6063 * feature. 6064 * 6065 * @returns The current instruction length in bytes. 6066 6066 * @param pVCpu The cross context virtual CPU structure. 6067 * @param cbLikely The likely instruction length. 6068 */ 6069 DECLINLINE(uint8_t) hmR0SvmGetInstrLengthHwAssist(PVMCPU pVCpu, uint8_t cbLikely) 6070 { 6071 Assert(cbLikely <= 15); /* See Intel spec. 2.3.11 "AVX Instruction Length" */ 6072 bool const fSupportsNextRipSave = hmR0SvmSupportsNextRipSave(pVCpu); 6073 if (fSupportsNextRipSave) 6074 { 6075 PCSVMVMCB pVmcb = hmR0SvmGetCurrentVmcb(pVCpu); 6076 uint8_t const cbInstr = pVmcb->ctrl.u64NextRIP - pVCpu->cpum.GstCtx.rip; 6077 Assert(cbInstr == cbLikely); 6078 return cbInstr; 6079 } 6080 return cbLikely; 6067 * 6068 * @remarks Requires the NRIP_SAVE feature to be supported by the CPU. 6069 */ 6070 DECLINLINE(uint8_t) hmR0SvmGetInstrLength(PVMCPU pVCpu) 6071 { 6072 Assert(hmR0SvmSupportsNextRipSave(pVCpu)); 6073 PCSVMVMCB pVmcb = hmR0SvmGetCurrentVmcb(pVCpu); 6074 return pVmcb->ctrl.u64NextRIP - pVCpu->cpum.GstCtx.rip; 6081 6075 } 6082 6076 … … 6173 6167 if (!pExitRec) 6174 6168 { 6175 rcStrict = IEMExecDecodedCpuid(pVCpu, hmR0SvmGetInstrLengthHwAssist(pVCpu, 2)); 6169 bool const fSupportsNextRipSave = hmR0SvmSupportsNextRipSave(pVCpu); 6170 if (fSupportsNextRipSave) 6171 { 6172 uint8_t const cbInstr = hmR0SvmGetInstrLength(pVCpu); 6173 rcStrict = IEMExecDecodedCpuid(pVCpu, cbInstr); 6174 } 6175 else 6176 { 6177 HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK); 6178 rcStrict = IEMExecOne(pVCpu); 6179 } 6180 6176 6181 if (rcStrict == VINF_IEM_RAISED_XCPT) 6182 { 6177 6183 rcStrict = VINF_SUCCESS; 6184 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 6185 } 6178 6186 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 6179 6187 } … … 6205 6213 HMSVM_VALIDATE_EXIT_HANDLER_PARAMS(pVCpu, pSvmTransient); 6206 6214 HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK); 6207 VBOXSTRICTRC rcStrict = IEMExecDecodedRdtsc(pVCpu, hmR0SvmGetInstrLengthHwAssist(pVCpu, 2)); 6215 6216 VBOXSTRICTRC rcStrict; 6217 bool const fSupportsNextRipSave = hmR0SvmSupportsNextRipSave(pVCpu); 6218 if (fSupportsNextRipSave) 6219 { 6220 uint8_t const cbInstr = hmR0SvmGetInstrLength(pVCpu); 6221 rcStrict = IEMExecDecodedRdtsc(pVCpu, cbInstr); 6222 } 6223 else 6224 rcStrict = IEMExecOne(pVCpu); 6225 6208 6226 if (rcStrict == VINF_SUCCESS) 6209 6227 pSvmTransient->fUpdateTscOffsetting = true; 6210 6228 else if (rcStrict == VINF_IEM_RAISED_XCPT) 6229 { 6211 6230 rcStrict = VINF_SUCCESS; 6231 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 6232 } 6212 6233 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 6213 6234 return VBOXSTRICTRC_TODO(rcStrict); … … 6221 6242 { 6222 6243 HMSVM_VALIDATE_EXIT_HANDLER_PARAMS(pVCpu, pSvmTransient); 6223 VBOXSTRICTRC rcStrict = IEMExecDecodedRdtscp(pVCpu, hmR0SvmGetInstrLengthHwAssist(pVCpu, 3));6224 6244 HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK); 6245 6246 VBOXSTRICTRC rcStrict; 6247 bool const fSupportsNextRipSave = hmR0SvmSupportsNextRipSave(pVCpu); 6248 if (fSupportsNextRipSave) 6249 { 6250 uint8_t const cbInstr = hmR0SvmGetInstrLength(pVCpu); 6251 rcStrict = IEMExecDecodedRdtscp(pVCpu, cbInstr); 6252 } 6253 else 6254 rcStrict = IEMExecOne(pVCpu); 6255 6225 6256 if (rcStrict == VINF_SUCCESS) 6226 6257 pSvmTransient->fUpdateTscOffsetting = true; 6227 6258 else if (rcStrict == VINF_IEM_RAISED_XCPT) 6259 { 6228 6260 rcStrict = VINF_SUCCESS; 6261 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 6262 } 6229 6263 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 6230 6264 return VBOXSTRICTRC_TODO(rcStrict); … … 6282 6316 } 6283 6317 6284 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); /* RIP updated by IEMExecDecodedInvlpg() or IEMExecOne(). */ 6318 if (rcStrict == VINF_IEM_RAISED_XCPT) 6319 { 6320 rcStrict = VINF_SUCCESS; 6321 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 6322 } 6323 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 6285 6324 return VBOXSTRICTRC_VAL(rcStrict); 6286 6325 } … … 6551 6590 HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, IEM_CPUMCTX_EXTRN_EXEC_DECODED_NO_MEM_MASK | CPUMCTX_EXTRN_ALL_MSRS); 6552 6591 rcStrict = IEMExecDecodedRdmsr(pVCpu, pVmcb->ctrl.u64NextRIP - pCtx->rip); 6553 if (RT_LIKELY(rcStrict == VINF_SUCCESS))6554 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); /* RIP updated by IEMExecDecodedRdmsr(). */6555 else6556 AssertMsg( rcStrict == VINF_IEM_RAISED_XCPT6557 || rcStrict == VINF_CPUM_R3_MSR_WRITE,6558 ("Unexpected IEMExecDecodedWrmsr status: %Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));6559 6592 } 6560 6593 else … … 6562 6595 HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK | CPUMCTX_EXTRN_ALL_MSRS); 6563 6596 rcStrict = IEMExecOne(pVCpu); 6564 if (RT_LIKELY(rcStrict == VINF_SUCCESS)) 6565 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); /* RIP updated by IEMExecOne(). */ 6566 else 6567 AssertMsg( rcStrict == VINF_IEM_RAISED_XCPT 6568 || rcStrict == VINF_CPUM_R3_MSR_READ, ("Unexpected IEMExecOne status: %Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 6569 } 6597 } 6598 6599 AssertMsg( rcStrict == VINF_SUCCESS 6600 || rcStrict == VINF_IEM_RAISED_XCPT 6601 || rcStrict == VINF_CPUM_R3_MSR_READ, 6602 ("hmR0SvmExitReadMsr: Unexpected status %Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 6603 6604 if (rcStrict == VINF_IEM_RAISED_XCPT) 6605 { 6606 rcStrict = VINF_SUCCESS; 6607 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 6608 } 6609 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 6570 6610 return rcStrict; 6571 6611 } … … 6580 6620 * @param pSvmTransient Pointer to the SVM-transient structure. 6581 6621 */ 6582 static VBOXSTRICTRC 6622 static VBOXSTRICTRC hmR0SvmExitWriteMsr(PVMCPU pVCpu, PSVMVMCB pVmcb, PSVMTRANSIENT pSvmTransient) 6583 6623 { 6584 6624 PCPUMCTX pCtx = &pVCpu->cpum.GstCtx; … … 6620 6660 HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, IEM_CPUMCTX_EXTRN_EXEC_DECODED_NO_MEM_MASK | CPUMCTX_EXTRN_ALL_MSRS); 6621 6661 rcStrict = IEMExecDecodedWrmsr(pVCpu, pVmcb->ctrl.u64NextRIP - pCtx->rip); 6622 if (RT_LIKELY(rcStrict == VINF_SUCCESS))6623 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); /* RIP updated by IEMExecDecodedWrmsr(). */6624 else6625 AssertMsg( rcStrict == VINF_IEM_RAISED_XCPT6626 || rcStrict == VINF_CPUM_R3_MSR_WRITE,6627 ("Unexpected IEMExecDecodedWrmsr status: %Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));6628 6662 } 6629 6663 else … … 6631 6665 HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK | CPUMCTX_EXTRN_ALL_MSRS); 6632 6666 rcStrict = IEMExecOne(pVCpu); 6633 if (RT_LIKELY(rcStrict == VINF_SUCCESS))6634 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); /* RIP updated by IEMExecOne(). */ 6635 else6636 AssertMsg(rcStrict == VINF_IEM_RAISED_XCPT6637 || rcStrict == VINF_CPUM_R3_MSR_WRITE, ("Unexpected IEMExecOne status: %Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));6638 }6667 } 6668 6669 AssertMsg( rcStrict == VINF_SUCCESS 6670 || rcStrict == VINF_IEM_RAISED_XCPT 6671 || rcStrict == VINF_CPUM_R3_MSR_WRITE, 6672 ("hmR0SvmExitWriteMsr: Unexpected status %Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 6639 6673 6640 6674 if (rcStrict == VINF_SUCCESS) … … 6665 6699 } 6666 6700 } 6667 6701 else if (rcStrict == VINF_IEM_RAISED_XCPT) 6702 { 6703 rcStrict = VINF_SUCCESS; 6704 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 6705 } 6706 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 6668 6707 return rcStrict; 6669 6708 } … … 6782 6821 /** @todo decode assists... */ 6783 6822 VBOXSTRICTRC rcStrict = IEMExecOne(pVCpu); 6784 if (rcStrict == VINF_IEM_RAISED_XCPT) 6823 if (RT_LIKELY(rcStrict == VINF_SUCCESS)) 6824 { 6825 PCPUMCTX pCtx = &pVCpu->cpum.GstCtx; 6826 pVCpu->hm.s.fLoadSaveGuestXcr0 = (pCtx->cr4 & X86_CR4_OSXSAVE) && pCtx->aXcr[0] != ASMGetXcr0(); 6827 Log4Func(("New XCR0=%#RX64 fLoadSaveGuestXcr0=%RTbool (cr4=%#RX64)\n", pCtx->aXcr[0], pVCpu->hm.s.fLoadSaveGuestXcr0, 6828 pCtx->cr4)); 6829 } 6830 else if (rcStrict == VINF_IEM_RAISED_XCPT) 6831 { 6832 rcStrict = VINF_SUCCESS; 6785 6833 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 6786 6787 PCPUMCTX pCtx = &pVCpu->cpum.GstCtx; 6788 pVCpu->hm.s.fLoadSaveGuestXcr0 = (pCtx->cr4 & X86_CR4_OSXSAVE) && pCtx->aXcr[0] != ASMGetXcr0(); 6789 Log4Func(("New XCR0=%#RX64 fLoadSaveGuestXcr0=%d (cr4=%RX64) rcStrict=%Rrc\n", pCtx->aXcr[0], pVCpu->hm.s.fLoadSaveGuestXcr0, 6790 pCtx->cr4, VBOXSTRICTRC_VAL(rcStrict))); 6791 6834 } 6792 6835 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 6793 6836 return VBOXSTRICTRC_TODO(rcStrict); … … 7699 7742 #endif 7700 7743 7701 uint8_t const cbInstr = hmR0SvmGetInstrLengthHwAssist(pVCpu, 3); 7702 VBOXSTRICTRC rcStrict = IEMExecDecodedClgi(pVCpu, cbInstr); 7744 VBOXSTRICTRC rcStrict; 7745 bool const fSupportsNextRipSave = hmR0SvmSupportsNextRipSave(pVCpu); 7746 if (fSupportsNextRipSave) 7747 { 7748 uint8_t const cbInstr = hmR0SvmGetInstrLength(pVCpu); 7749 rcStrict = IEMExecDecodedClgi(pVCpu, cbInstr); 7750 } 7751 else 7752 rcStrict = IEMExecOne(pVCpu); 7753 7703 7754 if (rcStrict == VINF_SUCCESS) 7704 7755 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_GUEST_HWVIRT); 7705 return VBOXSTRICTRC_VAL(rcStrict); 7756 else if (rcStrict == VINF_IEM_RAISED_XCPT) 7757 { 7758 rcStrict = VINF_SUCCESS; 7759 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 7760 } 7761 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 7762 return VBOXSTRICTRC_TODO(rcStrict); 7706 7763 } 7707 7764 … … 7723 7780 hmR0SvmClearCtrlIntercept(pVCpu, pVmcb, SVM_CTRL_INTERCEPT_STGI); 7724 7781 7725 uint8_t const cbInstr = hmR0SvmGetInstrLengthHwAssist(pVCpu, 3); 7726 VBOXSTRICTRC rcStrict = IEMExecDecodedStgi(pVCpu, cbInstr); 7782 VBOXSTRICTRC rcStrict; 7783 bool const fSupportsNextRipSave = hmR0SvmSupportsNextRipSave(pVCpu); 7784 if (fSupportsNextRipSave) 7785 { 7786 uint8_t const cbInstr = hmR0SvmGetInstrLength(pVCpu); 7787 rcStrict = IEMExecDecodedStgi(pVCpu, cbInstr); 7788 } 7789 else 7790 rcStrict = IEMExecOne(pVCpu); 7791 7727 7792 if (rcStrict == VINF_SUCCESS) 7728 7793 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_GUEST_HWVIRT); 7729 return VBOXSTRICTRC_VAL(rcStrict); 7794 else if (rcStrict == VINF_IEM_RAISED_XCPT) 7795 { 7796 rcStrict = VINF_SUCCESS; 7797 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 7798 } 7799 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 7800 return VBOXSTRICTRC_TODO(rcStrict); 7730 7801 } 7731 7802 … … 7749 7820 #endif 7750 7821 7751 uint8_t const cbInstr = hmR0SvmGetInstrLengthHwAssist(pVCpu, 3); 7752 VBOXSTRICTRC rcStrict = IEMExecDecodedVmload(pVCpu, cbInstr); 7822 VBOXSTRICTRC rcStrict; 7823 bool const fSupportsNextRipSave = hmR0SvmSupportsNextRipSave(pVCpu); 7824 if (fSupportsNextRipSave) 7825 { 7826 uint8_t const cbInstr = hmR0SvmGetInstrLength(pVCpu); 7827 rcStrict = IEMExecDecodedVmload(pVCpu, cbInstr); 7828 } 7829 else 7830 rcStrict = IEMExecOne(pVCpu); 7831 7753 7832 if (rcStrict == VINF_SUCCESS) 7754 7833 { … … 7758 7837 | HM_CHANGED_GUEST_SYSENTER_MSR_MASK); 7759 7838 } 7760 return VBOXSTRICTRC_VAL(rcStrict); 7839 else if (rcStrict == VINF_IEM_RAISED_XCPT) 7840 { 7841 rcStrict = VINF_SUCCESS; 7842 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 7843 } 7844 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 7845 return VBOXSTRICTRC_TODO(rcStrict); 7761 7846 } 7762 7847 … … 7776 7861 RT_NOREF(pVmcb); 7777 7862 #endif 7778 7779 uint8_t const cbInstr = hmR0SvmGetInstrLengthHwAssist(pVCpu, 3); 7780 VBOXSTRICTRC rcStrict = IEMExecDecodedVmsave(pVCpu, cbInstr); 7781 return VBOXSTRICTRC_VAL(rcStrict); 7863 VBOXSTRICTRC rcStrict; 7864 bool const fSupportsNextRipSave = hmR0SvmSupportsNextRipSave(pVCpu); 7865 if (fSupportsNextRipSave) 7866 { 7867 uint8_t const cbInstr = hmR0SvmGetInstrLength(pVCpu); 7868 rcStrict = IEMExecDecodedVmsave(pVCpu, cbInstr); 7869 } 7870 else 7871 rcStrict = IEMExecOne(pVCpu); 7872 7873 if (rcStrict == VINF_IEM_RAISED_XCPT) 7874 { 7875 rcStrict = VINF_SUCCESS; 7876 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 7877 } 7878 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 7879 return VBOXSTRICTRC_TODO(rcStrict); 7782 7880 } 7783 7881 … … 7791 7889 HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK); 7792 7890 7793 uint8_t const cbInstr = hmR0SvmGetInstrLengthHwAssist(pVCpu, 3); 7794 VBOXSTRICTRC rcStrict = IEMExecDecodedInvlpga(pVCpu, cbInstr); 7795 return VBOXSTRICTRC_VAL(rcStrict); 7891 VBOXSTRICTRC rcStrict; 7892 bool const fSupportsNextRipSave = hmR0SvmSupportsNextRipSave(pVCpu); 7893 if (fSupportsNextRipSave) 7894 { 7895 uint8_t const cbInstr = hmR0SvmGetInstrLength(pVCpu); 7896 rcStrict = IEMExecDecodedInvlpga(pVCpu, cbInstr); 7897 } 7898 else 7899 rcStrict = IEMExecOne(pVCpu); 7900 7901 if (rcStrict == VINF_IEM_RAISED_XCPT) 7902 { 7903 rcStrict = VINF_SUCCESS; 7904 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 7905 } 7906 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 7907 return VBOXSTRICTRC_TODO(rcStrict); 7796 7908 } 7797 7909 … … 7804 7916 HMSVM_VALIDATE_EXIT_HANDLER_PARAMS(pVCpu, pSvmTransient); 7805 7917 HMSVM_CPUMCTX_IMPORT_STATE(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK | IEM_CPUMCTX_EXTRN_SVM_VMRUN_MASK); 7918 7806 7919 VBOXSTRICTRC rcStrict; 7807 uint8_t const cbInstr = hmR0SvmGetInstrLengthHwAssist(pVCpu, 3); 7808 rcStrict = IEMExecDecodedVmrun(pVCpu, cbInstr); 7809 Log4Func(("IEMExecDecodedVmrun returns %Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 7920 bool const fSupportsNextRipSave = hmR0SvmSupportsNextRipSave(pVCpu); 7921 if (fSupportsNextRipSave) 7922 { 7923 uint8_t const cbInstr = hmR0SvmGetInstrLength(pVCpu); 7924 rcStrict = IEMExecDecodedVmrun(pVCpu, cbInstr); 7925 } 7926 else 7927 rcStrict = IEMExecOne(pVCpu); 7928 7810 7929 if (rcStrict == VINF_SUCCESS) 7811 7930 { … … 7813 7932 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_SVM_VMRUN_MASK); 7814 7933 } 7815 return VBOXSTRICTRC_VAL(rcStrict); 7934 else if (rcStrict == VINF_IEM_RAISED_XCPT) 7935 { 7936 rcStrict = VINF_SUCCESS; 7937 ASMAtomicUoOrU64(&pVCpu->hm.s.fCtxChanged, HM_CHANGED_XCPT_RAISED_MASK); 7938 } 7939 7940 HMSVM_CHECK_SINGLE_STEP(pVCpu, rcStrict); 7941 return VBOXSTRICTRC_TODO(rcStrict); 7816 7942 } 7817 7943
Note:
See TracChangeset
for help on using the changeset viewer.