Changeset 55248 in vbox
- Timestamp:
- Apr 14, 2015 1:43:25 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
-
include/VBox/vmm/em.h (modified) (1 diff)
-
include/VBox/vmm/hm.h (modified) (1 diff)
-
include/VBox/vmm/iem.h (modified) (2 diffs)
-
src/VBox/VMM/VMMAll/EMAll.cpp (modified) (8 diffs)
-
src/VBox/VMM/VMMAll/IEMAll.cpp (modified) (5 diffs)
-
src/VBox/VMM/VMMR0/HMVMXR0.cpp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/VBox/vmm/em.h
r53615 r55248 193 193 VMM_INT_DECL(int) EMInterpretDRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegDrx, uint32_t SrcRegGen); 194 194 VMM_INT_DECL(int) EMInterpretDRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegDrx); 195 VMM_INT_DECL(int) EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen);196 VMM_INT_DECL(int) EMInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx);197 VMM_INT_DECL(int) EMInterpretLMSW(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint16_t u16Data);198 VMM_INT_DECL(int) EMInterpretCLTS(PVM pVM, PVMCPU pVCpu);199 195 VMM_INT_DECL(int) EMInterpretRdmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); 200 196 VMM_INT_DECL(int) EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame); -
trunk/include/VBox/vmm/hm.h
r55129 r55248 208 208 VMMR0_INT_DECL(int) HMR0TestSwitcher3264(PVM pVM); 209 209 # endif 210 211 VMMR0_INT_DECL(int) HMR0EnsureCompleteBasicContext(PVMCPU pVCpu, PCPUMCTX pMixedCtx); 210 212 211 213 /** @} */ -
trunk/include/VBox/vmm/iem.h
r53615 r55248 51 51 52 52 53 /** @name IEM status codes. 54 * 55 * Not quite sure how this will play out in the end, just aliasing safe status 56 * codes for now. 57 * 58 * @{ */ 59 #define VINF_IEM_RAISED_XCPT VINF_EM_RESCHEDULE 60 /** @} */ 61 62 53 63 VMMDECL(VBOXSTRICTRC) IEMExecOne(PVMCPU pVCpu); 54 64 VMMDECL(VBOXSTRICTRC) IEMExecOneEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten); … … 72 82 VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoRead(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode, 73 83 bool fRepPrefix, uint8_t cbInstr); 84 VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedMovCRxWrite(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iCrReg, uint8_t iGReg); 85 VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedMovCRxRead(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iGReg, uint8_t iCrReg); 86 VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedClts(PVMCPU pVCpu, uint8_t cbInstr); 87 VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedLmsw(PVMCPU pVCpu, uint8_t cbInstr, uint16_t uValue); 74 88 /** @} */ 75 89 -
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r54862 r55248 1453 1453 1454 1454 /** @todo Clean up this mess. */ 1455 LogFlow((" EMInterpretCRxWrite at %RGv CR%d <- %RX64\n", (RTGCPTR)pRegFrame->rip, DestRegCrx, val));1455 LogFlow(("emInterpretCRxWrite at %RGv CR%d <- %RX64\n", (RTGCPTR)pRegFrame->rip, DestRegCrx, val)); 1456 1456 Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu)); 1457 1457 switch (DestRegCrx) … … 1610 1610 * 1611 1611 */ 1612 VMM_INT_DECL(int) EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen)1612 static int emInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen) 1613 1613 { 1614 1614 uint64_t val; … … 1629 1629 1630 1630 return VERR_EM_INTERPRETER; 1631 }1632 1633 /**1634 * Interpret LMSW.1635 *1636 * @returns VBox status code.1637 * @param pVM Pointer to the VM.1638 * @param pVCpu Pointer to the VMCPU.1639 * @param pRegFrame The register frame.1640 * @param u16Data LMSW source data.1641 *1642 */1643 VMM_INT_DECL(int) EMInterpretLMSW(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint16_t u16Data)1644 {1645 Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu));1646 uint64_t OldCr0 = CPUMGetGuestCR0(pVCpu);1647 1648 /* Only PE, MP, EM and TS can be changed; note that PE can't be cleared by this instruction. */1649 uint64_t NewCr0 = ( OldCr0 & ~( X86_CR0_MP | X86_CR0_EM | X86_CR0_TS))1650 | (u16Data & (X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS));1651 1652 return emUpdateCRx(pVM, pVCpu, pRegFrame, DISCREG_CR0, NewCr0);1653 }1654 1655 1656 /**1657 * Interpret CLTS.1658 *1659 * @returns VBox status code.1660 * @param pVM Pointer to the VM.1661 * @param pVCpu Pointer to the VMCPU.1662 *1663 */1664 VMM_INT_DECL(int) EMInterpretCLTS(PVM pVM, PVMCPU pVCpu)1665 {1666 NOREF(pVM);1667 1668 uint64_t cr0 = CPUMGetGuestCR0(pVCpu);1669 if (!(cr0 & X86_CR0_TS))1670 return VINF_SUCCESS;1671 return CPUMSetGuestCR0(pVCpu, cr0 & ~X86_CR0_TS);1672 1631 } 1673 1632 … … 1805 1764 * 1806 1765 */ 1807 VMM_INT_DECL(int) EMInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx)1766 static int emInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx) 1808 1767 { 1809 1768 Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu)); … … 3351 3310 static int emInterpretClts(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize) 3352 3311 { 3353 NOREF(pDis); NOREF(pRegFrame); NOREF(pvFault); NOREF(pcbSize); 3354 return EMInterpretCLTS(pVM, pVCpu); 3312 NOREF(pVM); NOREF(pDis); NOREF(pRegFrame); NOREF(pvFault); NOREF(pcbSize); 3313 3314 uint64_t cr0 = CPUMGetGuestCR0(pVCpu); 3315 if (!(cr0 & X86_CR0_TS)) 3316 return VINF_SUCCESS; 3317 return CPUMSetGuestCR0(pVCpu, cr0 & ~X86_CR0_TS); 3355 3318 } 3356 3319 … … 3364 3327 uint32_t val; 3365 3328 NOREF(pvFault); NOREF(pcbSize); 3329 Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu)); 3366 3330 3367 3331 int rc = DISQueryParamVal(pRegFrame, pDis, &pDis->Param1, ¶m1, DISQPVWHICH_SRC); … … 3383 3347 3384 3348 LogFlow(("emInterpretLmsw %x\n", val)); 3385 return EMInterpretLMSW(pVM, pVCpu, pRegFrame, val); 3349 uint64_t OldCr0 = CPUMGetGuestCR0(pVCpu); 3350 3351 /* Only PE, MP, EM and TS can be changed; note that PE can't be cleared by this instruction. */ 3352 uint64_t NewCr0 = ( OldCr0 & ~( X86_CR0_MP | X86_CR0_EM | X86_CR0_TS)) 3353 | (val & (X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS)); 3354 3355 return emUpdateCRx(pVM, pVCpu, pRegFrame, DISCREG_CR0, NewCr0); 3356 3386 3357 } 3387 3358 … … 3446 3417 NOREF(pvFault); NOREF(pcbSize); 3447 3418 if ((pDis->Param1.fUse == DISUSE_REG_GEN32 || pDis->Param1.fUse == DISUSE_REG_GEN64) && pDis->Param2.fUse == DISUSE_REG_CR) 3448 return EMInterpretCRxRead(pVM, pVCpu, pRegFrame, pDis->Param1.Base.idxGenReg, pDis->Param2.Base.idxCtrlReg);3419 return emInterpretCRxRead(pVM, pVCpu, pRegFrame, pDis->Param1.Base.idxGenReg, pDis->Param2.Base.idxCtrlReg); 3449 3420 3450 3421 if (pDis->Param1.fUse == DISUSE_REG_CR && (pDis->Param2.fUse == DISUSE_REG_GEN32 || pDis->Param2.fUse == DISUSE_REG_GEN64)) 3451 return EMInterpretCRxWrite(pVM, pVCpu, pRegFrame, pDis->Param1.Base.idxCtrlReg, pDis->Param2.Base.idxGenReg);3422 return emInterpretCRxWrite(pVM, pVCpu, pRegFrame, pDis->Param1.Base.idxCtrlReg, pDis->Param2.Base.idxGenReg); 3452 3423 3453 3424 AssertMsgFailedReturn(("Unexpected control register move\n"), VERR_EM_INTERPRETER); -
trunk/src/VBox/VMM/VMMAll/IEMAll.cpp
r55229 r55248 189 189 * Defined Constants And Macros * 190 190 *******************************************************************************/ 191 /** @name IEM status codes.192 *193 * Not quite sure how this will play out in the end, just aliasing safe status194 * codes for now.195 *196 * @{ */197 #define VINF_IEM_RAISED_XCPT VINF_EM_RESCHEDULE198 /** @} */199 200 191 /** Temporary hack to disable the double execution. Will be removed in favor 201 192 * of a dedicated execution mode in EM. */ … … 1106 1097 if (cbToTryRead > sizeof(pIemCpu->abOpcode) - pIemCpu->cbOpcode) 1107 1098 cbToTryRead = sizeof(pIemCpu->abOpcode) - pIemCpu->cbOpcode; 1099 /** @todo r=bird: Convert assertion into undefined opcode exception? */ 1108 1100 Assert(cbToTryRead >= cbMin - cbLeft); /* ASSUMPTION based on iemInitDecoderAndPrefetchOpcodes. */ 1109 1101 … … 1201 1193 { 1202 1194 uint8_t const offOpcode = pIemCpu->offOpcode; 1203 if (RT_UNLIKELY(offOpcode >= pIemCpu->cbOpcode)) 1204 return iemOpcodeGetNextU8Slow(pIemCpu, pu8); 1205 1206 *pu8 = pIemCpu->abOpcode[offOpcode]; 1207 pIemCpu->offOpcode = offOpcode + 1; 1208 return VINF_SUCCESS; 1195 if (RT_LIKELY(offOpcode < pIemCpu->cbOpcode)) 1196 { 1197 *pu8 = pIemCpu->abOpcode[offOpcode]; 1198 pIemCpu->offOpcode = offOpcode + 1; 1199 return VINF_SUCCESS; 1200 } 1201 return iemOpcodeGetNextU8Slow(pIemCpu, pu8); 1209 1202 } 1210 1203 … … 3859 3852 { 3860 3853 PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx); 3854 #ifdef IN_RING0 3855 int rc = HMR0EnsureCompleteBasicContext(IEMCPU_TO_VMCPU(pIemCpu), pCtx); 3856 AssertRCReturn(rc, rc); 3857 #endif 3861 3858 3862 3859 /* … … 11237 11234 } 11238 11235 11236 11237 11238 /** 11239 * Interface for HM and EM to write to a CRx register. 11240 * 11241 * @returns Strict VBox status code. 11242 * @param pVCpu The cross context per virtual CPU structure. 11243 * @param cbInstr The instruction length in bytes. 11244 * @param iCrReg The control register number (destination). 11245 * @param iGReg The general purpose register number (source). 11246 * 11247 * @remarks In ring-0 not all of the state needs to be synced in. 11248 */ 11249 VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedMovCRxWrite(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iCrReg, uint8_t iGReg) 11250 { 11251 AssertReturn(cbInstr - 2U <= 15U - 2U, VERR_IEM_INVALID_INSTR_LENGTH); 11252 Assert(iCrReg < 16); 11253 Assert(iGReg < 16); 11254 11255 PIEMCPU pIemCpu = &pVCpu->iem.s; 11256 iemInitExec(pIemCpu, false /*fBypassHandlers*/); 11257 VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_2(iemCImpl_mov_Cd_Rd, iCrReg, iGReg); 11258 return iemExecStatusCodeFiddling(pIemCpu, rcStrict); 11259 } 11260 11261 11262 /** 11263 * Interface for HM and EM to read from a CRx register. 11264 * 11265 * @returns Strict VBox status code. 11266 * @param pVCpu The cross context per virtual CPU structure. 11267 * @param cbInstr The instruction length in bytes. 11268 * @param iGReg The general purpose register number (destination). 11269 * @param iCrReg The control register number (source). 11270 * 11271 * @remarks In ring-0 not all of the state needs to be synced in. 11272 */ 11273 VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedMovCRxRead(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iGReg, uint8_t iCrReg) 11274 { 11275 AssertReturn(cbInstr - 2U <= 15U - 2U, VERR_IEM_INVALID_INSTR_LENGTH); 11276 Assert(iCrReg < 16); 11277 Assert(iGReg < 16); 11278 11279 PIEMCPU pIemCpu = &pVCpu->iem.s; 11280 iemInitExec(pIemCpu, false /*fBypassHandlers*/); 11281 VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_2(iemCImpl_mov_Rd_Cd, iGReg, iCrReg); 11282 return iemExecStatusCodeFiddling(pIemCpu, rcStrict); 11283 } 11284 11285 11286 /** 11287 * Interface for HM and EM to clear the CR0[TS] bit. 11288 * 11289 * @returns Strict VBox status code. 11290 * @param pVCpu The cross context per virtual CPU structure. 11291 * @param cbInstr The instruction length in bytes. 11292 * 11293 * @remarks In ring-0 not all of the state needs to be synced in. 11294 */ 11295 VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedClts(PVMCPU pVCpu, uint8_t cbInstr) 11296 { 11297 AssertReturn(cbInstr - 2U <= 15U - 2U, VERR_IEM_INVALID_INSTR_LENGTH); 11298 11299 PIEMCPU pIemCpu = &pVCpu->iem.s; 11300 iemInitExec(pIemCpu, false /*fBypassHandlers*/); 11301 VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_0(iemCImpl_clts); 11302 return iemExecStatusCodeFiddling(pIemCpu, rcStrict); 11303 } 11304 11305 11306 /** 11307 * Interface for HM and EM to emulate the LMSW instruction (loads CR0). 11308 * 11309 * @returns Strict VBox status code. 11310 * @param pVCpu The cross context per virtual CPU structure. 11311 * @param cbInstr The instruction length in bytes. 11312 * @param uValue The value to load into CR0. 11313 * 11314 * @remarks In ring-0 not all of the state needs to be synced in. 11315 */ 11316 VMM_INT_DECL(VBOXSTRICTRC) IEMExecDecodedLmsw(PVMCPU pVCpu, uint8_t cbInstr, uint16_t uValue) 11317 { 11318 AssertReturn(cbInstr - 3U <= 15U - 3U, VERR_IEM_INVALID_INSTR_LENGTH); 11319 11320 PIEMCPU pIemCpu = &pVCpu->iem.s; 11321 iemInitExec(pIemCpu, false /*fBypassHandlers*/); 11322 VBOXSTRICTRC rcStrict = IEM_CIMPL_CALL_1(iemCImpl_lmsw, uValue); 11323 return iemExecStatusCodeFiddling(pIemCpu, rcStrict); 11324 } 11325 -
trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp
r55129 r55248 6750 6750 6751 6751 return rc; 6752 } 6753 6754 6755 /** 6756 * Ensures that we've got a complete basic context. 6757 * 6758 * This excludes the FPU, SSE, AVX, and similar extended state. The interface 6759 * is for the interpreter. 6760 * 6761 * @returns VBox status code. 6762 * @param pVCpu Pointer to the VMCPU of the calling EMT. 6763 * @param pMixedCtx Pointer to the guest-CPU context which may have data 6764 * needing to be synced in. 6765 * @thread EMT(pVCpu) 6766 */ 6767 VMMR0_INT_DECL(int) HMR0EnsureCompleteBasicContext(PVMCPU pVCpu, PCPUMCTX pMixedCtx) 6768 { 6769 /* Note! Since this is only applicable to VT-x, the implementation is placed 6770 in the VT-x part of the sources instead of the generic stuff. */ 6771 if (pVCpu->CTX_SUFF(pVM)->hm.s.vmx.fSupported) 6772 return hmR0VmxSaveGuestState(pVCpu, pMixedCtx); 6773 return VINF_SUCCESS; 6752 6774 } 6753 6775 … … 10928 10950 STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatExitMovCRx, y2); 10929 10951 int rc = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient); 10952 rc |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient); 10930 10953 AssertRCReturn(rc, rc); 10931 10954 … … 10933 10956 uint32_t const uAccessType = VMX_EXIT_QUALIFICATION_CRX_ACCESS(uExitQualification); 10934 10957 PVM pVM = pVCpu->CTX_SUFF(pVM); 10958 VBOXSTRICTRC rcStrict; 10959 rc = hmR0VmxSaveGuestRipRspRflags(pVCpu, pMixedCtx); 10960 rc |= hmR0VmxSaveGuestSegmentRegs(pVCpu, pMixedCtx); /* Only really need CS+SS. */ 10935 10961 switch (uAccessType) 10936 10962 { 10937 10963 case VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE: /* MOV to CRx */ 10938 10964 { 10939 #if 010940 /* EMInterpretCRxWrite() references a lot of guest state (EFER, RFLAGS, Segment Registers, etc.) Sync entire state */10941 rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);10942 #else10943 rc = hmR0VmxSaveGuestRipRspRflags(pVCpu, pMixedCtx);10944 10965 rc |= hmR0VmxSaveGuestControlRegs(pVCpu, pMixedCtx); 10945 rc |= hmR0VmxSaveGuestSegmentRegs(pVCpu, pMixedCtx);10946 #endif10947 10966 AssertRCReturn(rc, rc); 10948 10967 10949 rc = EMInterpretCRxWrite(pVM, pVCpu, CPUMCTX2CORE(pMixedCtx),10950 VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification),10951 VMX_EXIT_QUALIFICATION_CRX_GENREG(uExitQualification));10952 Assert (rc == VINF_SUCCESS || rc == VERR_EM_INTERPRETER || rc == VINF_PGM_CHANGE_MODE || rc == VINF_PGM_SYNC_CR3);10953 10968 rcStrict = IEMExecDecodedMovCRxWrite(pVCpu, pVmxTransient->cbInstr, 10969 VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification), 10970 VMX_EXIT_QUALIFICATION_CRX_GENREG(uExitQualification)); 10971 AssertMsg(rcStrict == VINF_SUCCESS || rcStrict == VINF_IEM_RAISED_XCPT || rcStrict == VINF_PGM_CHANGE_MODE 10972 || rcStrict == VINF_PGM_SYNC_CR3, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 10954 10973 switch (VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification)) 10955 10974 { 10956 10975 case 0: /* CR0 */ 10957 10976 HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR0); 10958 Log4(("CRX CR0 write rc =%d CR0=%#RX64\n", rc, pMixedCtx->cr0));10977 Log4(("CRX CR0 write rcStrict=%Rrc CR0=%#RX64\n", VBOXSTRICTRC_VAL(rcStrict), pMixedCtx->cr0)); 10959 10978 break; 10960 10979 case 2: /* CR2 */ … … 10964 10983 Assert(!pVM->hm.s.fNestedPaging || !CPUMIsGuestPagingEnabledEx(pMixedCtx)); 10965 10984 HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR3); 10966 Log4(("CRX CR3 write rc =%d CR3=%#RX64\n", rc, pMixedCtx->cr3));10985 Log4(("CRX CR3 write rcStrict=%Rrc CR3=%#RX64\n", VBOXSTRICTRC_VAL(rcStrict), pMixedCtx->cr3)); 10967 10986 break; 10968 10987 case 4: /* CR4 */ 10969 10988 HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR4); 10970 Log4(("CRX CR4 write rc=% d CR4=%#RX64\n", rc, pMixedCtx->cr4));10989 Log4(("CRX CR4 write rc=%Rrc CR4=%#RX64\n", VBOXSTRICTRC_VAL(rcStrict), pMixedCtx->cr4)); 10971 10990 break; 10972 10991 case 8: /* CR8 */ 10973 10992 Assert(!(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW)); 10974 /* CR8 contains the APIC TPR. Was updated by EMInterpretCRxWrite(). */10993 /* CR8 contains the APIC TPR. Was updated by IEMExecDecodedMovCRxWrite(). */ 10975 10994 HMCPU_CF_SET(pVCpu, HM_CHANGED_VMX_GUEST_APIC_STATE); 10976 10995 break; … … 10986 11005 case VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ: /* MOV from CRx */ 10987 11006 { 10988 /* EMInterpretCRxRead() requires EFER MSR, CS. */10989 rc = hmR0VmxSaveGuestSegmentRegs(pVCpu, pMixedCtx);10990 11007 rc |= hmR0VmxSaveGuestControlRegs(pVCpu, pMixedCtx); 10991 11008 AssertRCReturn(rc, rc); 11009 10992 11010 Assert( !pVM->hm.s.fNestedPaging 10993 11011 || !CPUMIsGuestPagingEnabledEx(pMixedCtx) … … 10998 11016 || !(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW)); 10999 11017 11000 rc = EMInterpretCRxRead(pVM, pVCpu, CPUMCTX2CORE(pMixedCtx),11001 VMX_EXIT_QUALIFICATION_CRX_GENREG(uExitQualification),11002 VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification));11003 Assert (rc == VINF_SUCCESS || rc == VERR_EM_INTERPRETER);11018 rcStrict = IEMExecDecodedMovCRxRead(pVCpu, pVmxTransient->cbInstr, 11019 VMX_EXIT_QUALIFICATION_CRX_GENREG(uExitQualification), 11020 VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification)); 11021 AssertMsg(rcStrict == VINF_SUCCESS || rcStrict == VINF_IEM_RAISED_XCPT, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 11004 11022 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitCRxRead[VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification)]); 11005 Log4(("CRX CR%d Read access rc=%d\n", VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification), rc)); 11023 Log4(("CRX CR%d Read access rcStrict=%Rrc\n", VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification), 11024 VBOXSTRICTRC_VAL(rcStrict))); 11006 11025 break; 11007 11026 } … … 11009 11028 case VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS: /* CLTS (Clear Task-Switch Flag in CR0) */ 11010 11029 { 11011 rc = hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx);11030 rc |= hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx); 11012 11031 AssertRCReturn(rc, rc); 11013 rc = EMInterpretCLTS(pVM, pVCpu);11014 Assert RCReturn(rc, rc);11032 rcStrict = IEMExecDecodedClts(pVCpu, pVmxTransient->cbInstr); 11033 AssertMsg(rcStrict == VINF_SUCCESS || rcStrict == VINF_IEM_RAISED_XCPT, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 11015 11034 HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR0); 11016 11035 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitClts); 11017 Log4(("CRX CLTS write rc=%d\n", rc));11036 Log4(("CRX CLTS rcStrict=%d\n", VBOXSTRICTRC_VAL(rcStrict))); 11018 11037 break; 11019 11038 } … … 11021 11040 case VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW: /* LMSW (Load Machine-Status Word into CR0) */ 11022 11041 { 11023 rc = hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx);11042 rc |= hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx); 11024 11043 AssertRCReturn(rc, rc); 11025 rc = EMInterpretLMSW(pVM, pVCpu, CPUMCTX2CORE(pMixedCtx), VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(uExitQualification));11026 if (RT_LIKELY(rc == VINF_SUCCESS))11027 HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR0);11044 rcStrict = IEMExecDecodedLmsw(pVCpu, pVmxTransient->cbInstr, 11045 VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(uExitQualification)); 11046 AssertMsg(rcStrict == VINF_SUCCESS || rcStrict == VINF_IEM_RAISED_XCPT || rcStrict == VINF_PGM_CHANGE_MODE, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); 11028 11047 STAM_COUNTER_INC(&pVCpu->hm.s.StatExitLmsw); 11029 Log4(("CRX LMSW write rc=%d\n", rc));11048 Log4(("CRX LMSW rcStrict=%d\n", VBOXSTRICTRC_VAL(rcStrict))); 11030 11049 break; 11031 11050 } 11032 11051 11033 11052 default: 11034 { 11035 AssertMsgFailed(("Invalid access-type in Mov CRx VM-exit qualification %#x\n", uAccessType)); 11036 rc = VERR_VMX_UNEXPECTED_EXCEPTION; 11037 } 11038 } 11039 11040 /* Validate possible error codes. */ 11041 Assert(rc == VINF_SUCCESS || rc == VINF_PGM_CHANGE_MODE || rc == VERR_EM_INTERPRETER || rc == VINF_PGM_SYNC_CR3 11042 || rc == VERR_VMX_UNEXPECTED_EXCEPTION); 11043 if (RT_SUCCESS(rc)) 11044 { 11045 int rc2 = hmR0VmxAdvanceGuestRip(pVCpu, pMixedCtx, pVmxTransient); 11046 AssertRCReturn(rc2, rc2); 11047 } 11048 11053 AssertMsgFailedReturn(("Invalid access-type in Mov CRx VM-exit qualification %#x\n", uAccessType), 11054 VERR_VMX_UNEXPECTED_EXCEPTION); 11055 } 11056 11057 HMCPU_CF_SET(pVCpu, rcStrict != VINF_IEM_RAISED_XCPT ? HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RFLAGS : HM_CHANGED_ALL_GUEST); 11049 11058 STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExitMovCRx, y2); 11050 return rc;11059 return VBOXSTRICTRC_TODO(rcStrict); 11051 11060 } 11052 11061
Note:
See TracChangeset
for help on using the changeset viewer.

