VirtualBox

Changeset 47807 in vbox


Ignore:
Timestamp:
Aug 16, 2013 12:54:26 PM (12 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
88068
Message:

EM/HM: Don't switch to REM immediately, try up to 1024 instruction in IEM first - only HM exec mode. This covers most trips to REM when booting xppro without nested paging.

Location:
trunk
Files:
6 edited

Legend:

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

    r47671 r47807  
    7777    /** The VM has encountered a fatal error. (And everyone is panicing....) */
    7878    EMSTATE_GURU_MEDITATION,
     79    /** Executing in IEM, falling back on REM if we cannot switch back to HM or
     80     * RAW after a short while. */
     81    EMSTATE_IEM_THEN_REM,
    7982    /** Just a hack to ensure that we get a 32-bit integer. */
    8083    EMSTATE_MAKE_32BIT_HACK = 0x7fffffff
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r47752 r47807  
    16551655FNIEMOP_STUB(iemOp_cvtpi2ps_Vps_Qpi__cvtpi2pd_Vpd_Qpi__cvtsi2ss_Vss_Ey__cvtsi2sd_Vsd_Ey); //NEXT
    16561656/** Opcode 0x0f 0x2b. */
    1657 FNIEMOP_STUB(iemOp_movntps_Mps_Vps__movntpd_Mpd_Vpd);
     1657FNIEMOP_STUB(iemOp_movntps_Mps_Vps__movntpd_Mpd_Vpd); //NEXT:XP
    16581658/** Opcode 0x0f 0x2c. */
    16591659FNIEMOP_STUB(iemOp_cvttps2pi_Ppi_Wps__cvttpd2pi_Ppi_Wpd__cvttss2si_Gy_Wss__cvttsd2si_Yu_Wsd); //NEXT
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r47788 r47807  
    161161    {
    162162        PVMCPU pVCpu = &pVM->aCpus[i];
    163 
    164         pVCpu->em.s.offVMCPU = RT_OFFSETOF(VMCPU, em.s);
    165163
    166164        pVCpu->em.s.enmState     = (i == 0) ? EMSTATE_NONE : EMSTATE_WAIT_SIPI;
     
    421419        EM_REG_PROFILE(&pVCpu->em.s.StatHmExec,     "/PROF/CPU%d/EM/HmExec",         "Profiling Hardware Accelerated Mode execution.");
    422420        EM_REG_PROFILE(&pVCpu->em.s.StatIEMEmu,     "/PROF/CPU%d/EM/IEMEmuSingle",      "Profiling single instruction IEM execution.");
     421        EM_REG_PROFILE(&pVCpu->em.s.StatIEMThenREM, "/PROF/CPU%d/EM/IEMThenRem",        "Profiling IEM-then-REM instruction execution (by IEM).");
    423422        EM_REG_PROFILE(&pVCpu->em.s.StatREMEmu,     "/PROF/CPU%d/EM/REMEmuSingle",      "Profiling single instruction REM execution.");
    424423        EM_REG_PROFILE(&pVCpu->em.s.StatREMExec,    "/PROF/CPU%d/EM/REMExec",           "Profiling REM execution.");
     
    669668           || pVCpu->em.s.enmState == EMSTATE_IEM
    670669           || pVCpu->em.s.enmState == EMSTATE_REM
     670           || pVCpu->em.s.enmState == EMSTATE_IEM_THEN_REM
    671671         ? VINF_EM_RESCHEDULE
    672672         : VINF_SUCCESS;
     
    778778        case EMSTATE_DEBUG_HYPER:       return "EMSTATE_DEBUG_HYPER";
    779779        case EMSTATE_GURU_MEDITATION:   return "EMSTATE_GURU_MEDITATION";
     780        case EMSTATE_IEM_THEN_REM:      return "EMSTATE_IEM_THEN_REM";
    780781        default:                        return "Unknown!";
    781782    }
     
    12491250
    12501251
     1252static VBOXSTRICTRC emR3ExecuteIemThenRem(PVM pVM, PVMCPU pVCpu, bool *pfFFDone)
     1253{
     1254    LogFlow(("emR3ExecuteIemThenRem: %04x:%RGv\n", CPUMGetGuestCS(pVCpu), CPUMGetGuestRIP(pVCpu)));
     1255    *pfFFDone = false;
     1256
     1257    /*
     1258     * Execute in IEM for a while.
     1259     */
     1260    while (pVCpu->em.s.cIemThenRemInstructions < 1024)
     1261    {
     1262        VBOXSTRICTRC rcStrict = IEMExecLots(pVCpu);
     1263        if (rcStrict != VINF_SUCCESS)
     1264        {
     1265            if (   rcStrict == VERR_IEM_ASPECT_NOT_IMPLEMENTED
     1266                || rcStrict == VERR_IEM_INSTR_NOT_IMPLEMENTED)
     1267                break;
     1268
     1269            pVCpu->em.s.cIemThenRemInstructions++;
     1270            Log(("emR3ExecuteIemThenRem: returns %Rrc after %u instructions\n",
     1271                 VBOXSTRICTRC_VAL(rcStrict), pVCpu->em.s.cIemThenRemInstructions));
     1272            return rcStrict;
     1273        }
     1274        pVCpu->em.s.cIemThenRemInstructions++;
     1275
     1276        EMSTATE enmNewState = emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx);
     1277        if (enmNewState != EMSTATE_REM && enmNewState != EMSTATE_IEM_THEN_REM)
     1278        {
     1279            LogFlow(("emR3ExecuteIemThenRem: -> %d (%s) after %u instructions\n",
     1280                     enmNewState, emR3GetStateName(enmNewState), pVCpu->em.s.cIemThenRemInstructions));
     1281            pVCpu->em.s.enmPrevState = pVCpu->em.s.enmState;
     1282            pVCpu->em.s.enmState     = enmNewState;
     1283            return VINF_SUCCESS;
     1284        }
     1285
     1286        /*
     1287         * Check for pending actions.
     1288         */
     1289        if (   VM_FF_IS_PENDING(pVM, VM_FF_ALL_REM_MASK)
     1290            || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_ALL_REM_MASK))
     1291            return VINF_SUCCESS;
     1292    }
     1293
     1294    /*
     1295     * Switch to REM.
     1296     */
     1297    Log(("emR3ExecuteIemThenRem: -> EMSTATE_REM (after %u instructions)\n", pVCpu->em.s.cIemThenRemInstructions));
     1298    pVCpu->em.s.enmState = EMSTATE_REM;
     1299    return VINF_SUCCESS;
     1300}
     1301
     1302
    12511303/**
    12521304 * Decides whether to execute RAW, HWACC or REM.
     
    12951347         *       turns off monitoring features essential for raw mode!
    12961348         */
     1349#ifdef VBOX_WITH_FIRST_IEM_STEP
     1350        return EMSTATE_IEM_THEN_REM;
     1351#else
    12971352        return EMSTATE_REM;
     1353#endif
    12981354    }
    12991355
     
    20582114        else
    20592115            pVCpu->em.s.enmState = emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx);
     2116        pVCpu->em.s.cIemThenRemInstructions = 0;
    20602117        Log(("EMR3ExecuteVM: enmState=%s\n", emR3GetStateName(pVCpu->em.s.enmState)));
    20612118
     
    21242181                 */
    21252182                case VINF_EM_RESCHEDULE_REM:
     2183#ifdef VBOX_WITH_FIRST_IEM_STEP
     2184                    Assert(!pVM->em.s.fIemExecutesAll || pVCpu->em.s.enmState != EMSTATE_IEM);
     2185                    if (HMIsEnabled(pVM))
     2186                    {
     2187                        Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_REM: %d -> %d (EMSTATE_IEM_THEN_REM)\n",
     2188                              enmOldState, EMSTATE_IEM_THEN_REM));
     2189                        if (pVCpu->em.s.enmState != EMSTATE_IEM_THEN_REM)
     2190                        {
     2191                            pVCpu->em.s.enmState = EMSTATE_IEM_THEN_REM;
     2192                            pVCpu->em.s.cIemThenRemInstructions = 0;
     2193                        }
     2194                    }
     2195                    else
     2196                    {
     2197                        Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_REM: %d -> %d (EMSTATE_REM)\n", enmOldState, EMSTATE_REM));
     2198                        pVCpu->em.s.enmState = EMSTATE_REM;
     2199                    }
     2200#else
    21262201                    Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE_REM: %d -> %d (EMSTATE_REM)\n", enmOldState, EMSTATE_REM));
    21272202                    Assert(!pVM->em.s.fIemExecutesAll || pVCpu->em.s.enmState != EMSTATE_IEM);
    21282203                    pVCpu->em.s.enmState = EMSTATE_REM;
     2204#endif
    21292205                    break;
    21302206
     
    21502226                    EMSTATE enmState = emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx);
    21512227                    Log2(("EMR3ExecuteVM: VINF_EM_RESCHEDULE: %d -> %d (%s)\n", enmOldState, enmState, emR3GetStateName(enmState)));
     2228                    if (pVCpu->em.s.enmState != enmState && enmState == EMSTATE_IEM_THEN_REM)
     2229                        pVCpu->em.s.cIemThenRemInstructions = 0;
    21522230                    pVCpu->em.s.enmState = enmState;
    21532231                    break;
     
    21922270                        EMSTATE enmState = emR3Reschedule(pVM, pVCpu, pVCpu->em.s.pCtx);
    21932271                        Log2(("EMR3ExecuteVM: VINF_EM_RESET: %d -> %d (%s)\n", enmOldState, enmState, emR3GetStateName(enmState)));
     2272                        if (pVCpu->em.s.enmState != enmState && enmState == EMSTATE_IEM_THEN_REM)
     2273                            pVCpu->em.s.cIemThenRemInstructions = 0;
    21942274                        pVCpu->em.s.enmState = enmState;
    21952275                    }
     
    23282408                        || enmNewState == EMSTATE_HM
    23292409                        || enmNewState == EMSTATE_REM
     2410                        || enmNewState == EMSTATE_IEM_THEN_REM
    23302411                        || enmNewState == EMSTATE_DEBUG_GUEST_RAW
    23312412                        || enmNewState == EMSTATE_DEBUG_GUEST_HM
     
    23962477                    }
    23972478                    fFFDone = false;
     2479                    break;
     2480                }
     2481
     2482                /*
     2483                 * Execute in IEM, hoping we can quickly switch aback to HM
     2484                 * or RAW execution.  If our hopes fail, we go to REM.
     2485                 */
     2486                case EMSTATE_IEM_THEN_REM:
     2487                {
     2488                    STAM_PROFILE_START(&pVCpu->em.s.StatIEMThenREM, pIemThenRem);
     2489                    rc = VBOXSTRICTRC_TODO(emR3ExecuteIemThenRem(pVM, pVCpu, &fFFDone));
     2490                    STAM_PROFILE_STOP(&pVCpu->em.s.StatIEMThenREM, pIemThenRem);
    23982491                    break;
    23992492                }
  • trunk/src/VBox/VMM/VMMR3/EMHM.cpp

    r47790 r47807  
    206206# ifndef VBOX_WITH_FIRST_IEM_STEP
    207207        Log(("EMINS[rem]: %04x:%RGv RSP=%RGv\n", pCtx->cs.Sel, (RTGCPTR)pCtx->rip, (RTGCPTR)pCtx->rsp));
    208 # elif defined(DEBUG_bird)
    209         AssertFailed();
     208//# elif defined(DEBUG_bird)
     209//        AssertFailed();
    210210# endif
    211211        EMRemLock(pVM);
  • trunk/src/VBox/VMM/include/EMInternal.h

    r47788 r47807  
    337337typedef struct EMCPU
    338338{
    339     /** Offset to the VM structure.
    340      * See EMCPU2VM(). */
    341     RTUINT                  offVMCPU;
    342 
    343339    /** Execution Manager State. */
    344340    EMSTATE volatile        enmState;
     
    353349
    354350    uint8_t                 u8Padding[3];
     351
     352    /** The number of instructions we've executed in IEM since switching to the
     353     *  EMSTATE_IEM_THEN_REM state. */
     354    uint32_t                cIemThenRemInstructions;
    355355
    356356    /** Inhibit interrupts for this instruction. Valid only when VM_FF_INHIBIT_INTERRUPTS is set. */
     
    413413    STAMPROFILE             StatHmExec;
    414414    STAMPROFILE             StatIEMEmu;
     415    STAMPROFILE             StatIEMThenREM;
    415416    STAMPROFILE             StatREMEmu;
    416417    STAMPROFILE             StatREMExec;
  • trunk/src/VBox/VMM/testcase/tstVMStruct.h

    r46167 r47807  
    13331333    GEN_CHECK_OFF(VM, uCpuExecutionCap);
    13341334    GEN_CHECK_OFF(VM, cbSelf);
    1335     GEN_CHECK_OFF(VM, offVMCPU);
    13361335    GEN_CHECK_OFF(VM, pfnVMMRCToHostAsm);
    13371336    GEN_CHECK_OFF(VM, pfnVMMRCToHostAsmNoReturn);
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