VirtualBox

Changeset 47444 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Jul 29, 2013 12:37:31 AM (12 years ago)
Author:
vboxsync
Message:

IEM,HM,PGM: Started on string I/O optimizations using IEM (disabled). Cleaned up confusing status code handling in hmR0VmxCheckForceFlags (involving PGM) as well as some use of incorrect doxygen groups (@name).

Location:
trunk/src/VBox/VMM
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r47429 r47444  
    742742    if (rcOldPassUp == VINF_SUCCESS)
    743743        pIemCpu->rcPassUp = VBOXSTRICTRC_VAL(rcPassUp);
    744     /* If both are EM scheduling code, use EM priority rules. */
     744    /* If both are EM scheduling codes, use EM priority rules. */
    745745    else if (   rcOldPassUp >= VINF_EM_FIRST && rcOldPassUp <= VINF_EM_LAST
    746746             && rcPassUp    >= VINF_EM_FIRST && rcPassUp    <= VINF_EM_LAST)
     
    764764        Log(("IEM: rcPassUp=%Rrc  rcOldPassUp=%Rrc!\n", VBOXSTRICTRC_VAL(rcPassUp), rcOldPassUp));
    765765    return VINF_SUCCESS;
     766}
     767
     768
     769/**
     770 * Initializes the execution state.
     771 *
     772 * @param   pIemCpu             The per CPU IEM state.
     773 * @param   fBypassHandlers     Whether to bypass access handlers.
     774 */
     775DECLINLINE(void) iemInitExec(PIEMCPU pIemCpu, bool fBypassHandlers)
     776{
     777    PCPUMCTX pCtx  = pIemCpu->CTX_SUFF(pCtx);
     778    PVMCPU   pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
     779
     780#if defined(VBOX_STRICT) && (defined(IEM_VERIFICATION_MODE_FULL) || !defined(VBOX_WITH_RAW_MODE_NOT_R0))
     781    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->cs));
     782    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->ss));
     783    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->es));
     784    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->ds));
     785    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->fs));
     786    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->gs));
     787    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->ldtr));
     788    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->tr));
     789#endif
     790
     791#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     792    CPUMGuestLazyLoadHiddenCsAndSs(pVCpu);
     793#endif
     794    pIemCpu->uCpl               = CPUMGetGuestCPL(pVCpu);
     795    IEMMODE enmMode = CPUMIsGuestIn64BitCodeEx(pCtx)
     796                    ? IEMMODE_64BIT
     797                    : pCtx->cs.Attr.n.u1DefBig /** @todo check if this is correct... */
     798                    ? IEMMODE_32BIT
     799                    : IEMMODE_16BIT;
     800    pIemCpu->enmCpuMode         = enmMode;
     801#ifdef VBOX_STRICT
     802    pIemCpu->enmDefAddrMode     = (IEMMODE)0xc0fe;
     803    pIemCpu->enmEffAddrMode     = (IEMMODE)0xc0fe;
     804    pIemCpu->enmDefOpSize       = (IEMMODE)0xc0fe;
     805    pIemCpu->enmEffOpSize       = (IEMMODE)0xc0fe;
     806    pIemCpu->fPrefixes          = (IEMMODE)0xfeedbeef;
     807    pIemCpu->uRexReg            = 127;
     808    pIemCpu->uRexB              = 127;
     809    pIemCpu->uRexIndex          = 127;
     810    pIemCpu->iEffSeg            = 127;
     811    pIemCpu->offOpcode          = 127;
     812    pIemCpu->cbOpcode           = 127;
     813#endif
     814
     815    pIemCpu->cActiveMappings    = 0;
     816    pIemCpu->iNextMapping       = 0;
     817    pIemCpu->rcPassUp           = VINF_SUCCESS;
     818    pIemCpu->fBypassHandlers    = fBypassHandlers;
     819#ifdef VBOX_WITH_RAW_MODE_NOT_R0
     820    pIemCpu->fInPatchCode       = pIemCpu->uCpl == 0
     821                               && pCtx->cs.u64Base == 0
     822                               && pCtx->cs.u32Limit == UINT32_MAX
     823                               && PATMIsPatchGCAddr(IEMCPU_TO_VM(pIemCpu), pCtx->eip);
     824    if (!pIemCpu->fInPatchCode)
     825        CPUMRawLeave(pVCpu, CPUMCTX2CORE(pCtx), VINF_SUCCESS);
     826#endif
    766827}
    767828
     
    90219082
    90229083/**
    9023  * The actual code execution bits of IEMExecOne, IEMExecOneEx, and
    9024  * IEMExecOneWithPrefetchedByPC.
    9025  *
    9026  * @return  Strict VBox status code.
    9027  * @param   pVCpu       The current virtual CPU.
     9084 * Makes status code addjustments (pass up from I/O and access handler)
     9085 * as well as maintaining statistics.
     9086 *
     9087 * @returns Strict VBox status code to pass up.
    90289088 * @param   pIemCpu     The IEM per CPU data.
    9029  * @param   fExecuteInhibit     If set, execute the instruction following CLI,
    9030  *                      POP SS and MOV SS,GR.
    9031  */
    9032 DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecOneInner(PVMCPU pVCpu, PIEMCPU pIemCpu, bool fExecuteInhibit)
    9033 {
    9034     uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
    9035     VBOXSTRICTRC rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
    9036     if (rcStrict == VINF_SUCCESS)
    9037         pIemCpu->cInstructions++;
    9038 //#ifdef DEBUG
    9039 //    AssertMsg(pIemCpu->offOpcode == cbInstr || rcStrict != VINF_SUCCESS, ("%u %u\n", pIemCpu->offOpcode, cbInstr));
    9040 //#endif
    9041 
    9042     /* Execute the next instruction as well if a cli, pop ss or
    9043        mov ss, Gr has just completed successfully. */
    9044     if (   fExecuteInhibit
    9045         && rcStrict == VINF_SUCCESS
    9046         && VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
    9047         && EMGetInhibitInterruptsPC(pVCpu) == pIemCpu->CTX_SUFF(pCtx)->rip )
    9048     {
    9049         rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, pIemCpu->fBypassHandlers);
    9050         if (rcStrict == VINF_SUCCESS)
    9051         {
    9052             b; IEM_OPCODE_GET_NEXT_U8(&b);
    9053             rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
    9054             if (rcStrict == VINF_SUCCESS)
    9055                 pIemCpu->cInstructions++;
    9056         }
    9057         EMSetInhibitInterruptsPC(pVCpu, UINT64_C(0x7777555533331111));
    9058     }
    9059 
    9060     /*
    9061      * Return value fiddling and statistics.
    9062      */
     9089 * @param   rcStrict    The status from executing an instruction.
     9090 */
     9091DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecStatusCodeFiddling(PIEMCPU pIemCpu, VBOXSTRICTRC rcStrict)
     9092{
    90639093    if (rcStrict != VINF_SUCCESS)
    90649094    {
    90659095        if (RT_SUCCESS(rcStrict))
    90669096        {
    9067             AssertMsg(rcStrict >= VINF_EM_FIRST && rcStrict <= VINF_EM_LAST, ("rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     9097            AssertMsg(   (rcStrict >= VINF_EM_FIRST && rcStrict <= VINF_EM_LAST)
     9098                      || rcStrict == VINF_IOM_R3_IOPORT_READ
     9099                      || rcStrict == VINF_IOM_R3_IOPORT_WRITE
     9100                      || rcStrict == VINF_IOM_R3_MMIO_READ
     9101                      || rcStrict == VINF_IOM_R3_MMIO_READ_WRITE
     9102                      || rcStrict == VINF_IOM_R3_MMIO_WRITE
     9103                      , ("rcStrict=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    90689104            int32_t const rcPassUp = pIemCpu->rcPassUp;
    90699105            if (rcPassUp == VINF_SUCCESS)
     
    91009136    }
    91019137
     9138    return rcStrict;
     9139}
     9140
     9141
     9142/**
     9143 * The actual code execution bits of IEMExecOne, IEMExecOneEx, and
     9144 * IEMExecOneWithPrefetchedByPC.
     9145 *
     9146 * @return  Strict VBox status code.
     9147 * @param   pVCpu       The current virtual CPU.
     9148 * @param   pIemCpu     The IEM per CPU data.
     9149 * @param   fExecuteInhibit     If set, execute the instruction following CLI,
     9150 *                      POP SS and MOV SS,GR.
     9151 */
     9152DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecOneInner(PVMCPU pVCpu, PIEMCPU pIemCpu, bool fExecuteInhibit)
     9153{
     9154    uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
     9155    VBOXSTRICTRC rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
     9156    if (rcStrict == VINF_SUCCESS)
     9157        pIemCpu->cInstructions++;
     9158//#ifdef DEBUG
     9159//    AssertMsg(pIemCpu->offOpcode == cbInstr || rcStrict != VINF_SUCCESS, ("%u %u\n", pIemCpu->offOpcode, cbInstr));
     9160//#endif
     9161
     9162    /* Execute the next instruction as well if a cli, pop ss or
     9163       mov ss, Gr has just completed successfully. */
     9164    if (   fExecuteInhibit
     9165        && rcStrict == VINF_SUCCESS
     9166        && VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
     9167        && EMGetInhibitInterruptsPC(pVCpu) == pIemCpu->CTX_SUFF(pCtx)->rip )
     9168    {
     9169        rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu, pIemCpu->fBypassHandlers);
     9170        if (rcStrict == VINF_SUCCESS)
     9171        {
     9172            b; IEM_OPCODE_GET_NEXT_U8(&b);
     9173            rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
     9174            if (rcStrict == VINF_SUCCESS)
     9175                pIemCpu->cInstructions++;
     9176        }
     9177        EMSetInhibitInterruptsPC(pVCpu, UINT64_C(0x7777555533331111));
     9178    }
     9179
     9180    /*
     9181     * Return value fiddling, statistics and sanity assertions.
     9182     */
     9183    rcStrict = iemExecStatusCodeFiddling(pIemCpu, rcStrict);
     9184
    91029185    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pIemCpu->CTX_SUFF(pCtx)->cs));
    91039186    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pIemCpu->CTX_SUFF(pCtx)->ss));
     
    94819564#endif
    94829565
     9566
     9567
     9568/**
     9569 * Interface for HM and EM for executing string I/O OUT (write) instructions.
     9570 *
     9571 * This API ASSUMES that the caller has already verified that the guest code is
     9572 * allowed to access the I/O port.  (The I/O port is in the DX register in the
     9573 * guest state.)
     9574 *
     9575 * @returns Strict VBox status code.
     9576 * @param   pVCpu               The cross context per virtual CPU structure.
     9577 * @param   cbValue             The size of the I/O port access (1, 2, or 4).
     9578 * @param   enmAddrMode         The addressing mode.
     9579 * @param   fRepPrefix          Indicates whether a repeat prefix is used
     9580 *                              (doesn't matter which for this instruction).
     9581 * @param   cbInstr             The instruction length in bytes.
     9582 * @param   iEffSeg             The effective segment address.
     9583 */
     9584VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoWrite(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode,
     9585                                                bool fRepPrefix, uint8_t cbInstr, uint8_t iEffSeg)
     9586{
     9587    AssertMsgReturn(iEffSeg < X86_SREG_COUNT, ("%#x\n", iEffSeg), VERR_IEM_INVALID_EFF_SEG);
     9588    AssertReturn(cbInstr - 1U <= 14U, VERR_IEM_INVALID_INSTR_LENGTH);
     9589
     9590    /*
     9591     * State init.
     9592     */
     9593    PIEMCPU pIemCpu = &pVCpu->iem.s;
     9594    iemInitExec(pIemCpu, false /*fBypassHandlers*/);
     9595
     9596    /*
     9597     * Switch orgy for getting to the right handler.
     9598     */
     9599    VBOXSTRICTRC rcStrict;
     9600    if (fRepPrefix)
     9601    {
     9602        switch (enmAddrMode)
     9603        {
     9604            case IEMMODE_16BIT:
     9605                switch (cbValue)
     9606                {
     9607                    case 1: rcStrict = iemCImpl_rep_outs_op8_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9608                    case 2: rcStrict = iemCImpl_rep_outs_op16_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9609                    case 4: rcStrict = iemCImpl_rep_outs_op32_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9610                    default:
     9611                        AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE);
     9612                }
     9613                break;
     9614
     9615            case IEMMODE_32BIT:
     9616                switch (cbValue)
     9617                {
     9618                    case 1: rcStrict = iemCImpl_rep_outs_op8_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9619                    case 2: rcStrict = iemCImpl_rep_outs_op16_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9620                    case 4: rcStrict = iemCImpl_rep_outs_op32_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9621                    default:
     9622                        AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE);
     9623                }
     9624                break;
     9625
     9626            case IEMMODE_64BIT:
     9627                switch (cbValue)
     9628                {
     9629                    case 1: rcStrict = iemCImpl_rep_outs_op8_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9630                    case 2: rcStrict = iemCImpl_rep_outs_op16_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9631                    case 4: rcStrict = iemCImpl_rep_outs_op32_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9632                    default:
     9633                        AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE);
     9634                }
     9635                break;
     9636
     9637            default:
     9638                AssertMsgFailedReturn(("enmAddrMode=%d\n", enmAddrMode), VERR_IEM_INVALID_ADDRESS_MODE);
     9639        }
     9640    }
     9641    else
     9642    {
     9643        switch (enmAddrMode)
     9644        {
     9645            case IEMMODE_16BIT:
     9646                switch (cbValue)
     9647                {
     9648                    case 1: rcStrict = iemCImpl_outs_op8_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9649                    case 2: rcStrict = iemCImpl_outs_op16_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9650                    case 4: rcStrict = iemCImpl_outs_op32_addr16(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9651                    default:
     9652                        AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE);
     9653                }
     9654                break;
     9655
     9656            case IEMMODE_32BIT:
     9657                switch (cbValue)
     9658                {
     9659                    case 1: rcStrict = iemCImpl_outs_op8_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9660                    case 2: rcStrict = iemCImpl_outs_op16_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9661                    case 4: rcStrict = iemCImpl_outs_op32_addr32(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9662                    default:
     9663                        AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE);
     9664                }
     9665                break;
     9666
     9667            case IEMMODE_64BIT:
     9668                switch (cbValue)
     9669                {
     9670                    case 1: rcStrict = iemCImpl_outs_op8_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9671                    case 2: rcStrict = iemCImpl_outs_op16_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9672                    case 4: rcStrict = iemCImpl_outs_op32_addr64(pIemCpu, cbInstr, iEffSeg, true /*fIoChecked*/); break;
     9673                    default:
     9674                        AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE);
     9675                }
     9676                break;
     9677
     9678            default:
     9679                AssertMsgFailedReturn(("enmAddrMode=%d\n", enmAddrMode), VERR_IEM_INVALID_ADDRESS_MODE);
     9680        }
     9681    }
     9682
     9683    return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
     9684}
     9685
     9686
     9687/**
     9688 * Interface for HM and EM for executing string I/O IN (read) instructions.
     9689 *
     9690 * This API ASSUMES that the caller has already verified that the guest code is
     9691 * allowed to access the I/O port.  (The I/O port is in the DX register in the
     9692 * guest state.)
     9693 *
     9694 * @returns Strict VBox status code.
     9695 * @param   pVCpu               The cross context per virtual CPU structure.
     9696 * @param   cbValue             The size of the I/O port access (1, 2, or 4).
     9697 * @param   enmAddrMode         The addressing mode.
     9698 * @param   fRepPrefix          Indicates whether a repeat prefix is used
     9699 *                              (doesn't matter which for this instruction).
     9700 * @param   cbInstr             The instruction length in bytes.
     9701 */
     9702VMM_INT_DECL(VBOXSTRICTRC) IEMExecStringIoRead(PVMCPU pVCpu, uint8_t cbValue, IEMMODE enmAddrMode,
     9703                                               bool fRepPrefix, uint8_t cbInstr)
     9704{
     9705    AssertReturn(cbInstr - 1U <= 14U, VERR_IEM_INVALID_INSTR_LENGTH);
     9706
     9707    /*
     9708     * State init.
     9709     */
     9710    PIEMCPU pIemCpu = &pVCpu->iem.s;
     9711    iemInitExec(pIemCpu, false /*fBypassHandlers*/);
     9712
     9713    /*
     9714     * Switch orgy for getting to the right handler.
     9715     */
     9716    VBOXSTRICTRC rcStrict;
     9717    if (fRepPrefix)
     9718    {
     9719        switch (enmAddrMode)
     9720        {
     9721            case IEMMODE_16BIT:
     9722                switch (cbValue)
     9723                {
     9724                    case 1: rcStrict = iemCImpl_rep_ins_op8_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9725                    case 2: rcStrict = iemCImpl_rep_ins_op16_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9726                    case 4: rcStrict = iemCImpl_rep_ins_op32_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9727                    default:
     9728                        AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE);
     9729                }
     9730                break;
     9731
     9732            case IEMMODE_32BIT:
     9733                switch (cbValue)
     9734                {
     9735                    case 1: rcStrict = iemCImpl_rep_ins_op8_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9736                    case 2: rcStrict = iemCImpl_rep_ins_op16_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9737                    case 4: rcStrict = iemCImpl_rep_ins_op32_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9738                    default:
     9739                        AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE);
     9740                }
     9741                break;
     9742
     9743            case IEMMODE_64BIT:
     9744                switch (cbValue)
     9745                {
     9746                    case 1: rcStrict = iemCImpl_rep_ins_op8_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9747                    case 2: rcStrict = iemCImpl_rep_ins_op16_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9748                    case 4: rcStrict = iemCImpl_rep_ins_op32_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9749                    default:
     9750                        AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE);
     9751                }
     9752                break;
     9753
     9754            default:
     9755                AssertMsgFailedReturn(("enmAddrMode=%d\n", enmAddrMode), VERR_IEM_INVALID_ADDRESS_MODE);
     9756        }
     9757    }
     9758    else
     9759    {
     9760        switch (enmAddrMode)
     9761        {
     9762            case IEMMODE_16BIT:
     9763                switch (cbValue)
     9764                {
     9765                    case 1: rcStrict = iemCImpl_ins_op8_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9766                    case 2: rcStrict = iemCImpl_ins_op16_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9767                    case 4: rcStrict = iemCImpl_ins_op32_addr16(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9768                    default:
     9769                        AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE);
     9770                }
     9771                break;
     9772
     9773            case IEMMODE_32BIT:
     9774                switch (cbValue)
     9775                {
     9776                    case 1: rcStrict = iemCImpl_ins_op8_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9777                    case 2: rcStrict = iemCImpl_ins_op16_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9778                    case 4: rcStrict = iemCImpl_ins_op32_addr32(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9779                    default:
     9780                        AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE);
     9781                }
     9782                break;
     9783
     9784            case IEMMODE_64BIT:
     9785                switch (cbValue)
     9786                {
     9787                    case 1: rcStrict = iemCImpl_ins_op8_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9788                    case 2: rcStrict = iemCImpl_ins_op16_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9789                    case 4: rcStrict = iemCImpl_ins_op32_addr64(pIemCpu, cbInstr, true /*fIoChecked*/); break;
     9790                    default:
     9791                        AssertMsgFailedReturn(("cbValue=%#x\n", cbValue), VERR_IEM_INVALID_OPERAND_SIZE);
     9792                }
     9793                break;
     9794
     9795            default:
     9796                AssertMsgFailedReturn(("enmAddrMode=%d\n", enmAddrMode), VERR_IEM_INVALID_ADDRESS_MODE);
     9797        }
     9798    }
     9799
     9800    return iemExecStatusCodeFiddling(pIemCpu, rcStrict);
     9801}
     9802
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h

    r47288 r47444  
    10181018 * Implements 'INS' (no rep)
    10191019 */
    1020 IEM_CIMPL_DEF_0(RT_CONCAT4(iemCImpl_ins_op,OP_SIZE,_addr,ADDR_SIZE))
     1020IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_ins_op,OP_SIZE,_addr,ADDR_SIZE), bool, fIoChecked)
    10211021{
    10221022    PVM             pVM  = IEMCPU_TO_VM(pIemCpu);
     
    10381038     * ASSUMES nothing is read from the I/O port before traps are taken.
    10391039     */
    1040     rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, pCtx->dx, OP_SIZE / 8);
    1041     if (rcStrict != VINF_SUCCESS)
    1042         return rcStrict;
     1040    if (!fIoChecked)
     1041    {
     1042        rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, pCtx->dx, OP_SIZE / 8);
     1043        if (rcStrict != VINF_SUCCESS)
     1044            return rcStrict;
     1045    }
    10431046
    10441047    OP_TYPE        *puMem;
     
    10771080 * Implements 'REP INS'.
    10781081 */
    1079 IEM_CIMPL_DEF_0(RT_CONCAT4(iemCImpl_rep_ins_op,OP_SIZE,_addr,ADDR_SIZE))
     1082IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_rep_ins_op,OP_SIZE,_addr,ADDR_SIZE), bool, fIoChecked)
    10801083{
    10811084    PVM         pVM   = IEMCPU_TO_VM(pIemCpu);
     
    10871090     */
    10881091    uint16_t const  u16Port    = pCtx->dx;
    1089     VBOXSTRICTRC rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, u16Port, OP_SIZE / 8);
    1090     if (rcStrict != VINF_SUCCESS)
    1091         return rcStrict;
     1092    VBOXSTRICTRC    rcStrict;
     1093    if (!fIoChecked)
     1094    {
     1095        rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, u16Port, OP_SIZE / 8);
     1096        if (rcStrict != VINF_SUCCESS)
     1097            return rcStrict;
     1098    }
    10921099
    10931100    ADDR_TYPE       uCounterReg = pCtx->ADDR_rCX;
     
    11481155            /** @todo Change the I/O manager interface to make use of
    11491156             *        mapped buffers instead of leaving those bits to the
    1150              *        device implementation? */
     1157             *        device implementation! */
    11511158            PGMPAGEMAPLOCK PgLockMem;
    11521159            OP_TYPE *puMem;
     
    11711178                    {
    11721179                        if (IOM_SUCCESS(rcStrict))
     1180                        {
    11731181                            rcStrict = iemSetPassUpStatus(pIemCpu, rcStrict);
    1174                         if (uCounterReg == 0)
    1175                             iemRegAddToRip(pIemCpu, cbInstr);
     1182                            if (uCounterReg == 0)
     1183                                iemRegAddToRip(pIemCpu, cbInstr);
     1184                        }
    11761185                        iemMemPageUnmap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_W, puMem, &PgLockMem);
    11771186                        return rcStrict;
     
    12261235            if (rcStrict != VINF_SUCCESS)
    12271236            {
    1228                 if (IOM_SUCCESS(rcStrict))
    1229                     rcStrict = iemSetPassUpStatus(pIemCpu, rcStrict);
    12301237                if (uCounterReg == 0)
    12311238                    iemRegAddToRip(pIemCpu, cbInstr);
     1239                rcStrict = iemSetPassUpStatus(pIemCpu, rcStrict);
    12321240                return rcStrict;
    12331241            }
     
    12461254 * Implements 'OUTS' (no rep)
    12471255 */
    1248 IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_outs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)
     1256IEM_CIMPL_DEF_2(RT_CONCAT4(iemCImpl_outs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg, bool, fIoChecked)
    12491257{
    12501258    PVM             pVM  = IEMCPU_TO_VM(pIemCpu);
     
    12571265     * ASSUMES nothing is read from the I/O port before traps are taken.
    12581266     */
    1259     rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, pCtx->dx, OP_SIZE / 8);
    1260     if (rcStrict != VINF_SUCCESS)
    1261         return rcStrict;
     1267    if (!fIoChecked)
     1268    {
     1269        rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, pCtx->dx, OP_SIZE / 8);
     1270        if (rcStrict != VINF_SUCCESS)
     1271            return rcStrict;
     1272    }
    12621273
    12631274    OP_TYPE uValue;
     
    12871298 * Implements 'REP OUTS'.
    12881299 */
    1289 IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_rep_outs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)
     1300IEM_CIMPL_DEF_2(RT_CONCAT4(iemCImpl_rep_outs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg, bool, fIoChecked)
    12901301{
    12911302    PVM         pVM   = IEMCPU_TO_VM(pIemCpu);
     
    12971308     */
    12981309    uint16_t const  u16Port    = pCtx->dx;
    1299     VBOXSTRICTRC rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, u16Port, OP_SIZE / 8);
    1300     if (rcStrict != VINF_SUCCESS)
    1301         return rcStrict;
     1310    VBOXSTRICTRC    rcStrict;
     1311    if (!fIoChecked)
     1312    {
     1313        rcStrict = iemHlpCheckPortIOPermission(pIemCpu, pCtx, u16Port, OP_SIZE / 8);
     1314        if (rcStrict != VINF_SUCCESS)
     1315            return rcStrict;
     1316    }
    13021317
    13031318    ADDR_TYPE       uCounterReg = pCtx->ADDR_rCX;
     
    13721387                    {
    13731388                        if (IOM_SUCCESS(rcStrict))
     1389                        {
    13741390                            rcStrict = iemSetPassUpStatus(pIemCpu, rcStrict);
    1375                         if (uCounterReg == 0)
    1376                             iemRegAddToRip(pIemCpu, cbInstr);
     1391                            if (uCounterReg == 0)
     1392                                iemRegAddToRip(pIemCpu, cbInstr);
     1393                        }
    13771394                        iemMemPageUnmap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_R, puMem, &PgLockMem);
    13781395                        return rcStrict;
     
    14221439            {
    14231440                if (IOM_SUCCESS(rcStrict))
     1441                {
     1442                    if (uCounterReg == 0)
     1443                        iemRegAddToRip(pIemCpu, cbInstr);
    14241444                    rcStrict = iemSetPassUpStatus(pIemCpu, rcStrict);
    1425                 if (uCounterReg == 0)
    1426                     iemRegAddToRip(pIemCpu, cbInstr);
     1445                }
    14271446                return rcStrict;
    14281447            }
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r47415 r47444  
    83858385        switch (pIemCpu->enmEffAddrMode)
    83868386        {
    8387             case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op8_addr16);
    8388             case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op8_addr32);
    8389             case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op8_addr64);
     8387            case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op8_addr16, false);
     8388            case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op8_addr32, false);
     8389            case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op8_addr64, false);
    83908390            IEM_NOT_REACHED_DEFAULT_CASE_RET();
    83918391        }
     
    83968396        switch (pIemCpu->enmEffAddrMode)
    83978397        {
    8398             case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op8_addr16);
    8399             case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op8_addr32);
    8400             case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op8_addr64);
     8398            case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op8_addr16, false);
     8399            case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op8_addr32, false);
     8400            case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op8_addr64, false);
    84018401            IEM_NOT_REACHED_DEFAULT_CASE_RET();
    84028402        }
     
    84178417                switch (pIemCpu->enmEffAddrMode)
    84188418                {
    8419                     case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op16_addr16);
    8420                     case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op16_addr32);
    8421                     case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op16_addr64);
     8419                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op16_addr16, false);
     8420                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op16_addr32, false);
     8421                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op16_addr64, false);
    84228422                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
    84238423                }
     
    84278427                switch (pIemCpu->enmEffAddrMode)
    84288428                {
    8429                     case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op32_addr16);
    8430                     case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op32_addr32);
    8431                     case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_ins_op32_addr64);
     8429                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op32_addr16, false);
     8430                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op32_addr32, false);
     8431                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_ins_op32_addr64, false);
    84328432                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
    84338433                }
     
    84448444                switch (pIemCpu->enmEffAddrMode)
    84458445                {
    8446                     case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op16_addr16);
    8447                     case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op16_addr32);
    8448                     case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op16_addr64);
     8446                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op16_addr16, false);
     8447                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op16_addr32, false);
     8448                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op16_addr64, false);
    84498449                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
    84508450                }
     
    84548454                switch (pIemCpu->enmEffAddrMode)
    84558455                {
    8456                     case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op32_addr16);
    8457                     case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op32_addr32);
    8458                     case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_ins_op32_addr64);
     8456                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op32_addr16, false);
     8457                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op32_addr32, false);
     8458                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_ins_op32_addr64, false);
    84598459                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
    84608460                }
     
    84758475        switch (pIemCpu->enmEffAddrMode)
    84768476        {
    8477             case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op8_addr16, pIemCpu->iEffSeg);
    8478             case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op8_addr32, pIemCpu->iEffSeg);
    8479             case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op8_addr64, pIemCpu->iEffSeg);
     8477            case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op8_addr16, pIemCpu->iEffSeg, false);
     8478            case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op8_addr32, pIemCpu->iEffSeg, false);
     8479            case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op8_addr64, pIemCpu->iEffSeg, false);
    84808480            IEM_NOT_REACHED_DEFAULT_CASE_RET();
    84818481        }
     
    84868486        switch (pIemCpu->enmEffAddrMode)
    84878487        {
    8488             case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op8_addr16, pIemCpu->iEffSeg);
    8489             case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op8_addr32, pIemCpu->iEffSeg);
    8490             case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op8_addr64, pIemCpu->iEffSeg);
     8488            case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op8_addr16, pIemCpu->iEffSeg, false);
     8489            case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op8_addr32, pIemCpu->iEffSeg, false);
     8490            case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op8_addr64, pIemCpu->iEffSeg, false);
    84918491            IEM_NOT_REACHED_DEFAULT_CASE_RET();
    84928492        }
     
    85078507                switch (pIemCpu->enmEffAddrMode)
    85088508                {
    8509                     case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op16_addr16, pIemCpu->iEffSeg);
    8510                     case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op16_addr32, pIemCpu->iEffSeg);
    8511                     case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op16_addr64, pIemCpu->iEffSeg);
     8509                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op16_addr16, pIemCpu->iEffSeg, false);
     8510                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op16_addr32, pIemCpu->iEffSeg, false);
     8511                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op16_addr64, pIemCpu->iEffSeg, false);
    85128512                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
    85138513                }
     
    85178517                switch (pIemCpu->enmEffAddrMode)
    85188518                {
    8519                     case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op32_addr16, pIemCpu->iEffSeg);
    8520                     case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op32_addr32, pIemCpu->iEffSeg);
    8521                     case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op32_addr64, pIemCpu->iEffSeg);
     8519                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op32_addr16, pIemCpu->iEffSeg, false);
     8520                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op32_addr32, pIemCpu->iEffSeg, false);
     8521                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_rep_outs_op32_addr64, pIemCpu->iEffSeg, false);
    85228522                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
    85238523                }
     
    85348534                switch (pIemCpu->enmEffAddrMode)
    85358535                {
    8536                     case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op16_addr16, pIemCpu->iEffSeg);
    8537                     case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op16_addr32, pIemCpu->iEffSeg);
    8538                     case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op16_addr64, pIemCpu->iEffSeg);
     8536                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op16_addr16, pIemCpu->iEffSeg, false);
     8537                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op16_addr32, pIemCpu->iEffSeg, false);
     8538                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op16_addr64, pIemCpu->iEffSeg, false);
    85398539                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
    85408540                }
     
    85448544                switch (pIemCpu->enmEffAddrMode)
    85458545                {
    8546                     case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op32_addr16, pIemCpu->iEffSeg);
    8547                     case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op32_addr32, pIemCpu->iEffSeg);
    8548                     case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op32_addr64, pIemCpu->iEffSeg);
     8546                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op32_addr16, pIemCpu->iEffSeg, false);
     8547                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op32_addr32, pIemCpu->iEffSeg, false);
     8548                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_2(iemCImpl_outs_op32_addr64, pIemCpu->iEffSeg, false);
    85498549                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
    85508550                }
  • trunk/src/VBox/VMM/VMMAll/PGMAll.cpp

    r46420 r47444  
    17671767 * @remarks This must be called *AFTER* PGMUpdateCR3.
    17681768 *
    1769  * @returns VBox status code.
    17701769 * @param   pVCpu               Pointer to the VMCPU.
    17711770 * @param   paPdpes             The four PDPE values. The array pointed to must
     
    17741773 * @remarks No-long-jump zone!!!
    17751774 */
    1776 VMM_INT_DECL(int) PGMGstUpdatePaePdpes(PVMCPU pVCpu, PCX86PDPE paPdpes)
     1775VMM_INT_DECL(void) PGMGstUpdatePaePdpes(PVMCPU pVCpu, PCX86PDPE paPdpes)
    17771776{
    17781777    Assert(pVCpu->pgm.s.enmShadowMode == PGMMODE_EPT);
     
    17951794
    17961795    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES);
    1797     return VINF_SUCCESS;
    17981796}
    17991797
     
    20372035 * @returns VBox status code.
    20382036 * @retval  VINF_SUCCESS.
    2039  * @retval  (If applied when not in nested mode: VINF_PGM_SYNC_CR3 if monitoring
    2040  *          requires a CR3 sync. This can safely be ignored and overridden since
    2041  *          the FF will be set too then.)
     2037 * @retval  VINF_PGM_SYNC_CR3 if monitoring requires a CR3 sync (not for nested
     2038 *          paging modes).  This can safely be ignored and overridden since the
     2039 *          FF will be set too then.
    20422040 * @param   pVCpu       Pointer to the VMCPU.
    20432041 * @param   cr3         The new cr3.
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r47441 r47444  
    2929#include <VBox/vmm/pdmapi.h>
    3030#include <VBox/vmm/dbgf.h>
     31#include <VBox/vmm/iem.h>
    3132#include <VBox/vmm/iom.h>
    3233#include <VBox/vmm/selm.h>
     
    111112/** @} */
    112113
    113 /**
     114/** @name
    114115 * Flags to skip redundant reads of some common VMCS fields that are not part of
    115116 * the guest-CPU state but are in the transient structure.
     
    121122#define HMVMX_UPDATED_TRANSIENT_EXIT_INTERRUPTION_INFO        RT_BIT(4)
    122123#define HMVMX_UPDATED_TRANSIENT_EXIT_INTERRUPTION_ERROR_CODE  RT_BIT(5)
    123 
    124 /**
    125  * @name Exception bitmap mask for real-mode guests (real-on-v86).
     124/** @} */
     125
     126/**
     127 * Exception bitmap mask for real-mode guests (real-on-v86).
    126128 *
    127129 * We need to intercept all exceptions manually (except #PF). #NM is also
     
    136138                                      | RT_BIT(X86_XCPT_MF)             | RT_BIT(X86_XCPT_AC)    | RT_BIT(X86_XCPT_MC)    \
    137139                                      | RT_BIT(X86_XCPT_XF))
    138 /** @} */
    139 
    140 /**
    141  * @name Exception bitmap mask for all contributory exceptions.
     140
     141/**
     142 * Exception bitmap mask for all contributory exceptions.
    142143 *
    143144 * Page fault is deliberately excluded here as it's conditional as to whether
     
    146147#define HMVMX_CONTRIBUTORY_XCPT_MASK  (  RT_BIT(X86_XCPT_GP) | RT_BIT(X86_XCPT_NP) | RT_BIT(X86_XCPT_SS) | RT_BIT(X86_XCPT_TS) \
    147148                                       | RT_BIT(X86_XCPT_DE))
    148 /** @} */
    149149
    150150/** Maximum VM-instruction error number. */
     
    164164*   Structures and Typedefs                                                    *
    165165*******************************************************************************/
    166 /** @name VMX transient.
     166/**
     167 * VMX transient state.
    167168 *
    168169 * A state structure for holding miscellaneous information across
    169170 * VMX non-root operation and restored after the transition.
    170  *
    171  * @{ */
     171 */
    172172typedef struct VMXTRANSIENT
    173173{
     
    197197    /** The VM-exit instruction-length field. */
    198198    uint32_t        cbInstr;
     199    /** The VM-exit instruction-information field. */
     200    union
     201    {
     202        /** Plain unsigned int representation. */
     203        uint32_t    u;
     204        /** INS and OUTS information. */
     205        struct
     206        {
     207            uint32_t    u6Reserved0 : 6;
     208            /** The address size; 0=16-bit, 1=32-bit, 2=64-bit, rest undefined. */
     209            uint32_t    u3AddrSize : 3;
     210            uint32_t    u5Reserved1 : 5;
     211            /** The segment register (X86_SREG_XXX). */
     212            uint32_t    iSegReg : 3;
     213            uint32_t    uReserved2 : 14;
     214        } StrIo;
     215    }               ExitInstrInfo;
    199216    /** Whether the VM-entry failed or not. */
    200217    bool            fVMEntryFailed;
    201218    /** Alignment. */
    202     uint8_t         abAlignment1[7];
     219    uint8_t         abAlignment1[3];
    203220
    204221    /** The VM-entry interruption-information field. */
     
    221238     *  contributory exception or a page-fault. */
    222239    bool            fVectoringPF;
    223 } VMXTRANSIENT, *PVMXTRANSIENT;
     240} VMXTRANSIENT;
    224241AssertCompileMemberAlignment(VMXTRANSIENT, uExitReason,    sizeof(uint64_t));
    225242AssertCompileMemberAlignment(VMXTRANSIENT, uExitIntrInfo,  sizeof(uint64_t));
    226243AssertCompileMemberAlignment(VMXTRANSIENT, uEntryIntrInfo, sizeof(uint64_t));
    227 /** @} */
     244AssertCompileMemberSize(VMXTRANSIENT, ExitInstrInfo, sizeof(uint32_t));
     245/** Pointer to VMX transient state. */
     246typedef VMXTRANSIENT *PVMXTRANSIENT;
    228247
    229248
     
    249268    VMXMSREXIT_PASSTHRU_WRITE
    250269} VMXMSREXITWRITE;
     270
     271/**
     272 * VM-exit handler.
     273 *
     274 * @returns VBox status code.
     275 * @param   pVCpu           Pointer to the VMCPU.
     276 * @param   pMixedCtx       Pointer to the guest-CPU context. The data may be
     277 *                          out-of-sync. Make sure to update the required
     278 *                          fields before using them.
     279 * @param   pVmxTransient   Pointer to the VMX-transient structure.
     280 */
     281#ifndef HMVMX_USE_FUNCTION_TABLE
     282typedef int FNVMEXITHANDLER(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
     283#else
     284typedef DECLCALLBACK(int) FNVMEXITHANDLER(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
     285/** Pointer to VM-exit handler. */
     286typedef FNVMEXITHANDLER *PFNVMEXITHANDLER;
     287#endif
    251288
    252289
     
    263300#ifndef HMVMX_USE_FUNCTION_TABLE
    264301DECLINLINE(int)           hmR0VmxHandleExit(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient, uint32_t rcReason);
    265 #define HMVMX_EXIT_DECL   static int
     302# define HMVMX_EXIT_DECL  static int
    266303#else
    267 #define HMVMX_EXIT_DECL   static DECLCALLBACK(int)
     304# define HMVMX_EXIT_DECL  static DECLCALLBACK(int)
    268305#endif
    269306
    270 HMVMX_EXIT_DECL hmR0VmxExitXcptOrNmi(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    271 HMVMX_EXIT_DECL hmR0VmxExitExtInt(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    272 HMVMX_EXIT_DECL hmR0VmxExitTripleFault(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    273 HMVMX_EXIT_DECL hmR0VmxExitInitSignal(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    274 HMVMX_EXIT_DECL hmR0VmxExitSipi(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    275 HMVMX_EXIT_DECL hmR0VmxExitIoSmi(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    276 HMVMX_EXIT_DECL hmR0VmxExitSmi(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    277 HMVMX_EXIT_DECL hmR0VmxExitIntWindow(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    278 HMVMX_EXIT_DECL hmR0VmxExitNmiWindow(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    279 HMVMX_EXIT_DECL hmR0VmxExitTaskSwitch(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    280 HMVMX_EXIT_DECL hmR0VmxExitCpuid(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    281 HMVMX_EXIT_DECL hmR0VmxExitGetsec(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    282 HMVMX_EXIT_DECL hmR0VmxExitHlt(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    283 HMVMX_EXIT_DECL hmR0VmxExitInvd(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    284 HMVMX_EXIT_DECL hmR0VmxExitInvlpg(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    285 HMVMX_EXIT_DECL hmR0VmxExitRdpmc(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    286 HMVMX_EXIT_DECL hmR0VmxExitRdtsc(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    287 HMVMX_EXIT_DECL hmR0VmxExitRsm(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    288 HMVMX_EXIT_DECL hmR0VmxExitSetPendingXcptUD(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    289 HMVMX_EXIT_DECL hmR0VmxExitMovCRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    290 HMVMX_EXIT_DECL hmR0VmxExitMovDRx(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    291 HMVMX_EXIT_DECL hmR0VmxExitIoInstr(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    292 HMVMX_EXIT_DECL hmR0VmxExitRdmsr(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    293 HMVMX_EXIT_DECL hmR0VmxExitWrmsr(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    294 HMVMX_EXIT_DECL hmR0VmxExitErrInvalidGuestState(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    295 HMVMX_EXIT_DECL hmR0VmxExitErrMsrLoad(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    296 HMVMX_EXIT_DECL hmR0VmxExitErrUndefined(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    297 HMVMX_EXIT_DECL hmR0VmxExitMwait(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    298 HMVMX_EXIT_DECL hmR0VmxExitMtf(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    299 HMVMX_EXIT_DECL hmR0VmxExitMonitor(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    300 HMVMX_EXIT_DECL hmR0VmxExitPause(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    301 HMVMX_EXIT_DECL hmR0VmxExitErrMachineCheck(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    302 HMVMX_EXIT_DECL hmR0VmxExitTprBelowThreshold(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    303 HMVMX_EXIT_DECL hmR0VmxExitApicAccess(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    304 HMVMX_EXIT_DECL hmR0VmxExitXdtrAccess(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    305 HMVMX_EXIT_DECL hmR0VmxExitXdtrAccess(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    306 HMVMX_EXIT_DECL hmR0VmxExitEptViolation(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    307 HMVMX_EXIT_DECL hmR0VmxExitEptMisconfig(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    308 HMVMX_EXIT_DECL hmR0VmxExitRdtscp(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    309 HMVMX_EXIT_DECL hmR0VmxExitPreemptTimer(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    310 HMVMX_EXIT_DECL hmR0VmxExitWbinvd(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    311 HMVMX_EXIT_DECL hmR0VmxExitXsetbv(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    312 HMVMX_EXIT_DECL hmR0VmxExitRdrand(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    313 HMVMX_EXIT_DECL hmR0VmxExitInvpcid(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
     307/** @name VM-exit handlers.
     308 * @{
     309 */
     310static FNVMEXITHANDLER hmR0VmxExitXcptOrNmi;
     311static FNVMEXITHANDLER hmR0VmxExitExtInt;
     312static FNVMEXITHANDLER hmR0VmxExitTripleFault;
     313static FNVMEXITHANDLER hmR0VmxExitInitSignal;
     314static FNVMEXITHANDLER hmR0VmxExitSipi;
     315static FNVMEXITHANDLER hmR0VmxExitIoSmi;
     316static FNVMEXITHANDLER hmR0VmxExitSmi;
     317static FNVMEXITHANDLER hmR0VmxExitIntWindow;
     318static FNVMEXITHANDLER hmR0VmxExitNmiWindow;
     319static FNVMEXITHANDLER hmR0VmxExitTaskSwitch;
     320static FNVMEXITHANDLER hmR0VmxExitCpuid;
     321static FNVMEXITHANDLER hmR0VmxExitGetsec;
     322static FNVMEXITHANDLER hmR0VmxExitHlt;
     323static FNVMEXITHANDLER hmR0VmxExitInvd;
     324static FNVMEXITHANDLER hmR0VmxExitInvlpg;
     325static FNVMEXITHANDLER hmR0VmxExitRdpmc;
     326static FNVMEXITHANDLER hmR0VmxExitRdtsc;
     327static FNVMEXITHANDLER hmR0VmxExitRsm;
     328static FNVMEXITHANDLER hmR0VmxExitSetPendingXcptUD;
     329static FNVMEXITHANDLER hmR0VmxExitMovCRx;
     330static FNVMEXITHANDLER hmR0VmxExitMovDRx;
     331static FNVMEXITHANDLER hmR0VmxExitIoInstr;
     332static FNVMEXITHANDLER hmR0VmxExitRdmsr;
     333static FNVMEXITHANDLER hmR0VmxExitWrmsr;
     334static FNVMEXITHANDLER hmR0VmxExitErrInvalidGuestState;
     335static FNVMEXITHANDLER hmR0VmxExitErrMsrLoad;
     336static FNVMEXITHANDLER hmR0VmxExitErrUndefined;
     337static FNVMEXITHANDLER hmR0VmxExitMwait;
     338static FNVMEXITHANDLER hmR0VmxExitMtf;
     339static FNVMEXITHANDLER hmR0VmxExitMonitor;
     340static FNVMEXITHANDLER hmR0VmxExitPause;
     341static FNVMEXITHANDLER hmR0VmxExitErrMachineCheck;
     342static FNVMEXITHANDLER hmR0VmxExitTprBelowThreshold;
     343static FNVMEXITHANDLER hmR0VmxExitApicAccess;
     344static FNVMEXITHANDLER hmR0VmxExitXdtrAccess;
     345static FNVMEXITHANDLER hmR0VmxExitXdtrAccess;
     346static FNVMEXITHANDLER hmR0VmxExitEptViolation;
     347static FNVMEXITHANDLER hmR0VmxExitEptMisconfig;
     348static FNVMEXITHANDLER hmR0VmxExitRdtscp;
     349static FNVMEXITHANDLER hmR0VmxExitPreemptTimer;
     350static FNVMEXITHANDLER hmR0VmxExitWbinvd;
     351static FNVMEXITHANDLER hmR0VmxExitXsetbv;
     352static FNVMEXITHANDLER hmR0VmxExitRdrand;
     353static FNVMEXITHANDLER hmR0VmxExitInvpcid;
     354/** @} */
    314355
    315356static int      hmR0VmxExitXcptNM(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
     
    326367*******************************************************************************/
    327368#ifdef HMVMX_USE_FUNCTION_TABLE
    328 /**
    329  * VM-exit handler.
    330  *
    331  * @returns VBox status code.
    332  * @param   pVCpu           Pointer to the VMCPU.
    333  * @param   pMixedCtx       Pointer to the guest-CPU context. The data may be
    334  *                          out-of-sync. Make sure to update the required
    335  *                          fields before using them.
    336  * @param   pVmxTransient   Pointer to the VMX-transient structure.
    337  */
    338 typedef DECLCALLBACK(int) FNVMEXITHANDLER(PVMCPU pVCpu, PCPUMCTX pMixedCtx, PVMXTRANSIENT pVmxTransient);
    339 /** Pointer to VM-exit handler. */
    340 typedef FNVMEXITHANDLER *const PFNVMEXITHANDLER;
    341369
    342370/**
     
    582610
    583611/**
     612 * Reads the VM-exit instruction-information field from the VMCS into
     613 * the VMX transient structure.
     614 *
     615 * @returns VBox status code.
     616 * @param   pVCpu           The cross context per CPU structure.
     617 * @param   pVmxTransient   Pointer to the VMX transient structure.
     618 */
     619DECLINLINE(int) hmR0VmxReadExitInstrInfoVmcs(PVMCPU pVCpu, PVMXTRANSIENT pVmxTransient)
     620{
     621    if (!(pVmxTransient->fVmcsFieldsRead & HMVMX_UPDATED_TRANSIENT_EXIT_INSTR_LEN))
     622    {
     623        int rc = VMXReadVmcs32(VMX_VMCS32_RO_EXIT_INSTR_INFO, &pVmxTransient->cbInstr);
     624        AssertRCReturn(rc, rc);
     625        pVmxTransient->fVmcsFieldsRead |= HMVMX_UPDATED_TRANSIENT_EXIT_INSTR_LEN;
     626    }
     627    return VINF_SUCCESS;
     628}
     629
     630
     631/**
    584632 * Reads the exit qualification from the VMCS into the VMX transient structure.
    585633 *
     
    57175765    Assert(VMMRZCallRing3IsEnabled(pVCpu));
    57185766
    5719     int rc = VERR_INTERNAL_ERROR_5;
    57205767    if (   VM_FF_IS_PENDING(pVM, VM_FF_HM_TO_R3_MASK | VM_FF_REQUEST | VM_FF_PGM_POOL_FLUSH_PENDING | VM_FF_PDM_DMA)
    57215768        || VMCPU_FF_IS_PENDING(pVCpu,  VMCPU_FF_HM_TO_R3_MASK | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL
     
    57235770    {
    57245771        /* We need the control registers now, make sure the guest-CPU context is updated. */
    5725         rc = hmR0VmxSaveGuestControlRegs(pVCpu, pMixedCtx);
    5726         AssertRCReturn(rc, rc);
     5772        int rc2 = hmR0VmxSaveGuestControlRegs(pVCpu, pMixedCtx);
     5773        AssertRCReturn(rc2, rc2);
    57275774
    57285775        /* Pending HM CR3 sync. */
    57295776        if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_CR3))
    57305777        {
    5731             rc = PGMUpdateCR3(pVCpu, pMixedCtx->cr3);
    5732             Assert(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3);
     5778            int rc2 = PGMUpdateCR3(pVCpu, pMixedCtx->cr3);
     5779            AssertMsgReturn(rc2 == VINF_SUCCESS || rc2 == VINF_PGM_SYNC_CR3,
     5780                            ("%Rrc\n", rc2), RT_FAILURE_NP(rc2) ? rc2 : VERR_IPE_UNEXPECTED_INFO_STATUS);
    57335781            Assert(!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_CR3));
    57345782        }
     
    57375785        if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES))
    57385786        {
    5739             rc = PGMGstUpdatePaePdpes(pVCpu, &pVCpu->hm.s.aPdpes[0]);
    5740             AssertRC(rc);
     5787            PGMGstUpdatePaePdpes(pVCpu, &pVCpu->hm.s.aPdpes[0]);
    57415788            Assert(!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES));
    57425789        }
     
    57455792        if (VMCPU_FF_IS_PENDING(pVCpu,VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL))
    57465793        {
    5747             rc = PGMSyncCR3(pVCpu, pMixedCtx->cr0, pMixedCtx->cr3, pMixedCtx->cr4, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
    5748             if (rc != VINF_SUCCESS)
     5794            int rc2 = PGMSyncCR3(pVCpu, pMixedCtx->cr0, pMixedCtx->cr3, pMixedCtx->cr4, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_PGM_SYNC_CR3));
     5795            if (rc2 != VINF_SUCCESS)
    57495796            {
    5750                 AssertRC(rc);
    5751                 Log4(("hmR0VmxCheckForceFlags: PGMSyncCR3 forcing us back to ring-3. rc=%d\n", rc));
    5752                 return rc;
     5797                AssertRC(rc2);
     5798                Log4(("hmR0VmxCheckForceFlags: PGMSyncCR3 forcing us back to ring-3. rc2=%d\n", rc2));
     5799                return rc2;
    57535800            }
    57545801        }
     
    57605807        {
    57615808            STAM_COUNTER_INC(&pVCpu->hm.s.StatSwitchHmToR3FF);
    5762             rc = RT_UNLIKELY(VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3;
    5763             Log4(("hmR0VmxCheckForceFlags: HM_TO_R3 forcing us back to ring-3. rc=%d\n", rc));
    5764             return rc;
     5809            int rc2 = RT_UNLIKELY(VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY)) ? VINF_EM_NO_MEMORY : VINF_EM_RAW_TO_R3;
     5810            Log4(("hmR0VmxCheckForceFlags: HM_TO_R3 forcing us back to ring-3. rc=%d\n", rc2));
     5811            return rc2;
    57655812        }
    57665813
     
    57895836
    57905837    /* Paranoia. */
    5791     Assert(rc != VERR_EM_INTERPRETER);
    57925838    return VINF_SUCCESS;
    57935839}
     
    72057251        case VMX_EXIT_RDTSCP:                  rc = hmR0VmxExitRdtscp(pVCpu, pMixedCtx, pVmxTransient); break;
    72067252        case VMX_EXIT_APIC_ACCESS:             rc = hmR0VmxExitApicAccess(pVCpu, pMixedCtx, pVmxTransient); break;
    7207         case VMX_EXIT_XCPT_NMI:                rc = hmR0VmxExitXcptOrNmi(pVCpu, pMixedCtx, pVmxTransient); break;
     7253        case VMX_EXIT_XCPT_OR_NMI:             rc = hmR0VmxExitXcptOrNmi(pVCpu, pMixedCtx, pVmxTransient); break;
    72087254        case VMX_EXIT_MOV_CRX:                 rc = hmR0VmxExitMovCRx(pVCpu, pMixedCtx, pVmxTransient); break;
    72097255        case VMX_EXIT_EXT_INT:                 rc = hmR0VmxExitExtInt(pVCpu, pMixedCtx, pVmxTransient); break;
     
    83348380    bool     fIOWrite  = (   VMX_EXIT_QUALIFICATION_IO_DIRECTION(pVmxTransient->uExitQualification)
    83358381                          == VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT);
    8336     bool     fIOString = (VMX_EXIT_QUALIFICATION_IO_STRING(pVmxTransient->uExitQualification) == 1);
    8337     AssertReturn(uIOWidth <= 3 && uIOWidth != 2, VERR_HM_IPE_3);
     8382    bool     fIOString = VMX_EXIT_QUALIFICATION_IO_IS_STRING(pVmxTransient->uExitQualification);
     8383    AssertReturn(uIOWidth <= 3 && uIOWidth != 2, VERR_HMVMX_IPE_1);
    83388384
    83398385    /* I/O operation lookup arrays. */
     
    83438389    const uint32_t cbValue  = s_aIOSizes[uIOWidth];
    83448390    const uint32_t cbInstr  = pVmxTransient->cbInstr;
     8391    bool fUpdateRipAlready  = false; /* ugly hack, should be temporary. */
    83458392    PVM pVM                 = pVCpu->CTX_SUFF(pVM);
    83468393    if (fIOString)
    83478394    {
    8348         /* INS/OUTS - I/O String instruction. */
    8349         /** @todo for now manually disassemble later optimize by getting the fields from
    8350          *        the VMCS. VMX_VMCS_RO_EXIT_GUEST_LINEAR_ADDR contains the flat pointer
    8351          *        operand of the instruction. VMX_VMCS32_RO_EXIT_INSTR_INFO contains
    8352          *        segment prefix info.
    8353          *  bird: The linear address isn't worth more than a few ticks, esp. for
    8354          *        32-bit guests where we'd have to do limit checks.  Main point,
    8355          *        though, is that AMD doesn't have it. They both have segment reg,
    8356          *        address mode (size) and operand size. Though, Intel didn't have the
    8357          *        segment+addrsize on the early models (Footnote 3 on table 27-8, volume
    8358          *        3, July 2013 edition). */
     8395        /*
     8396         * INS/OUTS - I/O String instruction.
     8397         *
     8398         * Use instruction-information if available, otherwise fall back on
     8399         * interpreting the instruction.
     8400         */
     8401#if 0 /* Not quite ready, seem iSegReg assertion trigger once... Do we perhaps need to always read that in longjmp / preempt scenario? */
     8402        AssertReturn(pMixedCtx->dx == uIOPort, VERR_HMVMX_IPE_2);
     8403        if (MSR_IA32_VMX_BASIC_INFO_VMCS_INS_OUTS(pVM->hm.s.vmx.msr.vmx_basic_info))
     8404        {
     8405            rc  = hmR0VmxReadExitIntrInfoVmcs(pVCpu, pVmxTransient);
     8406            /** @todo optimize this, IEM should request the additional state if it needs it (GP, PF, ++). */
     8407            rc |= hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
     8408            AssertRCReturn(rc, rc);
     8409            AssertReturn(pVmxTransient->ExitInstrInfo.StrIo.u3AddrSize <= 2, VERR_HMVMX_IPE_3);
     8410            AssertCompile(IEMMODE_16BIT == 0 && IEMMODE_32BIT == 1 && IEMMODE_64BIT == 2);
     8411            IEMMODE enmAddrMode = (IEMMODE)pVmxTransient->ExitInstrInfo.StrIo.u3AddrSize;
     8412            bool    fRep        = VMX_EXIT_QUALIFICATION_IO_IS_REP(pVmxTransient->uExitQualification);
     8413            if (fIOWrite)
     8414            {
     8415                rc = IEMExecStringIoWrite(pVCpu, cbValue, enmAddrMode, fRep, cbInstr,
     8416                                          pVmxTransient->ExitInstrInfo.StrIo.iSegReg);
     8417                //if (rc == VINF_IOM_R3_IOPORT_WRITE)
     8418                //    hmR0SavePendingIOPortWriteStr(pVCpu, pMixedCtx->rip, cbValue, enmAddrMode, fRep, cbInstr,
     8419                //                                  pVmxTransient->ExitInstrInfo.StrIo.iSegReg);
     8420            }
     8421            else
     8422            {
     8423                AssertMsgReturn(pVmxTransient->ExitInstrInfo.StrIo.iSegReg == X86_SREG_ES,
     8424                                ("%#x (%#llx)\n", pVmxTransient->ExitInstrInfo.StrIo.iSegReg, pVmxTransient->ExitInstrInfo.u),
     8425                                VERR_HMVMX_IPE_4);
     8426                rc = IEMExecStringIoRead(pVCpu, cbValue, enmAddrMode, fRep, cbInstr);
     8427                //if (rc == VINF_IOM_R3_IOPORT_READ)
     8428                //    hmR0SavePendingIOPortReadStr(pVCpu, pMixedCtx->rip, cbValue, enmAddrMode, fRep, cbInstr);
     8429            }
     8430        }
     8431        else
     8432        {
     8433            /** @todo optimize this, IEM should request the additional state if it needs it (GP, PF, ++). */
     8434            rc = hmR0VmxSaveGuestState(pVCpu, pMixedCtx);
     8435            AssertRCReturn(rc, rc);
     8436            rc = IEMExecOne(pVCpu);
     8437        }
     8438        /** @todo IEM needs to be setting these flags somehow. */
     8439        pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_RIP;
     8440        fUpdateRipAlready = true;
     8441
     8442#else
    83598443        PDISCPUSTATE pDis = &pVCpu->hm.s.DisState;
    83608444        rc = EMInterpretDisasCurrent(pVM, pVCpu, pDis, NULL);
     
    83818465            rc = VINF_EM_RAW_EMULATE_INSTR;
    83828466        }
     8467#endif
    83838468    }
    83848469    else
    83858470    {
    8386         /* IN/OUT - I/O instruction. */
     8471        /*
     8472         * IN/OUT - I/O instruction.
     8473         */
    83878474        const uint32_t uAndVal = s_aIOOpAnd[uIOWidth];
    8388         Assert(!VMX_EXIT_QUALIFICATION_IO_REP(pVmxTransient->uExitQualification));
     8475        Assert(!VMX_EXIT_QUALIFICATION_IO_IS_REP(pVmxTransient->uExitQualification));
    83898476        if (fIOWrite)
    83908477        {
     
    84138500    if (IOM_SUCCESS(rc))
    84148501    {
    8415         pMixedCtx->rip += cbInstr;
    8416         pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_RIP;
     8502        if (!fUpdateRipAlready)
     8503        {
     8504            pMixedCtx->rip += cbInstr;
     8505            pVCpu->hm.s.fContextUseFlags |= HM_CHANGED_GUEST_RIP;
     8506        }
    84178507        if (RT_LIKELY(rc == VINF_SUCCESS))
    84188508        {
     
    84228512             * Note that the I/O breakpoint type is undefined if CR4.DE is 0.
    84238513             */
     8514            /** @todo We're not honoring I/O BPs if informational status code is returned.
     8515             *        We're also ignoring our own debugger's attempt at using I/O
     8516             *        breakpoints.  The whole host & guest debugger stuff needs to be
     8517             *        looked over at some point.  For now, it's just best effort. */
    84248518            rc = hmR0VmxSaveGuestDebugRegs(pVCpu, pMixedCtx);      /* For DR7. */
    84258519            AssertRCReturn(rc, rc);
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r47123 r47444  
    16131613        rc = VMXReadVmcs64(VMX_VMCS64_GUEST_PDPTE3_FULL, &aPdpes[3].u); AssertRCReturn(rc, rc);
    16141614
    1615         rc = PGMGstUpdatePaePdpes(pVCpu, &aPdpes[0]);
     1615        PGMGstUpdatePaePdpes(pVCpu, &aPdpes[0]);
    16161616        AssertRCReturn(rc, rc);
    16171617    }
     
    45984598
    45994599        uint32_t cbSize = g_aIOSize[uIOWidth];
    4600         if (VMX_EXIT_QUALIFICATION_IO_STRING(exitQualification))
     4600        if (VMX_EXIT_QUALIFICATION_IO_IS_STRING(exitQualification))
    46014601        {
    46024602            /* ins/outs */
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r47425 r47444  
    14991499            AssertPtr(pPdpes);
    15001500
    1501             int rc2 = PGMGstUpdatePaePdpes(pVCpu, pPdpes);
    1502             if (RT_FAILURE(rc2))
    1503                 return rc2;
     1501            PGMGstUpdatePaePdpes(pVCpu, pPdpes);
    15041502            Assert(!VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES));
    15051503        }
  • trunk/src/VBox/VMM/VMMR3/HM.cpp

    r47202 r47444  
    980980    LogRel(("HM: VMCS memory type              = %x\n", MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(pVM->hm.s.vmx.msr.vmx_basic_info)));
    981981    LogRel(("HM: Dual-monitor treatment        = %d\n", MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(pVM->hm.s.vmx.msr.vmx_basic_info)));
     982    LogRel(("HM: OUTS & INS instruction-info   = %d\n", MSR_IA32_VMX_BASIC_INFO_VMCS_INS_OUTS(pVM->hm.s.vmx.msr.vmx_basic_info)));
    982983    LogRel(("HM: Max resume loops              = %RX32\n", pVM->hm.s.cMaxResumeLoops));
    983984
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r47413 r47444  
    1919#define ___IEMInternal_h
    2020
     21#include <VBox/vmm/cpum.h>
     22#include <VBox/vmm/iem.h>
    2123#include <VBox/vmm/stam.h>
    22 #include <VBox/vmm/cpum.h>
    2324#include <VBox/param.h>
    2425
     
    5051typedef RTFLOAT32U const *PCRTFLOAT32U;
    5152
    52 
    53 /**
    54  * Operand or addressing mode.
    55  */
    56 typedef enum IEMMODE
    57 {
    58     IEMMODE_16BIT = 0,
    59     IEMMODE_32BIT,
    60     IEMMODE_64BIT
    61 } IEMMODE;
    62 AssertCompileSize(IEMMODE, 4);
    6353
    6454/**
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