VirtualBox

Changeset 23121 in vbox for trunk/src


Ignore:
Timestamp:
Sep 18, 2009 11:12:52 AM (15 years ago)
Author:
vboxsync
Message:

Paging updates:

  • use the dirty page handling after fewer writes
  • don't always invalidate PTEs in pgmHandlerPhysicalSetRamFlagsAndFlushShadowPTs; just flipping the X86_PTE_W bit is sufficient
Location:
trunk/src/VBox/VMM
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PGMInternal.h

    r23097 r23121  
    18221822    /** Number of times we've been out of user records. */
    18231823    STAMCOUNTER                 StatTrackFreeUpOneUser;
     1824    /** Nr of flushed entries. */
     1825    STAMCOUNTER                 StatTrackFlushEntry;
     1826    /** Nr of updated entries. */
     1827    STAMCOUNTER                 StatTrackFlushEntryKeep;
    18241828# endif
    18251829# ifdef PGMPOOL_WITH_GCPHYS_TRACKING
     
    18541858    /** Profiling the REP STOSD cases we've handled. */
    18551859    STAMPROFILE                 StatMonitorRZRepStosd;
     1860    /** Nr of handled PT faults. */
     1861    STAMCOUNTER                 StatMonitorRZFaultPT;
     1862    /** Nr of handled PD faults. */
     1863    STAMCOUNTER                 StatMonitorRZFaultPD;
     1864    /** Nr of handled PDPT faults. */
     1865    STAMCOUNTER                 StatMonitorRZFaultPDPT;
     1866    /** Nr of handled PML4 faults. */
     1867    STAMCOUNTER                 StatMonitorRZFaultPML4;
    18561868
    18571869    /** Profiling the R3 access handler. */
     
    18731885    /** Profiling the REP STOSD cases we've handled. */
    18741886    STAMPROFILE                 StatMonitorR3RepStosd;
     1887    /** Nr of handled PT faults. */
     1888    STAMCOUNTER                 StatMonitorR3FaultPT;
     1889    /** Nr of handled PD faults. */
     1890    STAMCOUNTER                 StatMonitorR3FaultPD;
     1891    /** Nr of handled PDPT faults. */
     1892    STAMCOUNTER                 StatMonitorR3FaultPDPT;
     1893    /** Nr of handled PML4 faults. */
     1894    STAMCOUNTER                 StatMonitorR3FaultPML4;
    18751895    /** The number of times we're called in an async thread an need to flush. */
    18761896    STAMCOUNTER                 StatMonitorR3Async;
     
    31063126int             pgmPoolSyncCR3(PVMCPU pVCpu);
    31073127bool            pgmPoolIsDirtyPage(PVM pVM, RTGCPHYS GCPhys);
    3108 int             pgmPoolTrackFlushGCPhys(PVM pVM, PPGMPAGE pPhysPage, bool *pfFlushTLBs);
     3128int             pgmPoolTrackUpdateGCPhys(PVM pVM, PPGMPAGE pPhysPage, bool fFlushPTEs, bool *pfFlushTLBs);
     3129DECLINLINE(int) pgmPoolTrackFlushGCPhys(PVM pVM, PPGMPAGE pPhysPage, bool *pfFlushTLBs)
     3130{
     3131    return pgmPoolTrackUpdateGCPhys(pVM, pPhysPage, true /* flush PTEs */, pfFlushTLBs);
     3132}
     3133
    31093134uint16_t        pgmPoolTrackPhysExtAddref(PVM pVM, uint16_t u16, uint16_t iShwPT);
    31103135void            pgmPoolTrackPhysExtDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPoolPage, PPGMPAGE pPhysPage);
  • trunk/src/VBox/VMM/PGMPool.cpp

    r23100 r23121  
    348348    STAM_REG(pVM, &pPool->StatTrackFlushGCPhysPTs,      STAMTYPE_PROFILE,   "/PGM/Pool/Track/FlushGCPhysPTs",       STAMUNIT_TICKS_PER_CALL, "Profiling of pgmPoolTrackFlushGCPhysPTs.");
    349349    STAM_REG(pVM, &pPool->StatTrackFlushGCPhysPTsSlow,  STAMTYPE_PROFILE,   "/PGM/Pool/Track/FlushGCPhysPTsSlow",   STAMUNIT_TICKS_PER_CALL, "Profiling of pgmPoolTrackFlushGCPhysPTsSlow.");
     350    STAM_REG(pVM, &pPool->StatTrackFlushEntry,          STAMTYPE_COUNTER,   "/PGM/Pool/Track/Entry/Flush",          STAMUNIT_COUNT,          "Nr of flushed entries.");
     351    STAM_REG(pVM, &pPool->StatTrackFlushEntryKeep,      STAMTYPE_COUNTER,   "/PGM/Pool/Track/Entry/Update",         STAMUNIT_COUNT,          "Nr of updated entries.");
    350352    STAM_REG(pVM, &pPool->StatTrackFreeUpOneUser,       STAMTYPE_COUNTER,   "/PGM/Pool/Track/FreeUpOneUser",        STAMUNIT_TICKS_PER_CALL, "The number of times we were out of user tracking records.");
    351353# endif
     
    367369    STAM_REG(pVM, &pPool->StatMonitorRZRepPrefix,       STAMTYPE_COUNTER,   "/PGM/Pool/Monitor/RZ/RepPrefix",       STAMUNIT_OCCURENCES,     "The number of times we've seen rep prefixes we can't handle.");
    368370    STAM_REG(pVM, &pPool->StatMonitorRZRepStosd,        STAMTYPE_PROFILE,   "/PGM/Pool/Monitor/RZ/RepStosd",        STAMUNIT_TICKS_PER_CALL, "Profiling the REP STOSD cases we've handled.");
     371    STAM_REG(pVM, &pPool->StatMonitorRZFaultPT,         STAMTYPE_COUNTER,   "/PGM/Pool/Monitor/RZ/Fault/PT",        STAMUNIT_OCCURENCES,     "Nr of handled PT faults.");
     372    STAM_REG(pVM, &pPool->StatMonitorRZFaultPD,         STAMTYPE_COUNTER,   "/PGM/Pool/Monitor/RZ/Fault/PD",        STAMUNIT_OCCURENCES,     "Nr of handled PD faults.");
     373    STAM_REG(pVM, &pPool->StatMonitorRZFaultPDPT,       STAMTYPE_COUNTER,   "/PGM/Pool/Monitor/RZ/Fault/PDPT",      STAMUNIT_OCCURENCES,     "Nr of handled PDPT faults.");
     374    STAM_REG(pVM, &pPool->StatMonitorRZFaultPML4,       STAMTYPE_COUNTER,   "/PGM/Pool/Monitor/RZ/Fault/PML4",      STAMUNIT_OCCURENCES,     "Nr of handled PML4 faults.");
    369375    STAM_REG(pVM, &pPool->StatMonitorR3,                STAMTYPE_PROFILE,   "/PGM/Pool/Monitor/R3",                 STAMUNIT_TICKS_PER_CALL, "Profiling the R3 access handler.");
    370376    STAM_REG(pVM, &pPool->StatMonitorR3EmulateInstr,    STAMTYPE_COUNTER,   "/PGM/Pool/Monitor/R3/EmulateInstr",    STAMUNIT_OCCURENCES,     "Times we've failed interpreting the instruction.");
     
    376382    STAM_REG(pVM, &pPool->StatMonitorR3RepPrefix,       STAMTYPE_COUNTER,   "/PGM/Pool/Monitor/R3/RepPrefix",       STAMUNIT_OCCURENCES,     "The number of times we've seen rep prefixes we can't handle.");
    377383    STAM_REG(pVM, &pPool->StatMonitorR3RepStosd,        STAMTYPE_PROFILE,   "/PGM/Pool/Monitor/R3/RepStosd",        STAMUNIT_TICKS_PER_CALL, "Profiling the REP STOSD cases we've handled.");
     384    STAM_REG(pVM, &pPool->StatMonitorR3FaultPT,         STAMTYPE_COUNTER,   "/PGM/Pool/Monitor/R3/Fault/PT",        STAMUNIT_OCCURENCES,     "Nr of handled PT faults.");
     385    STAM_REG(pVM, &pPool->StatMonitorR3FaultPD,         STAMTYPE_COUNTER,   "/PGM/Pool/Monitor/R3/Fault/PD",        STAMUNIT_OCCURENCES,     "Nr of handled PD faults.");
     386    STAM_REG(pVM, &pPool->StatMonitorR3FaultPDPT,       STAMTYPE_COUNTER,   "/PGM/Pool/Monitor/R3/Fault/PDPT",      STAMUNIT_OCCURENCES,     "Nr of handled PDPT faults.");
     387    STAM_REG(pVM, &pPool->StatMonitorR3FaultPML4,       STAMTYPE_COUNTER,   "/PGM/Pool/Monitor/R3/Fault/PML4",      STAMUNIT_OCCURENCES,     "Nr of handled PML4 faults.");
    378388    STAM_REG(pVM, &pPool->StatMonitorR3Async,           STAMTYPE_COUNTER,   "/PGM/Pool/Monitor/R3/Async",           STAMUNIT_OCCURENCES,     "Times we're called in an async thread and need to flush.");
    379389    STAM_REG(pVM, &pPool->cModifiedPages,               STAMTYPE_U16,       "/PGM/Pool/Monitor/cModifiedPages",     STAMUNIT_PAGES,          "The current cModifiedPages value.");
  • trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp

    r22890 r23121  
    223223            PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, uState);
    224224
    225             int rc2 = pgmPoolTrackFlushGCPhys(pVM, pPage, &fFlushTLBs);
     225            int rc2 = pgmPoolTrackUpdateGCPhys(pVM, pPage, false /* allow updates of PTEs (instead of flushing) */, &fFlushTLBs);
    226226            if (rc2 != VINF_SUCCESS && rc == VINF_SUCCESS)
    227227                rc = rc2;
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r23090 r23121  
    6666#endif
    6767
    68 void            pgmPoolTrackFlushGCPhysPT(PVM pVM, PPGMPAGE pPhysPage, uint16_t iShw, uint16_t cRefs);
    69 void            pgmPoolTrackFlushGCPhysPTs(PVM pVM, PPGMPAGE pPhysPage, uint16_t iPhysExt);
    7068int             pgmPoolTrackFlushGCPhysPTsSlow(PVM pVM, PPGMPAGE pPhysPage);
    7169PPGMPOOLPHYSEXT pgmPoolTrackPhysExtAlloc(PVM pVM, uint16_t *piPhysExt);
     
    272270            case PGMPOOLKIND_32BIT_PT_FOR_32BIT_PT:
    273271            {
     272                STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPT));
    274273                uShw.pv = PGMPOOL_PAGE_2_LOCKED_PTR(pVM, pPage);
    275274                const unsigned iShw = off / sizeof(X86PTE);
     
    295294            case PGMPOOLKIND_PAE_PT_FOR_32BIT_PT:
    296295            {
     296                STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPT));
    297297                uShw.pv = PGMPOOL_PAGE_2_LOCKED_PTR(pVM, pPage);
    298298                if (!((off ^ pPage->GCPhys) & (PAGE_SIZE / 2)))
     
    329329
    330330                LogFlow(("pgmPoolMonitorChainChanging PAE for 32 bits: iGst=%x iShw=%x idx = %d page idx=%d\n", iGst, iShw, iShwPdpt, pPage->enmKind - PGMPOOLKIND_PAE_PD0_FOR_32BIT_PD));
     331                STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPD));
    331332                if (iShwPdpt == pPage->enmKind - (unsigned)PGMPOOLKIND_PAE_PD0_FOR_32BIT_PD)
    332333                {
     
    391392                uShw.pv = PGMPOOL_PAGE_2_LOCKED_PTR(pVM, pPage);
    392393                const unsigned iShw = off / sizeof(X86PTEPAE);
     394                STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPT));
    393395                if (uShw.pPTPae->a[iShw].n.u1Present)
    394396                {
     
    441443
    442444                LogFlow(("pgmPoolMonitorChainChanging: PGMPOOLKIND_32BIT_PD %x\n", iShw));
     445                STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPD));
    443446#  ifndef IN_RING0
    444447                if (uShw.pPD->a[iShw].u & PGM_PDFLAGS_MAPPING)
     
    519522                uShw.pv = PGMPOOL_PAGE_2_LOCKED_PTR(pVM, pPage);
    520523                const unsigned iShw = off / sizeof(X86PDEPAE);
     524                STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPD));
    521525#ifndef IN_RING0
    522526                if (uShw.pPDPae->a[iShw].u & PGM_PDFLAGS_MAPPING)
     
    585589            case PGMPOOLKIND_PAE_PDPT:
    586590            {
     591                STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPDPT));
    587592                /*
    588593                 * Hopefully this doesn't happen very often:
     
    660665            case PGMPOOLKIND_64BIT_PD_FOR_64BIT_PD:
    661666            {
     667                STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPD));
    662668                uShw.pv = PGMPOOL_PAGE_2_LOCKED_PTR(pVM, pPage);
    663669                const unsigned iShw = off / sizeof(X86PDEPAE);
     
    696702            case PGMPOOLKIND_64BIT_PDPT_FOR_64BIT_PDPT:
    697703            {
     704                STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPDPT));
    698705                /*
    699706                 * Hopefully this doesn't happen very often:
     
    729736            case PGMPOOLKIND_64BIT_PML4:
    730737            {
     738                STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPML4));
    731739                /*
    732740                 * Hopefully this doesn't happen very often:
     
    11771185#endif
    11781186
    1179     /* Maximum nr of modifications depends on the guest mode. */
    1180     if (pDis->mode == CPUMODE_32BIT)
    1181         cMaxModifications = 48;
     1187#ifdef IN_RING0
     1188    /* Maximum nr of modifications depends on the page type. */
     1189    if (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT)
     1190        cMaxModifications = 4;
    11821191    else
    11831192        cMaxModifications = 24;
     1193#else
     1194    cMaxModifications = 48;
     1195#endif
    11841196
    11851197    /*
     
    13081320    }
    13091321
    1310 #ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT
     1322#if defined(PGMPOOL_WITH_OPTIMIZED_DIRTY_PT) && defined(IN_RING0)
    13111323    /* E.g. Windows 7 x64 initializes page tables and touches some pages in the table during the process. This
    13121324     * leads to pgm pool trashing and an excessive amount of write faults due to page monitoring.
     
    31003112 * Scans one shadow page table for mappings of a physical page.
    31013113 *
     3114 * @returns true/false indicating removal of all relevant PTEs
    31023115 * @param   pVM         The VM handle.
    31033116 * @param   pPhysPage   The guest page in question.
     3117 * @param   fFlushPTEs  Flush PTEs or allow them to be updated (e.g. in case of an RW bit change)
    31043118 * @param   iShw        The shadow page table.
    31053119 * @param   cRefs       The number of references made in that PT.
    3106  */
    3107 static void pgmPoolTrackFlushGCPhysPTInt(PVM pVM, PCPGMPAGE pPhysPage, uint16_t iShw, uint16_t cRefs)
    3108 {
    3109     LogFlow(("pgmPoolTrackFlushGCPhysPT: pPhysPage=%R[pgmpage] iShw=%d cRefs=%d\n", pPhysPage, iShw, cRefs));
     3120 * @param   pfKeptPTEs  Flag indicating removal of all relevant PTEs (out)
     3121 */
     3122static bool pgmPoolTrackFlushGCPhysPTInt(PVM pVM, PCPGMPAGE pPhysPage, bool fFlushPTEs, uint16_t iShw, uint16_t cRefs)
     3123{
     3124    LogFlow(("pgmPoolTrackFlushGCPhysPT: pPhysPage=%RHp iShw=%d cRefs=%d\n", PGM_PAGE_GET_HCPHYS(pPhysPage), iShw, cRefs));
    31103125    PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
     3126    bool bRet = false;
    31113127
    31123128    /*
     
    31283144            const uint32_t  u32 = PGM_PAGE_GET_HCPHYS(pPhysPage) | X86_PTE_P;
    31293145            PX86PT          pPT = (PX86PT)PGMPOOL_PAGE_2_PTR(pVM, pPage);
     3146            uint32_t        u32AndMask, u32OrMask;
     3147
     3148            u32AndMask = 0;
     3149            u32OrMask  = 0;
     3150
     3151            if (!fFlushPTEs)
     3152            {
     3153                switch (PGM_PAGE_GET_HNDL_PHYS_STATE(pPhysPage))
     3154                {
     3155                case PGM_PAGE_HNDL_PHYS_STATE_NONE:         /** No handler installed. */
     3156                case PGM_PAGE_HNDL_PHYS_STATE_DISABLED:     /** Monitoring is temporarily disabled. */
     3157                    u32OrMask = X86_PTE_RW;
     3158                    u32AndMask = UINT32_MAX;
     3159                    bRet = true;
     3160                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
     3161                    break;
     3162
     3163                case PGM_PAGE_HNDL_PHYS_STATE_WRITE:        /** Write access is monitored. */
     3164                    u32OrMask = 0;
     3165                    u32AndMask = ~X86_PTE_RW;
     3166                    bRet = true;
     3167                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
     3168                    break;
     3169                default:
     3170                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
     3171                    break;
     3172                }
     3173            }
     3174            else
     3175                STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
     3176
    31303177            for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pPT->a); i++)
    31313178                if ((pPT->a[i].u & (X86_PTE_PG_MASK | X86_PTE_P)) == u32)
    31323179                {
    31333180                    Log4(("pgmPoolTrackFlushGCPhysPTs: i=%d pte=%RX32 cRefs=%#x\n", i, pPT->a[i], cRefs));
    3134                     pPT->a[i].u = 0;
     3181                    pPT->a[i].u = (pPT->a[i].u & u32AndMask) | u32OrMask;
    31353182                    cRefs--;
    31363183                    if (!cRefs)
    3137                         return;
     3184                        return bRet;
    31383185                }
    31393186#ifdef LOG_ENABLED
     
    31573204            const uint64_t  u64 = PGM_PAGE_GET_HCPHYS(pPhysPage) | X86_PTE_P;
    31583205            PX86PTPAE       pPT = (PX86PTPAE)PGMPOOL_PAGE_2_PTR(pVM, pPage);
     3206            uint64_t        u64AndMask, u64OrMask;
     3207
     3208            u64OrMask = 0;
     3209            u64AndMask = 0;
     3210            if (!fFlushPTEs)
     3211            {
     3212                switch (PGM_PAGE_GET_HNDL_PHYS_STATE(pPhysPage))
     3213                {
     3214                case PGM_PAGE_HNDL_PHYS_STATE_NONE:         /** No handler installed. */
     3215                case PGM_PAGE_HNDL_PHYS_STATE_DISABLED:     /** Monitoring is temporarily disabled. */
     3216                    u64OrMask = X86_PTE_RW;
     3217                    u64AndMask = UINT64_MAX;
     3218                    bRet = true;
     3219                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
     3220                    break;
     3221
     3222                case PGM_PAGE_HNDL_PHYS_STATE_WRITE:        /** Write access is monitored. */
     3223                    u64OrMask = 0;
     3224                    u64AndMask = ~((uint64_t)X86_PTE_RW);
     3225                    bRet = true;
     3226                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
     3227                    break;
     3228
     3229                default:
     3230                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
     3231                    break;
     3232                }
     3233            }
     3234            else
     3235                STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
     3236
    31593237            for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pPT->a); i++)
    31603238                if ((pPT->a[i].u & (X86_PTE_PAE_PG_MASK | X86_PTE_P)) == u64)
    31613239                {
    31623240                    Log4(("pgmPoolTrackFlushGCPhysPTs: i=%d pte=%RX64 cRefs=%#x\n", i, pPT->a[i], cRefs));
    3163                     pPT->a[i].u = 0;
     3241                    pPT->a[i].u = (pPT->a[i].u & u64AndMask) | u64OrMask;
    31643242                    cRefs--;
    31653243                    if (!cRefs)
    3166                         return;
     3244                        return bRet;
    31673245                }
    31683246#ifdef LOG_ENABLED
     
    31863264                {
    31873265                    Log4(("pgmPoolTrackFlushGCPhysPTs: i=%d pte=%RX64 cRefs=%#x\n", i, pPT->a[i], cRefs));
     3266                    STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
    31883267                    pPT->a[i].u = 0;
    31893268                    cRefs--;
    31903269                    if (!cRefs)
    3191                         return;
     3270                        return bRet;
    31923271                }
    31933272#ifdef LOG_ENABLED
     
    32063285            AssertFatalMsgFailed(("enmKind=%d iShw=%d\n", pPage->enmKind, iShw));
    32073286    }
     3287    return bRet;
    32083288}
    32093289
     
    32143294 * @param   pVM         The VM handle.
    32153295 * @param   pPhysPage   The guest page in question.
     3296 * @param   fFlushPTEs  Flush PTEs or allow them to be updated (e.g. in case of an RW bit change)
    32163297 * @param   iShw        The shadow page table.
    32173298 * @param   cRefs       The number of references made in that PT.
    32183299 */
    3219 void pgmPoolTrackFlushGCPhysPT(PVM pVM, PPGMPAGE pPhysPage, uint16_t iShw, uint16_t cRefs)
     3300static void pgmPoolTrackFlushGCPhysPT(PVM pVM, PPGMPAGE pPhysPage, bool fFlushPTEs, uint16_t iShw, uint16_t cRefs)
    32203301{
    32213302    PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool); NOREF(pPool);
    3222     LogFlow(("pgmPoolTrackFlushGCPhysPT: pPhysPage=%R[pgmpage] iShw=%d cRefs=%d\n", pPhysPage, iShw, cRefs));
     3303
     3304    LogFlow(("pgmPoolTrackFlushGCPhysPT: pPhysPage=%RHp iShw=%d cRefs=%d\n", PGM_PAGE_GET_HCPHYS(pPhysPage), iShw, cRefs));
    32233305    STAM_PROFILE_START(&pPool->StatTrackFlushGCPhysPT, f);
    3224     pgmPoolTrackFlushGCPhysPTInt(pVM, pPhysPage, iShw, cRefs);
    3225     PGM_PAGE_SET_TRACKING(pPhysPage, 0);
     3306    bool fKeptPTEs = pgmPoolTrackFlushGCPhysPTInt(pVM, pPhysPage, fFlushPTEs, iShw, cRefs);
     3307    if (!fKeptPTEs)
     3308        PGM_PAGE_SET_TRACKING(pPhysPage, 0);
    32263309    STAM_PROFILE_STOP(&pPool->StatTrackFlushGCPhysPT, f);
    32273310}
     
    32333316 * @param   pVM         The VM handle.
    32343317 * @param   pPhysPage   The guest page in question.
     3318 * @param   fFlushPTEs  Flush PTEs or allow them to be updated (e.g. in case of an RW bit change)
    32353319 * @param   iPhysExt    The physical cross reference extent list to flush.
    32363320 */
    3237 void pgmPoolTrackFlushGCPhysPTs(PVM pVM, PPGMPAGE pPhysPage, uint16_t iPhysExt)
     3321static void pgmPoolTrackFlushGCPhysPTs(PVM pVM, PPGMPAGE pPhysPage, bool fFlushPTEs, uint16_t iPhysExt)
    32383322{
    32393323    Assert(PGMIsLockOwner(pVM));
    32403324    PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
     3325    bool     fKeepList = false;
     3326
    32413327    STAM_PROFILE_START(&pPool->StatTrackFlushGCPhysPTs, f);
    3242     LogFlow(("pgmPoolTrackFlushGCPhysPTs: pPhysPage=%R[pgmpage] iPhysExt\n", pPhysPage, iPhysExt));
    3243 
    3244     const uint16_t  iPhysExtStart = iPhysExt;
     3328    LogFlow(("pgmPoolTrackFlushGCPhysPTs: pPhysPage=%RHp iPhysExt\n", PGM_PAGE_GET_HCPHYS(pPhysPage), iPhysExt));
     3329
     3330    const uint16_t iPhysExtStart = iPhysExt;
    32453331    PPGMPOOLPHYSEXT pPhysExt;
    32463332    do
     
    32493335        pPhysExt = &pPool->CTX_SUFF(paPhysExts)[iPhysExt];
    32503336        for (unsigned i = 0; i < RT_ELEMENTS(pPhysExt->aidx); i++)
     3337        {
    32513338            if (pPhysExt->aidx[i] != NIL_PGMPOOL_IDX)
    32523339            {
    3253                 pgmPoolTrackFlushGCPhysPTInt(pVM, pPhysPage, pPhysExt->aidx[i], 1);
    3254                 pPhysExt->aidx[i] = NIL_PGMPOOL_IDX;
     3340                bool fKeptPTEs = pgmPoolTrackFlushGCPhysPTInt(pVM, pPhysPage, fFlushPTEs, pPhysExt->aidx[i], 1);
     3341                if (!fKeptPTEs)
     3342                    pPhysExt->aidx[i] = NIL_PGMPOOL_IDX;
     3343                else
     3344                    fKeepList = true;
    32553345            }
    3256 
     3346        }
    32573347        /* next */
    32583348        iPhysExt = pPhysExt->iNext;
    32593349    } while (iPhysExt != NIL_PGMPOOL_PHYSEXT_INDEX);
    32603350
    3261     /* insert the list into the free list and clear the ram range entry. */
    3262     pPhysExt->iNext = pPool->iPhysExtFreeHead;
    3263     pPool->iPhysExtFreeHead = iPhysExtStart;
    3264     PGM_PAGE_SET_TRACKING(pPhysPage, 0);
     3351    if (!fKeepList)
     3352    {
     3353        /* insert the list into the free list and clear the ram range entry. */
     3354        pPhysExt->iNext = pPool->iPhysExtFreeHead;
     3355        pPool->iPhysExtFreeHead = iPhysExtStart;
     3356        PGM_PAGE_SET_TRACKING(pPhysPage, 0);
     3357    }
    32653358
    32663359    STAM_PROFILE_STOP(&pPool->StatTrackFlushGCPhysPTs, f);
     
    32823375 * @param   pVM         The VM handle.
    32833376 * @param   pPhysPage   The guest page in question.
     3377 * @param   fFlushPTEs  Flush PTEs or allow them to be updated (e.g. in case of an RW bit change)
    32843378 * @param   pfFlushTLBs This is set to @a true if the shadow TLBs should be
    32853379 *                      flushed, it is NOT touched if this isn't necessary.
    32863380 *                      The caller MUST initialized this to @a false.
    32873381 */
    3288 int pgmPoolTrackFlushGCPhys(PVM pVM, PPGMPAGE pPhysPage, bool *pfFlushTLBs)
     3382int pgmPoolTrackUpdateGCPhys(PVM pVM, PPGMPAGE pPhysPage, bool fFlushPTEs, bool *pfFlushTLBs)
    32893383{
    32903384    PVMCPU pVCpu = VMMGetCpu(pVM);
     
    33143408                pgmPoolTrackFlushGCPhysPT(pVM,
    33153409                                          pPhysPage,
     3410                                          fFlushPTEs,
    33163411                                          PGMPOOL_TD_GET_IDX(u16),
    33173412                                          PGMPOOL_TD_GET_CREFS(u16));
    33183413            else if (u16 != PGMPOOL_TD_MAKE(PGMPOOL_TD_CREFS_PHYSEXT, PGMPOOL_TD_IDX_OVERFLOWED))
    3319                 pgmPoolTrackFlushGCPhysPTs(pVM, pPhysPage, PGMPOOL_TD_GET_IDX(u16));
     3414                pgmPoolTrackFlushGCPhysPTs(pVM, pPhysPage, fFlushPTEs, PGMPOOL_TD_GET_IDX(u16));
    33203415            else
    33213416                rc = pgmPoolTrackFlushGCPhysPTsSlow(pVM, pPhysPage);
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