VirtualBox

Changeset 23067 in vbox


Ignore:
Timestamp:
Sep 16, 2009 12:54:52 PM (15 years ago)
Author:
vboxsync
Message:

Flush page tables that have been updated with invalid entries.

Location:
trunk/src/VBox/VMM
Files:
2 edited

Legend:

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

    r22936 r23067  
    31023102
    31033103void            pgmPoolAddDirtyPage(PVM pVM, PPGMPOOL pPool, PPGMPOOLPAGE pPage);
    3104 void            pgmPoolResetDirtyPages(PVM pVM, bool fForceRemoval = false);
     3104void            pgmPoolResetDirtyPages(PVM pVM);
    31053105
    31063106int             pgmR3ExitShadowModeBeforePoolFlush(PVM pVM, PVMCPU pVCpu);
     
    31973197 * @param   pPGM        PGM handle.
    31983198 * @param   GCPhys      The GC physical address.
    3199  * @param   ppPage      Where to store the page poitner on success.
     3199 * @param   ppPage      Where to store the page pointer on success.
    32003200 */
    32013201DECLINLINE(int) pgmPhysGetPageEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage)
     
    32373237 * @param   pPGM        PGM handle.
    32383238 * @param   GCPhys      The GC physical address.
    3239  * @param   ppPage      Where to store the page poitner on success.
     3239 * @param   ppPage      Where to store the page pointer on success.
    32403240 * @param   ppRamHint   Where to read and store the ram list hint.
    32413241 *                      The caller initializes this to NULL before the call.
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r23060 r23067  
    14701470 *
    14711471 * @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 */
     1480DECLINLINE(unsigned) pgmPoolTrackFlushPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PTPAE pShwPT, PCX86PTPAE pGstPT, PCX86PTPAE pOldGstPT, bool fAllowRemoval, bool *pfFlush)
    14791481{
    14801482    unsigned cChanged = 0;
     
    14841486        AssertMsg(!pShwPT->a[i].n.u1Present, ("Unexpected PTE: idx=%d %RX64 (first=%d)\n", i, pShwPT->a[i].u,  pPage->iFirstPresent));
    14851487#endif
     1488    *pfFlush = false;
     1489
    14861490    for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++)
    14871491    {
     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        }
    14881504        if (pShwPT->a[i].n.u1Present)
    14891505        {
     
    15231539 * @param   pPool           The pool.
    15241540 * @param   idxSlot         Dirty array slot index
    1525  * @param   fForceRemoval   Force removal from the dirty page list
    1526  */
    1527 static void pgmPoolFlushDirtyPage(PVM pVM, PPGMPOOL pPool, unsigned idxSlot, bool fForceRemoval = false)
     1541 * @param   fAllowRemoval   Allow a reused page table to be removed
     1542 */
     1543static void pgmPoolFlushDirtyPage(PVM pVM, PPGMPOOL pPool, unsigned idxSlot, bool fAllowRemoval = false)
    15281544{
    15291545    PPGMPOOLPAGE pPage;
     
    15471563    void *pvShw = PGMPOOL_PAGE_2_LOCKED_PTR(pPool->CTX_SUFF(pVM), pPage);
    15481564    void *pvGst;
     1565    bool  fFlush;
    15491566    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);
    15511568    STAM_PROFILE_STOP(&pPool->StatTrackDeref,a);
    15521569
    15531570    /** 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    }
    15541579
    15551580    /* Write protect the page again to catch all write accesses. */
    15561581    rc = PGMHandlerPhysicalReset(pVM, pPage->GCPhys);
    15571582    Assert(rc == VINF_SUCCESS);
    1558     pPage->fDirty         = false;
     1583    pPage->fDirty = false;
    15591584
    15601585#ifdef VBOX_STRICT
     
    16101635    {
    16111636        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*/);
    16131638    }
    16141639    Assert(pPool->cDirtyPages < RT_ELEMENTS(pPool->aIdxDirtyPages));
     
    16911716 *
    16921717 * @param   pVM             VM Handle.
    1693  * @param   fForceRemoval   Force removal of all dirty pages
    1694  */
    1695 void pgmPoolResetDirtyPages(PVM pVM, bool fForceRemoval)
     1718 */
     1719void pgmPoolResetDirtyPages(PVM pVM)
    16961720{
    16971721    PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
     
    17041728    Log(("pgmPoolResetDirtyPages\n"));
    17051729    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*/);
    17071731
    17081732    pPool->idxFreeDirtyPage = 0;
     
    22592283#ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT
    22602284        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 */);
    22622286#endif
    22632287
     
    24772501
    24782502#ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT
    2479     pgmPoolResetDirtyPages(pVM, true /* force removal. */);
     2503    pgmPoolResetDirtyPages(pVM);
    24802504#endif
    24812505
     
    25192543
    25202544#ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT
    2521     pgmPoolResetDirtyPages(pVM, true /* force removal. */);
     2545    pgmPoolResetDirtyPages(pVM);
    25222546#endif
    25232547
     
    28942918#  ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT
    28952919    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 */);
    28972921#  endif
    28982922
     
    44714495#ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT
    44724496    if (pPage->fDirty)
    4473         pgmPoolFlushDirtyPage(pVM, pPool, pPage->idxDirty, true /* force removal */);
     4497        pgmPoolFlushDirtyPage(pVM, pPool, pPage->idxDirty, false /* do not remove */);
    44744498#endif
    44754499
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette