Lines Matching refs:pPage

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);
96 * @param pPage A page in the chain.
99 int pgmPoolMonitorChainFlush(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
101 LogFlow(("pgmPoolMonitorChainFlush: Flush page %RGp type=%d\n", pPage->GCPhys, pPage->enmKind));
106 uint16_t idx = pPage->idx;
107 if (pPage->iMonitoredPrev != NIL_PGMPOOL_IDX)
109 while (pPage->iMonitoredPrev != NIL_PGMPOOL_IDX)
111 idx = pPage->iMonitoredPrev;
112 Assert(idx != pPage->idx);
113 pPage = &pPool->aPages[idx];
123 idx = pPage->iMonitoredNext;
124 Assert(idx != pPage->idx);
125 if (pPage->idx >= PGMPOOL_IDX_FIRST)
127 int rc2 = pgmPoolFlushPage(pPool, pPage);
133 pPage = &pPool->aPages[idx];
172 * @param pPage The head page.
178 void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTGCPHYS GCPhysFault,
181 AssertMsg(pPage->iMonitoredPrev == NIL_PGMPOOL_IDX, ("%u (idx=%u)\n", pPage->iMonitoredPrev, pPage->idx));
201 LogFlow(("pgmPoolMonitorChainChanging: page idx=%d phys=%RGp (next=%d) kind=%s\n", pPage->idx, pPage->GCPhys, pPage->iMonitoredNext, pgmPoolPoolKindToStr(pPage->enmKind), cbWrite));
204 switch (pPage->enmKind)
209 uShw.pv = PGMPOOL_PAGE_2_PTR(pVM, pPage);
219 pgmPoolTracDerefGCPhysHint(pPool, pPage,
232 uShw.pv = PGMPOOL_PAGE_2_PTR(pVM, pPage);
233 if (!((off ^ pPage->GCPhys) & (PAGE_SIZE / 2)))
244 pgmPoolTracDerefGCPhysHint(pPool, pPage,
262 uShw.pv = PGMPOOL_PAGE_2_PTR(pVM, pPage);
264 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));
266 if (iShwPdpt == pPage->enmKind - (unsigned)PGMPOOLKIND_PAE_PD0_FOR_32BIT_PD)
284 pPage->idx,
310 pPage->idx,
323 uShw.pv = PGMPOOL_PAGE_2_PTR(pVM, pPage);
333 pgmPoolTracDerefGCPhysHint(pPool, pPage,
357 pgmPoolTracDerefGCPhysHint(pPool, pPage,
369 uShw.pv = PGMPOOL_PAGE_2_PTR(pVM, pPage);
391 pPage->idx,
419 pPage->idx,
433 pgmPoolFree(pVM, uShw.pPD->a[iShw].u & X86_PDE_PG_MASK, pPage->idx, iShw);
442 uShw.pv = PGMPOOL_PAGE_2_PTR(pVM, pPage);
469 pPage->idx,
498 pPage->idx,
515 const unsigned offPdpt = GCPhysFault - pPage->GCPhys;
517 uShw.pv = PGMPOOL_PAGE_2_PTR(pVM, pPage);
537 pPage->idx,
566 pPage->idx,
580 uShw.pv = PGMPOOL_PAGE_2_PTR(pVM, pPage);
588 pPage->idx,
605 pPage->idx,
620 uShw.pv = PGMPOOL_PAGE_2_PTR(pVM, pPage);
625 pgmPoolFree(pVM, uShw.pPDPT->a[iShw].u & X86_PDPE_PG_MASK, pPage->idx, iShw);
636 pgmPoolFree(pVM, uShw.pPDPT->a[iShw2].u & X86_PDPE_PG_MASK, pPage->idx, iShw2);
650 uShw.pv = PGMPOOL_PAGE_2_PTR(pVM, pPage);
655 pgmPoolFree(pVM, uShw.pPML4->a[iShw].u & X86_PML4E_PG_MASK, pPage->idx, iShw);
666 pgmPoolFree(pVM, uShw.pPML4->a[iShw2].u & X86_PML4E_PG_MASK, pPage->idx, iShw2);
675 AssertFatalMsgFailed(("enmKind=%d\n", pPage->enmKind));
680 if (pPage->iMonitoredNext == NIL_PGMPOOL_IDX)
682 pPage = &pPool->aPages[pPage->iMonitoredNext];
818 * @param pPage The pool page (head).
825 static int pgmPoolAccessHandlerFlush(PVM pVM, PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, PDISCPUSTATE pDis,
833 int rc = pgmPoolMonitorChainFlush(pPool, pPage);
885 * @param pPage The pool page (head).
891 DECLINLINE(int) pgmPoolAccessHandlerSTOSD(PVM pVM, PPGMPOOL pPool, PPGMPOOLPAGE pPage, PDISCPUSTATE pDis,
913 if (!pPage->cModifications++)
914 pgmPoolMonitorModifiedInsert(pPool, pPage);
928 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, (RTGCPTR)pu32, uIncrement);
931 pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, (RTGCPTR)pu32, uIncrement);
957 * @param pPage The pool page (head).
964 DECLINLINE(int) pgmPoolAccessHandlerSimple(PVM pVM, PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, PDISCPUSTATE pDis,
975 if (!pPage->cModifications++)
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);
1016 switch (pPage->enmKind)
1065 PPGMPOOLPAGE pPage = (PPGMPOOLPAGE)pvUser;
1071 LogFlow(("pgmPoolAccessHandler: pvFault=%RGv pPage=%p:{.idx=%d} GCPhysFault=%RGp\n", pvFault, pPage, pPage->idx, GCPhysFault));
1074 if (PHYS_PAGE_ADDRESS(GCPhysFault) != PHYS_PAGE_ADDRESS(pPage->GCPhys))
1077 Log(("CPU%d: pgmPoolAccessHandler pgm pool page for %RGp changed (to %RGp) while waiting!\n", pVCpu->idCpu, PHYS_PAGE_ADDRESS(GCPhysFault), PHYS_PAGE_ADDRESS(pPage->GCPhys)));
1083 if (pPage->fDirty)
1092 if (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT)
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);
1115 Assert(pPage->enmKind != PGMPOOLKIND_FREE);
1121 Assert(pPage->iMonitoredPrev == NIL_PGMPOOL_IDX);
1125 if ( pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT
1126 || pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_32BIT_PT)
1139 if ( pPage->GCPtrLastAccessHandlerRip >= pRegFrame->rip - 0x40 /* observed loops in Windows 7 x64 */
1140 && pPage->GCPtrLastAccessHandlerRip < pRegFrame->rip + 0x40
1141 && pvFault == (pPage->GCPtrLastAccessHandlerFault + pDis->Param1.cb)
1142 && pVCpu->pgm.s.cPoolAccessHandler == pPage->cLastAccessHandler + 1)
1144 Log(("Possible page reuse cMods=%d -> %d (locked=%d type=%s)\n", pPage->cModifications, pPage->cModifications * 2, pgmPoolIsPageLocked(pPage), pgmPoolPoolKindToStr(pPage->enmKind)));
1145 Assert(pPage->cModifications < 32000);
1146 pPage->cModifications = pPage->cModifications * 2;
1147 pPage->GCPtrLastAccessHandlerFault = pvFault;
1148 pPage->cLastAccessHandler = pVCpu->pgm.s.cPoolAccessHandler;
1149 if (pPage->cModifications >= cMaxModifications)
1156 if (pPage->cModifications >= cMaxModifications)
1157 Log(("Mod overflow %RGv cMods=%d (locked=%d type=%s)\n", pvFault, pPage->cModifications, pgmPoolIsPageLocked(pPage), pgmPoolPoolKindToStr(pPage->enmKind)));
1164 if ( ( pPage->cModifications < cMaxModifications /** @todo #define */ /** @todo need to check that it's not mapping EIP. */ /** @todo adjust this! */
1165 || pgmPoolIsPageLocked(pPage)
1175 rc = pgmPoolAccessHandlerSimple(pVM, pVCpu, pPool, pPage, pDis, pRegFrame, GCPhysFault, pvFault, &fReused);
1183 && !pPage->cLocked /* only applies to unlocked pages as we can't free locked ones (e.g. cr3 root). */
1187 pPage->GCPtrLastAccessHandlerFault = pvFault;
1188 pPage->cLastAccessHandler = pVCpu->pgm.s.cPoolAccessHandler;
1189 pPage->GCPtrLastAccessHandlerRip = pRegFrame->rip;
1191 if (pPage->cModifications > 8)
1192 pPage->cModifications = 2;
1194 else if (pPage->GCPtrLastAccessHandlerFault == pvFault)
1197 pPage->cLastAccessHandler = pVCpu->pgm.s.cPoolAccessHandler;
1201 pPage->GCPtrLastAccessHandlerFault = NIL_RTGCPTR;
1202 pPage->GCPtrLastAccessHandlerRip = 0;
1246 rc = pgmPoolAccessHandlerSTOSD(pVM, pPool, pPage, pDis, pRegFrame, GCPhysFault, pvFault);
1264 if ( pPage->cModifications >= cMaxModifications
1266 && (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT || pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_32BIT_PT)
1273 Assert(!pgmPoolIsPageLocked(pPage));
1274 Assert(pPage->fDirty == false);
1277 if ( pPage->iMonitoredNext != NIL_PGMPOOL_IDX
1278 || pPage->iMonitoredPrev != NIL_PGMPOOL_IDX)
1280 PPGMPOOLPAGE pPageHead = pPage;
1290 if (pPageHead != pPage)
1306 if ( pPage->iMonitoredNext == NIL_PGMPOOL_IDX
1307 && pPage->iMonitoredPrev == NIL_PGMPOOL_IDX)
1309 pgmPoolAddDirtyPage(pVM, pPool, pPage);
1312 rc = PGMHandlerPhysicalPageTempOff(pVM, pPage->GCPhys & PAGE_BASE_GC_MASK, pPage->GCPhys & PAGE_BASE_GC_MASK);
1322 pPage->GCPtrDirtyFault = pvFault;
1343 rc = pgmPoolAccessHandlerFlush(pVM, pVCpu, pPool, pPage, pDis, pRegFrame, GCPhysFault, pvFault);
1366 * @param pPage The page.
1370 static void pgmPoolTrackCheckPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PTPAE pGstPT)
1379 for (unsigned i = 0; i < RT_MIN(RT_ELEMENTS(pShwPT->a), pPage->iFirstPresent); i++)
1380 AssertMsg(!PGMSHWPTEPAE_IS_P(pShwPT->a[i]), ("Unexpected PTE: idx=%d %RX64 (first=%d)\n", i, PGMSHWPTEPAE_GET_LOG(pShwPT->a[i]), pPage->iFirstPresent));
1382 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++)
1398 rc = PGMPhysGCPhys2HCPhys(pVM, pPage->GCPhys, &HCPhysPT);
1432 * @param pPage The page.
1436 static void pgmPoolTrackCheckPTPae32Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PT pGstPT)
1445 for (unsigned i = 0; i < RT_MIN(RT_ELEMENTS(pShwPT->a), pPage->iFirstPresent); i++)
1446 AssertMsg(!PGMSHWPTEPAE_IS_P(pShwPT->a[i]), ("Unexpected PTE: idx=%d %RX64 (first=%d)\n", i, PGMSHWPTEPAE_GET_LOG(pShwPT->a[i]), pPage->iFirstPresent));
1448 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++)
1464 rc = PGMPhysGCPhys2HCPhys(pVM, pPage->GCPhys, &HCPhysPT);
1500 * @param pPage The page.
1507 DECLINLINE(unsigned) pgmPoolTrackFlushPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PTPAE pGstPT,
1513 for (unsigned i = 0; i < RT_MIN(RT_ELEMENTS(pShwPT->a), pPage->iFirstPresent); i++)
1514 AssertMsg(!PGMSHWPTEPAE_IS_P(pShwPT->a[i]), ("Unexpected PTE: idx=%d %RX64 (first=%d)\n", i, PGMSHWPTEPAE_GET_LOG(pShwPT->a[i]), pPage->iFirstPresent));
1518 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++)
1555 pgmPoolTracDerefGCPhysHint(pPool, pPage, PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]), pOldGstPT->a[i].u & X86_PTE_PAE_PG_MASK, i);
1568 * @param pPage The page.
1575 DECLINLINE(unsigned) pgmPoolTrackFlushPTPae32Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PT pGstPT,
1581 for (unsigned i = 0; i < RT_MIN(RT_ELEMENTS(pShwPT->a), pPage->iFirstPresent); i++)
1582 AssertMsg(!PGMSHWPTEPAE_IS_P(pShwPT->a[i]), ("Unexpected PTE: idx=%d %RX64 (first=%d)\n", i, PGMSHWPTEPAE_GET_LOG(pShwPT->a[i]), pPage->iFirstPresent));
1586 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++)
1623 pgmPoolTracDerefGCPhysHint(pPool, pPage, PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]), pOldGstPT->a[i].u & X86_PTE_PG_MASK, i);
1641 PPGMPOOLPAGE pPage;
1650 pPage = &pPool->aPages[idxPage];
1651 Assert(pPage->idx == idxPage);
1652 Assert(pPage->iMonitoredNext == NIL_PGMPOOL_IDX && pPage->iMonitoredPrev == NIL_PGMPOOL_IDX);
1654 AssertMsg(pPage->fDirty, ("Page %RGp (slot=%d) not marked dirty!", pPage->GCPhys, idxSlot));
1655 Log(("Flush dirty page %RGp cMods=%d\n", pPage->GCPhys, pPage->cModifications));
1663 int rc = PGMHandlerPhysicalReset(pVM, pPage->GCPhys & PAGE_BASE_GC_MASK);
1665 pPage->fDirty = false;
1670 rc = PGMShwGetPage(VMMGetCpu(pVM), pPage->GCPtrDirtyFault, &fFlags, &HCPhys);
1672 && (!(fFlags & X86_PTE_RW) || HCPhys != pPage->Core.Key))
1676 ("PGMShwGetPage -> GCPtr=%RGv rc=%d flags=%RX64\n", pPage->GCPtrDirtyFault, rc, fFlags));
1681 void *pvShw = PGMPOOL_PAGE_2_PTR(pVM, pPage);
1683 rc = PGM_GCPHYS_2_PTR_EX(pVM, pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
1687 if (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT)
1688 cChanges = pgmPoolTrackFlushPTPaePae(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PTPAE)pvGst,
1691 cChanges = pgmPoolTrackFlushPTPae32Bit(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PT)pvGst,
1700 Assert(pPage->cModifications);
1702 pPage->cModifications = 1; /* must use > 0 here */
1704 pPage->cModifications = RT_MAX(1, pPage->cModifications / 2);
1717 pgmPoolFlushPage(pPool, pPage);
1721 Log(("Removed dirty page %RGp cMods=%d cChanges=%d\n", pPage->GCPhys, pPage->cModifications, cChanges));
1735 * @param pPage The page.
1737 void pgmPoolAddDirtyPage(PVM pVM, PPGMPOOL pPool, PPGMPOOLPAGE pPage)
1743 Assert(!pPage->fDirty);
1747 Assert(pPage->iMonitoredNext == NIL_PGMPOOL_IDX && pPage->iMonitoredPrev == NIL_PGMPOOL_IDX);
1757 Log(("Add dirty page %RGp (slot=%d)\n", pPage->GCPhys, idxFree));
1765 int rc = PGM_GCPHYS_2_PTR_EX(pVM, pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
1766 memcpy(&pPool->aDirtyPages[idxFree].aPage[0], pvGst, (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT) ? PAGE_SIZE : PAGE_SIZE/2);
1768 void *pvShw = PGMPOOL_PAGE_2_PTR(pVM, pPage);
1769 if (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT)
1770 pgmPoolTrackCheckPTPaePae(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PTPAE)pvGst);
1772 pgmPoolTrackCheckPTPae32Bit(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PT)pvGst);
1778 pPage->fDirty = true;
1779 pPage->idxDirtyEntry = (uint8_t)idxFree; Assert(pPage->idxDirtyEntry == idxFree);
1780 pPool->aDirtyPages[idxFree].uIdx = pPage->idx;
1805 pgmPoolTrackClearPageUsers(pPool, pPage);
1830 PPGMPOOLPAGE pPage;
1833 pPage = &pPool->aPages[idxPage];
1834 if (pPage->GCPhys == GCPhys)
1927 PPGMPOOLPAGE pPage = &pPool->aPages[idxPage];
1928 if (pPage->GCPhys == GCPhysPT)
1962 * @param pPage The page.
1964 DECLINLINE(void) pgmPoolHashInsert(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
1966 Log3(("pgmPoolHashInsert: %RGp\n", pPage->GCPhys));
1967 Assert(pPage->GCPhys != NIL_RTGCPHYS); Assert(pPage->iNext == NIL_PGMPOOL_IDX);
1968 uint16_t iHash = PGMPOOL_HASH(pPage->GCPhys);
1969 pPage->iNext = pPool->aiHash[iHash];
1970 pPool->aiHash[iHash] = pPage->idx;
1978 * @param pPage The page.
1980 DECLINLINE(void) pgmPoolHashRemove(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
1982 Log3(("pgmPoolHashRemove: %RGp\n", pPage->GCPhys));
1983 uint16_t iHash = PGMPOOL_HASH(pPage->GCPhys);
1984 if (pPool->aiHash[iHash] == pPage->idx)
1985 pPool->aiHash[iHash] = pPage->iNext;
1992 if (i == pPage->idx)
1994 pPool->aPages[iPrev].iNext = pPage->iNext;
1999 AssertReleaseMsgFailed(("GCPhys=%RGp idx=%d\n", pPage->GCPhys, pPage->idx));
2005 pPage->iNext = NIL_PGMPOOL_IDX;
2028 PPGMPOOLPAGE pPage;
2049 pPage = &pPool->aPages[iToFree];
2055 if ( !pgmPoolIsPageLocked(pPage)
2056 && pPage->idx >= PGMPOOL_IDX_FIRST /* paranoia (#6349) */)
2059 pgmPoolCacheUsed(pPool, pPage);
2066 int rc = pgmPoolFlushPage(pPool, pPage);
2209 PPGMPOOLPAGE pPage = &pPool->aPages[i];
2210 Log4(("pgmPoolCacheAlloc: slot %d found page %RGp\n", i, pPage->GCPhys));
2211 if (pPage->GCPhys == GCPhys)
2213 if ( (PGMPOOLKIND)pPage->enmKind == enmKind
2214 && (PGMPOOLACCESS)pPage->enmAccess == enmAccess
2215 && pPage->fA20Enabled == fA20Enabled)
2220 pgmPoolCacheUsed(pPool, pPage);
2224 rc = pgmPoolTrackAddUser(pPool, pPage, iUser, iUserTable);
2227 Assert((PGMPOOLKIND)pPage->enmKind == enmKind);
2228 *ppPage = pPage;
2229 if (pPage->cModifications)
2230 pPage->cModifications = 1; /* reset counter (can't use 0, or else it will be reinserted in the modified list) */
2237 if ((PGMPOOLKIND)pPage->enmKind != enmKind)
2245 if (pgmPoolCacheReusedByKind((PGMPOOLKIND)pPage->enmKind, enmKind))
2248 pgmPoolFlushPage(pPool, pPage);
2255 i = pPage->iNext;
2269 * @param pPage The cached page.
2272 static void pgmPoolCacheInsert(PPGMPOOL pPool, PPGMPOOLPAGE pPage, bool fCanBeCached)
2277 Assert(!pPage->fCached);
2280 pPage->fCached = true;
2281 pgmPoolHashInsert(pPool, pPage);
2283 pPage, pPage->Core.Key, pPage->idx, pgmPoolPoolKindToStr(pPage->enmKind), pPage->GCPhys));
2289 pPage, pPage->Core.Key, pPage->idx, pgmPoolPoolKindToStr(pPage->enmKind), pPage->GCPhys));
2296 pPage->iAgePrev = NIL_PGMPOOL_IDX;
2297 pPage->iAgeNext = pPool->iAgeHead;
2299 pPool->aPages[pPool->iAgeHead].iAgePrev = pPage->idx;
2301 pPool->iAgeTail = pPage->idx;
2302 pPool->iAgeHead = pPage->idx;
2310 * @param pPage The cached page.
2312 static void pgmPoolCacheFlushPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
2314 Log3(("pgmPoolCacheFlushPage: %RGp\n", pPage->GCPhys));
2319 if (pPage->fCached)
2321 pPage->fCached = false;
2322 pgmPoolHashRemove(pPool, pPage);
2325 Assert(pPage->iNext == NIL_PGMPOOL_IDX);
2330 if (pPage->iAgeNext != NIL_PGMPOOL_IDX)
2331 pPool->aPages[pPage->iAgeNext].iAgePrev = pPage->iAgePrev;
2333 pPool->iAgeTail = pPage->iAgePrev;
2334 if (pPage->iAgePrev != NIL_PGMPOOL_IDX)
2335 pPool->aPages[pPage->iAgePrev].iAgeNext = pPage->iAgeNext;
2337 pPool->iAgeHead = pPage->iAgeNext;
2338 pPage->iAgeNext = NIL_PGMPOOL_IDX;
2339 pPage->iAgePrev = NIL_PGMPOOL_IDX;
2362 PPGMPOOLPAGE pPage = &pPool->aPages[i];
2363 if ( pPage->GCPhys - GCPhys < PAGE_SIZE
2364 && pPage != pNewPage)
2366 switch (pPage->enmKind)
2383 while (pPage->iMonitoredPrev != NIL_PGMPOOL_IDX)
2385 Assert(pPage->iMonitoredPrev != pPage->idx);
2386 pPage = &pPool->aPages[pPage->iMonitoredPrev];
2388 return pPage;
2409 AssertFatalMsgFailed(("enmKind=%d idx=%d\n", pPage->enmKind, pPage->idx));
2414 i = pPage->iNext;
2426 * @param pPage The cached page.
2428 static int pgmPoolMonitorInsert(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
2430 LogFlow(("pgmPoolMonitorInsert %RGp\n", pPage->GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK));
2435 switch (pPage->enmKind)
2473 AssertFatalMsgFailed(("This can't happen! enmKind=%d\n", pPage->enmKind));
2480 PPGMPOOLPAGE pPageHead = pgmPoolMonitorGetPageByGCPhys(pPool, pPage);
2483 Assert(pPageHead != pPage); Assert(pPageHead->iMonitoredNext != pPage->idx);
2484 Assert(pPageHead->iMonitoredPrev != pPage->idx);
2491 pPage->iMonitoredPrev = pPageHead->idx;
2492 pPage->iMonitoredNext = pPageHead->iMonitoredNext;
2494 pPool->aPages[pPageHead->iMonitoredNext].iMonitoredPrev = pPage->idx;
2495 pPageHead->iMonitoredNext = pPage->idx;
2500 Assert(pPage->iMonitoredNext == NIL_PGMPOOL_IDX); Assert(pPage->iMonitoredPrev == NIL_PGMPOOL_IDX);
2502 const RTGCPHYS GCPhysPage = pPage->GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK;
2505 pPool->pfnAccessHandlerR3, MMHyperCCToR3(pVM, pPage),
2506 pPool->pfnAccessHandlerR0, MMHyperCCToR0(pVM, pPage),
2507 pPool->pfnAccessHandlerRC, MMHyperCCToRC(pVM, pPage),
2515 pPage->fMonitored = true;
2526 * @param pPage The cached page.
2528 static int pgmPoolMonitorFlush(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
2533 switch (pPage->enmKind)
2565 Assert(!pPage->fMonitored);
2569 AssertFatalMsgFailed(("This can't happen! enmKind=%d\n", pPage->enmKind));
2571 Assert(pPage->fMonitored);
2578 if ( pPage->iMonitoredNext != NIL_PGMPOOL_IDX
2579 || pPage->iMonitoredPrev != NIL_PGMPOOL_IDX)
2581 if (pPage->iMonitoredPrev == NIL_PGMPOOL_IDX)
2583 PPGMPOOLPAGE pNewHead = &pPool->aPages[pPage->iMonitoredNext];
2585 rc = PGMHandlerPhysicalChangeUserArgs(pVM, pPage->GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK, MMHyperCCToR3(pVM, pNewHead),
2589 pPage->iMonitoredNext = NIL_PGMPOOL_IDX;
2593 pPool->aPages[pPage->iMonitoredPrev].iMonitoredNext = pPage->iMonitoredNext;
2594 if (pPage->iMonitoredNext != NIL_PGMPOOL_IDX)
2596 pPool->aPages[pPage->iMonitoredNext].iMonitoredPrev = pPage->iMonitoredPrev;
2597 pPage->iMonitoredNext = NIL_PGMPOOL_IDX;
2599 pPage->iMonitoredPrev = NIL_PGMPOOL_IDX;
2605 rc = PGMHandlerPhysicalDeregister(pVM, pPage->GCPhys & ~(RTGCPHYS)PAGE_OFFSET_MASK);
2611 pPage->fMonitored = false;
2616 pgmPoolMonitorModifiedRemove(pPool, pPage);
2626 * @param pPage The page.
2628 void pgmPoolMonitorModifiedInsert(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
2630 Log3(("pgmPoolMonitorModifiedInsert: idx=%d\n", pPage->idx));
2631 AssertMsg( pPage->iModifiedNext == NIL_PGMPOOL_IDX
2632 && pPage->iModifiedPrev == NIL_PGMPOOL_IDX
2633 && pPool->iModifiedHead != pPage->idx,
2635 pPage->iModifiedNext, pPage->iModifiedPrev, pPage->idx, pPage->cModifications,
2638 pPage->iModifiedNext = pPool->iModifiedHead;
2640 pPool->aPages[pPool->iModifiedHead].iModifiedPrev = pPage->idx;
2641 pPool->iModifiedHead = pPage->idx;
2655 * @param pPage The page which is believed to be in the list of modified pages.
2657 static void pgmPoolMonitorModifiedRemove(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
2659 Log3(("pgmPoolMonitorModifiedRemove: idx=%d cModifications=%d\n", pPage->idx, pPage->cModifications));
2660 if (pPool->iModifiedHead == pPage->idx)
2662 Assert(pPage->iModifiedPrev == NIL_PGMPOOL_IDX);
2663 pPool->iModifiedHead = pPage->iModifiedNext;
2664 if (pPage->iModifiedNext != NIL_PGMPOOL_IDX)
2666 pPool->aPages[pPage->iModifiedNext].iModifiedPrev = NIL_PGMPOOL_IDX;
2667 pPage->iModifiedNext = NIL_PGMPOOL_IDX;
2671 else if (pPage->iModifiedPrev != NIL_PGMPOOL_IDX)
2673 pPool->aPages[pPage->iModifiedPrev].iModifiedNext = pPage->iModifiedNext;
2674 if (pPage->iModifiedNext != NIL_PGMPOOL_IDX)
2676 pPool->aPages[pPage->iModifiedNext].iModifiedPrev = pPage->iModifiedPrev;
2677 pPage->iModifiedNext = NIL_PGMPOOL_IDX;
2679 pPage->iModifiedPrev = NIL_PGMPOOL_IDX;
2683 Assert(pPage->iModifiedPrev == NIL_PGMPOOL_IDX);
2684 pPage->cModifications = 0;
2709 PPGMPOOLPAGE pPage = &pPool->aPages[idx];
2710 idx = pPage->iModifiedNext;
2711 pPage->iModifiedNext = NIL_PGMPOOL_IDX;
2712 pPage->iModifiedPrev = NIL_PGMPOOL_IDX;
2713 pPage->cModifications = 0;
2813 * @param pPage The cached page.
2818 DECLINLINE(int) pgmPoolTrackInsert(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTGCPHYS GCPhys, uint16_t iUser, uint32_t iUserTable)
2831 if (pPage->iUserHead != NIL_PGMPOOL_USER_INDEX)
2833 uint16_t i = pPage->iUserHead;
2863 pPage->iUserHead = i;
2866 pPage->iUserHead = NIL_PGMPOOL_USER_INDEX;
2882 pgmPoolCacheInsert(pPool, pPage, fCanBeMonitored); /* This can be expanded. */
2885 rc = pgmPoolMonitorInsert(pPool, pPage);
2901 * @param pPage The cached page.
2905 static int pgmPoolTrackAddUser(PPGMPOOL pPool, PPGMPOOLPAGE pPage, uint16_t iUser, uint32_t iUserTable)
2907 Log3(("pgmPoolTrackAddUser: GCPhys=%RGp iUser=%%x iUserTable=%x\n", pPage->GCPhys, iUser, iUserTable));
2916 if (pPage->iUserHead != NIL_PGMPOOL_USER_INDEX)
2918 uint16_t i = pPage->iUserHead;
2945 paUsers[i].iNext = pPage->iUserHead;
2948 pPage->iUserHead = i;
2951 if (pPage->fDirty)
2952 pgmPoolFlushDirtyPage(pPool->CTX_SUFF(pVM), pPool, pPage->idxDirtyEntry, false /* do not remove */);
2958 pgmPoolCacheUsed(pPool, pPage);
2976 static void pgmPoolTrackFreeUser(PPGMPOOL pPool, PPGMPOOLPAGE pPage, uint16_t iUser, uint32_t iUserTable)
2978 Log3(("pgmPoolTrackFreeUser %RGp %x %x\n", pPage->GCPhys, iUser, iUserTable));
2987 uint16_t i = pPage->iUserHead;
2992 pPage->iUserHead = paUsers[i].iNext;
3010 pPage->iUserHead = paUsers[i].iNext;
3023 iUser, iUserTable, pPage->GCPhys));
3153 PPGMPOOLPAGE pPage = &pPool->aPages[iShw];
3158 switch (pPage->enmKind)
3165 PX86PT pPT = (PX86PT)PGMPOOL_PAGE_2_PTR(pVM, pPage);
3199 Assert(pPage->cPresent);
3201 pPage->cPresent--;
3219 Log(("iFirstPresent=%d cPresent=%d\n", pPage->iFirstPresent, pPage->cPresent));
3226 AssertFatalMsgFailed(("iFirstPresent=%d cPresent=%d u32=%RX32 poolkind=%x\n", pPage->iFirstPresent, pPage->cPresent, u32, pPage->enmKind));
3239 PPGMSHWPTPAE pPT = (PPGMSHWPTPAE)PGMPOOL_PAGE_2_PTR(pVM, pPage);
3274 Assert(pPage->cPresent);
3276 pPage->cPresent--;
3294 Log(("iFirstPresent=%d cPresent=%d\n", pPage->iFirstPresent, pPage->cPresent));
3300 AssertFatalMsgFailed(("iFirstPresent=%d cPresent=%d u64=%RX64 poolkind=%x iPte=%d PT=%RX64\n", pPage->iFirstPresent, pPage->cPresent, u64, pPage->enmKind, iPte, PGMSHWPTEPAE_GET_LOG(pPT->a[iPte])));
3312 PEPTPD pPD = (PEPTPD)PGMPOOL_PAGE_2_PTR(pVM, pPage);
3322 Assert(pPage->cPresent);
3324 pPage->cPresent--;
3330 Log(("iFirstPresent=%d cPresent=%d\n", pPage->iFirstPresent, pPage->cPresent));
3335 AssertFatalMsgFailed(("iFirstPresent=%d cPresent=%d\n", pPage->iFirstPresent, pPage->cPresent));
3346 PX86PD pPD = (PX86PD)PGMPOOL_PAGE_2_PTR(pVM, pPage);
3356 Assert(pPage->cPresent);
3358 pPage->cPresent--;
3363 Log(("iFirstPresent=%d cPresent=%d\n", pPage->iFirstPresent, pPage->cPresent));
3368 AssertFatalMsgFailed(("iFirstPresent=%d cPresent=%d\n", pPage->iFirstPresent, pPage->cPresent));
3375 AssertFatalMsgFailed(("enmKind=%d iShw=%d\n", pPage->enmKind, iShw));
3619 PPGMPOOLPAGE pPage = &pPool->aPages[iPage];
3620 if ( pPage->GCPhys != NIL_RTGCPHYS
3621 && pPage->cPresent)
3623 switch (pPage->enmKind)
3632 unsigned cPresent = pPage->cPresent;
3633 PX86PT pPT = (PX86PT)PGMPOOL_PAGE_2_PTR(pVM, pPage);
3634 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pPT->a); i++)
3643 Assert(pPage->cPresent);
3645 pPage->cPresent--;
3661 unsigned cPresent = pPage->cPresent;
3662 PPGMSHWPTPAE pPT = (PPGMSHWPTPAE)PGMPOOL_PAGE_2_PTR(pVM, pPage);
3663 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pPT->a); i++)
3672 Assert(pPage->cPresent);
3674 pPage->cPresent--;
3686 unsigned cPresent = pPage->cPresent;
3687 PEPTPT pPT = (PEPTPT)PGMPOOL_PAGE_2_PTR(pVM, pPage);
3688 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pPT->a); i++)
3697 Assert(pPage->cPresent);
3699 pPage->cPresent--;
3736 static void pgmPoolTrackClearPageUser(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PCPGMPOOLUSER pUser)
3746 LogFlow(("pgmPoolTrackClearPageUser: clear %x in %s (%RGp) (flushing %s)\n", iUserTable, pgmPoolPoolKindToStr(pUserPage->enmKind), pUserPage->Core.Key, pgmPoolPoolKindToStr(pPage->enmKind)));
3761 Assert(!pgmPoolIsPageLocked(pPage));
3870 static void pgmPoolTrackClearPageUsers(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
3875 LogFlow(("pgmPoolTrackClearPageUsers %RGp\n", pPage->GCPhys));
3878 uint16_t i = pPage->iUserHead;
3882 pgmPoolTrackClearPageUser(pPool, pPage, &paUsers[i]);
3893 pPage->iUserHead = NIL_PGMPOOL_USER_INDEX;
4117 * @param pPage The page.
4121 void pgmPoolTrackPhysExtDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMPAGE pPhysPage, uint16_t iPte)
4125 AssertFatalMsg(cRefs == PGMPOOL_TD_CREFS_PHYSEXT, ("cRefs=%d pPhysPage=%R[pgmpage] pPage=%p:{.idx=%d}\n", cRefs, pPhysPage, pPage, pPage->idx));
4143 if ( paPhysExts[iPhysExt].aidx[i] == pPage->idx
4152 Log2(("pgmPoolTrackPhysExtDerefGCPhys: pPhysPage=%R[pgmpage] idx=%d\n", pPhysPage, pPage->idx));
4164 Log2(("pgmPoolTrackPhysExtDerefGCPhys: pPhysPage=%R[pgmpage] idx=%d lonely\n", pPhysPage, pPage->idx));
4170 Log2(("pgmPoolTrackPhysExtDerefGCPhys: pPhysPage=%R[pgmpage] idx=%d head\n", pPhysPage, pPage->idx));
4177 Log2(("pgmPoolTrackPhysExtDerefGCPhys: pPhysPage=%R[pgmpage] idx=%d in list\n", pPhysPage, pPage->idx));
4193 AssertFatalMsgFailed(("not-found! cRefs=%d pPhysPage=%R[pgmpage] pPage=%p:{.idx=%d}\n", cRefs, pPhysPage, pPage, pPage->idx));
4207 * @param pPage The page.
4212 static void pgmPoolTracDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTHCPHYS HCPhys, RTGCPHYS GCPhys, uint16_t iPte)
4228 Assert(pPage->cPresent);
4230 pPage->cPresent--;
4232 pgmTrackDerefGCPhys(pPool, pPage, pPhysPage, iPte);
4247 * @param pPage The page.
4252 void pgmPoolTracDerefGCPhysHint(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTHCPHYS HCPhys, RTGCPHYS GCPhysHint, uint16_t iPte)
4268 Assert(pPage->cPresent);
4270 pPage->cPresent--;
4272 pgmTrackDerefGCPhys(pPool, pPage, pPhysPage, iPte);
4293 Assert(pPage->cPresent);
4295 pPage->cPresent--;
4297 pgmTrackDerefGCPhys(pPool, pPage, &pRam->aPages[iPage], iPte);
4312 * @param pPage The page.
4316 DECLINLINE(void) pgmPoolTrackDerefPT32Bit32Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PT pShwPT, PCX86PT pGstPT)
4318 RTGCPHYS32 const fPgMask = pPage->fA20Enabled ? X86_PTE_PG_MASK : X86_PTE_PG_MASK & ~RT_BIT_32(20);
4319 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++)
4326 pgmPoolTracDerefGCPhysHint(pPool, pPage, pShwPT->a[i].u & X86_PTE_PG_MASK, pGstPT->a[i].u & fPgMask, i);
4327 if (!pPage->cPresent)
4338 * @param pPage The page.
4342 DECLINLINE(void) pgmPoolTrackDerefPTPae32Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PT pGstPT)
4344 RTGCPHYS32 const fPgMask = pPage->fA20Enabled ? X86_PTE_PG_MASK : X86_PTE_PG_MASK & ~RT_BIT_32(20);
4345 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++)
4353 pgmPoolTracDerefGCPhysHint(pPool, pPage, PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]), pGstPT->a[i].u & fPgMask, i);
4354 if (!pPage->cPresent)
4365 * @param pPage The page.
4369 DECLINLINE(void) pgmPoolTrackDerefPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PTPAE pGstPT)
4371 RTGCPHYS const fPgMask = pPage->fA20Enabled ? X86_PTE_PAE_PG_MASK : X86_PTE_PAE_PG_MASK & ~RT_BIT_64(20);
4372 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++)
4380 pgmPoolTracDerefGCPhysHint(pPool, pPage, PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]), pGstPT->a[i].u & fPgMask, i);
4381 if (!pPage->cPresent)
4392 * @param pPage The page.
4395 DECLINLINE(void) pgmPoolTrackDerefPT32Bit4MB(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PT pShwPT)
4397 RTGCPHYS const GCPhysA20Mask = pPage->fA20Enabled ? UINT64_MAX : ~RT_BIT_64(20);
4398 RTGCPHYS GCPhys = pPage->GCPhys + PAGE_SIZE * pPage->iFirstPresent;
4399 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++, GCPhys += PAGE_SIZE)
4406 pgmPoolTracDerefGCPhys(pPool, pPage, pShwPT->a[i].u & X86_PTE_PG_MASK, GCPhys & GCPhysA20Mask, i);
4407 if (!pPage->cPresent)
4418 * @param pPage The page.
4421 DECLINLINE(void) pgmPoolTrackDerefPTPaeBig(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT)
4423 RTGCPHYS const GCPhysA20Mask = pPage->fA20Enabled ? UINT64_MAX : ~RT_BIT_64(20);
4424 RTGCPHYS GCPhys = pPage->GCPhys + PAGE_SIZE * pPage->iFirstPresent;
4425 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++, GCPhys += PAGE_SIZE)
4433 pgmPoolTracDerefGCPhys(pPool, pPage, PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]), GCPhys & GCPhysA20Mask, i);
4434 if (!pPage->cPresent)
4445 * @param pPage The page.
4448 DECLINLINE(void) pgmPoolTrackDerefPTEPT(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PEPTPT pShwPT)
4450 RTGCPHYS const GCPhysA20Mask = pPage->fA20Enabled ? UINT64_MAX : ~RT_BIT_64(20);
4451 RTGCPHYS GCPhys = pPage->GCPhys + PAGE_SIZE * pPage->iFirstPresent;
4452 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++, GCPhys += PAGE_SIZE)
4458 i, pShwPT->a[i].u & EPT_PTE_PG_MASK, pPage->GCPhys));
4459 pgmPoolTracDerefGCPhys(pPool, pPage, pShwPT->a[i].u & EPT_PTE_PG_MASK, GCPhys & GCPhysA20Mask, i);
4460 if (!pPage->cPresent)
4471 * @param pPage The page.
4474 DECLINLINE(void) pgmPoolTrackDerefPD(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PD pShwPD)
4485 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4497 * @param pPage The page.
4500 DECLINLINE(void) pgmPoolTrackDerefPDPae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PDPAE pShwPD)
4511 i, pShwPD->a[i].u & X86_PDE2M_PAE_PG_MASK, pPage->GCPhys));
4512 pgmPoolTracDerefGCPhys(pPool, pPage, pShwPD->a[i].u & X86_PDE2M_PAE_PG_MASK,
4513 pPage->GCPhys + i * 2 * _1M /* pPage->GCPhys = base address of the memory described by the PD */,
4522 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4536 * @param pPage The page.
4539 DECLINLINE(void) pgmPoolTrackDerefPDPTPae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PDPT pShwPDPT)
4550 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4562 * @param pPage The page.
4565 DECLINLINE(void) pgmPoolTrackDerefPDPT64Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PDPT pShwPDPT)
4574 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4587 * @param pPage The page.
4590 DECLINLINE(void) pgmPoolTrackDerefPML464Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PML4 pShwPML4)
4599 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4612 * @param pPage The page.
4615 DECLINLINE(void) pgmPoolTrackDerefPDEPT(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PEPTPD pShwPD)
4626 i, pShwPD->a[i].u & X86_PDE2M_PAE_PG_MASK, pPage->GCPhys));
4627 pgmPoolTracDerefGCPhys(pPool, pPage, pShwPD->a[i].u & X86_PDE2M_PAE_PG_MASK,
4628 pPage->GCPhys + i * 2 * _1M /* pPage->GCPhys = base address of the memory described by the PD */,
4636 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4650 * @param pPage The page.
4653 DECLINLINE(void) pgmPoolTrackDerefPDPTEPT(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PEPTPDPT pShwPDPT)
4662 pgmPoolTrackFreeUser(pPool, pSubPage, pPage->idx, i);
4677 * @param pPage The page.
4679 static void pgmPoolTrackDeref(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
4685 void *pvShw = PGMPOOL_PAGE_2_PTR(pVM, pPage);
4686 switch (pPage->enmKind)
4692 int rc = PGM_GCPHYS_2_PTR(pVM, pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
4693 pgmPoolTrackDerefPT32Bit32Bit(pPool, pPage, (PX86PT)pvShw, (PCX86PT)pvGst);
4703 int rc = PGM_GCPHYS_2_PTR_EX(pVM, pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
4704 pgmPoolTrackDerefPTPae32Bit(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PT)pvGst);
4714 int rc = PGM_GCPHYS_2_PTR(pVM, pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
4715 pgmPoolTrackDerefPTPaePae(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PTPAE)pvGst);
4725 pgmPoolTrackDerefPT32Bit4MB(pPool, pPage, (PX86PT)pvShw);
4735 pgmPoolTrackDerefPTPaeBig(pPool, pPage, (PPGMSHWPTPAE)pvShw);
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);
4784 AssertFatalMsgFailed(("enmKind=%d\n", pPage->enmKind));
4791 pPage->fZeroed = true;
4792 Assert(!pPage->cPresent);
4808 int pgmPoolFlushPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage, bool fFlush)
4815 LogFlow(("pgmPoolFlushPage: pPage=%p:{.Key=%RHp, .idx=%d, .enmKind=%s, .GCPhys=%RGp}\n",
4816 pPage, pPage->Core.Key, pPage->idx, pgmPoolPoolKindToStr(pPage->enmKind), pPage->GCPhys));
4822 AssertMsgReturn(pPage->idx >= PGMPOOL_IDX_FIRST,
4824 pgmPoolPoolKindToStr(pPage->enmKind), pPage->idx),
4832 if (pgmPoolIsPageLocked(pPage))
4834 AssertMsg( pPage->enmKind == PGMPOOLKIND_64BIT_PML4
4835 || pPage->enmKind == PGMPOOLKIND_PAE_PDPT
4836 || pPage->enmKind == PGMPOOLKIND_PAE_PDPT_FOR_32BIT
4837 || pPage->enmKind == PGMPOOLKIND_32BIT_PD
4838 || pPage->enmKind == PGMPOOLKIND_PAE_PD_FOR_PAE_PD
4839 || pPage->enmKind == PGMPOOLKIND_PAE_PD0_FOR_32BIT_PD
4840 || pPage->enmKind == PGMPOOLKIND_PAE_PD1_FOR_32BIT_PD
4841 || pPage->enmKind == PGMPOOLKIND_PAE_PD2_FOR_32BIT_PD
4842 || pPage->enmKind == PGMPOOLKIND_PAE_PD3_FOR_32BIT_PD
4843 || pPage->enmKind == PGMPOOLKIND_ROOT_NESTED,
4844 ("Can't free the shadow CR3! (%RHp vs %RHp kind=%d\n", PGMGetHyperCR3(VMMGetCpu(pVM)), pPage->Core.Key, pPage->enmKind));
4845 Log(("pgmPoolFlushPage: current active shadow CR3, rejected. enmKind=%s idx=%d\n", pgmPoolPoolKindToStr(pPage->enmKind), pPage->idx));
4859 pPage->fZeroed = false;
4862 if (pPage->fDirty)
4863 pgmPoolFlushDirtyPage(pVM, pPool, pPage->idxDirtyEntry, false /* do not remove */);
4867 if (pPage->iUserHead != NIL_PGMPOOL_USER_INDEX)
4873 pgmPoolTrackClearPageUsers(pPool, pPage);
4875 pgmPoolTrackDeref(pPool, pPage);
4881 pgmPoolCacheFlushPage(pPool, pPage);
4891 if (pPage->fMonitored)
4892 rc = pgmPoolMonitorFlush(pPool, pPage);
4897 Assert(pPage->iNext == NIL_PGMPOOL_IDX);
4898 pPage->iNext = pPool->iFreeHead;
4899 pPool->iFreeHead = pPage->idx;
4900 pPage->enmKind = PGMPOOLKIND_FREE;
4901 pPage->enmAccess = PGMPOOLACCESS_DONTCARE;
4902 pPage->GCPhys = NIL_RTGCPHYS;
4903 pPage->fReusedFlushPending = false;
4933 void pgmPoolFreeByPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage, uint16_t iUser, uint32_t iUserTable)
4938 LogFlow(("pgmPoolFreeByPage: pPage=%p:{.Key=%RHp, .idx=%d, enmKind=%s} iUser=%d iUserTable=%#x\n",
4939 pPage, pPage->Core.Key, pPage->idx, pgmPoolPoolKindToStr(pPage->enmKind), iUser, iUserTable));
4940 AssertReturnVoid(pPage->idx >= PGMPOOL_IDX_FIRST); /* paranoia (#6349) */
4944 pgmPoolTrackFreeUser(pPool, pPage, iUser, iUserTable);
4945 if (!pPage->fCached)
4946 pgmPoolFlushPage(pPool, pPage);
5072 PPGMPOOLPAGE pPage = &pPool->aPages[iNew];
5073 pPool->iFreeHead = pPage->iNext;
5074 pPage->iNext = NIL_PGMPOOL_IDX;
5080 pPage->enmKind = enmKind;
5081 pPage->enmAccess = enmAccess;
5082 pPage->GCPhys = GCPhys;
5083 pPage->fA20Enabled = fA20Enabled;
5084 pPage->fSeenNonGlobal = false; /* Set this to 'true' to disable this feature. */
5085 pPage->fMonitored = false;
5086 pPage->fCached = false;
5087 pPage->fDirty = false;
5088 pPage->fReusedFlushPending = false;
5089 pPage->cModifications = 0;
5090 pPage->iModifiedNext = NIL_PGMPOOL_IDX;
5091 pPage->iModifiedPrev = NIL_PGMPOOL_IDX;
5092 pPage->cPresent = 0;
5093 pPage->iFirstPresent = NIL_PGMPOOL_PRESENT_INDEX;
5094 pPage->idxDirtyEntry = 0;
5095 pPage->GCPtrLastAccessHandlerFault = NIL_RTGCPTR;
5096 pPage->GCPtrLastAccessHandlerRip = NIL_RTGCPTR;
5097 pPage->cLastAccessHandler = 0;
5098 pPage->cLocked = 0;
5100 pPage->GCPtrDirtyFault = NIL_RTGCPTR;
5106 int rc3 = pgmPoolTrackInsert(pPool, pPage, GCPhys, iUser, iUserTable);
5110 pPage->enmKind = PGMPOOLKIND_FREE;
5111 pPage->enmAccess = PGMPOOLACCESS_DONTCARE;
5112 pPage->GCPhys = NIL_RTGCPHYS;
5113 pPage->iNext = pPool->iFreeHead;
5114 pPool->iFreeHead = pPage->idx;
5129 if (!pPage->fZeroed)
5132 void *pv = PGMPOOL_PAGE_2_PTR(pVM, pPage);
5137 *ppPage = pPage;
5139 pgmPoolLockPage(pPool, pPage);
5142 rc, pPage, pPage->Core.Key, pPage->idx, pPage->fCached, pPage->fMonitored));
5180 PPGMPOOLPAGE pPage = (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, HCPhys & X86_PTE_PAE_PG_MASK);
5182 AssertFatalMsg(pPage && pPage->enmKind != PGMPOOLKIND_FREE, ("HCPhys=%RHp pPage=%p idx=%d\n", HCPhys, pPage, (pPage) ? pPage->idx : 0));
5183 return pPage;
5224 PPGMPOOLPAGE pPage = &pPool->aPages[i];
5225 if (pPage->GCPhys - GCPhys < PAGE_SIZE)
5227 switch (pPage->enmKind)
5245 if (pPage->fDirty)
5250 Assert(!pgmPoolIsPageLocked(pPage));
5251 pgmPoolMonitorChainFlush(pPool, pPage);
5274 AssertFatalMsgFailed(("enmKind=%d idx=%d\n", pPage->enmKind, pPage->idx));
5279 i = pPage->iNext;
5340 PPGMPOOLPAGE pPage = &pPool->aPages[i];
5342 Assert(pPage->Core.Key == MMPage2Phys(pVM, pPage->pvPageR3));
5343 if (pPage->fMonitored)
5344 pgmPoolMonitorFlush(pPool, pPage);
5345 pPage->iModifiedNext = NIL_PGMPOOL_IDX;
5346 pPage->iModifiedPrev = NIL_PGMPOOL_IDX;
5347 pPage->iMonitoredNext = NIL_PGMPOOL_IDX;
5348 pPage->iMonitoredPrev = NIL_PGMPOOL_IDX;
5349 pPage->cModifications = 0;
5350 pPage->GCPhys = NIL_RTGCPHYS;
5351 pPage->enmKind = PGMPOOLKIND_FREE;
5352 pPage->enmAccess = PGMPOOLACCESS_DONTCARE;
5353 Assert(pPage->idx == i);
5354 pPage->iNext = i + 1;
5355 pPage->fA20Enabled = true;
5356 pPage->fZeroed = false; /* This could probably be optimized, but better safe than sorry. */
5357 pPage->fSeenNonGlobal = false;
5358 pPage->fMonitored = false;
5359 pPage->fDirty = false;
5360 pPage->fCached = false;
5361 pPage->fReusedFlushPending = false;
5362 pPage->iUserHead = NIL_PGMPOOL_USER_INDEX;
5363 pPage->iAgeNext = NIL_PGMPOOL_IDX;
5364 pPage->iAgePrev = NIL_PGMPOOL_IDX;
5365 pPage->GCPtrLastAccessHandlerRip = NIL_RTGCPTR;
5366 pPage->GCPtrLastAccessHandlerFault = NIL_RTGCPTR;
5367 pPage->cLastAccessHandler = 0;
5368 pPage->cLocked = 0;
5370 pPage->GCPtrDirtyFault = NIL_RTGCPTR;