Lines Matching refs:pPool

49 static void pgmPoolTrackClearPageUsers(PPGMPOOL pPool, PPGMPOOLPAGE pPage);
50 static void pgmPoolTrackDeref(PPGMPOOL pPool, PPGMPOOLPAGE pPage);
51 static int pgmPoolTrackAddUser(PPGMPOOL pPool, PPGMPOOLPAGE pPage, uint16_t iUser, uint32_t iUserTable);
52 static void pgmPoolMonitorModifiedRemove(PPGMPOOL pPool, PPGMPOOLPAGE pPage);
60 static void pgmPoolTrackCheckPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PTPAE pGstPT);
95 * @param pPool The pool.
99 int pgmPoolMonitorChainFlush(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
113 pPage = &pPool->aPages[idx];
127 int rc2 = pgmPoolFlushPage(pPool, pPage);
133 pPage = &pPool->aPages[idx];
171 * @param pPool The pool.
178 void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTGCPHYS GCPhysFault,
183 PVM pVM = pPool->CTX_SUFF(pVM);
208 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPT));
219 pgmPoolTracDerefGCPhysHint(pPool, pPage,
231 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPT));
244 pgmPoolTracDerefGCPhysHint(pPool, pPage,
265 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPD));
325 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPT));
333 pgmPoolTracDerefGCPhysHint(pPool, pPage,
357 pgmPoolTracDerefGCPhysHint(pPool, pPage,
373 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPD));
444 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPD));
508 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPDPT));
579 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPD));
615 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPDPT));
645 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FaultPML4));
682 pPage = &pPool->aPages[pPage->iMonitoredNext];
694 * @param pPool The pool.
698 DECLINLINE(bool) pgmPoolMonitorIsForking(PPGMPOOL pPool, PDISCPUSTATE pDis, unsigned offFault)
721 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,Fork));
817 * @param pPool The pool.
825 static int pgmPoolAccessHandlerFlush(PVM pVM, PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, PDISCPUSTATE pDis,
833 int rc = pgmPoolMonitorChainFlush(pPool, pPage);
860 STAM_COUNTER_INC(&pPool->StatMonitorRZIntrFailPatch2);
866 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,EmulateInstr));
884 * @param pPool The pool.
891 DECLINLINE(int) pgmPoolAccessHandlerSTOSD(PVM pVM, PPGMPOOL pPool, PPGMPOOLPAGE pPage, PDISCPUSTATE pDis,
914 pgmPoolMonitorModifiedInsert(pPool, pPage);
922 PVMCPU pVCpu = VMMGetCpu(pPool->CTX_SUFF(pVM));
928 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, (RTGCPTR)pu32, uIncrement);
931 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, (RTGCPTR)pu32, uIncrement);
956 * @param pPool The pool.
964 DECLINLINE(int) pgmPoolAccessHandlerSimple(PVM pVM, PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, PDISCPUSTATE pDis,
976 pgmPoolMonitorModifiedInsert(pPool, pPage);
987 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, pvFault, cbWrite);
991 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, pvFault, 8);
992 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault + 8, pvFault + 8, cbWrite - 8);
1010 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,EmulateInstr));
1034 STAM_COUNTER_INC(&pPool->StatForceFlushReused);
1063 STAM_PROFILE_START(&pVM->pgm.s.CTX_SUFF(pPool)->CTX_SUFF_Z(StatMonitor), a);
1064 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
1078 STAM_PROFILE_STOP_EX(&pVM->pgm.s.CTX_SUFF(pPool)->CTX_SUFF_Z(StatMonitor), &pPool->CTX_MID_Z(StatMonitor,Handled), a);
1094 void *pvShw = PGMPOOL_PAGE_2_PTR(pPool->CTX_SUFF(pVM), pPage);
1096 int rc = PGM_GCPHYS_2_PTR(pPool->CTX_SUFF(pVM), pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
1097 pgmPoolTrackCheckPTPaePae(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PTPAE)pvGst);
1151 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FlushReinit));
1168 && !pgmPoolMonitorIsForking(pPool, pDis, GCPhysFault & PAGE_OFFSET_MASK))
1175 rc = pgmPoolAccessHandlerSimple(pVM, pVCpu, pPool, pPage, pDis, pRegFrame, GCPhysFault, pvFault, &fReused);
1205 STAM_PROFILE_STOP_EX(&pVM->pgm.s.CTX_SUFF(pPool)->CTX_SUFF_Z(StatMonitor), &pPool->CTX_MID_Z(StatMonitor,Handled), a);
1246 rc = pgmPoolAccessHandlerSTOSD(pVM, pPool, pPage, pDis, pRegFrame, GCPhysFault, pvFault);
1247 STAM_PROFILE_STOP_EX(&pVM->pgm.s.CTX_SUFF(pPool)->CTX_SUFF_Z(StatMonitor), &pPool->CTX_MID_Z(StatMonitor,RepStosd), a);
1254 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,RepPrefix));
1269 && !pgmPoolMonitorIsForking(pPool, pDis, GCPhysFault & PAGE_OFFSET_MASK))
1284 pPageHead = &pPool->aPages[pPageHead->iMonitoredPrev];
1292 STAM_COUNTER_INC(&pPool->StatDirtyPageDupFlush);
1294 int rc2 = pgmPoolFlushPage(pPool, pPageHead);
1301 pPageHead = &pPool->aPages[idxNext];
1309 pgmPoolAddDirtyPage(pVM, pPool, pPage);
1325 STAM_PROFILE_STOP(&pVM->pgm.s.CTX_SUFF(pPool)->CTX_SUFF_Z(StatMonitor), a);
1333 STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FlushModOverflow));
1343 rc = pgmPoolAccessHandlerFlush(pVM, pVCpu, pPool, pPage, pDis, pRegFrame, GCPhysFault, pvFault);
1351 STAM_PROFILE_STOP_EX(&pVM->pgm.s.CTX_SUFF(pPool)->CTX_SUFF_Z(StatMonitor), &pPool->CTX_MID_Z(StatMonitor,FlushPage), a);
1365 * @param pPool The pool.
1370 static void pgmPoolTrackCheckPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PTPAE pGstPT)
1376 PVM pVM = pPool->CTX_SUFF(pVM);
1401 for (unsigned iPage = 0; iPage < pPool->cCurPages; iPage++)
1403 PPGMPOOLPAGE pTempPage = &pPool->aPages[iPage];
1431 * @param pPool The pool.
1436 static void pgmPoolTrackCheckPTPae32Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PT pGstPT)
1442 PVM pVM = pPool->CTX_SUFF(pVM);
1467 for (unsigned iPage = 0; iPage < pPool->cCurPages; iPage++)
1469 PPGMPOOLPAGE pTempPage = &pPool->aPages[iPage];
1499 * @param pPool The pool.
1507 DECLINLINE(unsigned) pgmPoolTrackFlushPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PTPAE pGstPT,
1526 if (!PGMPhysIsGCPhysValid(pPool->CTX_SUFF(pVM), pGstPT->a[i].u & X86_PTE_PAE_PG_MASK))
1539 int rc = PGMPhysGCPhys2HCPhys(pPool->CTX_SUFF(pVM), pGstPT->a[i].u & X86_PTE_PAE_PG_MASK, &HCPhys);
1555 pgmPoolTracDerefGCPhysHint(pPool, pPage, PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]), pOldGstPT->a[i].u & X86_PTE_PAE_PG_MASK, i);
1567 * @param pPool The pool.
1575 DECLINLINE(unsigned) pgmPoolTrackFlushPTPae32Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PT pGstPT,
1594 if (!PGMPhysIsGCPhysValid(pPool->CTX_SUFF(pVM), pGstPT->a[i].u & X86_PTE_PG_MASK))
1607 int rc = PGMPhysGCPhys2HCPhys(pPool->CTX_SUFF(pVM), pGstPT->a[i].u & X86_PTE_PG_MASK, &HCPhys);
1623 pgmPoolTracDerefGCPhysHint(pPool, pPage, PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]), pOldGstPT->a[i].u & X86_PTE_PG_MASK, i);
1635 * @param pPool The pool.
1639 static void pgmPoolFlushDirtyPage(PVM pVM, PPGMPOOL pPool, unsigned idxSlot, bool fAllowRemoval = false)
1644 Assert(idxSlot < RT_ELEMENTS(pPool->aDirtyPages));
1645 if (pPool->aDirtyPages[idxSlot].uIdx == NIL_PGMPOOL_IDX)
1648 idxPage = pPool->aDirtyPages[idxSlot].uIdx;
1650 pPage = &pPool->aPages[idxPage];
1680 STAM_PROFILE_START(&pPool->StatTrackDeref,a);
1688 cChanges = pgmPoolTrackFlushPTPaePae(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PTPAE)pvGst,
1689 (PCX86PTPAE)&pPool->aDirtyPages[idxSlot].aPage[0], fAllowRemoval, &fFlush);
1691 cChanges = pgmPoolTrackFlushPTPae32Bit(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PT)pvGst,
1692 (PCX86PT)&pPool->aDirtyPages[idxSlot].aPage[0], fAllowRemoval, &fFlush);
1696 STAM_PROFILE_STOP(&pPool->StatTrackDeref,a);
1706 STAM_COUNTER_INC(&pPool->StatResetDirtyPages);
1707 if (pPool->cDirtyPages == RT_ELEMENTS(pPool->aDirtyPages))
1708 pPool->idxFreeDirtyPage = idxSlot;
1710 pPool->cDirtyPages--;
1711 pPool->aDirtyPages[idxSlot].uIdx = NIL_PGMPOOL_IDX;
1712 Assert(pPool->cDirtyPages <= RT_ELEMENTS(pPool->aDirtyPages));
1717 pgmPoolFlushPage(pPool, pPage);
1718 STAM_COUNTER_INC(&pPool->StatForceFlushReused);
1734 * @param pPool The pool.
1737 void pgmPoolAddDirtyPage(PVM pVM, PPGMPOOL pPool, PPGMPOOLPAGE pPage)
1742 AssertCompile(RT_ELEMENTS(pPool->aDirtyPages) == 8 || RT_ELEMENTS(pPool->aDirtyPages) == 16);
1745 idxFree = pPool->idxFreeDirtyPage;
1746 Assert(idxFree < RT_ELEMENTS(pPool->aDirtyPages));
1749 if (pPool->cDirtyPages >= RT_ELEMENTS(pPool->aDirtyPages))
1751 STAM_COUNTER_INC(&pPool->StatDirtyPageOverFlowFlush);
1752 pgmPoolFlushDirtyPage(pVM, pPool, idxFree, true /* allow removal of reused page tables*/);
1754 Assert(pPool->cDirtyPages < RT_ELEMENTS(pPool->aDirtyPages));
1755 AssertMsg(pPool->aDirtyPages[idxFree].uIdx == NIL_PGMPOOL_IDX, ("idxFree=%d cDirtyPages=%d\n", idxFree, pPool->cDirtyPages));
1766 memcpy(&pPool->aDirtyPages[idxFree].aPage[0], pvGst, (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT) ? PAGE_SIZE : PAGE_SIZE/2);
1770 pgmPoolTrackCheckPTPaePae(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PTPAE)pvGst);
1772 pgmPoolTrackCheckPTPae32Bit(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PT)pvGst);
1777 STAM_COUNTER_INC(&pPool->StatDirtyPage);
1780 pPool->aDirtyPages[idxFree].uIdx = pPage->idx;
1781 pPool->cDirtyPages++;
1783 pPool->idxFreeDirtyPage = (pPool->idxFreeDirtyPage + 1) & (RT_ELEMENTS(pPool->aDirtyPages) - 1);
1784 if ( pPool->cDirtyPages < RT_ELEMENTS(pPool->aDirtyPages)
1785 && pPool->aDirtyPages[pPool->idxFreeDirtyPage].uIdx != NIL_PGMPOOL_IDX)
1788 for (i = 1; i < RT_ELEMENTS(pPool->aDirtyPages); i++)
1790 idxFree = (pPool->idxFreeDirtyPage + i) & (RT_ELEMENTS(pPool->aDirtyPages) - 1);
1791 if (pPool->aDirtyPages[idxFree].uIdx == NIL_PGMPOOL_IDX)
1793 pPool->idxFreeDirtyPage = idxFree;
1797 Assert(i != RT_ELEMENTS(pPool->aDirtyPages));
1800 Assert(pPool->cDirtyPages == RT_ELEMENTS(pPool->aDirtyPages) || pPool->aDirtyPages[pPool->idxFreeDirtyPage].uIdx == NIL_PGMPOOL_IDX);
1805 pgmPoolTrackClearPageUsers(pPool, pPage);
1819 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
1821 if (!pPool->cDirtyPages)
1826 for (unsigned i = 0; i < RT_ELEMENTS(pPool->aDirtyPages); i++)
1828 if (pPool->aDirtyPages[i].uIdx != NIL_PGMPOOL_IDX)
1831 unsigned idxPage = pPool->aDirtyPages[i].uIdx;
1833 pPage = &pPool->aPages[idxPage];
1849 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
1851 Assert(pPool->cDirtyPages <= RT_ELEMENTS(pPool->aDirtyPages));
1853 if (!pPool->cDirtyPages)
1857 for (unsigned i = 0; i < RT_ELEMENTS(pPool->aDirtyPages); i++)
1858 pgmPoolFlushDirtyPage(pVM, pPool, i, true /* allow removal of reused page tables*/);
1860 pPool->idxFreeDirtyPage = 0;
1861 if ( pPool->cDirtyPages != RT_ELEMENTS(pPool->aDirtyPages)
1862 && pPool->aDirtyPages[pPool->idxFreeDirtyPage].uIdx != NIL_PGMPOOL_IDX)
1865 for (i = 1; i < RT_ELEMENTS(pPool->aDirtyPages); i++)
1867 if (pPool->aDirtyPages[i].uIdx == NIL_PGMPOOL_IDX)
1869 pPool->idxFreeDirtyPage = i;
1873 AssertMsg(i != RT_ELEMENTS(pPool->aDirtyPages), ("cDirtyPages %d", pPool->cDirtyPages));
1876 Assert(pPool->aDirtyPages[pPool->idxFreeDirtyPage].uIdx == NIL_PGMPOOL_IDX || pPool->cDirtyPages == RT_ELEMENTS(pPool->aDirtyPages));
1889 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
1891 Assert(pPool->cDirtyPages <= RT_ELEMENTS(pPool->aDirtyPages));
1893 if (!pPool->cDirtyPages)
1897 for (unsigned i = 0; i < RT_ELEMENTS(pPool->aDirtyPages); i++)
1911 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
1913 Assert(pPool->cDirtyPages <= RT_ELEMENTS(pPool->aDirtyPages));
1914 unsigned idxDirtyPage = RT_ELEMENTS(pPool->aDirtyPages);
1916 if (!pPool->cDirtyPages)
1921 for (unsigned i = 0; i < RT_ELEMENTS(pPool->aDirtyPages); i++)
1923 if (pPool->aDirtyPages[i].uIdx != NIL_PGMPOOL_IDX)
1925 unsigned idxPage = pPool->aDirtyPages[i].uIdx;
1927 PPGMPOOLPAGE pPage = &pPool->aPages[idxPage];
1936 if (idxDirtyPage != RT_ELEMENTS(pPool->aDirtyPages))
1938 pgmPoolFlushDirtyPage(pVM, pPool, idxDirtyPage, true /* allow removal of reused page tables*/);
1939 if ( pPool->cDirtyPages != RT_ELEMENTS(pPool->aDirtyPages)
1940 && pPool->aDirtyPages[pPool->idxFreeDirtyPage].uIdx != NIL_PGMPOOL_IDX)
1943 for (i = 0; i < RT_ELEMENTS(pPool->aDirtyPages); i++)
1945 if (pPool->aDirtyPages[i].uIdx == NIL_PGMPOOL_IDX)
1947 pPool->idxFreeDirtyPage = i;
1951 AssertMsg(i != RT_ELEMENTS(pPool->aDirtyPages), ("cDirtyPages %d", pPool->cDirtyPages));
1961 * @param pPool The pool.
1964 DECLINLINE(void) pgmPoolHashInsert(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
1969 pPage->iNext = pPool->aiHash[iHash];
1970 pPool->aiHash[iHash] = pPage->idx;
1977 * @param pPool The pool.
1980 DECLINLINE(void) pgmPoolHashRemove(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
1984 if (pPool->aiHash[iHash] == pPage->idx)
1985 pPool->aiHash[iHash] = pPage->iNext;
1988 uint16_t iPrev = pPool->aiHash[iHash];
1991 const int16_t i = pPool->aPages[iPrev].iNext;
1994 pPool->aPages[iPrev].iNext = pPage->iNext;
2014 * @param pPool The pool.
2017 static int pgmPoolCacheFreeOne(PPGMPOOL pPool, uint16_t iUser)
2020 const PVM pVM = pPool->CTX_SUFF(pVM);
2022 Assert(pPool->iAgeHead != pPool->iAgeTail); /* We shouldn't be here if there < 2 cached entries! */
2023 STAM_COUNTER_INC(&pPool->StatCacheFreeUpOne);
2031 uint16_t iToFree = pPool->iAgeTail;
2033 iToFree = pPool->aPages[iToFree].iAgePrev;
2035 if (pPool->aPages[iToFree].iUserHead != NIL_PGMPOOL_USER_INDEX)
2037 uint16_t i = pPool->aPages[iToFree].iAgePrev;
2038 for (unsigned j = 0; j < 10 && i != NIL_PGMPOOL_USER_INDEX; j++, i = pPool->aPages[i].iAgePrev)
2040 if (pPool->aPages[iToFree].iUserHead == NIL_PGMPOOL_USER_INDEX)
2049 pPage = &pPool->aPages[iToFree];
2059 pgmPoolCacheUsed(pPool, pPage);
2066 int rc = pgmPoolFlushPage(pPool, pPage);
2186 * @param pPool The pool.
2197 static int pgmPoolCacheAlloc(PPGMPOOL pPool, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, PGMPOOLACCESS enmAccess, bool fA20Enabled,
2203 unsigned i = pPool->aiHash[PGMPOOL_HASH(GCPhys)];
2209 PPGMPOOLPAGE pPage = &pPool->aPages[i];
2220 pgmPoolCacheUsed(pPool, pPage);
2224 rc = pgmPoolTrackAddUser(pPool, pPage, iUser, iUserTable);
2231 STAM_COUNTER_INC(&pPool->StatCacheHits);
2247 STAM_COUNTER_INC(&pPool->StatCacheKindMismatches);
2248 pgmPoolFlushPage(pPool, pPage);
2260 STAM_COUNTER_INC(&pPool->StatCacheMisses);
2268 * @param pPool The pool.
2272 static void pgmPoolCacheInsert(PPGMPOOL pPool, PPGMPOOLPAGE pPage, bool fCanBeCached)
2281 pgmPoolHashInsert(pPool, pPage);
2284 STAM_COUNTER_INC(&pPool->StatCacheCacheable);
2290 STAM_COUNTER_INC(&pPool->StatCacheUncacheable);
2297 pPage->iAgeNext = pPool->iAgeHead;
2298 if (pPool->iAgeHead != NIL_PGMPOOL_IDX)
2299 pPool->aPages[pPool->iAgeHead].iAgePrev = pPage->idx;
2301 pPool->iAgeTail = pPage->idx;
2302 pPool->iAgeHead = pPage->idx;
2309 * @param pPool The pool.
2312 static void pgmPoolCacheFlushPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
2322 pgmPoolHashRemove(pPool, pPage);
2331 pPool->aPages[pPage->iAgeNext].iAgePrev = pPage->iAgePrev;
2333 pPool->iAgeTail = pPage->iAgePrev;
2335 pPool->aPages[pPage->iAgePrev].iAgeNext = pPage->iAgeNext;
2337 pPool->iAgeHead = pPage->iAgeNext;
2348 * @param pPool The Pool
2351 static PPGMPOOLPAGE pgmPoolMonitorGetPageByGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pNewPage)
2357 unsigned i = pPool->aiHash[PGMPOOL_HASH(GCPhys)];
2362 PPGMPOOLPAGE pPage = &pPool->aPages[i];
2386 pPage = &pPool->aPages[pPage->iMonitoredPrev];
2425 * @param pPool The pool.
2428 static int pgmPoolMonitorInsert(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
2480 PPGMPOOLPAGE pPageHead = pgmPoolMonitorGetPageByGCPhys(pPool, pPage);
2488 pgmPoolFlushDirtyPage(pPool->CTX_SUFF(pVM), pPool, pPageHead->idxDirtyEntry, false /* do not remove */);
2494 pPool->aPages[pPageHead->iMonitoredNext].iMonitoredPrev = pPage->idx;
2501 PVM pVM = pPool->CTX_SUFF(pVM);
2505 pPool->pfnAccessHandlerR3, MMHyperCCToR3(pVM, pPage),
2506 pPool->pfnAccessHandlerR0, MMHyperCCToR0(pVM, pPage),
2507 pPool->pfnAccessHandlerRC, MMHyperCCToRC(pVM, pPage),
2508 pPool->pszAccessHandler);
2525 * @param pPool The pool.
2528 static int pgmPoolMonitorFlush(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
2576 const PVM pVM = pPool->CTX_SUFF(pVM);
2583 PPGMPOOLPAGE pNewHead = &pPool->aPages[pPage->iMonitoredNext];
2593 pPool->aPages[pPage->iMonitoredPrev].iMonitoredNext = pPage->iMonitoredNext;
2596 pPool->aPages[pPage->iMonitoredNext].iMonitoredPrev = pPage->iMonitoredPrev;
2616 pgmPoolMonitorModifiedRemove(pPool, pPage);
2625 * @param pPool The pool.
2628 void pgmPoolMonitorModifiedInsert(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
2633 && pPool->iModifiedHead != pPage->idx,
2636 pPool->iModifiedHead, pPool->cModifiedPages));
2638 pPage->iModifiedNext = pPool->iModifiedHead;
2639 if (pPool->iModifiedHead != NIL_PGMPOOL_IDX)
2640 pPool->aPages[pPool->iModifiedHead].iModifiedPrev = pPage->idx;
2641 pPool->iModifiedHead = pPage->idx;
2642 pPool->cModifiedPages++;
2644 if (pPool->cModifiedPages > pPool->cModifiedPagesHigh)
2645 pPool->cModifiedPagesHigh = pPool->cModifiedPages;
2654 * @param pPool The pool.
2657 static void pgmPoolMonitorModifiedRemove(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
2660 if (pPool->iModifiedHead == pPage->idx)
2663 pPool->iModifiedHead = pPage->iModifiedNext;
2666 pPool->aPages[pPage->iModifiedNext].iModifiedPrev = NIL_PGMPOOL_IDX;
2669 pPool->cModifiedPages--;
2673 pPool->aPages[pPage->iModifiedPrev].iModifiedNext = pPage->iModifiedNext;
2676 pPool->aPages[pPage->iModifiedNext].iModifiedPrev = pPage->iModifiedPrev;
2680 pPool->cModifiedPages--;
2696 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
2697 LogFlow(("pgmPoolMonitorModifiedClearAll: cModifiedPages=%d\n", pPool->cModifiedPages));
2705 uint16_t idx = pPool->iModifiedHead;
2706 pPool->iModifiedHead = NIL_PGMPOOL_IDX;
2709 PPGMPOOLPAGE pPage = &pPool->aPages[idx];
2716 AssertMsg(cPages == pPool->cModifiedPages, ("%d != %d\n", cPages, pPool->cModifiedPages));
2717 pPool->cModifiedPages = 0;
2782 * @param pPool The pool.
2785 static int pgmPoolTrackFreeOneUser(PPGMPOOL pPool, uint16_t iUser)
2787 STAM_COUNTER_INC(&pPool->StatTrackFreeUpOneUser);
2795 int rc2 = pgmPoolCacheFreeOne(pPool, iUser);
2798 } while (pPool->iUserFreeHead == NIL_PGMPOOL_USER_INDEX);
2812 * @param pPool The pool.
2818 DECLINLINE(int) pgmPoolTrackInsert(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTGCPHYS GCPhys, uint16_t iUser, uint32_t iUserTable)
2821 PPGMPOOLUSER paUsers = pPool->CTX_SUFF(paUsers);
2836 Assert(i < pPool->cMaxUsers);
2846 uint16_t i = pPool->iUserFreeHead;
2849 rc = pgmPoolTrackFreeOneUser(pPool, iUser);
2852 i = pPool->iUserFreeHead;
2859 pPool->iUserFreeHead = paUsers[i].iNext;
2882 pgmPoolCacheInsert(pPool, pPage, fCanBeMonitored); /* This can be expanded. */
2885 rc = pgmPoolMonitorInsert(pPool, pPage);
2900 * @param pPool The pool.
2905 static int pgmPoolTrackAddUser(PPGMPOOL pPool, PPGMPOOLPAGE pPage, uint16_t iUser, uint32_t iUserTable)
2908 PPGMPOOLUSER paUsers = pPool->CTX_SUFF(paUsers);
2921 Assert(i < pPool->cMaxUsers);
2932 uint16_t i = pPool->iUserFreeHead;
2935 int rc = pgmPoolTrackFreeOneUser(pPool, iUser);
2938 i = pPool->iUserFreeHead;
2940 pPool->iUserFreeHead = paUsers[i].iNext;
2952 pgmPoolFlushDirtyPage(pPool->CTX_SUFF(pVM), pPool, pPage->idxDirtyEntry, false /* do not remove */);
2958 pgmPoolCacheUsed(pPool, pPage);
2969 * @param pPool The pool.
2976 static void pgmPoolTrackFreeUser(PPGMPOOL pPool, PPGMPOOLPAGE pPage, uint16_t iUser, uint32_t iUserTable)
2979 PPGMPOOLUSER paUsers = pPool->CTX_SUFF(paUsers);
2995 paUsers[i].iNext = pPool->iUserFreeHead;
2996 pPool->iUserFreeHead = i;
3013 paUsers[i].iNext = pPool->iUserFreeHead;
3014 pPool->iUserFreeHead = i;
3145 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
3152 AssertFatalMsg(iShw < pPool->cCurPages && iShw != NIL_PGMPOOL_IDX, ("iShw=%d\n", iShw));
3153 PPGMPOOLPAGE pPage = &pPool->aPages[iShw];
3178 STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
3185 STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
3189 STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
3194 STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
3200 Assert(pPool->cPresent);
3202 pPool->cPresent--;
3252 STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
3259 STAM_COUNTER_INC(&pPool->StatTrackFlushEntryKeep);
3264 STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
3269 STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
3275 Assert(pPool->cPresent);
3277 pPool->cPresent--;
3317 STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
3323 Assert(pPool->cPresent);
3325 pPool->cPresent--;
3351 STAM_COUNTER_INC(&pPool->StatTrackFlushEntry);
3357 Assert(pPool->cPresent);
3359 pPool->cPresent--;
3395 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool); NOREF(pPool);
3401 STAM_PROFILE_START(&pPool->StatTrackFlushGCPhysPT, f);
3405 STAM_PROFILE_STOP(&pPool->StatTrackFlushGCPhysPT, f);
3420 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
3423 STAM_PROFILE_START(&pPool->StatTrackFlushGCPhysPTs, f);
3430 Assert(iPhysExt < pPool->cMaxPhysExts);
3431 pPhysExt = &pPool->CTX_SUFF(paPhysExts)[iPhysExt];
3453 pPhysExt->iNext = pPool->iPhysExtFreeHead;
3454 pPool->iPhysExtFreeHead = iPhysExtStart;
3459 STAM_PROFILE_STOP(&pPool->StatTrackFlushGCPhysPTs, f);
3593 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
3594 STAM_PROFILE_START(&pPool->StatTrackFlushGCPhysPTsSlow, s);
3596 pPool->cUsedPages, pPool->cPresent, pPhysPage));
3601 if ( pPool->cPresent > 1024
3604 LogFlow(("pgmPoolTrackFlushGCPhysPTsSlow: giving up... (cPresent=%d)\n", pPool->cPresent));
3605 STAM_PROFILE_STOP(&pPool->StatTrackFlushGCPhysPTsSlow, s);
3615 unsigned cLeft = pPool->cUsedPages;
3616 unsigned iPage = pPool->cCurPages;
3619 PPGMPOOLPAGE pPage = &pPool->aPages[iPage];
3644 Assert(pPool->cPresent);
3646 pPool->cPresent--;
3673 Assert(pPool->cPresent);
3675 pPool->cPresent--;
3698 Assert(pPool->cPresent);
3700 pPool->cPresent--;
3716 STAM_PROFILE_STOP(&pPool->StatTrackFlushGCPhysPTsSlow, s);
3721 if (pPool->cPresent > 1024)
3723 LogFlow(("pgmPoolTrackFlushGCPhysPTsSlow: giving up... (cPresent=%d)\n", pPool->cPresent));
3736 static void pgmPoolTrackClearPageUser(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PCPGMPOOLUSER pUser)
3739 Assert(pUser->iUser < pPool->cCurPages);
3745 PPGMPOOLPAGE pUserPage = &pPool->aPages[pUser->iUser];
3757 u.pau64 = (uint64_t *)PGMPOOL_PAGE_2_PTR(pPool->CTX_SUFF(pVM), pUserPage);
3863 PGM_DYNMAP_UNUSED_HINT_VM(pPool->CTX_SUFF(pVM), u.pau64);
3870 static void pgmPoolTrackClearPageUsers(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
3877 PPGMPOOLUSER paUsers = pPool->CTX_SUFF(paUsers);
3882 pgmPoolTrackClearPageUser(pPool, pPage, &paUsers[i]);
3887 paUsers[i].iNext = pPool->iUserFreeHead;
3888 pPool->iUserFreeHead = i;
3907 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
3908 uint16_t iPhysExt = pPool->iPhysExtFreeHead;
3911 STAM_COUNTER_INC(&pPool->StamTrackPhysExtAllocFailures);
3914 PPGMPOOLPHYSEXT pPhysExt = &pPool->CTX_SUFF(paPhysExts)[iPhysExt];
3915 pPool->iPhysExtFreeHead = pPhysExt->iNext;
3931 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
3932 Assert(iPhysExt < pPool->cMaxPhysExts);
3933 PPGMPOOLPHYSEXT pPhysExt = &pPool->CTX_SUFF(paPhysExts)[iPhysExt];
3939 pPhysExt->iNext = pPool->iPhysExtFreeHead;
3940 pPool->iPhysExtFreeHead = iPhysExt;
3953 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
3959 Assert(iPhysExt < pPool->cMaxPhysExts);
3960 pPhysExt = &pPool->CTX_SUFF(paPhysExts)[iPhysExt];
3971 pPhysExt->iNext = pPool->iPhysExtFreeHead;
3972 pPool->iPhysExtFreeHead = iPhysExtStart;
3990 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
3991 PPGMPOOLPHYSEXT paPhysExts = pPool->CTX_SUFF(paPhysExts);
4021 Assert(iPhysExt < pPool->cMaxPhysExts);
4116 * @param pPool The pool.
4121 void pgmPoolTrackPhysExtDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMPAGE pPhysPage, uint16_t iPte)
4123 PVM pVM = pPool->CTX_SUFF(pVM);
4133 PPGMPOOLPHYSEXT paPhysExts = pPool->CTX_SUFF(paPhysExts);
4136 Assert(iPhysExt < pPool->cMaxPhysExts);
4206 * @param pPool The pool.
4212 static void pgmPoolTracDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTHCPHYS HCPhys, RTGCPHYS GCPhys, uint16_t iPte)
4217 PVM pVM = pPool->CTX_SUFF(pVM);
4229 Assert(pPool->cPresent);
4231 pPool->cPresent--;
4232 pgmTrackDerefGCPhys(pPool, pPage, pPhysPage, iPte);
4246 * @param pPool The pool.
4252 void pgmPoolTracDerefGCPhysHint(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTHCPHYS HCPhys, RTGCPHYS GCPhysHint, uint16_t iPte)
4260 PVM pVM = pPool->CTX_SUFF(pVM);
4269 Assert(pPool->cPresent);
4271 pPool->cPresent--;
4272 pgmTrackDerefGCPhys(pPool, pPage, pPhysPage, iPte);
4282 STAM_COUNTER_INC(&pPool->StatTrackLinearRamSearches);
4283 PPGMRAMRANGE pRam = pPool->CTX_SUFF(pVM)->pgm.s.CTX_SUFF(pRamRangesX);
4294 Assert(pPool->cPresent);
4296 pPool->cPresent--;
4297 pgmTrackDerefGCPhys(pPool, pPage, &pRam->aPages[iPage], iPte);
4311 * @param pPool The pool.
4316 DECLINLINE(void) pgmPoolTrackDerefPT32Bit32Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PT pShwPT, PCX86PT pGstPT)
4326 pgmPoolTracDerefGCPhysHint(pPool, pPage, pShwPT->a[i].u & X86_PTE_PG_MASK, pGstPT->a[i].u & fPgMask, i);
4337 * @param pPool The pool.
4342 DECLINLINE(void) pgmPoolTrackDerefPTPae32Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PT pGstPT)
4353 pgmPoolTracDerefGCPhysHint(pPool, pPage, PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]), pGstPT->a[i].u & fPgMask, i);
4364 * @param pPool The pool.
4369 DECLINLINE(void) pgmPoolTrackDerefPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PTPAE pGstPT)
4380 pgmPoolTracDerefGCPhysHint(pPool, pPage, PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]), pGstPT->a[i].u & fPgMask, i);
4391 * @param pPool The pool.
4395 DECLINLINE(void) pgmPoolTrackDerefPT32Bit4MB(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PT pShwPT)
4406 pgmPoolTracDerefGCPhys(pPool, pPage, pShwPT->a[i].u & X86_PTE_PG_MASK, GCPhys & GCPhysA20Mask, i);
4417 * @param pPool The pool.
4421 DECLINLINE(void) pgmPoolTrackDerefPTPaeBig(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT)
4433 pgmPoolTracDerefGCPhys(pPool, pPage, PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]), GCPhys & GCPhysA20Mask, i);
4444 * @param pPool The pool.
4448 DECLINLINE(void) pgmPoolTrackDerefPTEPT(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PEPTPT pShwPT)
4459 pgmPoolTracDerefGCPhys(pPool, pPage, pShwPT->a[i].u & EPT_PTE_PG_MASK, GCPhys & GCPhysA20Mask, i);
4470 * @param pPool The pool.
4474 DECLINLINE(void) pgmPoolTrackDerefPD(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PD pShwPD)
4483 PPGMPOOLPAGE pSubPage = (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, pShwPD->a[i].u & X86_PDE_PG_MASK);
4485 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4496 * @param pPool The pool.
4500 DECLINLINE(void) pgmPoolTrackDerefPDPae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PDPAE pShwPD)
4512 pgmPoolTracDerefGCPhys(pPool, pPage, pShwPD->a[i].u & X86_PDE2M_PAE_PG_MASK,
4520 PPGMPOOLPAGE pSubPage = (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, pShwPD->a[i].u & X86_PDE_PAE_PG_MASK);
4522 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4535 * @param pPool The pool.
4539 DECLINLINE(void) pgmPoolTrackDerefPDPTPae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PDPT pShwPDPT)
4548 PPGMPOOLPAGE pSubPage = (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, pShwPDPT->a[i].u & X86_PDPE_PG_MASK);
4550 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4561 * @param pPool The pool.
4565 DECLINLINE(void) pgmPoolTrackDerefPDPT64Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PDPT pShwPDPT)
4572 PPGMPOOLPAGE pSubPage = (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, pShwPDPT->a[i].u & X86_PDPE_PG_MASK);
4574 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4586 * @param pPool The pool.
4590 DECLINLINE(void) pgmPoolTrackDerefPML464Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PML4 pShwPML4)
4597 PPGMPOOLPAGE pSubPage = (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, pShwPML4->a[i].u & X86_PDPE_PG_MASK);
4599 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4611 * @param pPool The pool.
4615 DECLINLINE(void) pgmPoolTrackDerefPDEPT(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PEPTPD pShwPD)
4627 pgmPoolTracDerefGCPhys(pPool, pPage, pShwPD->a[i].u & X86_PDE2M_PAE_PG_MASK,
4634 PPGMPOOLPAGE pSubPage = (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, pShwPD->a[i].u & EPT_PDE_PG_MASK);
4636 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4649 * @param pPool The pool.
4653 DECLINLINE(void) pgmPoolTrackDerefPDPTEPT(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PEPTPDPT pShwPDPT)
4660 PPGMPOOLPAGE pSubPage = (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, pShwPDPT->a[i].u & EPT_PDPTE_PG_MASK);
4662 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4676 * @param pPool The pool.
4679 static void pgmPoolTrackDeref(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
4684 PVM pVM = pPool->CTX_SUFF(pVM);
4690 STAM_PROFILE_START(&pPool->StatTrackDerefGCPhys, g);
4693 pgmPoolTrackDerefPT32Bit32Bit(pPool, pPage, (PX86PT)pvShw, (PCX86PT)pvGst);
4695 STAM_PROFILE_STOP(&pPool->StatTrackDerefGCPhys, g);
4701 STAM_PROFILE_START(&pPool->StatTrackDerefGCPhys, g);
4704 pgmPoolTrackDerefPTPae32Bit(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PT)pvGst);
4706 STAM_PROFILE_STOP(&pPool->StatTrackDerefGCPhys, g);
4712 STAM_PROFILE_START(&pPool->StatTrackDerefGCPhys, g);
4715 pgmPoolTrackDerefPTPaePae(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PTPAE)pvGst);
4717 STAM_PROFILE_STOP(&pPool->StatTrackDerefGCPhys, g);
4724 STAM_PROFILE_START(&pPool->StatTrackDerefGCPhys, g);
4725 pgmPoolTrackDerefPT32Bit4MB(pPool, pPage, (PX86PT)pvShw);
4726 STAM_PROFILE_STOP(&pPool->StatTrackDerefGCPhys, g);
4734 STAM_PROFILE_START(&pPool->StatTrackDerefGCPhys, g);
4735 pgmPoolTrackDerefPTPaeBig(pPool, pPage, (PPGMSHWPTPAE)pvShw);
4736 STAM_PROFILE_STOP(&pPool->StatTrackDerefGCPhys, g);
4748 pgmPoolTrackDerefPDPae(pPool, pPage, (PX86PDPAE)pvShw);
4753 pgmPoolTrackDerefPD(pPool, pPage, (PX86PD)pvShw);
4759 pgmPoolTrackDerefPDPTPae(pPool, pPage, (PX86PDPT)pvShw);
4764 pgmPoolTrackDerefPDPT64Bit(pPool, pPage, (PX86PDPT)pvShw);
4768 pgmPoolTrackDerefPML464Bit(pPool, pPage, (PX86PML4)pvShw);
4772 pgmPoolTrackDerefPTEPT(pPool, pPage, (PEPTPT)pvShw);
4776 pgmPoolTrackDerefPDEPT(pPool, pPage, (PEPTPD)pvShw);
4780 pgmPoolTrackDerefPDPTEPT(pPool, pPage, (PEPTPDPT)pvShw);
4788 STAM_PROFILE_START(&pPool->StatZeroPage, z);
4790 STAM_PROFILE_STOP(&pPool->StatZeroPage, z);
4804 * @param pPool The pool.
4808 int pgmPoolFlushPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage, bool fFlush)
4810 PVM pVM = pPool->CTX_SUFF(pVM);
4814 STAM_PROFILE_START(&pPool->StatFlushPage, f);
4863 pgmPoolFlushDirtyPage(pVM, pPool, pPage->idxDirtyEntry, false /* do not remove */);
4873 pgmPoolTrackClearPageUsers(pPool, pPage);
4874 STAM_PROFILE_START(&pPool->StatTrackDeref,a);
4875 pgmPoolTrackDeref(pPool, pPage);
4876 STAM_PROFILE_STOP(&pPool->StatTrackDeref,a);
4881 pgmPoolCacheFlushPage(pPool, pPage);
4892 rc = pgmPoolMonitorFlush(pPool, pPage);
4898 pPage->iNext = pPool->iFreeHead;
4899 pPool->iFreeHead = pPage->idx;
4905 pPool->cUsedPages--;
4915 STAM_PROFILE_STOP(&pPool->StatFlushPage, f);
4926 * @param pPool The pool.
4933 void pgmPoolFreeByPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage, uint16_t iUser, uint32_t iUserTable)
4935 PVM pVM = pPool->CTX_SUFF(pVM);
4937 STAM_PROFILE_START(&pPool->StatFree, a);
4944 pgmPoolTrackFreeUser(pPool, pPage, iUser, iUserTable);
4946 pgmPoolFlushPage(pPool, pPage);
4948 STAM_PROFILE_STOP(&pPool->StatFree, a);
4959 * @param pPool The pool.
4963 static int pgmPoolMakeMoreFreePages(PPGMPOOL pPool, PGMPOOLKIND enmKind, uint16_t iUser)
4965 PVM pVM = pPool->CTX_SUFF(pVM);
4972 if ( pPool->cCurPages < pPool->cMaxPages
4980 STAM_PROFILE_ADV_SUSPEND(&pPool->StatAlloc, a);
4988 STAM_PROFILE_ADV_RESUME(&pPool->StatAlloc, a);
4989 if (pPool->iFreeHead != NIL_PGMPOOL_IDX)
4996 return pgmPoolCacheFreeOne(pPool, iUser);
5028 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
5029 STAM_PROFILE_ADV_START(&pPool->StatAlloc, a);
5038 if (pPool->fCacheEnabled)
5040 int rc2 = pgmPoolCacheAlloc(pPool, GCPhys, enmKind, enmAccess, fA20Enabled, iUser, iUserTable, ppPage);
5044 pgmPoolLockPage(pPool, *ppPage);
5046 STAM_PROFILE_ADV_STOP(&pPool->StatAlloc, a);
5056 uint16_t iNew = pPool->iFreeHead;
5059 rc = pgmPoolMakeMoreFreePages(pPool, enmKind, iUser);
5064 STAM_PROFILE_ADV_STOP(&pPool->StatAlloc, a);
5067 iNew = pPool->iFreeHead;
5072 PPGMPOOLPAGE pPage = &pPool->aPages[iNew];
5073 pPool->iFreeHead = pPage->iNext;
5079 pPool->cUsedPages++; /* physical handler registration / pgmPoolTrackFlushGCPhysPTsSlow requirement. */
5106 int rc3 = pgmPoolTrackInsert(pPool, pPage, GCPhys, iUser, iUserTable);
5109 pPool->cUsedPages--;
5113 pPage->iNext = pPool->iFreeHead;
5114 pPool->iFreeHead = pPage->idx;
5116 STAM_PROFILE_ADV_STOP(&pPool->StatAlloc, a);
5125 if (pPool->cUsedPages > pPool->cUsedPagesHigh)
5126 pPool->cUsedPagesHigh = pPool->cUsedPages;
5131 STAM_PROFILE_START(&pPool->StatZeroPage, z);
5134 STAM_PROFILE_STOP(&pPool->StatZeroPage, z);
5139 pgmPoolLockPage(pPool, pPage);
5143 STAM_PROFILE_ADV_STOP(&pPool->StatAlloc, a);
5161 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
5162 pgmPoolFreeByPage(pPool, pgmPoolGetPage(pPool, HCPhys), iUser, iUserTable);
5170 * @param pPool The pool.
5173 PPGMPOOLPAGE pgmPoolGetPage(PPGMPOOL pPool, RTHCPHYS HCPhys)
5175 PGM_LOCK_ASSERT_OWNER(pPool->CTX_SUFF(pVM));
5180 PPGMPOOLPAGE pPage = (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, HCPhys & X86_PTE_PAE_PG_MASK);
5191 * @param pPool The pool.
5194 PPGMPOOLPAGE pgmPoolQueryPageForDbg(PPGMPOOL pPool, RTHCPHYS HCPhys)
5196 PGM_LOCK_ASSERT_OWNER(pPool->CTX_SUFF(pVM));
5197 return (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, HCPhys & X86_PTE_PAE_PG_MASK);
5210 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
5218 unsigned i = pPool->aiHash[PGMPOOL_HASH(GCPhys)];
5224 PPGMPOOLPAGE pPage = &pPool->aPages[i];
5246 STAM_COUNTER_INC(&pPool->StatForceFlushDirtyPage);
5249 STAM_COUNTER_INC(&pPool->StatForceFlushPage);
5251 pgmPoolMonitorChainFlush(pPool, pPage);
5309 * @param pPool The pool.
5313 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
5316 STAM_PROFILE_START(&pPool->StatR3Reset, a);
5322 if (pPool->cCurPages <= PGMPOOL_IDX_FIRST)
5324 STAM_PROFILE_STOP(&pPool->StatR3Reset, a);
5338 for (unsigned i = pPool->cCurPages - 1; i >= PGMPOOL_IDX_FIRST; i--)
5340 PPGMPOOLPAGE pPage = &pPool->aPages[i];
5344 pgmPoolMonitorFlush(pPool, pPage);
5373 pPool->aPages[pPool->cCurPages - 1].iNext = NIL_PGMPOOL_IDX;
5374 pPool->iFreeHead = PGMPOOL_IDX_FIRST;
5375 pPool->cUsedPages = 0;
5380 pPool->cPresent = 0;
5381 pPool->iUserFreeHead = 0;
5382 PPGMPOOLUSER paUsers = pPool->CTX_SUFF(paUsers);
5383 const unsigned cMaxUsers = pPool->cMaxUsers;
5404 pPool->iPhysExtFreeHead = 0;
5405 PPGMPOOLPHYSEXT paPhysExts = pPool->CTX_SUFF(paPhysExts);
5406 const unsigned cMaxPhysExts = pPool->cMaxPhysExts;
5422 pPool->cModifiedPages = 0;
5423 pPool->iModifiedHead = NIL_PGMPOOL_IDX;
5428 for (unsigned i = 0; i < RT_ELEMENTS(pPool->aiHash); i++)
5429 pPool->aiHash[i] = NIL_PGMPOOL_IDX;
5430 pPool->iAgeHead = NIL_PGMPOOL_IDX;
5431 pPool->iAgeTail = NIL_PGMPOOL_IDX;
5435 pPool->idxFreeDirtyPage = 0;
5436 pPool->cDirtyPages = 0;
5437 for (unsigned i = 0; i < RT_ELEMENTS(pPool->aDirtyPages); i++)
5438 pPool->aDirtyPages[i].uIdx = NIL_PGMPOOL_IDX;
5455 STAM_PROFILE_STOP(&pPool->StatR3Reset, a);