VirtualBox

Changeset 74693 in vbox


Ignore:
Timestamp:
Oct 9, 2018 5:15:41 AM (6 years ago)
Author:
vboxsync
Message:

VMM/IEM: Nested VMX: bugref:9180 VM-exit bits; Added Mov DRx intercepts. Fixed INS/OUTS intercept to compute and store the missing guest-linear address field.

Location:
trunk
Files:
3 edited

Legend:

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

    r74683 r74693  
    25042504#define VMXINSTRID_IO_OUT                                       (0x16 | VMXINSTRID_VALID)
    25052505#define VMXINSTRID_IO_OUTS                                      (0x17 | VMXINSTRID_VALID)
     2506#define VMXINSTRID_MOV_TO_DRX                                   (0x18 | VMXINSTRID_VALID)
     2507#define VMXINSTRID_MOV_FROM_DRX                                 (0x19 | VMXINSTRID_VALID)
    25062508/** @} */
    25072509
     
    26122614/** 8-11: General purpose register number. */
    26132615#define VMX_EXIT_QUAL_DRX_GENREG(a)                             (((a) >> 8) & 0xf)
    2614 /** Rest: reserved. */
     2616
     2617/** Bit fields for Exit qualification due to Mov DRx. */
     2618#define VMX_BF_EXIT_QUAL_DRX_REGISTER_SHIFT                     0
     2619#define VMX_BF_EXIT_QUAL_DRX_REGISTER_MASK                      UINT64_C(0x0000000000000007)
     2620#define VMX_BF_EXIT_QUAL_DRX_RSVD_1_SHIFT                       3
     2621#define VMX_BF_EXIT_QUAL_DRX_RSVD_1_MASK                        UINT64_C(0x0000000000000008)
     2622#define VMX_BF_EXIT_QUAL_DRX_DIRECTION_SHIFT                    4
     2623#define VMX_BF_EXIT_QUAL_DRX_DIRECTION_MASK                     UINT64_C(0x0000000000000010)
     2624#define VMX_BF_EXIT_QUAL_DRX_RSVD_5_7_SHIFT                     5
     2625#define VMX_BF_EXIT_QUAL_DRX_RSVD_5_7_MASK                      UINT64_C(0x00000000000000e0)
     2626#define VMX_BF_EXIT_QUAL_DRX_GENREG_SHIFT                       8
     2627#define VMX_BF_EXIT_QUAL_DRX_GENREG_MASK                        UINT64_C(0x0000000000000f00)
     2628#define VMX_BF_EXIT_QUAL_DRX_RSVD_12_63_SHIFT                   12
     2629#define VMX_BF_EXIT_QUAL_DRX_RSVD_12_63_MASK                    UINT64_C(0xfffffffffffff000)
     2630RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_QUAL_DRX_, UINT64_C(0), UINT64_MAX,
     2631                            (REGISTER, RSVD_1, DIRECTION, RSVD_5_7, GENREG, RSVD_12_63));
    26152632/** @} */
    26162633
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r74661 r74693  
    52825282{
    52835283    IEM_SVM_CHECK_READ_CR0_INTERCEPT(pVCpu, 0 /* uExitInfo1 */, 0 /* uExitInfo2 */);
     5284    /** @todo NSTVMX: SMSW CR0 masking. */
    52845285
    52855286    switch (enmEffOpSize)
     
    59015902IEM_CIMPL_DEF_2(iemCImpl_mov_Rd_Dd, uint8_t, iGReg, uint8_t, iDrReg)
    59025903{
     5904#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     5905    /*
     5906     * Check nested-guest VMX intercept.
     5907     * Unlike most other intercepts, the Mov DRx intercept takes preceedence
     5908     * over CPL and CR4.DE and even DR4/DR5 checks.
     5909     *
     5910     * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally".
     5911     */
     5912    if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
     5913    {
     5914        VBOXSTRICTRC rcStrict = iemVmxVmexitInstrMovDrX(pVCpu, VMXINSTRID_MOV_FROM_DRX, iDrReg, iGReg, cbInstr);
     5915        if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE)
     5916            return rcStrict;
     5917    }
     5918#endif
     5919
    59035920    /*
    59045921     * Check preconditions.
    59055922     */
    5906 
    59075923    /* Raise GPs. */
    59085924    if (pVCpu->iem.s.uCpl != 0)
     
    59946010IEM_CIMPL_DEF_2(iemCImpl_mov_Dd_Rd, uint8_t, iDrReg, uint8_t, iGReg)
    59956011{
     6012#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
     6013    /*
     6014     * Check nested-guest VMX intercept.
     6015     * Unlike most other intercepts, the Mov DRx intercept takes preceedence
     6016     * over CPL and CR4.DE and even DR4/DR5 checks.
     6017     *
     6018     * See Intel spec. 25.1.3 "Instructions That Cause VM Exits Conditionally".
     6019     */
     6020    if (IEM_VMX_IS_NON_ROOT_MODE(pVCpu))
     6021    {
     6022        VBOXSTRICTRC rcStrict = iemVmxVmexitInstrMovDrX(pVCpu, VMXINSTRID_MOV_TO_DRX, iDrReg, iGReg, cbInstr);
     6023        if (rcStrict != VINF_VMX_INTERCEPT_NOT_ACTIVE)
     6024            return rcStrict;
     6025    }
     6026#endif
     6027
    59966028    /*
    59976029     * Check preconditions.
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplVmxInstr.cpp.h

    r74684 r74693  
    32923292
    32933293/**
     3294 * VMX VM-exit handler for VM-exits due to 'Mov DRx,GReg' (DRx write) and 'Mov
     3295 * GReg,DRx' (DRx read).
     3296 *
     3297 * @returns VBox strict status code.
     3298 * @param   pVCpu       The cross context virtual CPU structure.
     3299 * @param   uInstrid    The instruction identity (VMXINSTRID_MOV_TO_DRX or
     3300 *                      VMXINSTRID_MOV_FROM_DRX).
     3301 * @param   iDrReg      The debug register being accessed.
     3302 * @param   iGReg       The general register to/from which the DRx value is being
     3303 *                      store/loaded.
     3304 * @param   cbInstr     The instruction length in bytes.
     3305 */
     3306IEM_STATIC VBOXSTRICTRC iemVmxVmexitInstrMovDrX(PVMCPU pVCpu, VMXINSTRID uInstrId, uint8_t iDrReg, uint8_t iGReg,
     3307                                                uint8_t cbInstr)
     3308{
     3309    Assert(iDrReg <= 7);
     3310    Assert(uInstrId == VMXINSTRID_MOV_TO_DRX || uInstrId == VMXINSTRID_MOV_FROM_DRX);
     3311
     3312    PCVMXVVMCS pVmcs = pVCpu->cpum.GstCtx.hwvirt.vmx.CTX_SUFF(pVmcs);
     3313    Assert(pVmcs);
     3314
     3315    if (pVmcs->u32ProcCtls & VMX_PROC_CTLS_MOV_DR_EXIT)
     3316    {
     3317        uint32_t const uDirection = uInstrId == VMXINSTRID_MOV_TO_DRX ? VMX_EXIT_QUAL_DRX_DIRECTION_WRITE
     3318                                                                      : VMX_EXIT_QUAL_DRX_DIRECTION_READ;
     3319        VMXVEXITINFO ExitInfo;
     3320        RT_ZERO(ExitInfo);
     3321        ExitInfo.uReason = VMX_EXIT_MOV_DRX;
     3322        ExitInfo.cbInstr = cbInstr;
     3323        ExitInfo.u64Qual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_DRX_REGISTER,  iDrReg)
     3324                         | RT_BF_MAKE(VMX_BF_EXIT_QUAL_DRX_DIRECTION, uDirection)
     3325                         | RT_BF_MAKE(VMX_BF_EXIT_QUAL_DRX_GENREG,    iGReg);
     3326        return iemVmxVmexitInstrWithInfo(pVCpu, &ExitInfo);
     3327    }
     3328
     3329    return VINF_VMX_INTERCEPT_NOT_ACTIVE;
     3330}
     3331
     3332
     3333/**
    32943334 * VMX VM-exit handler for VM-exits due to I/O instructions (IN and OUT).
    32953335 *
     
    33553395    if (fIntercept)
    33563396    {
    3357         uint32_t const uDirection = uInstrId == VMXINSTRID_IO_INS ? VMX_EXIT_QUAL_IO_DIRECTION_IN
    3358                                                                   : VMX_EXIT_QUAL_IO_DIRECTION_OUT;
     3397        /*
     3398         * Figure out the guest-linear address and the direction bit (INS/OUTS).
     3399         */
     3400        /** @todo r=ramshankar: Is there something in IEM that already does this? */
     3401        static uint64_t const s_auAddrSizeMasks[] = { UINT64_C(0xffff), UINT64_C(0xffffffff), UINT64_C(0xffffffffffffffff) };
     3402        uint8_t const  iSegReg       = ExitInstrInfo.StrIo.iSegReg;
     3403        uint8_t const  uAddrSize     = ExitInstrInfo.StrIo.u3AddrSize;
     3404        uint64_t const uAddrSizeMask = s_auAddrSizeMasks[uAddrSize];
     3405
     3406        uint32_t uDirection;
     3407        uint64_t uGuestLinearAddr;
     3408        if (uInstrId == VMXINSTRID_IO_INS)
     3409        {
     3410            uDirection = VMX_EXIT_QUAL_IO_DIRECTION_IN;
     3411            uGuestLinearAddr = pVCpu->cpum.GstCtx.aSRegs[iSegReg].u64Base + (pVCpu->cpum.GstCtx.rdi & uAddrSizeMask);
     3412        }
     3413        else
     3414        {
     3415            uDirection = VMX_EXIT_QUAL_IO_DIRECTION_OUT;
     3416            uGuestLinearAddr = pVCpu->cpum.GstCtx.aSRegs[iSegReg].u64Base + (pVCpu->cpum.GstCtx.rsi & uAddrSizeMask);
     3417        }
     3418
     3419        /*
     3420         * If the segment is ununsable, the guest-linear address in undefined.
     3421         * We shall clear it for consistency.
     3422         *
     3423         * See Intel spec. 27.2.1 "Basic VM-Exit Information".
     3424         */
     3425        if (pVCpu->cpum.GstCtx.aSRegs[iSegReg].Attr.n.u1Unusable)
     3426            uGuestLinearAddr = 0;
     3427
    33593428        VMXVEXITINFO ExitInfo;
    33603429        RT_ZERO(ExitInfo);
    3361         ExitInfo.uReason   = VMX_EXIT_IO_INSTR;
    3362         ExitInfo.cbInstr   = cbInstr;
    3363         ExitInfo.InstrInfo = ExitInstrInfo;
    3364         ExitInfo.u64Qual = RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_WIDTH,     cbAccess - 1)
    3365                          | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_DIRECTION, uDirection)
    3366                          | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_IS_STRING, 1)
    3367                          | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_IS_REP,    fRep)
    3368                          | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_ENCODING,  0)     /* DX (not immediate). */
    3369                          | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_PORT,      u16Port);
     3430        ExitInfo.uReason            = VMX_EXIT_IO_INSTR;
     3431        ExitInfo.cbInstr            = cbInstr;
     3432        ExitInfo.InstrInfo          = ExitInstrInfo;
     3433        ExitInfo.u64GuestLinearAddr = uGuestLinearAddr;
     3434        ExitInfo.u64Qual            = RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_WIDTH,     cbAccess - 1)
     3435                                    | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_DIRECTION, uDirection)
     3436                                    | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_IS_STRING, 1)
     3437                                    | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_IS_REP,    fRep)
     3438                                    | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_ENCODING,  VMX_EXIT_QUAL_IO_ENCODING_DX)
     3439                                    | RT_BF_MAKE(VMX_BF_EXIT_QUAL_IO_PORT,      u16Port);
    33703440        return iemVmxVmexitInstrWithInfo(pVCpu, &ExitInfo);
    33713441    }
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