VirtualBox

Changeset 17137 in vbox for trunk


Ignore:
Timestamp:
Feb 25, 2009 4:18:51 PM (16 years ago)
Author:
vboxsync
Message:

VBOX_WITH_PGMPOOL_PAGING_ONLY: explicit locking of root CR3 pages

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

Legend:

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

    r17134 r17137  
    148148    if (pVM->pgm.s.CTX_SUFF(pShwPageCR3))
    149149    {
     150        Assert(pVM->pgm.s.pShwPageCR3R3->enmKind != PGMPOOLKIND_FREE);
     151
     152        /* Mark the page as unlocked; allow flushing again. */
     153        pgmPoolUnlockPage(pPool, pVM->pgm.s.CTX_SUFF(pShwPageCR3));
     154
    150155        /* Remove the hypervisor mappings from the shadow page table. */
    151156        pgmMapDeactivateCR3(pVM, pVM->pgm.s.CTX_SUFF(pShwPageCR3));
    152157
    153         /* It might have been freed already by a pool flush (see e.g. PGMR3MappingsUnfix). */
    154         /** @todo Coordinate this better with the pool. */
    155         if (pVM->pgm.s.pShwPageCR3R3->enmKind != PGMPOOLKIND_FREE)
    156             pgmPoolFreeByPage(pPool, pVM->pgm.s.pShwPageCR3R3, pVM->pgm.s.iShwUser, pVM->pgm.s.iShwUserTable);
     158        pgmPoolFreeByPage(pPool, pVM->pgm.s.pShwPageCR3R3, pVM->pgm.s.iShwUser, pVM->pgm.s.iShwUserTable);
    157159        pVM->pgm.s.pShwPageCR3R3 = 0;
    158160        pVM->pgm.s.pShwPageCR3RC = 0;
     
    179181    }
    180182    AssertRCReturn(rc, rc);
     183
     184    /* Mark the page as locked; disallow flushing. */
     185    pgmPoolLockPage(pPool, pVM->pgm.s.pShwPageCR3R3);
     186
    181187    pVM->pgm.s.pShwPageCR3R0 = MMHyperCCToR0(pVM, pVM->pgm.s.pShwPageCR3R3);
    182188    pVM->pgm.s.pShwPageCR3RC = MMHyperCCToRC(pVM, pVM->pgm.s.pShwPageCR3R3);
  • trunk/src/VBox/VMM/PGMInternal.h

    r17134 r17137  
    5757 * Enable to use the PGM pool for all levels in the paging chain in all paging modes.
    5858 */
    59 //#define VBOX_WITH_PGMPOOL_PAGING_ONLY
     59#define VBOX_WITH_PGMPOOL_PAGING_ONLY
    6060
    6161/**
     
    16391639     * It's a hack required because of REMR3NotifyHandlerPhysicalDeregister. */
    16401640    bool volatile       fReusedFlushPending;
    1641 #ifndef VBOX_WITH_PGMPOOL_PAGING_ONLY
     1641#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
     1642    /** Used to indicate that this page can't be flushed. Important for cr3 root pages or shadow pae pd pages). */
     1643    bool                fLocked;
     1644#else
    16421645    /** Used to indicate that the guest is mapping the page is also used as a CR3.
    16431646     * In these cases the access handler acts differently and will check
     
    29822985
    29832986#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
    2984 bool            pgmPoolIsActiveRootPage(PVM pVM, PPGMPOOLPAGE pPage);
     2987int             pgmPoolLockPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage);
     2988int             pgmPoolUnlockPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage);
     2989
     2990bool            pgmPoolIsPageLocked(PVM pVM, PPGMPOOLPAGE pPage);
    29852991
    29862992void            pgmMapClearShadowPDEs(PVM pVM, PPGMPOOLPAGE pShwPageCR3, PPGMMAPPING pMap, unsigned iOldPDE);
     
    47254731#endif /* PGMPOOL_WITH_CACHE */
    47264732
     4733#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
     4734/**
     4735 * Locks a page to prevent flushing (important for cr3 root pages or shadow pae pd pages).
     4736 *
     4737 * @returns VBox status code.
     4738 * @param   pVM         VM Handle.
     4739 * @param   pPage       PGM pool page
     4740 */
     4741DECLINLINE(int) pgmPoolLockPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
     4742{
     4743    Assert(!pPage->fLocked);
     4744    pPage->fLocked = true;
     4745    return VINF_SUCCESS;
     4746}
     4747
     4748/**
     4749 * Unlocks a page to allow flushing again
     4750 *
     4751 * @returns VBox status code.
     4752 * @param   pVM         VM Handle.
     4753 * @param   pPage       PGM pool page
     4754 */
     4755DECLINLINE(int) pgmPoolUnlockPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
     4756{
     4757    Assert(pPage->fLocked);
     4758    pPage->fLocked = false;
     4759    return VINF_SUCCESS;
     4760}
     4761#endif
     4762
    47274763/**
    47284764 * Tells if mappings are to be put into the shadow page table or not
  • trunk/src/VBox/VMM/PGMPool.cpp

    r16922 r17137  
    587587    else if (    (   pPage->cModifications < 96 /* it's cheaper here. */
    588588#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
    589                   || pgmPoolIsActiveRootPage(pVM, pPage)
     589                  || pgmPoolIsPageLocked(pVM, pPage)
    590590#else
    591591                  || pPage->fCR3Mix
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r17135 r17137  
    46594659    /** NOTE: We can't deal with jumps to ring 3 here as we're now in an inconsistent state! */
    46604660#  endif
     4661    /* Mark the page as locked; disallow flushing. */
     4662    pgmPoolLockPage(pPool, pNewShwPageCR3);
     4663
    46614664    pVM->pgm.s.iShwUser      = SHW_POOL_ROOT_IDX;
    46624665    pVM->pgm.s.iShwUserTable = GCPhysCR3 >> PAGE_SHIFT;
     
    47014704    if (pOldShwPageCR3)
    47024705    {
     4706        Assert(pOldShwPageCR3->enmKind != PGMPOOLKIND_FREE);
    47034707#  ifndef PGM_WITHOUT_MAPPINGS
    47044708        /* Remove the hypervisor mappings from the shadow page table. */
    47054709        pgmMapDeactivateCR3(pVM, pOldShwPageCR3);
    47064710#  endif
    4707         /* It might have been freed already by a pool flush (see e.g. PGMR3MappingsUnfix). */
    4708         /** @todo Coordinate this better with the pool. */
    4709         if (pOldShwPageCR3->enmKind != PGMPOOLKIND_FREE)
    4710             pgmPoolFreeByPage(pPool, pOldShwPageCR3, iOldShwUser, iOldShwUserTable);
     4711        /* Mark the page as unlocked; allow flushing again. */
     4712        pgmPoolUnlockPage(pPool, pOldShwPageCR3);
     4713
     4714        pgmPoolFreeByPage(pPool, pOldShwPageCR3, iOldShwUser, iOldShwUserTable);
    47114715    }
    47124716
     
    48034807    {
    48044808        PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
     4809
     4810        /* Mark the page as unlocked; allow flushing again. */
     4811        pgmPoolUnlockPage(pPool, pVM->pgm.s.CTX_SUFF(pShwPageCR3));
     4812
    48054813        pgmPoolFreeByPage(pPool, pVM->pgm.s.CTX_SUFF(pShwPageCR3), pVM->pgm.s.iShwUser, pVM->pgm.s.iShwUserTable);
    48064814        pVM->pgm.s.pShwPageCR3R3 = 0;
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r17135 r17137  
    910910#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
    911911/**
    912  * Checks if the page is the active CR3 or is one of the four PDs of a PAE PDPT
    913  *
    914  * @returns VBox status code (appropriate for GC return).
     912 * Checks if the page is locked (e.g. the active CR3 or one of the four PDs of a PAE PDPT)
     913 *
     914 * @returns VBox status code.
    915915 * @param   pVM         VM Handle.
    916916 * @param   pPage       PGM pool page
    917917 */
    918 bool pgmPoolIsActiveRootPage(PVM pVM, PPGMPOOLPAGE pPage)
    919 {
    920     /* First check the simple case. */
    921     if (pPage == pVM->pgm.s.CTX_SUFF(pShwPageCR3))
    922     {
    923         LogFlow(("pgmPoolIsActiveRootPage found CR3 root\n"));
     918bool pgmPoolIsPageLocked(PVM pVM, PPGMPOOLPAGE pPage)
     919{
     920    if (pPage->fLocked)
     921    {
     922        LogFlow(("pgmPoolIsPageLocked found root page %s\n", pgmPoolPoolKindToStr(pPage->enmKind)));
    924923        if (pPage->cModifications)
    925924            pPage->cModifications = 1; /* reset counter (can't use 0, or else it will be reinserted in the modified list) */
    926925        return true;
    927926    }
     927
     928#ifdef VBOX_STRICT
     929    Assert(pPage != pVM->pgm.s.CTX_SUFF(pShwPageCR3));
    928930
    929931# ifndef IN_RING0
     
    946948                    for (unsigned i=0;i<X86_PG_PAE_PDPE_ENTRIES;i++)
    947949                    {
    948                         if (   (pPdpt->a[i].u & PGM_PLXFLAGS_MAPPING)
    949                             &&  pPage->Core.Key == (pPdpt->a[i].u & X86_PDPE_PG_MASK))
    950                         {
    951                             Assert(pPdpt->a[i].n.u1Present);
    952                             LogFlow(("pgmPoolIsActiveRootPage found PAE PDPE root\n"));
    953                             if (pPage->cModifications)
    954                                 pPage->cModifications = 1; /* reset counter (can't use 0, or else it will be reinserted in the modified list) */
    955                             return true;
    956                         }
     950                        Assert(   !(pPdpt->a[i].u & PGM_PLXFLAGS_MAPPING)
     951                               || (pPage->Core.Key != (pPdpt->a[i].u & X86_PDPE_PG_MASK)));
    957952                    }
    958953                    break;
     
    964959    }
    965960# endif
     961#endif /* VBOX_STRICT */
    966962    return false;
    967963}
     
    13151311    if (    (   pPage->cModifications < 48   /** @todo #define */ /** @todo need to check that it's not mapping EIP. */ /** @todo adjust this! */
    13161312#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
    1317              || pgmPoolIsActiveRootPage(pVM, pPage)
     1313             || pgmPoolIsPageLocked(pVM, pPage)
    13181314#else
    13191315             || pPage->fCR3Mix
     
    14781474     */
    14791475#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
    1480     if (pgmPoolIsActiveRootPage(pPool->CTX_SUFF(pVM), pPage))
     1476    if (pgmPoolIsPageLocked(pPool->CTX_SUFF(pVM), pPage))
    14811477#else
    14821478    if (PGMGetHyperCR3(pPool->CTX_SUFF(pVM)) == pPage->Core.Key)
     
    31573153    /* Safety precaution in case we change the paging for other modes too in the future. */
    31583154#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
    3159     Assert(!pgmPoolIsActiveRootPage(pPool->CTX_SUFF(pVM), pPage));
     3155    Assert(!pgmPoolIsPageLocked(pPool->CTX_SUFF(pVM), pPage));
    31603156#else
    31613157    Assert(PGMGetHyperCR3(pPool->CTX_SUFF(pVM)) != pPage->Core.Key);
     
    43604356     */
    43614357#ifdef VBOX_WITH_PGMPOOL_PAGING_ONLY
    4362     if (pgmPoolIsActiveRootPage(pPool->CTX_SUFF(pVM), pPage))
     4358    if (pgmPoolIsPageLocked(pPool->CTX_SUFF(pVM), pPage))
    43634359    {
    43644360        AssertMsg(   pPage->enmKind == PGMPOOLKIND_64BIT_PML4
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