VirtualBox

Changeset 72488 in vbox for trunk/src/VBox/VMM/VMMR3


Ignore:
Timestamp:
Jun 9, 2018 12:24:35 PM (6 years ago)
Author:
vboxsync
Message:

NEM,CPUM,EM: Don't sync in/out the entire state when leaving the inner NEM loop, only what IEM/TRPM might need. Speeds up MMIO and I/O requiring return to ring-3. bugref:9044

Location:
trunk/src/VBox/VMM/VMMR3
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r72461 r72488  
    3737*********************************************************************************************************************************/
    3838#define LOG_GROUP LOG_GROUP_EM
     39#define VMCPU_INCL_CPUM_GST_CTX /* for CPUM_IMPORT_GUEST_STATE_RET */
    3940#include <VBox/vmm/em.h>
    4041#include <VBox/vmm/vmm.h>
     
    9596#endif
    9697static int emR3RemExecute(PVM pVM, PVMCPU pVCpu, bool *pfFFDone);
    97 int emR3HighPriorityPostForcedActions(PVM pVM, PVMCPU pVCpu, int rc);
    9898
    9999
     
    11981198            fInREMState = emR3RemExecuteSyncBack(pVM, pVCpu);
    11991199#endif
    1200             rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
     1200            rc = VBOXSTRICTRC_TODO(emR3HighPriorityPostForcedActions(pVM, pVCpu, rc));
    12011201        }
    12021202
     
    16101610 * Executes all high priority post execution force actions.
    16111611 *
    1612  * @returns rc or a fatal status code.
     1612 * @returns Strict VBox status code.  Typically @a rc, but may be upgraded to
     1613 *          fatal error status code.
    16131614 *
    16141615 * @param   pVM         The cross context VM structure.
    16151616 * @param   pVCpu       The cross context virtual CPU structure.
    1616  * @param   rc          The current rc.
     1617 * @param   rc          The current strict VBox status code rc.
    16171618 */
    1618 int emR3HighPriorityPostForcedActions(PVM pVM, PVMCPU pVCpu, int rc)
     1619VBOXSTRICTRC emR3HighPriorityPostForcedActions(PVM pVM, PVMCPU pVCpu, VBOXSTRICTRC rc)
    16191620{
    16201621    VBOXVMM_EM_FF_HIGH(pVCpu, pVM->fGlobalForcedActions, pVCpu->fLocalForcedActions, rc);
     
    16261627    if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_CR3))
    16271628    {
     1629        CPUM_IMPORT_EXTRN_RCSTRICT(pVCpu, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_CR3 | CPUMCTX_EXTRN_CR4 | CPUMCTX_EXTRN_EFER, rc);
    16281630        int rc2 = PGMUpdateCR3(pVCpu, CPUMGetGuestCR3(pVCpu));
    16291631        if (RT_FAILURE(rc2))
     
    16351637    if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HM_UPDATE_PAE_PDPES))
    16361638    {
     1639        CPUM_IMPORT_EXTRN_RCSTRICT(pVCpu, CPUMCTX_EXTRN_CR0 | CPUMCTX_EXTRN_CR3 | CPUMCTX_EXTRN_CR4 | CPUMCTX_EXTRN_EFER, rc);
    16371640        if (CPUMIsGuestInPAEMode(pVCpu))
    16381641        {
     
    16491652    /* IEM has pending work (typically memory write after INS instruction). */
    16501653    if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_IEM))
    1651         rc = VBOXSTRICTRC_TODO(IEMR3ProcessForceFlag(pVM, pVCpu, rc));
     1654        rc = IEMR3ProcessForceFlag(pVM, pVCpu, rc);
    16521655
    16531656    /* IOM has pending work (comitting an I/O or MMIO write). */
    16541657    if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_IOM))
    1655         rc = VBOXSTRICTRC_TODO(IOMR3ProcessForceFlag(pVM, pVCpu, rc));
     1658        rc = IOMR3ProcessForceFlag(pVM, pVCpu, rc);
    16561659
    16571660#ifdef VBOX_WITH_RAW_MODE
     
    18291832        if (VM_FF_IS_PENDING(pVM, VM_FF_EMT_RENDEZVOUS))
    18301833        {
     1834            CPUM_IMPORT_EXTRN_RCSTRICT(pVCpu, ~CPUMCTX_EXTRN_KEEPER_MASK, rc);
    18311835            rc2 = VMMR3EmtRendezvousFF(pVM, pVCpu);
    18321836            UPDATE_RC();
     
    18761880            || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_DBGF) )
    18771881        {
     1882            CPUM_IMPORT_EXTRN_RCSTRICT(pVCpu, ~CPUMCTX_EXTRN_KEEPER_MASK, rc);
    18781883            rc2 = DBGFR3VMMForcedAction(pVM, pVCpu);
    18791884            UPDATE_RC();
     
    18851890        if (VM_FF_TEST_AND_CLEAR(pVM, VM_FF_RESET))
    18861891        {
     1892            CPUM_IMPORT_EXTRN_RCSTRICT(pVCpu, ~CPUMCTX_EXTRN_KEEPER_MASK, rc);
    18871893            rc2 = VBOXSTRICTRC_TODO(VMR3ResetFF(pVM));
    18881894            UPDATE_RC();
     
    18961902            &&  VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_CSAM_SCAN_PAGE))
    18971903        {
    1898             PCPUMCTX pCtx = pVCpu->em.s.pCtx;
    1899 
    19001904            /** @todo check for 16 or 32 bits code! (D bit in the code selector) */
    19011905            Log(("Forced action VMCPU_FF_CSAM_SCAN_PAGE\n"));
    1902 
     1906            CPUM_IMPORT_EXTRN_RCSTRICT(pVCpu, ~CPUMCTX_EXTRN_KEEPER_MASK, rc);
     1907            PCPUMCTX pCtx = pVCpu->em.s.pCtx;
    19031908            CSAMR3CheckCodeEx(pVM, pCtx, pCtx->eip);
    19041909            VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_CSAM_SCAN_PAGE);
     
    19451950        if (VM_FF_IS_PENDING(pVM, VM_FF_EMT_RENDEZVOUS))
    19461951        {
     1952            CPUM_IMPORT_EXTRN_RCSTRICT(pVCpu, ~CPUMCTX_EXTRN_KEEPER_MASK, rc);
    19471953            rc2 = VMMR3EmtRendezvousFF(pVM, pVCpu);
    19481954            UPDATE_RC();
     
    19651971        if (VM_FF_IS_PENDING_EXCEPT(pVM, VM_FF_REQUEST, VM_FF_PGM_NO_MEMORY))
    19661972        {
     1973            CPUM_IMPORT_EXTRN_RCSTRICT(pVCpu, ~CPUMCTX_EXTRN_KEEPER_MASK, rc);
    19671974            rc2 = VMR3ReqProcessU(pVM->pUVM, VMCPUID_ANY, false /*fPriorityOnly*/);
    19681975            if (rc2 == VINF_EM_OFF || rc2 == VINF_EM_TERMINATE) /** @todo this shouldn't be necessary */
     
    20192026        if (VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_REQUEST))
    20202027        {
     2028            CPUM_IMPORT_EXTRN_RCSTRICT(pVCpu, ~CPUMCTX_EXTRN_KEEPER_MASK, rc);
    20212029            rc2 = VMR3ReqProcessU(pVM->pUVM, pVCpu->idCpu, false /*fPriorityOnly*/);
    20222030            if (rc2 == VINF_EM_OFF || rc2 == VINF_EM_TERMINATE || rc2 == VINF_EM_RESET)
     
    20792087            &&  !VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY))
    20802088        {
     2089            CPUM_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_RIP);
    20812090            if (CPUMGetGuestRIP(pVCpu) != EMGetInhibitInterruptsPC(pVCpu))
    20822091            {
     
    21082117                    {
    21092118                        fWakeupPending = true;
    2110 #ifdef VBOX_STRICT
     2119# ifdef VBOX_STRICT
    21112120                        rcIrq = rc2;
    2112 #endif
     2121# endif
    21132122                    }
    21142123                    if (fResched)
     
    21182127#endif
    21192128                {
     2129                    CPUM_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_RFLAGS);
    21202130                    if (   VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC)
    21212131#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
     
    21302140                        /* Note: it's important to make sure the return code from TRPMR3InjectEvent isn't ignored! */
    21312141                        /** @todo this really isn't nice, should properly handle this */
     2142                        CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_XCPT_MASK);
    21322143                        rc2 = TRPMR3InjectEvent(pVM, pVCpu, TRPM_HARDWARE_INT);
    21332144                        Log(("EM: TRPMR3InjectEvent -> %d\n", rc2));
     
    21652176            && !VM_FF_IS_PENDING(pVM, VM_FF_PGM_NO_MEMORY) )
    21662177        {
     2178            CPUM_IMPORT_EXTRN_RCSTRICT(pVCpu, ~CPUMCTX_EXTRN_KEEPER_MASK, rc);
    21672179            rc2 = DBGFR3VMMForcedAction(pVM, pVCpu);
    21682180            UPDATE_RC();
     
    21752187            && VM_FF_IS_PENDING(pVM, VM_FF_EMT_RENDEZVOUS))
    21762188        {
     2189            CPUM_IMPORT_EXTRN_RCSTRICT(pVCpu, ~CPUMCTX_EXTRN_KEEPER_MASK, rc);
    21772190            rc2 = VMMR3EmtRendezvousFF(pVM, pVCpu);
    21782191            UPDATE_RC();
  • trunk/src/VBox/VMM/VMMR3/EMHM.cpp

    r70979 r72488  
    2121*********************************************************************************************************************************/
    2222#define LOG_GROUP LOG_GROUP_EM
     23#define VMCPU_INCL_CPUM_GST_CTX
    2324#include <VBox/vmm/em.h>
    2425#include <VBox/vmm/vmm.h>
     
    129130            || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
    130131        {
    131             rcStrict = emR3HighPriorityPostForcedActions(pVM, pVCpu, VBOXSTRICTRC_TODO(rcStrict));
     132            rcStrict = emR3HighPriorityPostForcedActions(pVM, pVCpu, rcStrict);
    132133            LogFlow(("EMR3HmSingleInstruction: FFs after -> %Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    133134        }
     
    468469        if (    VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK)
    469470            ||  VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
    470             rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
     471            rc = VBOXSTRICTRC_TODO(emR3HighPriorityPostForcedActions(pVM, pVCpu, rc));
    471472
    472473        /*
  • trunk/src/VBox/VMM/VMMR3/EMR3Nem.cpp

    r72207 r72488  
    2121*********************************************************************************************************************************/
    2222#define LOG_GROUP LOG_GROUP_EM
     23#define VMCPU_INCL_CPUM_GST_CTX
    2324#include <VBox/vmm/em.h>
    2425#include <VBox/vmm/vmm.h>
     
    7475
    7576/**
    76  * Executes instruction in HM mode if we can.
     77 * Executes instruction in NEM mode if we can.
    7778 *
    7879 * This is somewhat comparable to REMR3EmulateInstruction.
     
    9091VBOXSTRICTRC emR3NemSingleInstruction(PVM pVM, PVMCPU pVCpu, uint32_t fFlags)
    9192{
    92     PCPUMCTX pCtx = pVCpu->em.s.pCtx;
     93    Assert(pVCpu->em.s.pCtx == &pVCpu->cpum.GstCtx);
    9394    Assert(!(fFlags & ~EM_ONE_INS_FLAGS_MASK));
    9495
    95     if (!NEMR3CanExecuteGuest(pVM, pVCpu, pCtx))
     96    if (!NEMR3CanExecuteGuest(pVM, pVCpu, &pVCpu->cpum.GstCtx))
    9697        return VINF_EM_RESCHEDULE;
    9798
    98     uint64_t const uOldRip = pCtx->rip;
     99    uint64_t const uOldRip = pVCpu->cpum.GstCtx.rip;
    99100    for (;;)
    100101    {
     
    105106            || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_PRE_RAW_MASK))
    106107        {
    107             VBOXSTRICTRC rcStrict = emR3NemForcedActions(pVM, pVCpu, pCtx);
     108            VBOXSTRICTRC rcStrict = emR3NemForcedActions(pVM, pVCpu, &pVCpu->cpum.GstCtx);
    108109            if (rcStrict != VINF_SUCCESS)
    109110            {
     
    129130            || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
    130131        {
    131             rcStrict = emR3HighPriorityPostForcedActions(pVM, pVCpu, VBOXSTRICTRC_TODO(rcStrict));
     132            rcStrict = emR3HighPriorityPostForcedActions(pVM, pVCpu, rcStrict);
    132133            LogFlow(("emR3NemSingleInstruction: FFs after -> %Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    133134        }
     
    135136        if (rcStrict != VINF_SUCCESS && (rcStrict < VINF_EM_FIRST || rcStrict > VINF_EM_LAST))
    136137        {
    137             rcStrict = emR3NemHandleRC(pVM, pVCpu, pCtx, VBOXSTRICTRC_TODO(rcStrict));
     138            rcStrict = emR3NemHandleRC(pVM, pVCpu, &pVCpu->cpum.GstCtx, VBOXSTRICTRC_TODO(rcStrict));
    138139            Log(("emR3NemSingleInstruction: emR3NemHandleRC -> %Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
    139140        }
     
    142143         * Done?
    143144         */
     145        CPUM_ASSERT_NOT_EXTRN(pVCpu, CPUMCTX_EXTRN_RIP);
    144146        if (   (rcStrict != VINF_SUCCESS && rcStrict != VINF_EM_DBG_STEPPED)
    145147            || !(fFlags & EM_ONE_INS_FLAGS_RIP_CHANGE)
    146             || pCtx->rip != uOldRip)
    147         {
    148             if (rcStrict == VINF_SUCCESS && pCtx->rip != uOldRip)
     148            || pVCpu->cpum.GstCtx.rip != uOldRip)
     149        {
     150            if (rcStrict == VINF_SUCCESS && pVCpu->cpum.GstCtx.rip != uOldRip)
    149151                rcStrict = VINF_EM_DBG_STEPPED;
    150             Log(("emR3NemSingleInstruction: returns %Rrc (rip %llx -> %llx)\n", VBOXSTRICTRC_VAL(rcStrict), uOldRip, pCtx->rip));
     152            Log(("emR3NemSingleInstruction: returns %Rrc (rip %llx -> %llx)\n",
     153                 VBOXSTRICTRC_VAL(rcStrict), uOldRip, pVCpu->cpum.GstCtx.rip));
     154            CPUM_IMPORT_EXTRN_RET(pVCpu, ~CPUMCTX_EXTRN_KEEPER_MASK);
    151155            return rcStrict;
    152156        }
     
    172176#endif
    173177{
    174 #ifdef LOG_ENABLED
     178#if defined(LOG_ENABLED)
    175179    PCPUMCTX pCtx = pVCpu->em.s.pCtx;
    176180#endif
     
    195199     */
    196200    STAM_PROFILE_START(&pVCpu->em.s.StatIEMEmu, a);
     201    CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK);
    197202    rc = VBOXSTRICTRC_TODO(IEMExecOne(pVCpu));
    198203    STAM_PROFILE_STOP(&pVCpu->em.s.StatIEMEmu, a);
     
    203208#ifdef VBOX_WITH_REM
    204209        STAM_PROFILE_START(&pVCpu->em.s.StatREMEmu, b);
     210        CPUM_IMPORT_EXTRN_RET(pVCpu, ~CPUMCTX_EXTRN_KEEPER_MASK);
    205211        EMRemLock(pVM);
    206212        /* Flush the recompiler TLB if the VCPU has changed. */
     
    216222#endif /* !VBOX_WITH_REM */
    217223    }
    218 
    219 #ifdef EM_NOTIFY_HM
    220     if (pVCpu->em.s.enmState == EMSTATE_DEBUG_GUEST_HM)
    221         HMR3NotifyEmulated(pVCpu);
    222 #endif
    223224    return rc;
    224225}
     
    278279     * Hand it over to the interpreter.
    279280     */
     281    CPUM_IMPORT_EXTRN_RET(pVCpu, IEM_CPUMCTX_EXTRN_MUST_MASK);
    280282    VBOXSTRICTRC rcStrict = IEMExecOne(pVCpu);
    281283    LogFlow(("emR3NemExecuteIOInstruction: %Rrc\n", VBOXSTRICTRC_VAL(rcStrict)));
     
    443445         */
    444446        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_RESUME_GUEST_MASK);
    445         if (    VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK)
    446             ||  VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
    447             rcStrict = emR3HighPriorityPostForcedActions(pVM, pVCpu, VBOXSTRICTRC_TODO(rcStrict));
     447        if (   VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK)
     448            || VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
     449            rcStrict = emR3HighPriorityPostForcedActions(pVM, pVCpu, rcStrict);
    448450
    449451        /*
     
    478480
    479481    /*
    480      * Return to outer loop.
    481      */
     482     * Return to outer loop, making sure the fetch all state as we leave.
     483     *
     484     * Note! Not using CPUM_IMPORT_EXTRN_RET here, to prioritize an rcStrict error
     485     *       status over import errors.
     486     */
     487    if (pCtx->fExtrn)
     488    {
     489        int rcImport = NEMImportStateOnDemand(pVCpu, pCtx, pCtx->fExtrn);
     490        AssertReturn(RT_SUCCESS(rcImport) || RT_FAILURE_NP(rcStrict), rcImport);
     491    }
    482492#if defined(LOG_ENABLED) && defined(DEBUG)
    483493    RTLogFlush(NULL);
  • trunk/src/VBox/VMM/VMMR3/EMRaw.cpp

    r69111 r72488  
    2121*********************************************************************************************************************************/
    2222#define LOG_GROUP LOG_GROUP_EM
     23#define VMCPU_INCL_CPUM_GST_CTX
    2324#include <VBox/vmm/em.h>
    2425#include <VBox/vmm/vmm.h>
     
    140141     * Deal with the return code.
    141142     */
    142     rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
     143    rc = VBOXSTRICTRC_TODO(emR3HighPriorityPostForcedActions(pVM, pVCpu, rc));
    143144    rc = emR3RawHandleRC(pVM, pVCpu, pCtx, rc);
    144145    rc = emR3RawUpdateForceFlag(pVM, pVCpu, pCtx, rc);
     
    220221     * Deal with the return codes.
    221222     */
    222     rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
     223    rc = VBOXSTRICTRC_TODO(emR3HighPriorityPostForcedActions(pVM, pVCpu, rc));
    223224    rc = emR3RawHandleRC(pVM, pVCpu, pCtx, rc);
    224225    rc = emR3RawUpdateForceFlag(pVM, pVCpu, pCtx, rc);
     
    14261427        if (    VM_FF_IS_PENDING(pVM, VM_FF_HIGH_PRIORITY_POST_MASK)
    14271428            ||  VMCPU_FF_IS_PENDING(pVCpu, VMCPU_FF_HIGH_PRIORITY_POST_MASK))
    1428             rc = emR3HighPriorityPostForcedActions(pVM, pVCpu, rc);
     1429            rc = VBOXSTRICTRC_TODO(emR3HighPriorityPostForcedActions(pVM, pVCpu, rc));
    14291430
    14301431#ifdef VBOX_STRICT
  • trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp

    r72484 r72488  
    12351235                            STAMR3RegisterF(pVM, &pNemCpu->StatBreakOnStatus,       STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of status code breaks",           "/NEM/CPU%u/BreakOnStatus", iCpu);
    12361236                            STAMR3RegisterF(pVM, &pNemCpu->StatImportOnDemand,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of on-demand state imports",      "/NEM/CPU%u/ImportOnDemand", iCpu);
     1237                            STAMR3RegisterF(pVM, &pNemCpu->StatImportOnReturn,      STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of state imports on loop return", "/NEM/CPU%u/ImportOnReturn", iCpu);
     1238                            STAMR3RegisterF(pVM, &pNemCpu->StatImportOnReturnSkipped, STAMTYPE_COUNTER, STAMVISIBILITY_ALWAYS, STAMUNIT_OCCURENCES, "Number of skipped state imports on loop return", "/NEM/CPU%u/ImportOnReturnSkipped", iCpu);
    12371239                        }
    12381240
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