VirtualBox

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


Ignore:
Timestamp:
Jun 21, 2018 3:41:14 PM (7 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
123148
Message:

EM,IEM,VMX: Working on configuring exit history optimziations. Currently enabled in ring-0 for NEM but disabled for HM. bugref:9198

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/Makefile.kmk

    r72503 r72642  
    690690        VMMR0/GMMR0.cpp \
    691691        VMMR0/GVMMR0.cpp \
     692        VMMR0/EMR0.cpp \
    692693        VMMR0/HMR0.cpp \
    693694        VMMR0/HMR0A.asm \
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r72636 r72642  
    438438}
    439439
     440#ifndef IN_RC
    440441
    441442/**
     
    601602                                              PEMEXITENTRY pHistEntry, uint64_t uExitNo)
    602603{
     604# ifdef IN_RING0
     605    /* Disregard the preempt disabled flag. */
     606    uFlagsAndType &= ~EMEXIT_F_PREEMPT_DISABLED;
     607# endif
     608
    603609    /*
    604610     * Work the hash table.
    605611     */
    606612    AssertCompile(RT_ELEMENTS(pVCpu->em.s.aExitRecords) == 1024);
    607 #define EM_EXIT_RECORDS_IDX_MASK 0x3ff
     613# define EM_EXIT_RECORDS_IDX_MASK 0x3ff
    608614    uintptr_t  idxSlot  = ((uintptr_t)uFlatPC >> 1) & EM_EXIT_RECORDS_IDX_MASK;
    609615    PEMEXITREC pExitRec = &pVCpu->em.s.aExitRecords[idxSlot];
     
    733739}
    734740
     741#endif /* !IN_RC */
    735742
    736743/**
     
    761768    pHistEntry->idxSlot       = UINT32_MAX;
    762769
     770#ifndef IN_RC
    763771    /*
    764772     * If common exit type, we will insert/update the exit into the exit record hash table.
    765773     */
    766774    if (   (uFlagsAndType & (EMEXIT_F_KIND_MASK | EMEXIT_F_CS_EIP | EMEXIT_F_UNFLATTENED_PC)) == EMEXIT_F_KIND_EM
     775# ifdef IN_RING0
     776        && pVCpu->em.s.fExitOptimizationEnabledR0
     777        && ( !(uFlagsAndType & EMEXIT_F_PREEMPT_DISABLED) || pVCpu->em.s.fExitOptimizationEnabledR0PreemptDisabled)
     778# else
    767779        && pVCpu->em.s.fExitOptimizationEnabled
    768         && uFlatPC != UINT64_MAX)
     780# endif
     781        && uFlatPC != UINT64_MAX
     782       )
    769783        return emHistoryAddOrUpdateRecord(pVCpu, uFlagsAndType, uFlatPC, pHistEntry, uExitNo);
     784#endif
    770785    return NULL;
    771786}
     
    842857    pHistEntry->uFlagsAndType = uFlagsAndType | (pHistEntry->uFlagsAndType & (EMEXIT_F_CS_EIP | EMEXIT_F_UNFLATTENED_PC));
    843858
     859#ifndef IN_RC
    844860    /*
    845861     * If common exit type, we will insert/update the exit into the exit record hash table.
    846862     */
    847863    if (   (uFlagsAndType & (EMEXIT_F_KIND_MASK | EMEXIT_F_CS_EIP | EMEXIT_F_UNFLATTENED_PC)) == EMEXIT_F_KIND_EM
     864# ifdef IN_RING0
     865        && pVCpu->em.s.fExitOptimizationEnabledR0
     866        && ( !(uFlagsAndType & EMEXIT_F_PREEMPT_DISABLED) || pVCpu->em.s.fExitOptimizationEnabledR0PreemptDisabled)
     867# else
    848868        && pVCpu->em.s.fExitOptimizationEnabled
    849         && pHistEntry->uFlatPC != UINT64_MAX)
     869# endif
     870        && pHistEntry->uFlatPC != UINT64_MAX
     871       )
    850872        return emHistoryAddOrUpdateRecord(pVCpu, uFlagsAndType, pHistEntry->uFlatPC, pHistEntry, uExitNo);
     873#endif
    851874    return NULL;
    852875}
     
    879902    pHistEntry->uFlatPC       = uFlatPC;
    880903
     904#ifndef IN_RC
    881905    /*
    882906     * If common exit type, we will insert/update the exit into the exit record hash table.
    883907     */
    884908    if (   (uFlagsAndType & (EMEXIT_F_KIND_MASK | EMEXIT_F_CS_EIP | EMEXIT_F_UNFLATTENED_PC)) == EMEXIT_F_KIND_EM
    885         && pVCpu->em.s.fExitOptimizationEnabled)
     909# ifdef IN_RING0
     910        && pVCpu->em.s.fExitOptimizationEnabledR0
     911        && ( !(uFlagsAndType & EMEXIT_F_PREEMPT_DISABLED) || pVCpu->em.s.fExitOptimizationEnabledR0PreemptDisabled)
     912# else
     913        && pVCpu->em.s.fExitOptimizationEnabled
     914# endif
     915       )
    886916        return emHistoryAddOrUpdateRecord(pVCpu, uFlagsAndType, uFlatPC, pHistEntry, uExitNo);
     917#endif
    887918    return NULL;
    888919}
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r72607 r72642  
    1419314193#endif
    1419414194        {
    14195             uint32_t cInstructionSinceLastExit = 0;
     14195#ifdef IN_RING0
     14196            bool const fCheckPreemptionPending   = !RTThreadPreemptIsPossible() || !RTThreadPreemptIsEnabled(NIL_RTTHREAD);
     14197#endif
     14198            uint32_t   cInstructionSinceLastExit = 0;
    1419614199
    1419714200            /*
     
    1425814261                                {
    1425914262#ifdef IN_RING0
    14260                                     if (!RTThreadPreemptIsPending(NIL_RTTHREAD))
     14263                                    if (   !fCheckPreemptionPending
     14264                                        || !RTThreadPreemptIsPending(NIL_RTTHREAD))
    1426114265#endif
    1426214266                                    {
  • trunk/src/VBox/VMM/VMMR0/HMVMXR0.cpp

    r72639 r72642  
    1185411854
    1185511855    VBOXSTRICTRC rcStrict;
    11856     PCEMEXITREC pExitRec = EMHistoryUpdateFlagsAndTypeAndPC(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_CPUID),
    11857                                                             pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base);
     11856    PCEMEXITREC pExitRec;
     11857    pExitRec = EMHistoryUpdateFlagsAndTypeAndPC(pVCpu,
     11858                                                EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM | EMEXIT_F_PREEMPT_DISABLED,
     11859                                                                           EMEXITTYPE_CPUID),
     11860                                                pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base);
    1185811861    if (!pExitRec)
    1185911862    {
     
    1282512828                                                    !fIOString
    1282612829                                                    ? !fIOWrite
    12827                                                     ? EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_IO_PORT_READ)
    12828                                                     : EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_IO_PORT_WRITE)
     12830                                                    ? EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM | EMEXIT_F_PREEMPT_DISABLED,
     12831                                                                                 EMEXITTYPE_IO_PORT_READ)
     12832                                                    : EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM | EMEXIT_F_PREEMPT_DISABLED,
     12833                                                                                 EMEXITTYPE_IO_PORT_WRITE)
    1282912834                                                    : !fIOWrite
    12830                                                     ? EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_IO_PORT_STR_READ)
    12831                                                     : EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_IO_PORT_STR_WRITE),
     12835                                                    ? EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM | EMEXIT_F_PREEMPT_DISABLED,
     12836                                                                                 EMEXITTYPE_IO_PORT_STR_READ)
     12837                                                    : EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM | EMEXIT_F_PREEMPT_DISABLED,
     12838                                                                                 EMEXITTYPE_IO_PORT_STR_WRITE),
    1283212839                                                    pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base);
    1283312840    if (!pExitRec)
     
    1331813325
    1331913326    VBOXSTRICTRC rcStrict;
    13320     PCEMEXITREC pExitRec = EMHistoryUpdateFlagsAndTypeAndPC(pVCpu, EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM, EMEXITTYPE_MMIO),
    13321                                                             pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base);
     13327    PCEMEXITREC pExitRec;
     13328    pExitRec = EMHistoryUpdateFlagsAndTypeAndPC(pVCpu,
     13329                                                EMEXIT_MAKE_FLAGS_AND_TYPE(EMEXIT_F_KIND_EM | EMEXIT_F_PREEMPT_DISABLED,
     13330                                                                           EMEXITTYPE_MMIO),
     13331                                                pVCpu->cpum.GstCtx.rip + pVCpu->cpum.GstCtx.cs.u64Base);
    1332213332    if (!pExitRec)
    1332313333    {
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r72617 r72642  
    3030# include <VBox/vmm/nem.h>
    3131#endif
     32#include <VBox/vmm/em.h>
    3233#include <VBox/vmm/stam.h>
    3334#include <VBox/vmm/tm.h>
     
    470471                {
    471472                    VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
    472 #ifdef VBOX_WITH_PCI_PASSTHROUGH
    473                     rc = PciRawR0InitVM(pGVM, pVM);
    474 #endif
     473                    rc = EMR0InitVM(pGVM, pVM);
    475474                    if (RT_SUCCESS(rc))
    476475                    {
    477476                        VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
    478                         rc = GIMR0InitVM(pVM);
     477#ifdef VBOX_WITH_PCI_PASSTHROUGH
     478                        rc = PciRawR0InitVM(pGVM, pVM);
     479#endif
    479480                        if (RT_SUCCESS(rc))
    480481                        {
    481                             VMM_CHECK_SMAP_CHECK2(pVM, rc = VERR_VMM_RING0_ASSERTION);
     482                            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
     483                            rc = GIMR0InitVM(pVM);
    482484                            if (RT_SUCCESS(rc))
    483485                            {
    484                                 GVMMR0DoneInitVM(pGVM);
    485 
    486                                 /*
    487                                  * Collect a bit of info for the VM release log.
    488                                  */
    489                                 pVM->vmm.s.fIsPreemptPendingApiTrusty = RTThreadPreemptIsPendingTrusty();
    490                                 pVM->vmm.s.fIsPreemptPossible         = RTThreadPreemptIsPossible();;
    491 
    492                                 VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
    493                                 return rc;
     486                                VMM_CHECK_SMAP_CHECK2(pVM, rc = VERR_VMM_RING0_ASSERTION);
     487                                if (RT_SUCCESS(rc))
     488                                {
     489                                    GVMMR0DoneInitVM(pGVM);
     490
     491                                    /*
     492                                     * Collect a bit of info for the VM release log.
     493                                     */
     494                                    pVM->vmm.s.fIsPreemptPendingApiTrusty = RTThreadPreemptIsPendingTrusty();
     495                                    pVM->vmm.s.fIsPreemptPossible         = RTThreadPreemptIsPossible();;
     496
     497                                    VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
     498                                    return rc;
     499                                }
     500
     501                                /* bail out*/
     502                                GIMR0TermVM(pVM);
    494503                            }
    495 
    496                             /* bail out*/
    497                             GIMR0TermVM(pVM);
     504#ifdef VBOX_WITH_PCI_PASSTHROUGH
     505                            PciRawR0TermVM(pGVM, pVM);
     506#endif
    498507                        }
    499 #ifdef VBOX_WITH_PCI_PASSTHROUGH
    500                         PciRawR0TermVM(pGVM, pVM);
    501 #endif
    502508                    }
    503509                }
  • trunk/src/VBox/VMM/VMMR3/EM.cpp

    r72634 r72642  
    149149    }
    150150
    151     /**
    152      * @cfgm{/EM/ExitOptimizationEnabled, bool, true for NEM otherwise false}
    153      * Whether to try correlate exit history, detect hot spots and try optimize
    154      * these using IEM if there are other exits close by.
    155      * @todo enable for HM too.
    156      */
     151    LogRel(("EMR3Init: fRecompileUser=%RTbool fRecompileSupervisor=%RTbool fRawRing1Enabled=%RTbool fIemExecutesAll=%RTbool fGuruOnTripleFault=%RTbool\n",
     152            pVM->fRecompileUser, pVM->fRecompileSupervisor, pVM->fRawRing1Enabled, pVM->em.s.fIemExecutesAll, pVM->em.s.fGuruOnTripleFault));
     153
     154    /** @cfgm{/EM/ExitOptimizationEnabled, bool, true}
     155     * Whether to try correlate exit history in any context, detect hot spots and
     156     * try optimize these using IEM if there are other exits close by.  This
     157     * overrides the context specific settings. */
    157158    bool fExitOptimizationEnabled = true;
    158     rc = CFGMR3QueryBoolDef(pCfgEM, "ExitOptimizationEnabled", &fExitOptimizationEnabled, VM_IS_NEM_ENABLED(pVM));
     159    rc = CFGMR3QueryBoolDef(pCfgEM, "ExitOptimizationEnabled", &fExitOptimizationEnabled, true);
    159160    AssertLogRelRCReturn(rc, rc);
    160161
     162    /** @cfgm{/EM/ExitOptimizationEnabledR0, bool, true}
     163     * Whether to optimize exits in ring-0.  Setting this to false will also disable
     164     * the /EM/ExitOptimizationEnabledR0PreemptDisabled setting.  Depending on preemption
     165     * capabilities of the host kernel, this optimization may be unavailable. */
     166    bool fExitOptimizationEnabledR0 = true;
     167    rc = CFGMR3QueryBoolDef(pCfgEM, "ExitOptimizationEnabledR0", &fExitOptimizationEnabledR0, true);
     168    AssertLogRelRCReturn(rc, rc);
     169    fExitOptimizationEnabledR0 &= fExitOptimizationEnabled;
     170
     171    /** @cfgm{/EM/ExitOptimizationEnabledR0PreemptDisabled, bool, false}
     172     * Whether to optimize exits in ring-0 when preemption is disable (or preemption
     173     * hooks are in effect). */
     174    /** @todo change the default to true here */
     175    bool fExitOptimizationEnabledR0PreemptDisabled = true;
     176    rc = CFGMR3QueryBoolDef(pCfgEM, "ExitOptimizationEnabledR0PreemptDisabled", &fExitOptimizationEnabledR0PreemptDisabled, false);
     177    AssertLogRelRCReturn(rc, rc);
     178    fExitOptimizationEnabledR0PreemptDisabled &= fExitOptimizationEnabledR0;
     179
    161180    for (VMCPUID i = 0; i < pVM->cCpus; i++)
    162         pVM->aCpus[i].em.s.fExitOptimizationEnabled = fExitOptimizationEnabled;
    163 
    164     LogRel(("EMR3Init: fRecompileUser=%RTbool fRecompileSupervisor=%RTbool fRawRing1Enabled=%RTbool fIemExecutesAll=%RTbool fGuruOnTripleFault=%RTbool fExitOptimizationEnabled=%RTbool\n",
    165             pVM->fRecompileUser, pVM->fRecompileSupervisor, pVM->fRawRing1Enabled, pVM->em.s.fIemExecutesAll, pVM->em.s.fGuruOnTripleFault, fExitOptimizationEnabled));
     181    {
     182        pVM->aCpus[i].em.s.fExitOptimizationEnabled                  = fExitOptimizationEnabled;
     183        pVM->aCpus[i].em.s.fExitOptimizationEnabledR0                = fExitOptimizationEnabledR0;
     184        pVM->aCpus[i].em.s.fExitOptimizationEnabledR0PreemptDisabled = fExitOptimizationEnabledR0PreemptDisabled;
     185    }
    166186
    167187#ifdef VBOX_WITH_REM
     
    502522
    503523/**
     524 * Called when a VM initialization stage is completed.
     525 *
     526 * @returns VBox status code.
     527 * @param   pVM             The cross context VM structure.
     528 * @param   enmWhat         The initialization state that was completed.
     529 */
     530VMMR3_INT_DECL(int) EMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat)
     531{
     532    if (enmWhat == VMINITCOMPLETED_RING0)
     533        LogRel(("EM: Exit history optimizations: enabled=%RTbool enabled-r0=%RTbool enabled-r0-no-preemption=%RTbool\n",
     534                pVM->aCpus[0].em.s.fExitOptimizationEnabled, pVM->aCpus[0].em.s.fExitOptimizationEnabledR0,
     535                pVM->aCpus[0].em.s.fExitOptimizationEnabledR0PreemptDisabled));
     536    return VINF_SUCCESS;
     537}
     538
     539
     540/**
    504541 * Applies relocations to data and code managed by this
    505542 * component. This function will be called at init and
  • trunk/src/VBox/VMM/VMMR3/VM.cpp

    r72343 r72642  
    11971197    if (RT_SUCCESS(rc))
    11981198        rc = CPUMR3InitCompleted(pVM, enmWhat);
     1199    if (RT_SUCCESS(rc))
     1200        rc = EMR3InitCompleted(pVM, enmWhat);
    11991201    if (enmWhat == VMINITCOMPLETED_RING3)
    12001202    {
  • trunk/src/VBox/VMM/include/EMInternal.h

    r72634 r72642  
    503503     * wrapped around or not.  */
    504504    uint64_t                iNextExit;
    505     /** Whether exit optimizations are enabled or not. */
    506     bool                    fExitOptimizationEnabled;
     505    /** Whether exit optimizations are enabled or not (in general). */
     506    bool                    fExitOptimizationEnabled : 1;
     507    /** Whether exit optimizations are enabled for ring-0 (in general). */
     508    bool                    fExitOptimizationEnabledR0 : 1;
     509    /** Whether exit optimizations are enabled for ring-0 when preemption is disabled. */
     510    bool                    fExitOptimizationEnabledR0PreemptDisabled : 1;
    507511    /** Explicit padding. */
    508512    bool                    afPadding2[1];
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette