VirtualBox

Changeset 56628 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Jun 24, 2015 7:44:56 PM (9 years ago)
Author:
vboxsync
Message:

IEM: Postpone INS memory writes to ring-3 if we hit an access handler. We cannot redo the read, that will only mess things us. This introduces a new per-cpu forced flag, VMCPU_FF_IEM, that must cause immediate return to ring-3 where it will be serviced ASAP. IEM will try return VINF_EM_RAW_TO_R3 as well to help make sure we get back to ring-3.

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

Legend:

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

    r56413 r56628  
    769769    PVMCPU   pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
    770770
     771    Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_IEM));
     772    Assert(pIemCpu->PendingCommit.enmFn == IEMCOMMIT_INVALID);
     773
    771774#if defined(VBOX_STRICT) && (defined(IEM_VERIFICATION_MODE_FULL) || !defined(VBOX_WITH_RAW_MODE_NOT_R0))
    772775    Assert(CPUMSELREG_ARE_HIDDEN_PARTS_VALID(pVCpu, &pCtx->cs));
     
    829832    PCPUMCTX pCtx  = pIemCpu->CTX_SUFF(pCtx);
    830833    PVMCPU   pVCpu = IEMCPU_TO_VMCPU(pIemCpu);
     834
     835    Assert(!VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_IEM));
     836    Assert(pIemCpu->PendingCommit.enmFn == IEMCOMMIT_INVALID);
    831837
    832838#if defined(VBOX_STRICT) && (defined(IEM_VERIFICATION_MODE_FULL) || !defined(VBOX_WITH_RAW_MODE_NOT_R0))
     
    1071210718                      || rcStrict == VINF_CPUM_R3_MSR_WRITE
    1071310719                      || rcStrict == VINF_EM_RAW_EMULATE_INSTR
     10720                      || rcStrict == VINF_EM_RAW_TO_R3
    1071410721                      /* raw-mode / virt handlers only: */
    1071510722                      || rcStrict == VINF_EM_RAW_EMULATE_INSTR_GDT_FAULT
     
    1155211559}
    1155311560
     11561#ifdef IN_RING3
     11562
     11563/**
     11564 * Called by force-flag handling code when VMCPU_FF_IEM is set.
     11565 *
     11566 * @returns Merge between @a rcStrict and what the commit operation returned.
     11567 * @param   pVCpu           Pointer to the cross context CPU structure for the
     11568 *                          calling EMT.
     11569 * @param   rcStrict        The status code returned by ring-0 or raw-mode.
     11570 */
     11571VMMR3_INT_DECL(VBOXSTRICTRC) IEMR3DoPendingAction(PVMCPU pVCpu, VBOXSTRICTRC rcStrict)
     11572{
     11573    PIEMCPU      pIemCpu = &pVCpu->iem.s;
     11574
     11575    /*
     11576     * Retrieve and reset the pending commit.
     11577     */
     11578    IEMCOMMIT const enmFn = pIemCpu->PendingCommit.enmFn;
     11579    pIemCpu->PendingCommit.enmFn = IEMCOMMIT_INVALID;
     11580    VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_IEM);
     11581
     11582    /*
     11583     * Must reset pass-up status code.
     11584     */
     11585    pIemCpu->rcPassUp = VINF_SUCCESS;
     11586
     11587    /*
     11588     * Call the function.  Currently using switch here instead of function
     11589     * pointer table as a switch won't get skewed.
     11590     */
     11591    VBOXSTRICTRC rcStrictCommit;
     11592    switch (enmFn)
     11593    {
     11594        case IEMCOMMIT_INS_OP8_ADDR16:          rcStrictCommit = iemR3CImpl_commit_ins_op8_addr16(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11595        case IEMCOMMIT_INS_OP8_ADDR32:          rcStrictCommit = iemR3CImpl_commit_ins_op8_addr32(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11596        case IEMCOMMIT_INS_OP8_ADDR64:          rcStrictCommit = iemR3CImpl_commit_ins_op8_addr64(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11597        case IEMCOMMIT_INS_OP16_ADDR16:         rcStrictCommit = iemR3CImpl_commit_ins_op16_addr16(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11598        case IEMCOMMIT_INS_OP16_ADDR32:         rcStrictCommit = iemR3CImpl_commit_ins_op16_addr32(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11599        case IEMCOMMIT_INS_OP16_ADDR64:         rcStrictCommit = iemR3CImpl_commit_ins_op16_addr64(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11600        case IEMCOMMIT_INS_OP32_ADDR16:         rcStrictCommit = iemR3CImpl_commit_ins_op32_addr16(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11601        case IEMCOMMIT_INS_OP32_ADDR32:         rcStrictCommit = iemR3CImpl_commit_ins_op32_addr32(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11602        case IEMCOMMIT_INS_OP32_ADDR64:         rcStrictCommit = iemR3CImpl_commit_ins_op32_addr64(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11603        case IEMCOMMIT_REP_INS_OP8_ADDR16:      rcStrictCommit = iemR3CImpl_commit_rep_ins_op8_addr16(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11604        case IEMCOMMIT_REP_INS_OP8_ADDR32:      rcStrictCommit = iemR3CImpl_commit_rep_ins_op8_addr32(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11605        case IEMCOMMIT_REP_INS_OP8_ADDR64:      rcStrictCommit = iemR3CImpl_commit_rep_ins_op8_addr64(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11606        case IEMCOMMIT_REP_INS_OP16_ADDR16:     rcStrictCommit = iemR3CImpl_commit_rep_ins_op16_addr16(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11607        case IEMCOMMIT_REP_INS_OP16_ADDR32:     rcStrictCommit = iemR3CImpl_commit_rep_ins_op16_addr32(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11608        case IEMCOMMIT_REP_INS_OP16_ADDR64:     rcStrictCommit = iemR3CImpl_commit_rep_ins_op16_addr64(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11609        case IEMCOMMIT_REP_INS_OP32_ADDR16:     rcStrictCommit = iemR3CImpl_commit_rep_ins_op32_addr16(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11610        case IEMCOMMIT_REP_INS_OP32_ADDR32:     rcStrictCommit = iemR3CImpl_commit_rep_ins_op32_addr32(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11611        case IEMCOMMIT_REP_INS_OP32_ADDR64:     rcStrictCommit = iemR3CImpl_commit_rep_ins_op32_addr64(pIemCpu, pIemCpu->PendingCommit.cbInstr); break;
     11612        default:
     11613            AssertLogRelMsgFailedReturn(("enmFn=%#x (%d)\n", pIemCpu->PendingCommit.enmFn, pIemCpu->PendingCommit.enmFn), VERR_IEM_IPE_2);
     11614    }
     11615
     11616    /*
     11617     * Merge status code (if any) with the incomming one.
     11618     */
     11619    rcStrictCommit = iemExecStatusCodeFiddling(pIemCpu, rcStrictCommit);
     11620    if (RT_LIKELY(rcStrictCommit == VINF_SUCCESS))
     11621        return rcStrict;
     11622    if (RT_LIKELY(rcStrict == VINF_SUCCESS || rcStrict == VINF_EM_RAW_TO_R3))
     11623        return rcStrictCommit;
     11624
     11625    /* Complicated. */
     11626    if (RT_FAILURE(rcStrict))
     11627        return rcStrict;
     11628    if (RT_FAILURE(rcStrictCommit))
     11629        return rcStrictCommit;
     11630    if (   rcStrict >= VINF_EM_FIRST
     11631        && rcStrict <= VINF_EM_LAST)
     11632    {
     11633        if (   rcStrictCommit >= VINF_EM_FIRST
     11634            && rcStrictCommit <= VINF_EM_LAST)
     11635            return rcStrict < rcStrictCommit ? rcStrict : rcStrictCommit;
     11636
     11637        /* This really shouldn't happen. Check PGM + handler code! */
     11638        AssertLogRelMsgFailedReturn(("rcStrictCommit=%Rrc rcStrict=%Rrc enmFn=%d\n", VBOXSTRICTRC_VAL(rcStrictCommit), VBOXSTRICTRC_VAL(rcStrict), enmFn), VERR_IEM_IPE_1);
     11639    }
     11640    /* This shouldn't really happen either, see IOM_SUCCESS. */
     11641    AssertLogRelMsgFailedReturn(("rcStrictCommit=%Rrc rcStrict=%Rrc enmFn=%d\n", VBOXSTRICTRC_VAL(rcStrictCommit), VBOXSTRICTRC_VAL(rcStrict), enmFn), VERR_IEM_IPE_2);
     11642}
     11643
     11644#endif /* IN_RING */
     11645
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h

    r56416 r56628  
    10151015#if OP_SIZE != 64
    10161016
     1017# if !defined(IN_RING3) && !defined(IEMCIMPL_INS_INLINES)
     1018#  define IEMCIMPL_INS_INLINES 1
     1019
     1020/**
     1021 * Check if we should postpone committing an INS instruction to ring-3, or if we
     1022 * should rather panic.
     1023 *
     1024 * @returns true if we should postpone it, false if it's better to panic.
     1025 * @param   rcStrictMem     The status code returned by the memory write.
     1026 */
     1027DECLINLINE(bool) iemCImpl_ins_shouldPostponeCommitToRing3(VBOXSTRICTRC rcStrictMem)
     1028{
     1029    /*
     1030     * The following requires executing the write in ring-3.
     1031     * See PGMPhysWrite for status code explanations.
     1032     */
     1033    if (   rcStrictMem == VINF_IOM_R3_MMIO_WRITE
     1034        || rcStrictMem == VINF_IOM_R3_MMIO_READ_WRITE
     1035        || rcStrictMem == VINF_EM_RAW_EMULATE_INSTR
     1036# ifdef IN_RC
     1037        || rcStrictMem == VINF_EM_RAW_EMULATE_INSTR_LDT_FAULT
     1038        || rcStrictMem == VINF_EM_RAW_EMULATE_INSTR_TSS_FAULT
     1039        || rcStrictMem == VINF_EM_RAW_EMULATE_INSTR_IDT_FAULT
     1040        || rcStrictMem == VINF_CSAM_PENDING_ACTION
     1041        || rcStrictMem == VINF_PATM_CHECK_PATCH_PAGE
     1042# endif
     1043       )
     1044        return true;
     1045
     1046    /* For the other status code, the pass-up handling should already have
     1047       caught them. So, anything getting down here is a real problem worth
     1048       meditating over. */
     1049    return false;
     1050}
     1051
     1052
     1053/**
     1054 * Merges a iemCImpl_ins_shouldPostponeCommitToRing3() status with the I/O port
     1055 * status.
     1056 *
     1057 * @returns status code.
     1058 * @param   rcStrictPort    The status returned by the I/O port read.
     1059 * @param   rcStrictMem     The status code returned by the memory write.
     1060 */
     1061DECLINLINE(VBOXSTRICTRC) iemCImpl_ins_mergePostponedCommitStatuses(VBOXSTRICTRC rcStrictPort, VBOXSTRICTRC rcStrictMem)
     1062{
     1063    /* Turns out we don't need a lot of merging, since we'll be redoing the
     1064       write anyway.  (CSAM, PATM status codes, perhaps, but that's about it.) */
     1065    return rcStrictPort == VINF_SUCCESS ? VINF_EM_RAW_TO_R3 : rcStrictPort;
     1066}
     1067
     1068# endif /* !IN_RING3 || !IEMCIMPL_INS_INLINES */
     1069
     1070
    10171071/**
    10181072 * Implements 'INS' (no rep)
     
    10671121            iemRegAddToRipAndClearRF(pIemCpu, cbInstr);
    10681122        }
     1123#ifndef IN_RING3
    10691124        /* iemMemMap already checked permissions, so this may only be real errors
    1070            or access handlers meddling. The access handler case is going to
    1071            cause misbehavior if the instruction is re-interpreted or smth. So,
    1072            we fail with an internal error here instead. */
     1125           or access handlers meddling. In the access handler case, we must postpone
     1126           the instruction committing to ring-3. */
     1127        else if (iemCImpl_ins_shouldPostponeCommitToRing3(rcStrict2))
     1128        {
     1129            pIemCpu->PendingCommit.cbInstr = cbInstr;
     1130            pIemCpu->PendingCommit.uValue  = u32Value;
     1131            pIemCpu->PendingCommit.enmFn   = RT_CONCAT4(IEMCOMMIT_INS_OP,OP_SIZE,_ADDR,ADDR_SIZE);
     1132            pIemCpu->cPendingCommit++;
     1133            VMCPU_FF_SET(IEMCPU_TO_VMCPU(pIemCpu), VMCPU_FF_IEM);
     1134            Log(("%s: Postponing to ring-3; cbInstr=%#x u32Value=%#x rcStrict2=%Rrc rcStrict=%Rrc\n", __FUNCTION__,
     1135                 cbInstr, u32Value, VBOXSTRICTRC_VAL(rcStrict2),  VBOXSTRICTRC_VAL(rcStrict)));
     1136            rcStrict = iemCImpl_ins_mergePostponedCommitStatuses(rcStrict, rcStrict2);
     1137        }
     1138#endif
    10731139        else
    1074             AssertLogRelMsgFailedReturn(("rcStrict2=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict2)), VERR_IEM_IPE_1);
     1140            AssertLogRelMsgFailedReturn(("rcStrict2=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict2)), RT_FAILURE_NP(rcStrict2) ? rcStrict2 : VERR_IEM_IPE_1);
    10751141    }
    10761142    return rcStrict;
    10771143}
     1144
     1145
     1146# ifdef IN_RING3
     1147/**
     1148 * Called in ring-3 when raw-mode or ring-0 was forced to return while
     1149 * committing the instruction (hit access handler).
     1150 */
     1151IEM_CIMPL_DEF_0(RT_CONCAT4(iemR3CImpl_commit_ins_op,OP_SIZE,_addr,ADDR_SIZE))
     1152{
     1153    PCPUMCTX     pCtx     = pIemCpu->CTX_SUFF(pCtx);
     1154    VBOXSTRICTRC rcStrict = RT_CONCAT(iemMemStoreDataU,OP_SIZE)(pIemCpu, X86_SREG_ES, pCtx->ADDR_rDI, (OP_TYPE)pIemCpu->PendingCommit.uValue);
     1155    if (rcStrict == VINF_SUCCESS)
     1156    {
     1157        if (!pCtx->eflags.Bits.u1DF)
     1158            pCtx->ADDR_rDI += OP_SIZE / 8;
     1159        else
     1160            pCtx->ADDR_rDI -= OP_SIZE / 8;
     1161        iemRegAddToRipAndClearRF(pIemCpu, cbInstr);
     1162    }
     1163    return rcStrict;
     1164}
     1165# endif /* IN_RING3 */
    10781166
    10791167
     
    12171305            *puMem = (OP_TYPE)u32Value;
    12181306            VBOXSTRICTRC rcStrict2 = iemMemCommitAndUnmap(pIemCpu, puMem, IEM_ACCESS_DATA_W);
    1219             AssertLogRelMsgReturn(rcStrict2 == VINF_SUCCESS, ("rcStrict2=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict2)),
    1220                                   VERR_IEM_IPE_1); /* See non-rep version. */
     1307            if (rcStrict2 == VINF_SUCCESS)
     1308            { /* likely */ }
     1309#ifndef IN_RING3
     1310            /* iemMemMap already checked permissions, so this may only be real errors
     1311               or access handlers meddling. In the access handler case, we must postpone
     1312               the instruction committing to ring-3. */
     1313            else if (iemCImpl_ins_shouldPostponeCommitToRing3(rcStrict2))
     1314            {
     1315                pIemCpu->PendingCommit.cbInstr = cbInstr;
     1316                pIemCpu->PendingCommit.uValue  = u32Value;
     1317                pIemCpu->PendingCommit.enmFn   = RT_CONCAT4(IEMCOMMIT_REP_INS_OP,OP_SIZE,_ADDR,ADDR_SIZE);
     1318                pIemCpu->cPendingCommit++;
     1319                VMCPU_FF_SET(IEMCPU_TO_VMCPU(pIemCpu), VMCPU_FF_IEM);
     1320                Log(("%s: Postponing to ring-3; cbInstr=%#x u32Value=%#x rcStrict2=%Rrc rcStrict=%Rrc\n", __FUNCTION__,
     1321                     cbInstr, u32Value, VBOXSTRICTRC_VAL(rcStrict2),  VBOXSTRICTRC_VAL(rcStrict)));
     1322                return iemCImpl_ins_mergePostponedCommitStatuses(rcStrict, rcStrict2);
     1323            }
     1324#endif
     1325            else
     1326                AssertLogRelMsgFailedReturn(("rcStrict2=%Rrc\n", VBOXSTRICTRC_VAL(rcStrict2)),
     1327                                            RT_FAILURE(rcStrict2) ? rcStrict2 : VERR_IEM_IPE_1);
    12211328
    12221329            pCtx->ADDR_rDI = uAddrReg += cbIncr;
     
    12401347    return VINF_SUCCESS;
    12411348}
     1349
     1350# ifdef IN_RING3
     1351/**
     1352 * Called in ring-3 when raw-mode or ring-0 was forced to return while
     1353 * committing the instruction (hit access handler).
     1354 */
     1355IEM_CIMPL_DEF_0(RT_CONCAT4(iemR3CImpl_commit_rep_ins_op,OP_SIZE,_addr,ADDR_SIZE))
     1356{
     1357    PCPUMCTX     pCtx     = pIemCpu->CTX_SUFF(pCtx);
     1358    VBOXSTRICTRC rcStrict = RT_CONCAT(iemMemStoreDataU,OP_SIZE)(pIemCpu, X86_SREG_ES, pCtx->ADDR_rDI, (OP_TYPE)pIemCpu->PendingCommit.uValue);
     1359    if (rcStrict == VINF_SUCCESS)
     1360    {
     1361        if (!pCtx->eflags.Bits.u1DF)
     1362            pCtx->ADDR_rDI += OP_SIZE / 8;
     1363        else
     1364            pCtx->ADDR_rDI -= OP_SIZE / 8;
     1365        pCtx->ADDR_rCX -= 1;
     1366        if (pCtx->ADDR_rCX == 0)
     1367            iemRegAddToRipAndClearRF(pIemCpu, cbInstr);
     1368    }
     1369    return rcStrict;
     1370}
     1371# endif /* IN_RING3 */
    12421372
    12431373
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r56460 r56628  
    1136611366                  || rcStrict == VINF_EM_DBG_BREAKPOINT
    1136711367                  || rcStrict == VINF_EM_RAW_GUEST_TRAP
     11368                  || rcStrict == VINF_EM_RAW_TO_R3
    1136811369                  || rcStrict == VINF_TRPM_XCPT_DISPATCHED, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    1136911370    }
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r56064 r56628  
    15751575    }
    15761576
     1577    /* IEM has pending work (typically memory write after INS instruction). */
     1578    if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_IEM))
     1579        rc = VBOXSTRICTRC_TODO(IEMR3DoPendingAction(pVCpu, rc));
     1580
    15771581#ifdef VBOX_WITH_RAW_MODE
    15781582    if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_CSAM_PENDING_ACTION))
  • trunk/src/VBox/VMM/VMMR3/IEMR3.cpp

    r56287 r56628  
    6565        STAMR3RegisterF(pVM, &pVCpu->iem.s.cbWritten,                 STAMTYPE_U32,       STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,
    6666                        "Approx bytes written",              "/IEM/CPU%u/cbWritten", idCpu);
     67        STAMR3RegisterF(pVM, &pVCpu->iem.s.cPendingCommit,            STAMTYPE_U32,       STAMVISIBILITY_ALWAYS, STAMUNIT_BYTES,
     68                        "Times RC/R0 had to postpone instruction committing to ring-3", "/IEM/CPU%u/cPendingCommit", idCpu);
    6769
    6870        /*
  • trunk/src/VBox/VMM/VMMR3/VMM.cpp

    r56287 r56628  
    24162416        PRINT_FLAG(VMCPU_FF_,PDM_CRITSECT);
    24172417        PRINT_FLAG(VMCPU_FF_,UNHALT);
     2418        PRINT_FLAG(VMCPU_FF_,IEM);
    24182419        PRINT_FLAG(VMCPU_FF_,REQUEST);
    24192420        PRINT_FLAG(VMCPU_FF_,HM_UPDATE_CR3);
  • trunk/src/VBox/VMM/VMMRC/TRPMRCHandlers.cpp

    r56287 r56628  
    213213                                          | VMCPU_FF_REQUEST | VMCPU_FF_PGM_SYNC_CR3 | VMCPU_FF_PGM_SYNC_CR3_NON_GLOBAL
    214214                                          | VMCPU_FF_PDM_CRITSECT
     215                                          | VMCPU_FF_IEM
    215216                                          | VMCPU_FF_SELM_SYNC_GDT | VMCPU_FF_SELM_SYNC_LDT
    216217                                          | VMCPU_FF_SELM_SYNC_TSS | VMCPU_FF_TRPM_SYNC_IDT
     
    223224            rc = VINF_EM_NO_MEMORY;
    224225        /* Pending Ring-3 action. */
    225         else if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_TO_R3 | VMCPU_FF_PDM_CRITSECT))
     226        else if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_TO_R3 | VMCPU_FF_PDM_CRITSECT | VMCPU_FF_IEM))
    226227        {
    227228            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_TO_R3);
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r56287 r56628  
    123123/** Pointer to a const FPU result consisting of two output values and FSW. */
    124124typedef IEMFPURESULTTWO const *PCIEMFPURESULTTWO;
     125
     126
     127/**
     128 * IEM pending commit function index.
     129 */
     130typedef enum IEMCOMMIT
     131{
     132    /** Invalid / nothing pending. */
     133    IEMCOMMIT_INVALID = 0,
     134    /** @name INS
     135     * @{  */
     136    IEMCOMMIT_INS_OP8_ADDR16,
     137    IEMCOMMIT_INS_OP8_ADDR32,
     138    IEMCOMMIT_INS_OP8_ADDR64,
     139    IEMCOMMIT_INS_OP16_ADDR16,
     140    IEMCOMMIT_INS_OP16_ADDR32,
     141    IEMCOMMIT_INS_OP16_ADDR64,
     142    IEMCOMMIT_INS_OP32_ADDR16,
     143    IEMCOMMIT_INS_OP32_ADDR32,
     144    IEMCOMMIT_INS_OP32_ADDR64,
     145    /** @} */
     146    /** @name REP INS
     147     * @{  */
     148    IEMCOMMIT_REP_INS_OP8_ADDR16,
     149    IEMCOMMIT_REP_INS_OP8_ADDR32,
     150    IEMCOMMIT_REP_INS_OP8_ADDR64,
     151    IEMCOMMIT_REP_INS_OP16_ADDR16,
     152    IEMCOMMIT_REP_INS_OP16_ADDR32,
     153    IEMCOMMIT_REP_INS_OP16_ADDR64,
     154    IEMCOMMIT_REP_INS_OP32_ADDR16,
     155    IEMCOMMIT_REP_INS_OP32_ADDR32,
     156    IEMCOMMIT_REP_INS_OP32_ADDR64,
     157    /** @} */
     158    /** End of valid functions. */
     159    IEMCOMMIT_END,
     160    /** Make sure the type is int in call contexts. */
     161    IEMCOMMIT_32BIT_HACK = 0x7fffffff
     162} IEMCOMMIT;
     163AssertCompile(sizeof(IEMCOMMIT) == 4);
    125164
    126165
     
    253292    /** Number of times rcPassUp has been used. */
    254293    uint32_t                cRetPassUpStatus;
     294    /** Number of times RZ left with instruction commit pending for ring-3. */
     295    uint32_t                cPendingCommit;
    255296#ifdef IEM_VERIFICATION_MODE_FULL
    256297    /** The Number of I/O port reads that has been performed. */
     
    322363    /** @}*/
    323364
    324     /** Alignment padding for aMemMappings. */
    325     uint8_t                 abAlignment2[4];
    326 
    327365    /** The number of active guest memory mappings. */
    328366    uint8_t                 cActiveMappings;
     
    376414        uint8_t             ab[512];
    377415    } aBounceBuffers[3];
     416
     417    /** @name Pending Instruction Commit (R0/RC postponed it to Ring-3).
     418     * @{ */
     419    struct
     420    {
     421        /** The commit function to call. */
     422        IEMCOMMIT           enmFn;
     423        /** The instruction size. */
     424        uint8_t             cbInstr;
     425        /** Generic value to commit. */
     426        uint64_t            uValue;
     427    } PendingCommit;
     428    /** @} */
    378429
    379430    /** @name Target CPU information.
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