Changeset 23067 in vbox
- Timestamp:
- Sep 16, 2009 12:54:52 PM (15 years ago)
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/PGMInternal.h
r22936 r23067 3102 3102 3103 3103 void pgmPoolAddDirtyPage(PVM pVM, PPGMPOOL pPool, PPGMPOOLPAGE pPage); 3104 void pgmPoolResetDirtyPages(PVM pVM , bool fForceRemoval = false);3104 void pgmPoolResetDirtyPages(PVM pVM); 3105 3105 3106 3106 int pgmR3ExitShadowModeBeforePoolFlush(PVM pVM, PVMCPU pVCpu); … … 3197 3197 * @param pPGM PGM handle. 3198 3198 * @param GCPhys The GC physical address. 3199 * @param ppPage Where to store the page poi tner on success.3199 * @param ppPage Where to store the page pointer on success. 3200 3200 */ 3201 3201 DECLINLINE(int) pgmPhysGetPageEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage) … … 3237 3237 * @param pPGM PGM handle. 3238 3238 * @param GCPhys The GC physical address. 3239 * @param ppPage Where to store the page poi tner on success.3239 * @param ppPage Where to store the page pointer on success. 3240 3240 * @param ppRamHint Where to read and store the ram list hint. 3241 3241 * The caller initializes this to NULL before the call. -
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
r23060 r23067 1470 1470 * 1471 1471 * @returns nr of changed PTEs 1472 * @param pPool The pool. 1473 * @param pPage The page. 1474 * @param pShwPT The shadow page table (mapping of the page). 1475 * @param pGstPT The guest page table. 1476 * @param pOldGstPT The old cached guest page table. 1477 */ 1478 DECLINLINE(unsigned) pgmPoolTrackFlushPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PTPAE pShwPT, PCX86PTPAE pGstPT, PCX86PTPAE pOldGstPT) 1472 * @param pPool The pool. 1473 * @param pPage The page. 1474 * @param pShwPT The shadow page table (mapping of the page). 1475 * @param pGstPT The guest page table. 1476 * @param pOldGstPT The old cached guest page table. 1477 * @param fAllowRemoval Bail out as soon as we encounter an invalid PTE 1478 * @param pfFlush Flush reused page table (out) 1479 */ 1480 DECLINLINE(unsigned) pgmPoolTrackFlushPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PTPAE pShwPT, PCX86PTPAE pGstPT, PCX86PTPAE pOldGstPT, bool fAllowRemoval, bool *pfFlush) 1479 1481 { 1480 1482 unsigned cChanged = 0; … … 1484 1486 AssertMsg(!pShwPT->a[i].n.u1Present, ("Unexpected PTE: idx=%d %RX64 (first=%d)\n", i, pShwPT->a[i].u, pPage->iFirstPresent)); 1485 1487 #endif 1488 *pfFlush = false; 1489 1486 1490 for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++) 1487 1491 { 1492 /* Check the new value written by the guest. If present and with a bogus physical address, then 1493 * it's fairly safe to assume the guest is reusing the PT. 1494 */ 1495 if ( fAllowRemoval 1496 && pGstPT->a[i].n.u1Present) 1497 { 1498 if (!PGMPhysIsGCPhysValid(pPool->CTX_SUFF(pVM), pGstPT->a[i].u & X86_PTE_PAE_PG_MASK)) 1499 { 1500 *pfFlush = true; 1501 return ++cChanged; 1502 } 1503 } 1488 1504 if (pShwPT->a[i].n.u1Present) 1489 1505 { … … 1523 1539 * @param pPool The pool. 1524 1540 * @param idxSlot Dirty array slot index 1525 * @param f ForceRemoval Force removal from the dirty page list1526 */ 1527 static void pgmPoolFlushDirtyPage(PVM pVM, PPGMPOOL pPool, unsigned idxSlot, bool f ForceRemoval = false)1541 * @param fAllowRemoval Allow a reused page table to be removed 1542 */ 1543 static void pgmPoolFlushDirtyPage(PVM pVM, PPGMPOOL pPool, unsigned idxSlot, bool fAllowRemoval = false) 1528 1544 { 1529 1545 PPGMPOOLPAGE pPage; … … 1547 1563 void *pvShw = PGMPOOL_PAGE_2_LOCKED_PTR(pPool->CTX_SUFF(pVM), pPage); 1548 1564 void *pvGst; 1565 bool fFlush; 1549 1566 int rc = PGM_GCPHYS_2_PTR(pPool->CTX_SUFF(pVM), pPage->GCPhys, &pvGst); AssertReleaseRC(rc); 1550 unsigned cChanges = pgmPoolTrackFlushPTPaePae(pPool, pPage, (PX86PTPAE)pvShw, (PCX86PTPAE)pvGst, (PCX86PTPAE)&pPool->aDirtyPages[idxSlot][0] );1567 unsigned cChanges = pgmPoolTrackFlushPTPaePae(pPool, pPage, (PX86PTPAE)pvShw, (PCX86PTPAE)pvGst, (PCX86PTPAE)&pPool->aDirtyPages[idxSlot][0], fAllowRemoval, &fFlush); 1551 1568 STAM_PROFILE_STOP(&pPool->StatTrackDeref,a); 1552 1569 1553 1570 /** Note: we might want to consider keeping the dirty page active in case there were many changes. */ 1571 if (fFlush) 1572 { 1573 Assert(fAllowRemoval); 1574 Log(("Flush reused page table!\n")); 1575 pgmPoolFlushPage(pPool, pPage); 1576 STAM_COUNTER_INC(&pPool->StatForceFlushReused); 1577 return; 1578 } 1554 1579 1555 1580 /* Write protect the page again to catch all write accesses. */ 1556 1581 rc = PGMHandlerPhysicalReset(pVM, pPage->GCPhys); 1557 1582 Assert(rc == VINF_SUCCESS); 1558 pPage->fDirty 1583 pPage->fDirty = false; 1559 1584 1560 1585 #ifdef VBOX_STRICT … … 1610 1635 { 1611 1636 STAM_COUNTER_INC(&pPool->StatDirtyPageOverFlowFlush); 1612 pgmPoolFlushDirtyPage(pVM, pPool, idxFree, true /* force removal*/);1637 pgmPoolFlushDirtyPage(pVM, pPool, idxFree, true /* allow removal of reused page tables*/); 1613 1638 } 1614 1639 Assert(pPool->cDirtyPages < RT_ELEMENTS(pPool->aIdxDirtyPages)); … … 1691 1716 * 1692 1717 * @param pVM VM Handle. 1693 * @param fForceRemoval Force removal of all dirty pages 1694 */ 1695 void pgmPoolResetDirtyPages(PVM pVM, bool fForceRemoval) 1718 */ 1719 void pgmPoolResetDirtyPages(PVM pVM) 1696 1720 { 1697 1721 PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool); … … 1704 1728 Log(("pgmPoolResetDirtyPages\n")); 1705 1729 for (unsigned i = 0; i < RT_ELEMENTS(pPool->aIdxDirtyPages); i++) 1706 pgmPoolFlushDirtyPage(pVM, pPool, i, fForceRemoval);1730 pgmPoolFlushDirtyPage(pVM, pPool, i, true /* allow removal of reused page tables*/); 1707 1731 1708 1732 pPool->idxFreeDirtyPage = 0; … … 2259 2283 #ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT 2260 2284 if (pPageHead->fDirty) 2261 pgmPoolFlushDirtyPage(pPool->CTX_SUFF(pVM), pPool, pPageHead->idxDirty, true /* force removal*/);2285 pgmPoolFlushDirtyPage(pPool->CTX_SUFF(pVM), pPool, pPageHead->idxDirty, false /* do not remove */); 2262 2286 #endif 2263 2287 … … 2477 2501 2478 2502 #ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT 2479 pgmPoolResetDirtyPages(pVM , true /* force removal. */);2503 pgmPoolResetDirtyPages(pVM); 2480 2504 #endif 2481 2505 … … 2519 2543 2520 2544 #ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT 2521 pgmPoolResetDirtyPages(pVM , true /* force removal. */);2545 pgmPoolResetDirtyPages(pVM); 2522 2546 #endif 2523 2547 … … 2894 2918 # ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT 2895 2919 if (pPage->fDirty) 2896 pgmPoolFlushDirtyPage(pPool->CTX_SUFF(pVM), pPool, pPage->idxDirty, true /* force removal*/);2920 pgmPoolFlushDirtyPage(pPool->CTX_SUFF(pVM), pPool, pPage->idxDirty, false /* do not remove */); 2897 2921 # endif 2898 2922 … … 4471 4495 #ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT 4472 4496 if (pPage->fDirty) 4473 pgmPoolFlushDirtyPage(pVM, pPool, pPage->idxDirty, true /* force removal*/);4497 pgmPoolFlushDirtyPage(pVM, pPool, pPage->idxDirty, false /* do not remove */); 4474 4498 #endif 4475 4499
Note:
See TracChangeset
for help on using the changeset viewer.