- Timestamp:
- Sep 18, 2009 11:12:52 AM (15 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PGMInternal.h
r23097 r23121 1822 1822 /** Number of times we've been out of user records. */ 1823 1823 STAMCOUNTER StatTrackFreeUpOneUser; 1824 /** Nr of flushed entries. */ 1825 STAMCOUNTER StatTrackFlushEntry; 1826 /** Nr of updated entries. */ 1827 STAMCOUNTER StatTrackFlushEntryKeep; 1824 1828 # endif 1825 1829 # ifdef PGMPOOL_WITH_GCPHYS_TRACKING … … 1854 1858 /** Profiling the REP STOSD cases we've handled. */ 1855 1859 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; 1856 1868 1857 1869 /** Profiling the R3 access handler. */ … … 1873 1885 /** Profiling the REP STOSD cases we've handled. */ 1874 1886 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; 1875 1895 /** The number of times we're called in an async thread an need to flush. */ 1876 1896 STAMCOUNTER StatMonitorR3Async; … … 3106 3126 int pgmPoolSyncCR3(PVMCPU pVCpu); 3107 3127 bool pgmPoolIsDirtyPage(PVM pVM, RTGCPHYS GCPhys); 3108 int pgmPoolTrackFlushGCPhys(PVM pVM, PPGMPAGE pPhysPage, bool *pfFlushTLBs); 3128 int pgmPoolTrackUpdateGCPhys(PVM pVM, PPGMPAGE pPhysPage, bool fFlushPTEs, bool *pfFlushTLBs); 3129 DECLINLINE(int) pgmPoolTrackFlushGCPhys(PVM pVM, PPGMPAGE pPhysPage, bool *pfFlushTLBs) 3130 { 3131 return pgmPoolTrackUpdateGCPhys(pVM, pPhysPage, true /* flush PTEs */, pfFlushTLBs); 3132 } 3133 3109 3134 uint16_t pgmPoolTrackPhysExtAddref(PVM pVM, uint16_t u16, uint16_t iShwPT); 3110 3135 void pgmPoolTrackPhysExtDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPoolPage, PPGMPAGE pPhysPage); -
trunk/src/VBox/VMM/PGMPool.cpp
r23100 r23121 348 348 STAM_REG(pVM, &pPool->StatTrackFlushGCPhysPTs, STAMTYPE_PROFILE, "/PGM/Pool/Track/FlushGCPhysPTs", STAMUNIT_TICKS_PER_CALL, "Profiling of pgmPoolTrackFlushGCPhysPTs."); 349 349 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."); 350 352 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."); 351 353 # endif … … 367 369 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."); 368 370 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."); 369 375 STAM_REG(pVM, &pPool->StatMonitorR3, STAMTYPE_PROFILE, "/PGM/Pool/Monitor/R3", STAMUNIT_TICKS_PER_CALL, "Profiling the R3 access handler."); 370 376 STAM_REG(pVM, &pPool->StatMonitorR3EmulateInstr, STAMTYPE_COUNTER, "/PGM/Pool/Monitor/R3/EmulateInstr", STAMUNIT_OCCURENCES, "Times we've failed interpreting the instruction."); … … 376 382 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."); 377 383 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."); 378 388 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."); 379 389 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 223 223 PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, uState); 224 224 225 int rc2 = pgmPoolTrack FlushGCPhys(pVM, pPage, &fFlushTLBs);225 int rc2 = pgmPoolTrackUpdateGCPhys(pVM, pPage, false /* allow updates of PTEs (instead of flushing) */, &fFlushTLBs); 226 226 if (rc2 != VINF_SUCCESS && rc == VINF_SUCCESS) 227 227 rc = rc2; -
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
r23090 r23121 66 66 #endif 67 67 68 void pgmPoolTrackFlushGCPhysPT(PVM pVM, PPGMPAGE pPhysPage, uint16_t iShw, uint16_t cRefs);69 void pgmPoolTrackFlushGCPhysPTs(PVM pVM, PPGMPAGE pPhysPage, uint16_t iPhysExt);70 68 int pgmPoolTrackFlushGCPhysPTsSlow(PVM pVM, PPGMPAGE pPhysPage); 71 69 PPGMPOOLPHYSEXT pgmPoolTrackPhysExtAlloc(PVM pVM, uint16_t *piPhysExt); … … 272 270 case PGMPOOLKIND_32BIT_PT_FOR_32BIT_PT: 273 271 { 272 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPT)); 274 273 uShw.pv = PGMPOOL_PAGE_2_LOCKED_PTR(pVM, pPage); 275 274 const unsigned iShw = off / sizeof(X86PTE); … … 295 294 case PGMPOOLKIND_PAE_PT_FOR_32BIT_PT: 296 295 { 296 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPT)); 297 297 uShw.pv = PGMPOOL_PAGE_2_LOCKED_PTR(pVM, pPage); 298 298 if (!((off ^ pPage->GCPhys) & (PAGE_SIZE / 2))) … … 329 329 330 330 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)); 331 332 if (iShwPdpt == pPage->enmKind - (unsigned)PGMPOOLKIND_PAE_PD0_FOR_32BIT_PD) 332 333 { … … 391 392 uShw.pv = PGMPOOL_PAGE_2_LOCKED_PTR(pVM, pPage); 392 393 const unsigned iShw = off / sizeof(X86PTEPAE); 394 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPT)); 393 395 if (uShw.pPTPae->a[iShw].n.u1Present) 394 396 { … … 441 443 442 444 LogFlow(("pgmPoolMonitorChainChanging: PGMPOOLKIND_32BIT_PD %x\n", iShw)); 445 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPD)); 443 446 # ifndef IN_RING0 444 447 if (uShw.pPD->a[iShw].u & PGM_PDFLAGS_MAPPING) … … 519 522 uShw.pv = PGMPOOL_PAGE_2_LOCKED_PTR(pVM, pPage); 520 523 const unsigned iShw = off / sizeof(X86PDEPAE); 524 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPD)); 521 525 #ifndef IN_RING0 522 526 if (uShw.pPDPae->a[iShw].u & PGM_PDFLAGS_MAPPING) … … 585 589 case PGMPOOLKIND_PAE_PDPT: 586 590 { 591 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPDPT)); 587 592 /* 588 593 * Hopefully this doesn't happen very often: … … 660 665 case PGMPOOLKIND_64BIT_PD_FOR_64BIT_PD: 661 666 { 667 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPD)); 662 668 uShw.pv = PGMPOOL_PAGE_2_LOCKED_PTR(pVM, pPage); 663 669 const unsigned iShw = off / sizeof(X86PDEPAE); … … 696 702 case PGMPOOLKIND_64BIT_PDPT_FOR_64BIT_PDPT: 697 703 { 704 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPDPT)); 698 705 /* 699 706 * Hopefully this doesn't happen very often: … … 729 736 case PGMPOOLKIND_64BIT_PML4: 730 737 { 738 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPML4)); 731 739 /* 732 740 * Hopefully this doesn't happen very often: … … 1177 1185 #endif 1178 1186 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; 1182 1191 else 1183 1192 cMaxModifications = 24; 1193 #else 1194 cMaxModifications = 48; 1195 #endif 1184 1196 1185 1197 /* … … 1308 1320 } 1309 1321 1310 #if def PGMPOOL_WITH_OPTIMIZED_DIRTY_PT1322 #if defined(PGMPOOL_WITH_OPTIMIZED_DIRTY_PT) && defined(IN_RING0) 1311 1323 /* E.g. Windows 7 x64 initializes page tables and touches some pages in the table during the process. This 1312 1324 * leads to pgm pool trashing and an excessive amount of write faults due to page monitoring. … … 3100 3112 * Scans one shadow page table for mappings of a physical page. 3101 3113 * 3114 * @returns true/false indicating removal of all relevant PTEs 3102 3115 * @param pVM The VM handle. 3103 3116 * @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) 3104 3118 * @param iShw The shadow page table. 3105 3119 * @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 */ 3122 static 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)); 3110 3125 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool); 3126 bool bRet = false; 3111 3127 3112 3128 /* … … 3128 3144 const uint32_t u32 = PGM_PAGE_GET_HCPHYS(pPhysPage) | X86_PTE_P; 3129 3145 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 3130 3177 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pPT->a); i++) 3131 3178 if ((pPT->a[i].u & (X86_PTE_PG_MASK | X86_PTE_P)) == u32) 3132 3179 { 3133 3180 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; 3135 3182 cRefs--; 3136 3183 if (!cRefs) 3137 return ;3184 return bRet; 3138 3185 } 3139 3186 #ifdef LOG_ENABLED … … 3157 3204 const uint64_t u64 = PGM_PAGE_GET_HCPHYS(pPhysPage) | X86_PTE_P; 3158 3205 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 3159 3237 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pPT->a); i++) 3160 3238 if ((pPT->a[i].u & (X86_PTE_PAE_PG_MASK | X86_PTE_P)) == u64) 3161 3239 { 3162 3240 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; 3164 3242 cRefs--; 3165 3243 if (!cRefs) 3166 return ;3244 return bRet; 3167 3245 } 3168 3246 #ifdef LOG_ENABLED … … 3186 3264 { 3187 3265 Log4(("pgmPoolTrackFlushGCPhysPTs: i=%d pte=%RX64 cRefs=%#x\n", i, pPT->a[i], cRefs)); 3266 STAM_COUNTER_INC(&pPool->StatTrackFlushEntry); 3188 3267 pPT->a[i].u = 0; 3189 3268 cRefs--; 3190 3269 if (!cRefs) 3191 return ;3270 return bRet; 3192 3271 } 3193 3272 #ifdef LOG_ENABLED … … 3206 3285 AssertFatalMsgFailed(("enmKind=%d iShw=%d\n", pPage->enmKind, iShw)); 3207 3286 } 3287 return bRet; 3208 3288 } 3209 3289 … … 3214 3294 * @param pVM The VM handle. 3215 3295 * @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) 3216 3297 * @param iShw The shadow page table. 3217 3298 * @param cRefs The number of references made in that PT. 3218 3299 */ 3219 void pgmPoolTrackFlushGCPhysPT(PVM pVM, PPGMPAGE pPhysPage, uint16_t iShw, uint16_t cRefs)3300 static void pgmPoolTrackFlushGCPhysPT(PVM pVM, PPGMPAGE pPhysPage, bool fFlushPTEs, uint16_t iShw, uint16_t cRefs) 3220 3301 { 3221 3302 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)); 3223 3305 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); 3226 3309 STAM_PROFILE_STOP(&pPool->StatTrackFlushGCPhysPT, f); 3227 3310 } … … 3233 3316 * @param pVM The VM handle. 3234 3317 * @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) 3235 3319 * @param iPhysExt The physical cross reference extent list to flush. 3236 3320 */ 3237 void pgmPoolTrackFlushGCPhysPTs(PVM pVM, PPGMPAGE pPhysPage, uint16_t iPhysExt)3321 static void pgmPoolTrackFlushGCPhysPTs(PVM pVM, PPGMPAGE pPhysPage, bool fFlushPTEs, uint16_t iPhysExt) 3238 3322 { 3239 3323 Assert(PGMIsLockOwner(pVM)); 3240 3324 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool); 3325 bool fKeepList = false; 3326 3241 3327 STAM_PROFILE_START(&pPool->StatTrackFlushGCPhysPTs, f); 3242 LogFlow(("pgmPoolTrackFlushGCPhysPTs: pPhysPage=%R [pgmpage] iPhysExt\n", pPhysPage, iPhysExt));3243 3244 const uint16_t 3328 LogFlow(("pgmPoolTrackFlushGCPhysPTs: pPhysPage=%RHp iPhysExt\n", PGM_PAGE_GET_HCPHYS(pPhysPage), iPhysExt)); 3329 3330 const uint16_t iPhysExtStart = iPhysExt; 3245 3331 PPGMPOOLPHYSEXT pPhysExt; 3246 3332 do … … 3249 3335 pPhysExt = &pPool->CTX_SUFF(paPhysExts)[iPhysExt]; 3250 3336 for (unsigned i = 0; i < RT_ELEMENTS(pPhysExt->aidx); i++) 3337 { 3251 3338 if (pPhysExt->aidx[i] != NIL_PGMPOOL_IDX) 3252 3339 { 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; 3255 3345 } 3256 3346 } 3257 3347 /* next */ 3258 3348 iPhysExt = pPhysExt->iNext; 3259 3349 } while (iPhysExt != NIL_PGMPOOL_PHYSEXT_INDEX); 3260 3350 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 } 3265 3358 3266 3359 STAM_PROFILE_STOP(&pPool->StatTrackFlushGCPhysPTs, f); … … 3282 3375 * @param pVM The VM handle. 3283 3376 * @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) 3284 3378 * @param pfFlushTLBs This is set to @a true if the shadow TLBs should be 3285 3379 * flushed, it is NOT touched if this isn't necessary. 3286 3380 * The caller MUST initialized this to @a false. 3287 3381 */ 3288 int pgmPoolTrack FlushGCPhys(PVM pVM, PPGMPAGE pPhysPage, bool *pfFlushTLBs)3382 int pgmPoolTrackUpdateGCPhys(PVM pVM, PPGMPAGE pPhysPage, bool fFlushPTEs, bool *pfFlushTLBs) 3289 3383 { 3290 3384 PVMCPU pVCpu = VMMGetCpu(pVM); … … 3314 3408 pgmPoolTrackFlushGCPhysPT(pVM, 3315 3409 pPhysPage, 3410 fFlushPTEs, 3316 3411 PGMPOOL_TD_GET_IDX(u16), 3317 3412 PGMPOOL_TD_GET_CREFS(u16)); 3318 3413 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)); 3320 3415 else 3321 3416 rc = pgmPoolTrackFlushGCPhysPTsSlow(pVM, pPhysPage);
Note:
See TracChangeset
for help on using the changeset viewer.