VirtualBox

Changeset 47326 in vbox


Ignore:
Timestamp:
Jul 22, 2013 9:46:43 PM (11 years ago)
Author:
vboxsync
Message:

IEM: Implemented the mwait & monitor instructions. (Still work to be done on mwait in EM, but that's a different topic.)

Location:
trunk
Files:
6 edited

Legend:

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

    r46423 r47326  
    195195VMM_INT_DECL(int)               EMInterpretWrmsr(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
    196196VMM_INT_DECL(bool)              EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx);
    197 VMM_INT_DECL(int)               EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx);
     197VMM_INT_DECL(int)               EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx, RTGCPHYS GCPhys);
    198198VMM_INT_DECL(int)               EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx);
    199199
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r46420 r47326  
    181181 * @param   rcx                 The content of RCX.
    182182 * @param   rdx                 The content of RDX.
    183  */
    184 VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx)
     183 * @param   GCPhys              The physical address corresponding to rax.
     184 */
     185VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx, RTGCPHYS GCPhys)
    185186{
    186187    pVCpu->em.s.MWait.uMonitorRAX = rax;
     
    188189    pVCpu->em.s.MWait.uMonitorRDX = rdx;
    189190    pVCpu->em.s.MWait.fWait |= EMMWAIT_FLAG_MONITOR_ACTIVE;
     191    /** @todo Make use of GCPhys. */
    190192    /** @todo Complete MONITOR implementation.  */
    191193    return VINF_SUCCESS;
     
    13721374        return VERR_EM_INTERPRETER; /* not supported */
    13731375
    1374     EMMonitorWaitPrepare(pVCpu, pRegFrame->rax, pRegFrame->rcx, pRegFrame->rdx);
     1376    EMMonitorWaitPrepare(pVCpu, pRegFrame->rax, pRegFrame->rcx, pRegFrame->rdx, NIL_RTGCPHYS);
    13751377    return VINF_SUCCESS;
    13761378}
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r47319 r47326  
    301301    (   ((a_fEdx) & (X86_CPUID_FEATURE_EDX_TSC | 0)) \
    302302     || iemRegIsIntelCpuIdFeaturePresent(pIemCpu, (a_fEdx), 0) )
     303
     304/**
     305 * Checks if an Intel CPUID feature is present.
     306 */
     307#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_ECX(a_fEcx)  \
     308    ( iemRegIsIntelCpuIdFeaturePresent(pIemCpu, 0, (a_fEcx)) )
    303309
    304310/**
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r47319 r47326  
    43084308
    43094309/**
     4310 * Implements 'MONITOR'.
     4311 */
     4312IEM_CIMPL_DEF_1(iemCImpl_monitor, uint8_t, iEffSeg)
     4313{
     4314    /*
     4315     * Permission checks.
     4316     */
     4317    if (pIemCpu->uCpl != 0)
     4318    {
     4319        Log2(("monitor: CPL != 0\n"));
     4320        return iemRaiseUndefinedOpcode(pIemCpu); /** @todo MSR[0xC0010015].MonMwaitUserEn if we care. */
     4321    }
     4322    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_ECX(X86_CPUID_FEATURE_ECX_MONITOR))
     4323    {
     4324        Log2(("monitor: Not in CPUID\n"));
     4325        return iemRaiseUndefinedOpcode(pIemCpu);
     4326    }
     4327
     4328    /*
     4329     * Gather the operands and validate them.
     4330     */
     4331    PCPUMCTX pCtx       = pIemCpu->CTX_SUFF(pCtx);
     4332    RTGCPTR  GCPtrMem   = pIemCpu->enmCpuMode == IEMMODE_64BIT ? pCtx->rax : pCtx->eax;
     4333    uint32_t uEcx       = pCtx->ecx;
     4334    uint32_t uEdx       = pCtx->edx;
     4335/** @todo Test whether EAX or ECX is processed first, i.e. do we get \#PF or
     4336 *        \#GP first. */
     4337    if (uEcx != 0)
     4338    {
     4339        Log2(("monitor rax=%RX64, ecx=%RX32, edx=%RX32; ECX != 0 -> #GP(0)\n", GCPtrMem, uEcx, uEdx));
     4340        return iemRaiseGeneralProtectionFault0(pIemCpu);
     4341    }
     4342
     4343    VBOXSTRICTRC rcStrict = iemMemApplySegment(pIemCpu, IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_DATA, iEffSeg, 1, &GCPtrMem);
     4344    if (rcStrict != VINF_SUCCESS)
     4345        return rcStrict;
     4346
     4347    RTGCPHYS GCPhysMem;
     4348    rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, GCPtrMem, IEM_ACCESS_TYPE_READ | IEM_ACCESS_WHAT_DATA, &GCPhysMem);
     4349    if (rcStrict != VINF_SUCCESS)
     4350        return rcStrict;
     4351
     4352    /*
     4353     * Call EM to prepare the monitor/wait.
     4354     */
     4355    rcStrict = EMMonitorWaitPrepare(IEMCPU_TO_VMCPU(pIemCpu), pCtx->rax, pCtx->rcx, pCtx->rdx, GCPhysMem);
     4356    Assert(rcStrict == VINF_SUCCESS);
     4357
     4358    iemRegAddToRip(pIemCpu, cbInstr);
     4359    return rcStrict;
     4360}
     4361
     4362
     4363/**
     4364 * Implements 'MWAIT'.
     4365 */
     4366IEM_CIMPL_DEF_0(iemCImpl_mwait)
     4367{
     4368    /*
     4369     * Permission checks.
     4370     */
     4371    if (pIemCpu->uCpl != 0)
     4372    {
     4373        Log2(("mwait: CPL != 0\n"));
     4374        /** @todo MSR[0xC0010015].MonMwaitUserEn if we care. (Remember to check
     4375         *        EFLAGS.VM then.) */
     4376        return iemRaiseUndefinedOpcode(pIemCpu);
     4377    }
     4378    if (!IEM_IS_INTEL_CPUID_FEATURE_PRESENT_ECX(X86_CPUID_FEATURE_ECX_MONITOR))
     4379    {
     4380        Log2(("mwait: Not in CPUID\n"));
     4381        return iemRaiseUndefinedOpcode(pIemCpu);
     4382    }
     4383
     4384    /*
     4385     * Gather the operands and validate them.
     4386     */
     4387    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     4388    uint32_t uEax = pCtx->eax;
     4389    uint32_t uEcx = pCtx->ecx;
     4390    if (uEcx != 0)
     4391    {
     4392        /* Only supported extension is break on IRQ when IF=0. */
     4393        if (uEcx > 1)
     4394        {
     4395            Log2(("mwait eax=%RX32, ecx=%RX32; ECX > 1 -> #GP(0)\n", uEax, uEcx));
     4396            return iemRaiseGeneralProtectionFault0(pIemCpu);
     4397        }
     4398        uint32_t fMWaitFeatures = 0;
     4399        uint32_t uIgnore = 0;
     4400        CPUMGetGuestCpuId(IEMCPU_TO_VMCPU(pIemCpu), 5, &uIgnore, &uIgnore, &fMWaitFeatures, &uIgnore);
     4401        if (    (fMWaitFeatures & (X86_CPUID_MWAIT_ECX_EXT | X86_CPUID_MWAIT_ECX_BREAKIRQIF0))
     4402            !=                    (X86_CPUID_MWAIT_ECX_EXT | X86_CPUID_MWAIT_ECX_BREAKIRQIF0))
     4403        {
     4404            Log2(("mwait eax=%RX32, ecx=%RX32; break-on-IRQ-IF=0 extension not enabled -> #GP(0)\n", uEax, uEcx));
     4405            return iemRaiseGeneralProtectionFault0(pIemCpu);
     4406        }
     4407    }
     4408
     4409    /*
     4410     * Call EM to prepare the monitor/wait.
     4411     */
     4412    VBOXSTRICTRC rcStrict = EMMonitorWaitPerform(IEMCPU_TO_VMCPU(pIemCpu), uEax, uEcx);
     4413
     4414    iemRegAddToRip(pIemCpu, cbInstr);
     4415    return rcStrict;
     4416}
     4417
     4418
     4419/**
    43104420 * Implements 'CPUID'.
    43114421 */
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r47323 r47326  
    810810FNIEMOP_DEF(iemOp_Grp7_monitor)
    811811{
    812     NOREF(pIemCpu);
    813     IEMOP_BITCH_ABOUT_STUB();
    814     return VERR_IEM_INSTR_NOT_IMPLEMENTED;
     812    IEMOP_MNEMONIC("monitor");
     813    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     814    return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_monitor, pIemCpu->iEffSeg);
    815815}
    816816
     
    819819FNIEMOP_DEF(iemOp_Grp7_mwait)
    820820{
    821     NOREF(pIemCpu);
    822     IEMOP_BITCH_ABOUT_STUB();
    823     return VERR_IEM_INSTR_NOT_IMPLEMENTED;
     821    IEMOP_MNEMONIC("mwait");
     822    IEMOP_HLP_DONE_DECODING_NO_LOCK_PREFIX();
     823    return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_mwait);
    824824}
    825825
  • trunk/src/VBox/VMM/testcase/tstIEMCheckMc.cpp

    r47307 r47326  
    134134#define IEM_IS_AMD_CPUID_FEATURES_ANY_PRESENT(a_fEdx, a_fEcx) (g_fRandom)
    135135#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX(a_fEdx)      (g_fRandom)
     136#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_ECX(a_fEcx)      (g_fRandom)
    136137#define IEM_IS_INTEL_CPUID_FEATURE_PRESENT_EDX_ON_HOST(a_fEdx) (g_fRandom)
    137138#define IEM_IS_GUEST_CPU_AMD(a_pIemCpu)                     (g_fRandom)
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