VirtualBox

Changeset 32384 in vbox


Ignore:
Timestamp:
Sep 10, 2010 9:57:16 AM (14 years ago)
Author:
vboxsync
Message:

Extended dirty page optimization for the pae/32-bit shw/gst combination (disabled).

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r32366 r32384  
    15721572# if    defined(PGMPOOL_WITH_OPTIMIZED_DIRTY_PT) \
    15731573     && PGM_WITH_PAGING(PGM_GST_TYPE, PGM_SHW_TYPE) \
    1574      && (PGM_GST_TYPE == PGM_TYPE_PAE || PGM_GST_TYPE == PGM_TYPE_AMD64)
     1574     && (PGM_GST_TYPE == PGM_TYPE_PAE || PGM_GST_TYPE == PGM_TYPE_AMD64 || PGM_SHW_TYPE == PGM_TYPE_PAE /* pae/32bit combo */)
    15751575    if (pShwPage->fDirty)
    15761576    {
     
    15811581        pGstPT->a[iPTDst].u = PteSrc.u;
    15821582    }
     1583# else
     1584    Assert(!pShwPage->fDirty);
    15831585# endif
    15841586
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r32362 r32384  
    12471247    if (    pPage->cModifications >= cMaxModifications
    12481248        &&  !fForcedFlush
    1249         &&  pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT
     1249# if 1
     1250        &&  (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT)
     1251# else /* test code */
     1252        &&  (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT || pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_32BIT_PT)
     1253# endif
    12501254        &&  (   fNotReusedNotForking
    12511255             || (   !pgmPoolMonitorIsReused(pVM, pVCpu, pRegFrame, pDis, pvFault)
     
    14051409    AssertMsg(!cErrors, ("cErrors=%d: last rc=%d idx=%d guest %RX64 shw=%RX64 vs %RHp\n", cErrors, LastRc, LastPTE, pGstPT->a[LastPTE].u, PGMSHWPTEPAE_GET_LOG(pShwPT->a[LastPTE]), LastHCPhys));
    14061410}
     1411
     1412/**
     1413 * Check references to guest physical memory in a PAE / 32-bit page table.
     1414 *
     1415 * @param   pPool       The pool.
     1416 * @param   pPage       The page.
     1417 * @param   pShwPT      The shadow page table (mapping of the page).
     1418 * @param   pGstPT      The guest page table.
     1419 */
     1420static void pgmPoolTrackCheckPTPae32Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PT pGstPT)
     1421{
     1422    unsigned cErrors    = 0;
     1423    int      LastRc     = -1;           /* initialized to shut up gcc */
     1424    unsigned LastPTE    = ~0U;          /* initialized to shut up gcc */
     1425    RTHCPHYS LastHCPhys = NIL_RTHCPHYS; /* initialized to shut up gcc */
     1426    PVM      pVM        = pPool->CTX_SUFF(pVM);
     1427
     1428#ifdef VBOX_STRICT
     1429    for (unsigned i = 0; i < RT_MIN(RT_ELEMENTS(pShwPT->a), pPage->iFirstPresent); i++)
     1430        AssertMsg(!PGMSHWPTEPAE_IS_P(pShwPT->a[i]), ("Unexpected PTE: idx=%d %RX64 (first=%d)\n", i, PGMSHWPTEPAE_GET_LOG(pShwPT->a[i]),  pPage->iFirstPresent));
     1431#endif
     1432    for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++)
     1433    {
     1434        if (PGMSHWPTEPAE_IS_P(pShwPT->a[i]))
     1435        {
     1436            RTHCPHYS HCPhys = NIL_RTHCPHYS;
     1437            int rc = PGMPhysGCPhys2HCPhys(pVM, pGstPT->a[i].u & X86_PTE_PG_MASK, &HCPhys);
     1438            if (    rc != VINF_SUCCESS
     1439                ||  PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]) != HCPhys)
     1440            {
     1441                Log(("rc=%d idx=%d guest %x shw=%RX64 vs %RHp\n", rc, i, pGstPT->a[i].u, PGMSHWPTEPAE_GET_LOG(pShwPT->a[i]), HCPhys));
     1442                LastPTE     = i;
     1443                LastRc      = rc;
     1444                LastHCPhys  = HCPhys;
     1445                cErrors++;
     1446
     1447                RTHCPHYS HCPhysPT = NIL_RTHCPHYS;
     1448                rc = PGMPhysGCPhys2HCPhys(pVM, pPage->GCPhys, &HCPhysPT);
     1449                AssertRC(rc);
     1450
     1451                for (unsigned iPage = 0; iPage < pPool->cCurPages; iPage++)
     1452                {
     1453                    PPGMPOOLPAGE pTempPage = &pPool->aPages[iPage];
     1454
     1455                    if (pTempPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_32BIT_PT)
     1456                    {
     1457                        PPGMSHWPTPAE pShwPT2 = (PPGMSHWPTPAE)PGMPOOL_PAGE_2_PTR(pVM, pTempPage);
     1458
     1459                        for (unsigned j = 0; j < RT_ELEMENTS(pShwPT->a); j++)
     1460                        {
     1461                            if (   PGMSHWPTEPAE_IS_P_RW(pShwPT2->a[j])
     1462                                && PGMSHWPTEPAE_GET_HCPHYS(pShwPT2->a[j]) == HCPhysPT)
     1463                            {
     1464                                Log(("GCPhys=%RGp idx=%d %RX64 vs %RX64\n", pTempPage->GCPhys, j, PGMSHWPTEPAE_GET_LOG(pShwPT->a[j]), PGMSHWPTEPAE_GET_LOG(pShwPT2->a[j])));
     1465                            }
     1466                        }
     1467
     1468                        PGM_DYNMAP_UNUSED_HINT_VM(pVM, pShwPT2);
     1469                    }
     1470                }
     1471            }
     1472        }
     1473    }
     1474    AssertMsg(!cErrors, ("cErrors=%d: last rc=%d idx=%d guest %x shw=%RX64 vs %RHp\n", cErrors, LastRc, LastPTE, pGstPT->a[LastPTE].u, PGMSHWPTEPAE_GET_LOG(pShwPT->a[LastPTE]), LastHCPhys));
     1475}
     1476
    14071477#  endif /* VBOX_STRICT */
    14081478
     
    14741544}
    14751545
     1546/**
     1547 * Clear references to guest physical memory in a PAE / PAE page table.
     1548 *
     1549 * @returns nr of changed PTEs
     1550 * @param   pPool           The pool.
     1551 * @param   pPage           The page.
     1552 * @param   pShwPT          The shadow page table (mapping of the page).
     1553 * @param   pGstPT          The guest page table.
     1554 * @param   pOldGstPT       The old cached guest page table.
     1555 * @param   fAllowRemoval   Bail out as soon as we encounter an invalid PTE
     1556 * @param   pfFlush         Flush reused page table (out)
     1557 */
     1558DECLINLINE(unsigned) pgmPoolTrackFlushPTPae32Bit(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PPGMSHWPTPAE pShwPT, PCX86PT pGstPT,
     1559                                                 PCX86PT pOldGstPT, bool fAllowRemoval, bool *pfFlush)
     1560{
     1561    unsigned cChanged = 0;
     1562
     1563#ifdef VBOX_STRICT
     1564    for (unsigned i = 0; i < RT_MIN(RT_ELEMENTS(pShwPT->a), pPage->iFirstPresent); i++)
     1565        AssertMsg(!PGMSHWPTEPAE_IS_P(pShwPT->a[i]), ("Unexpected PTE: idx=%d %RX64 (first=%d)\n", i, PGMSHWPTEPAE_GET_LOG(pShwPT->a[i]),  pPage->iFirstPresent));
     1566#endif
     1567    *pfFlush = false;
     1568
     1569    for (unsigned i = pPage->iFirstPresent; i < RT_ELEMENTS(pShwPT->a); i++)
     1570    {
     1571        /* Check the new value written by the guest. If present and with a bogus physical address, then
     1572         * it's fairly safe to assume the guest is reusing the PT.
     1573         */
     1574        if (    fAllowRemoval
     1575            &&  pGstPT->a[i].n.u1Present)
     1576        {
     1577            if (!PGMPhysIsGCPhysValid(pPool->CTX_SUFF(pVM), pGstPT->a[i].u & X86_PTE_PG_MASK))
     1578            {
     1579                *pfFlush = true;
     1580                return ++cChanged;
     1581            }
     1582        }
     1583        if (PGMSHWPTEPAE_IS_P(pShwPT->a[i]))
     1584        {
     1585            /* If the old cached PTE is identical, then there's no need to flush the shadow copy. */
     1586            if ((pGstPT->a[i].u & X86_PTE_PG_MASK) == (pOldGstPT->a[i].u & X86_PTE_PG_MASK))
     1587            {
     1588#ifdef VBOX_STRICT
     1589                RTHCPHYS HCPhys = NIL_RTGCPHYS;
     1590                int rc = PGMPhysGCPhys2HCPhys(pPool->CTX_SUFF(pVM), pGstPT->a[i].u & X86_PTE_PG_MASK, &HCPhys);
     1591                AssertMsg(rc == VINF_SUCCESS && PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]) == HCPhys, ("rc=%d guest %x old %x shw=%RX64 vs %RHp\n", rc, pGstPT->a[i].u, pOldGstPT->a[i].u, PGMSHWPTEPAE_GET_LOG(pShwPT->a[i]), HCPhys));
     1592#endif
     1593                uint64_t uHostAttr  = PGMSHWPTEPAE_GET_U(pShwPT->a[i]) & (X86_PTE_P | X86_PTE_US | X86_PTE_A | X86_PTE_D | X86_PTE_G);
     1594                bool     fHostRW    = !!(PGMSHWPTEPAE_GET_U(pShwPT->a[i]) & X86_PTE_RW);
     1595                uint64_t uGuestAttr = pGstPT->a[i].u & (X86_PTE_P | X86_PTE_US | X86_PTE_A | X86_PTE_D | X86_PTE_G);
     1596                bool     fGuestRW   = !!(pGstPT->a[i].u & X86_PTE_RW);
     1597
     1598                if (    uHostAttr == uGuestAttr
     1599                    &&  fHostRW <= fGuestRW)
     1600                    continue;
     1601            }
     1602            cChanged++;
     1603            /* Something was changed, so flush it. */
     1604            Log4(("pgmPoolTrackDerefPTPaePae: i=%d pte=%RX64 hint=%x\n",
     1605                  i, PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]), pOldGstPT->a[i].u & X86_PTE_PG_MASK));
     1606            pgmPoolTracDerefGCPhysHint(pPool, pPage, PGMSHWPTEPAE_GET_HCPHYS(pShwPT->a[i]), pOldGstPT->a[i].u & X86_PTE_PG_MASK, i);
     1607            PGMSHWPTEPAE_ATOMIC_SET(pShwPT->a[i], 0);
     1608        }
     1609    }
     1610    return cChanged;
     1611}
    14761612
    14771613/**
     
    15291665    rc = PGM_GCPHYS_2_PTR(pVM, pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
    15301666    bool  fFlush;
    1531     unsigned cChanges = pgmPoolTrackFlushPTPaePae(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PTPAE)pvGst,
    1532                                                   (PCX86PTPAE)&pPool->aDirtyPages[idxSlot].aPage[0], fAllowRemoval, &fFlush);
     1667    unsigned cChanges;
     1668
     1669    if (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT)
     1670        cChanges = pgmPoolTrackFlushPTPaePae(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PTPAE)pvGst,
     1671                                             (PCX86PTPAE)&pPool->aDirtyPages[idxSlot].aPage[0], fAllowRemoval, &fFlush);
     1672    else
     1673        cChanges = pgmPoolTrackFlushPTPae32Bit(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PT)pvGst,
     1674                                               (PCX86PT)&pPool->aDirtyPages[idxSlot].aPage[0], fAllowRemoval, &fFlush);
     1675
    15331676    PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvGst);
    15341677    PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvShw);
     
    16051748#ifdef VBOX_STRICT
    16061749    void *pvShw = PGMPOOL_PAGE_2_PTR(pVM, pPage);
    1607     pgmPoolTrackCheckPTPaePae(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PTPAE)pvGst);
     1750    if (pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT)
     1751        pgmPoolTrackCheckPTPaePae(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PTPAE)pvGst);
     1752    else
     1753        pgmPoolTrackCheckPTPae32Bit(pPool, pPage, (PPGMSHWPTPAE)pvShw, (PCX86PT)pvGst);
    16081754    PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvShw);
    16091755#endif
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