VirtualBox

Changeset 46562 in vbox for trunk


Ignore:
Timestamp:
Jun 14, 2013 1:41:37 PM (12 years ago)
Author:
vboxsync
Message:

VMM: AMD-V bits and VT-x comment nit.

Location:
trunk/src/VBox/VMM/VMMR0
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/HMSVMR0.cpp

    r46557 r46562  
    27472747 *
    27482748 * @return VBox status code.
    2749  * @param   pVCpu     hmR0SvmExitReadDRx      Pointer to the VMCPU.
     2749 * @param   pVCpu           Pointer to the VMCPU.
    27502750 * @param   pCpu            Pointer to the disassembler state.
    27512751 * @param   pRegFrame       Pointer to the register frame.
     
    28232823    SVMEVENT Event;
    28242824    Event.u          = 0;
     2825    Event.n.u1Valid  = 1;
    28252826    Event.n.u3Type   = SVM_EVENT_EXCEPTION;
     2827    Event.n.u8Vector = X86_XCPT_UD;
     2828    hmR0SvmSetPendingEvent(pVCpu, &Event);
     2829}
     2830
     2831
     2832/**
     2833 * Sets an debug (#DB) exception as pending-for-injection into the VM.
     2834 *
     2835 * @param   pVCpu       Pointer to the VMCPU.
     2836 */
     2837DECLINLINE(void) hmR0SvmSetPendingXcptDB(PVMCPU pVCpu)
     2838{
     2839    SVMEVENT Event;
     2840    Event.u          = 0;
    28262841    Event.n.u1Valid  = 1;
    2827     Event.n.u8Vector = X86_XCPT_UD;
     2842    Event.n.u3Type   = SVM_EVENT_EXCEPTION;
     2843    Event.n.u8Vector = X86_XCPT_DB;
    28282844    hmR0SvmSetPendingEvent(pVCpu, &Event);
    28292845}
     
    32083224HMSVM_EXIT_DECL hmR0SvmExitWriteDRx(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSvmTransient)
    32093225{
     3226    HMSVM_VALIDATE_EXIT_HANDLER_PARAMS();
    32103227    /* For now it's the same since we interpret the instruction anyway. Will change when using of Decode Assist is implemented. */
    32113228    int rc = hmR0SvmExitReadDRx(pVCpu, pCtx, pSvmTransient);
     
    32163233
    32173234
     3235/**
     3236 * #VMEXIT handler for I/O instructions (SVM_EXIT_IOIO). Conditional #VMEXIT.
     3237 */
     3238HMSVM_EXIT_DECL hmR0SvmExitIOInstr(PVMCPU pVCpu, PCPUMCTX pCtx, PSVMTRANSIENT pSvmTransient)
     3239{
     3240    HMSVM_VALIDATE_EXIT_HANDLER_PARAMS();
     3241
     3242    /* I/O operation lookup arrays. */
     3243    static uint32_t const s_aIOSize[8]  = { 0, 1, 2, 0, 4, 0, 0, 0 };                   /* Size of the I/O accesses in bytes. */
     3244    static uint32_t const s_aIOOpAnd[8] = { 0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0 };  /* AND masks for saving
     3245                                                                                            the result (in AL/AX/EAX). */
     3246
     3247    /* Refer AMD spec. 15.10.2 "IN and OUT Behaviour" and Figure 15-2. "EXITINFO1 for IOIO Intercept" for the format. */
     3248    SVMIOIOEXIT IoExitInfo;
     3249    IoExitInfo.u       = (uint32_t)pVmcb->ctrl.u64ExitInfo1;
     3250    uint32_t uIOWidth  = (IoExitInfo.u >> 4) & 0x7;
     3251    uint32_t uIOSize   = s_aIOSize[uIOWidth];
     3252    uint32_t uAndVal   = s_aIOOpAnd[uIOWidth];
     3253
     3254    if (RT_UNLIKELY(!uIOSize))
     3255    {
     3256        AssertMsgFailed(("hmR0SvmExitIOInstr: Invalid IO operation. uIOWidth=%u\n", uIOWidth));
     3257        return VERR_EM_INTERPRETER;
     3258    }
     3259
     3260    int rc;
     3261    if (IoExitInfo.n.u1STR)
     3262    {
     3263        /* INS/OUTS - I/O String instruction. */
     3264        PDISCPUSTATE pDis = &pVCpu->hm.s.DisState;
     3265
     3266        /** @todo Huh? why can't we use the segment prefix information given by AMD-V
     3267         *        in EXITINFO1? Investigate once this thing is up and running. */
     3268
     3269        rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL);
     3270        if (rc == VINF_SUCCESS)
     3271        {
     3272            if (IoExitInfo.n.u1Type == 0)   /* OUT */
     3273            {
     3274                rc = IOMInterpretOUTSEx(pVM, pVCpu, CPUMCTX2CORE(pCtx), IoExitInfo.n.u16Port, pDis->fPrefix,
     3275                                        (DISCPUMODE)pDis->uAddrMode, uIOSize);
     3276                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIOStringWrite);
     3277            }
     3278            else
     3279            {
     3280                rc = IOMInterpretINSEx(pVM, pVCpu, CPUMCTX2CORE(pCtx), IoExitInfo.n.u16Port, pDis->fPrefix,
     3281                                       (DISCPUMODE)pDis->uAddrMode, uIOSize);
     3282                STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIOStringRead);
     3283            }
     3284        }
     3285        else
     3286            rc = VINF_EM_RAW_EMULATE_INSTR;
     3287    }
     3288    else
     3289    {
     3290        /* IN/OUT - I/O instruction. */
     3291        Assert(!IoExitInfo.n.u1REP);
     3292
     3293        if (IoExitInfo.n.u1Type == 0)   /* OUT */
     3294        {
     3295            rc = IOMIOPortWrite(pVM, pVCpu, IoExitInfo.n.u16Port, pCtx->eax & uAndVal, uIOSize);
     3296            if (rc == VINF_IOM_R3_IOPORT_WRITE)
     3297                HMR0SavePendingIOPortWrite(pVCpu, pCtx->rip, pVmcb->ctrl.u64ExitInfo2, IoExitInfo.n.u16Port, uAndVal, uIOSize);
     3298
     3299            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIOWrite);
     3300        }
     3301        else
     3302        {
     3303            uint32_t u32Val = 0;
     3304
     3305            rc = IOMIOPortRead(pVM, pVCpu, IoExitInfo.n.u16Port, &u32Val, uIOSize);
     3306            if (IOM_SUCCESS(rc))
     3307            {
     3308                /* Save result of I/O IN instr. in AL/AX/EAX. */
     3309                pCtx->eax = (pCtx->eax & ~uAndVal) | (u32Val & uAndVal);
     3310            }
     3311            else if (rc == VINF_IOM_R3_IOPORT_READ)
     3312                HMR0SavePendingIOPortRead(pVCpu, pCtx->rip, pVmcb->ctrl.u64ExitInfo2, IoExitInfo.n.u16Port, uAndVal, uIOSize);
     3313
     3314            STAM_COUNTER_INC(&pVCpu->hm.s.StatExitIORead);
     3315        }
     3316    }
     3317
     3318    if (IOM_SUCCESS(rc))
     3319    {
     3320        /* AMD-V saves the RIP of the instruction following the IO instruction in EXITINFO2. */
     3321        pCtx->rip = pVmcb->ctrl.u64ExitInfo2;
     3322
     3323        if (RT_LIKELY(rc == VINF_SUCCESS))
     3324        {
     3325            /* If any IO breakpoints are armed, then we should check if a debug trap needs to be generated. */
     3326            if (pCtx->dr[7] & X86_DR7_ENABLED_MASK)
     3327            {
     3328                /* I/O breakpoint length, in bytes. */
     3329                static uint32_t const s_aIOBPLen[4] = { 1, 2, 0, 4 };
     3330
     3331                STAM_COUNTER_INC(&pVCpu->hm.s.StatDRxIoCheck);
     3332                for (unsigned i = 0; i < 4; i++)
     3333                {
     3334                    unsigned uBPLen = s_aIOBPLen[X86_DR7_GET_LEN(pCtx->dr[7], i)];
     3335
     3336                    if (   IoExitInfo.n.u16Port >= pCtx->dr[i]
     3337                        && IoExitInfo.n.u16Port < pCtx->dr[i] + uBPLen
     3338                        && (pCtx->dr[7] & (X86_DR7_L(i) | X86_DR7_G(i)))
     3339                        && (pCtx->dr[7] & X86_DR7_RW(i, X86_DR7_RW_IO)) == X86_DR7_RW(i, X86_DR7_RW_IO))
     3340                    {
     3341                        Assert(CPUMIsGuestDebugStateActive(pVCpu));
     3342
     3343                        /* Clear all breakpoint status flags and set the one we just hit. */
     3344                        pCtx->dr[6] &= ~(X86_DR6_B0 | X86_DR6_B1 | X86_DR6_B2 | X86_DR6_B3);
     3345                        pCtx->dr[6] |= (uint64_t)RT_BIT(i);
     3346
     3347                        /*
     3348                         * Note: AMD64 Architecture Programmer's Manual 13.1:
     3349                         * Bits 15:13 of the DR6 register is never cleared by the processor and must be cleared
     3350                         * by software after the contents have been read.
     3351                         */
     3352                        pVmcb->guest.u64DR6 = pCtx->dr[6];
     3353
     3354                        /* X86_DR7_GD will be cleared if drx accesses should be trapped inside the guest. */
     3355                        pCtx->dr[7] &= ~X86_DR7_GD;
     3356
     3357                        /* Paranoia. */
     3358                        pMixedCtx->dr[7] &= 0xffffffff;                                             /* Upper 32 bits MBZ. */
     3359                        pMixedCtx->dr[7] &= ~(RT_BIT(11) | RT_BIT(12) | RT_BIT(14) | RT_BIT(15));   /* MBZ. */
     3360                        pMixedCtx->dr[7] |= 0x400;                                                  /* MB1. */
     3361
     3362                        pVmcb->guest.u64DR7 = pCtx->dr[7];
     3363                        pVmcb->ctrl.u64VmcbCleanBits &= ~HMSVM_VMCB_CLEAN_DRX;
     3364
     3365                        /* Inject the debug exception. */
     3366                        hmR0SvmSetPendingXcptDB(pVCpu);
     3367                        break;
     3368                    }
     3369                }
     3370            }
     3371        }
     3372    }
     3373
     3374#ifdef DEBUG
     3375    if (rc == VINF_IOM_R3_IOPORT_READ)
     3376        Assert(IoExitInfo.n.u1Type != 0);
     3377    else if (rc == VINF_IOM_R3_IOPORT_WRITE)
     3378        Assert(IoExitInfo.n.u1Type == 0);
     3379    else
     3380    {
     3381        AssertMsg(   RT_FAILURE(rc)
     3382                  || rc == VINF_SUCCESS
     3383                  || rc == VINF_EM_RAW_EMULATE_INSTR
     3384                  || rc == VINF_EM_RAW_GUEST_TRAP
     3385                  || rc == VINF_TRPM_XCPT_DISPATCHED, ("%Rrc\n", rc));
     3386    }
     3387#endif
     3388    return rc;
     3389}
     3390
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r46552 r46562  
    82198219
    82208220    /* I/O operation lookup arrays. */
    8221     static const uint32_t s_aIOSize[4]  = { 1, 2, 0, 4 };                   /* Size of the I/O Accesses. */
     8221    static const uint32_t s_aIOSize[4]  = { 1, 2, 0, 4 };                   /* Size of the I/O accesses. */
    82228222    static const uint32_t s_aIOOpAnd[4] = { 0xff, 0xffff, 0, 0xffffffff };  /* AND masks for saving the result (in AL/AX/EAX). */
    82238223
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