VirtualBox

Changeset 55248 in vbox


Ignore:
Timestamp:
Apr 14, 2015 1:43:25 PM (9 years ago)
Author:
vboxsync
Message:

HMR0VMX,EM,IEM: Moved the CRx related interpretation methods from EM to IEM (VT-x only) to avoid tinkering with the EMAll.cpp stuff any more.

Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/em.h

    r53615 r55248  
    193193VMM_INT_DECL(int)               EMInterpretDRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegDrx, uint32_t SrcRegGen);
    194194VMM_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);
    199195VMM_INT_DECL(int)               EMInterpretRdmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
    200196VMM_INT_DECL(int)               EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
  • trunk/include/VBox/vmm/hm.h

    r55129 r55248  
    208208VMMR0_INT_DECL(int)             HMR0TestSwitcher3264(PVM pVM);
    209209# endif
     210
     211VMMR0_INT_DECL(int)             HMR0EnsureCompleteBasicContext(PVMCPU pVCpu, PCPUMCTX pMixedCtx);
    210212
    211213/** @} */
  • trunk/include/VBox/vmm/iem.h

    r53615 r55248  
    5151
    5252
     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
    5363VMMDECL(VBOXSTRICTRC)       IEMExecOne(PVMCPU pVCpu);
    5464VMMDECL(VBOXSTRICTRC)       IEMExecOneEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten);
     
    7282VMM_INT_DECL(VBOXSTRICTRC)  IEMExecStringIoRead(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode,
    7383                                                bool fRepPrefix, uint8_t cbInstr);
     84VMM_INT_DECL(VBOXSTRICTRC)  IEMExecDecodedMovCRxWrite(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iCrReg, uint8_t iGReg);
     85VMM_INT_DECL(VBOXSTRICTRC)  IEMExecDecodedMovCRxRead(PVMCPU pVCpu, uint8_t cbInstr, uint8_t iGReg, uint8_t iCrReg);
     86VMM_INT_DECL(VBOXSTRICTRC)  IEMExecDecodedClts(PVMCPU pVCpu, uint8_t cbInstr);
     87VMM_INT_DECL(VBOXSTRICTRC)  IEMExecDecodedLmsw(PVMCPU pVCpu, uint8_t cbInstr, uint16_t uValue);
    7488/** @}  */
    7589
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r54862 r55248  
    14531453
    14541454    /** @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));
    14561456    Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu));
    14571457    switch (DestRegCrx)
     
    16101610 *
    16111611 */
    1612 VMM_INT_DECL(int) EMInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen)
     1612static int emInterpretCRxWrite(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegCrx, uint32_t SrcRegGen)
    16131613{
    16141614    uint64_t val;
     
    16291629
    16301630    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);
    16721631}
    16731632
     
    18051764 *
    18061765 */
    1807 VMM_INT_DECL(int) EMInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx)
     1766static int emInterpretCRxRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame, uint32_t DestRegGen, uint32_t SrcRegCrx)
    18081767{
    18091768    Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu));
     
    33513310static int emInterpretClts(PVM pVM, PVMCPU pVCpu, PDISCPUSTATE pDis, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize)
    33523311{
    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);
    33553318}
    33563319
     
    33643327    uint32_t    val;
    33653328    NOREF(pvFault); NOREF(pcbSize);
     3329    Assert(pRegFrame == CPUMGetGuestCtxCore(pVCpu));
    33663330
    33673331    int rc = DISQueryParamVal(pRegFrame, pDis, &pDis->Param1, &param1, DISQPVWHICH_SRC);
     
    33833347
    33843348    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
    33863357}
    33873358
     
    34463417    NOREF(pvFault); NOREF(pcbSize);
    34473418    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);
    34493420
    34503421    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);
    34523423
    34533424    AssertMsgFailedReturn(("Unexpected control register move\n"), VERR_EM_INTERPRETER);
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r55229 r55248  
    189189*   Defined Constants And Macros                                               *
    190190*******************************************************************************/
    191 /** @name IEM status codes.
    192  *
    193  * Not quite sure how this will play out in the end, just aliasing safe status
    194  * codes for now.
    195  *
    196  * @{ */
    197 #define VINF_IEM_RAISED_XCPT    VINF_EM_RESCHEDULE
    198 /** @} */
    199 
    200191/** Temporary hack to disable the double execution.  Will be removed in favor
    201192 * of a dedicated execution mode in EM. */
     
    11061097    if (cbToTryRead > sizeof(pIemCpu->abOpcode) - pIemCpu->cbOpcode)
    11071098        cbToTryRead = sizeof(pIemCpu->abOpcode) - pIemCpu->cbOpcode;
     1099/** @todo r=bird: Convert assertion into undefined opcode exception? */
    11081100    Assert(cbToTryRead >= cbMin - cbLeft); /* ASSUMPTION based on iemInitDecoderAndPrefetchOpcodes. */
    11091101
     
    12011193{
    12021194    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);
    12091202}
    12101203
     
    38593852{
    38603853    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
    38613858
    38623859    /*
     
    1123711234}
    1123811235
     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 */
     11249VMM_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 */
     11273VMM_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 */
     11295VMM_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 */
     11316VMM_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  
    67506750
    67516751    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 */
     6767VMMR0_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;
    67526774}
    67536775
     
    1092810950    STAM_PROFILE_ADV_START(&pVCpu->hm.s.StatExitMovCRx, y2);
    1092910951    int rc = hmR0VmxReadExitQualificationVmcs(pVCpu, pVmxTransient);
     10952    rc |= hmR0VmxReadExitInstrLenVmcs(pVmxTransient);
    1093010953    AssertRCReturn(rc, rc);
    1093110954
     
    1093310956    uint32_t const uAccessType           = VMX_EXIT_QUALIFICATION_CRX_ACCESS(uExitQualification);
    1093410957    PVM pVM                              = pVCpu->CTX_SUFF(pVM);
     10958    VBOXSTRICTRC rcStrict;
     10959    rc  = hmR0VmxSaveGuestRipRspRflags(pVCpu, pMixedCtx);
     10960    rc |= hmR0VmxSaveGuestSegmentRegs(pVCpu, pMixedCtx); /* Only really need CS+SS. */
    1093510961    switch (uAccessType)
    1093610962    {
    1093710963        case VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE:       /* MOV to CRx */
    1093810964        {
    10939 #if 0
    10940             /* EMInterpretCRxWrite() references a lot of guest state (EFER, RFLAGS, Segment Registers, etc.) Sync entire state */
    10941             rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
    10942 #else
    10943             rc  = hmR0VmxSaveGuestRipRspRflags(pVCpu, pMixedCtx);
    1094410965            rc |= hmR0VmxSaveGuestControlRegs(pVCpu, pMixedCtx);
    10945             rc |= hmR0VmxSaveGuestSegmentRegs(pVCpu, pMixedCtx);
    10946 #endif
    1094710966            AssertRCReturn(rc, rc);
    1094810967
    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)));
    1095410973            switch (VMX_EXIT_QUALIFICATION_CRX_REGISTER(uExitQualification))
    1095510974            {
    1095610975                case 0: /* CR0 */
    1095710976                    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));
    1095910978                    break;
    1096010979                case 2: /* CR2 */
     
    1096410983                    Assert(!pVM->hm.s.fNestedPaging || !CPUMIsGuestPagingEnabledEx(pMixedCtx));
    1096510984                    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));
    1096710986                    break;
    1096810987                case 4: /* CR4 */
    1096910988                    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));
    1097110990                    break;
    1097210991                case 8: /* CR8 */
    1097310992                    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(). */
    1097510994                    HMCPU_CF_SET(pVCpu, HM_CHANGED_VMX_GUEST_APIC_STATE);
    1097610995                    break;
     
    1098611005        case VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ:        /* MOV from CRx */
    1098711006        {
    10988             /* EMInterpretCRxRead() requires EFER MSR, CS. */
    10989             rc  = hmR0VmxSaveGuestSegmentRegs(pVCpu, pMixedCtx);
    1099011007            rc |= hmR0VmxSaveGuestControlRegs(pVCpu, pMixedCtx);
    1099111008            AssertRCReturn(rc, rc);
     11009
    1099211010            Assert(   !pVM->hm.s.fNestedPaging
    1099311011                   || !CPUMIsGuestPagingEnabledEx(pMixedCtx)
     
    1099811016                   || !(pVCpu->hm.s.vmx.u32ProcCtls & VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW));
    1099911017
    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)));
    1100411022            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)));
    1100611025            break;
    1100711026        }
     
    1100911028        case VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS:        /* CLTS (Clear Task-Switch Flag in CR0) */
    1101011029        {
    11011             rc = hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx);
     11030            rc |= hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx);
    1101211031            AssertRCReturn(rc, rc);
    11013             rc = EMInterpretCLTS(pVM, pVCpu);
    11014             AssertRCReturn(rc, rc);
     11032            rcStrict = IEMExecDecodedClts(pVCpu, pVmxTransient->cbInstr);
     11033            AssertMsg(rcStrict == VINF_SUCCESS || rcStrict == VINF_IEM_RAISED_XCPT, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    1101511034            HMCPU_CF_SET(pVCpu, HM_CHANGED_GUEST_CR0);
    1101611035            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)));
    1101811037            break;
    1101911038        }
     
    1102111040        case VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW:        /* LMSW (Load Machine-Status Word into CR0) */
    1102211041        {
    11023             rc = hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx);
     11042            rc |= hmR0VmxSaveGuestCR0(pVCpu, pMixedCtx);
    1102411043            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)));
    1102811047            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)));
    1103011049            break;
    1103111050        }
    1103211051
    1103311052        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);
    1104911058    STAM_PROFILE_ADV_STOP(&pVCpu->hm.s.StatExitMovCRx, y2);
    11050     return rc;
     11059    return VBOXSTRICTRC_TODO(rcStrict);
    1105111060}
    1105211061
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette