VirtualBox

Changeset 22695 in vbox for trunk


Ignore:
Timestamp:
Sep 2, 2009 8:41:52 AM (15 years ago)
Author:
vboxsync
Message:

Must flush pgm pool pages in PGMR3PhysGCPhys2CCPtrExternal to avoid changing dormant pgm pool pages.

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/pgm.h

    r21217 r22695  
    349349VMMDECL(bool)       PGMHandlerPhysicalIsRegistered(PVM pVM, RTGCPHYS GCPhys);
    350350VMMDECL(bool)       PGMHandlerVirtualIsRegistered(PVM pVM, RTGCPTR GCPtr);
     351VMMDECL(void)       PGMPoolFlushPage(PVM pVM, RTGCPHYS GCPhys);
    351352VMMDECL(bool)       PGMPhysIsA20Enabled(PVMCPU pVCpu);
    352353VMMDECL(bool)       PGMPhysIsGCPhysValid(PVM pVM, RTGCPHYS GCPhys);
  • trunk/src/VBox/VMM/PGMInternal.h

    r22600 r22695  
    17951795    /** Profiling pgmPoolFree(). */
    17961796    STAMPROFILE                 StatFree;
     1797    /** Counting explicit flushes by PGMPoolFlushPage(). */
     1798    STAMCOUNTER                 StatForceFlushPage;
    17971799    /** Profiling time spent zeroing pages. */
    17981800    STAMPROFILE                 StatZeroPage;
  • trunk/src/VBox/VMM/PGMPhys.cpp

    r22138 r22695  
    369369        AssertFatalRC(rc2);
    370370        PPGMPAGE pPage = pTlbe->pPage;
    371 #if 1
    372371        if (PGM_PAGE_IS_MMIO(pPage))
    373 #else
    374         if (PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage))
    375 #endif
    376372        {
    377373            PGMPhysReleasePageMappingLock(pVM, pLock);
    378374            rc = VERR_PGM_PHYS_PAGE_RESERVED;
     375        }
     376        else
     377        if (PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage))
     378        {
     379            /* We *must* flush any corresponding pgm pool page here, otherwise we'll
     380             * not be informed about writes and keep bogus gst->shw mappings around.
     381             */
     382            PGMPoolFlushPage(pVM, *pGCPhys);
     383            Assert(!PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage));
    379384        }
    380385    }
     
    428433    {
    429434        PPGMPAGE pPage = pTlbe->pPage;
    430 #if 1
    431435        if (PGM_PAGE_IS_MMIO(pPage))
    432436            rc = VERR_PGM_PHYS_PAGE_RESERVED;
    433 #else
     437        else
    434438        if (PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage))
    435             rc = VERR_PGM_PHYS_PAGE_RESERVED;
    436 #endif
     439        {
     440            /* We *must* flush any corresponding pgm pool page here, otherwise we'll
     441             * not be informed about writes and keep bogus gst->shw mappings around.
     442             */
     443            PGMPoolFlushPage(pVM, GCPhys);
     444            Assert(!PGM_PAGE_HAS_ACTIVE_HANDLERS(pPage));
     445        }
    437446        else
    438447        {
  • trunk/src/VBox/VMM/PGMPool.cpp

    r22510 r22695  
    325325    STAM_REG(pVM, &pPool->StatFlushPage,                STAMTYPE_PROFILE,   "/PGM/Pool/FlushPage",      STAMUNIT_TICKS_PER_CALL,    "Profiling of pgmPoolFlushPage.");
    326326    STAM_REG(pVM, &pPool->StatFree,                     STAMTYPE_PROFILE,   "/PGM/Pool/Free",           STAMUNIT_TICKS_PER_CALL,    "Profiling of pgmPoolFree.");
     327    STAM_REG(pVM, &pPool->StatForceFlushPage,           STAMTYPE_COUNTER,   "/PGM/Pool/FlushForce",     STAMUNIT_OCCURENCES,        "Counting explicit flushes by PGMPoolFlushPage().");   
    327328    STAM_REG(pVM, &pPool->StatZeroPage,                 STAMTYPE_PROFILE,   "/PGM/Pool/ZeroPage",       STAMUNIT_TICKS_PER_CALL,    "Profiling time spent zeroing pages. Overlaps with Alloc.");
    328329# ifdef PGMPOOL_WITH_USER_TRACKING
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r22605 r22695  
    13801380DECLINLINE(void) pgmPoolTrackCheckPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PTPAE pShwPT, PCX86PTPAE pGstPT)
    13811381{
     1382    unsigned cErrors = 0;
    13821383    for (unsigned i = 0; i < RT_ELEMENTS(pShwPT->a); i++)
    13831384    {
     
    13861387            RTHCPHYS HCPhys = -1;
    13871388            int rc = PGMPhysGCPhys2HCPhys(pPool->CTX_SUFF(pVM), pGstPT->a[i].u & X86_PTE_PAE_PG_MASK, &HCPhys);
    1388             AssertMsg(rc == VINF_SUCCESS && (pShwPT->a[i].u & X86_PTE_PAE_PG_MASK) == HCPhys, ("rc=%d guest %RX64 shw=%RX64 vs %RHp\n", rc, pGstPT->a[i].u, pShwPT->a[i].u, HCPhys));
     1389            if (    rc != VINF_SUCCESS
     1390                ||  (pShwPT->a[i].u & X86_PTE_PAE_PG_MASK) != HCPhys)
     1391            {
     1392                RTHCPHYS HCPhysPT = -1;
     1393                Log(("rc=%d idx=%d guest %RX64 shw=%RX64 vs %RHp\n", rc, i, pGstPT->a[i].u, pShwPT->a[i].u, HCPhys));
     1394                cErrors++;
     1395
     1396                int rc = PGMPhysGCPhys2HCPhys(pPool->CTX_SUFF(pVM), pPage->GCPhys, &HCPhysPT);
     1397                AssertRC(rc);
     1398
     1399                for (unsigned i = 0; i < pPool->cCurPages; i++)
     1400                {
     1401                    PPGMPOOLPAGE pTempPage = &pPool->aPages[i];
     1402
     1403                    if (pTempPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT)
     1404                    {
     1405                        PX86PTPAE pShwPT2 = (PX86PTPAE)PGMPOOL_PAGE_2_LOCKED_PTR(pPool->CTX_SUFF(pVM), pTempPage);
     1406
     1407                        for (unsigned j = 0; j < RT_ELEMENTS(pShwPT->a); j++)
     1408                        {
     1409                            if (    pShwPT2->a[j].n.u1Present
     1410                                &&  pShwPT2->a[j].n.u1Write
     1411                                &&  ((pShwPT2->a[j].u & X86_PTE_PAE_PG_MASK) == HCPhysPT))
     1412                            {
     1413                                Log(("GCPhys=%RGp idx=%d %RX64 vs %RX64\n", pTempPage->GCPhys, j, pShwPT->a[j].u, pShwPT2->a[j].u));
     1414                            }
     1415                        }
     1416                    }
     1417                }
     1418            }
     1419        }
     1420    }
     1421    Assert(!cErrors);
     1422}
     1423
     1424void pgmPoolTrackCheckAllPTPaePae(pVM)
     1425{
     1426    PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
     1427
     1428    for (unsigned i = 0; i < pPool->cCurPages; i++)
     1429    {
     1430        PPGMPOOLPAGE pPage = &pPool->aPages[i];
     1431
     1432        if (    pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT
     1433            &&  !pPage->fDirty)
     1434        {
     1435            void *pvShw = PGMPOOL_PAGE_2_LOCKED_PTR(pPool->CTX_SUFF(pVM), pPage);
     1436            void *pvGst;
     1437            int rc = PGM_GCPHYS_2_PTR(pPool->CTX_SUFF(pVM), pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
     1438
     1439            pgmPoolTrackCheckPTPaePae(pPool, pPage, (PX86PTPAE)pvShw, (PCX86PTPAE)pvGst);
    13891440        }
    13901441    }
     
    46694720}
    46704721
     4722/**
     4723 * Flush the specified page if present
     4724 *
     4725 * @param   pVM     The VM handle.
     4726 * @param   GCPhys  Guest physical address of the page to flush
     4727 */
     4728VMMDECL(void) PGMPoolFlushPage(PVM pVM, RTGCPHYS GCPhys)
     4729{
     4730#ifdef PGMPOOL_WITH_CACHE
     4731    PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
     4732
     4733    /*
     4734     * Look up the GCPhys in the hash.
     4735     */
     4736    GCPhys = GCPhys & ~(RTGCPHYS)(PAGE_SIZE - 1);
     4737    unsigned i = pPool->aiHash[PGMPOOL_HASH(GCPhys)];
     4738    if (i == NIL_PGMPOOL_IDX)
     4739        return;
     4740
     4741    do
     4742    {
     4743        PPGMPOOLPAGE pPage = &pPool->aPages[i];
     4744        if (pPage->GCPhys - GCPhys < PAGE_SIZE)
     4745        {
     4746            switch (pPage->enmKind)
     4747            {
     4748                case PGMPOOLKIND_32BIT_PT_FOR_32BIT_PT:
     4749                case PGMPOOLKIND_PAE_PT_FOR_32BIT_PT:
     4750                case PGMPOOLKIND_PAE_PT_FOR_PAE_PT:
     4751                case PGMPOOLKIND_PAE_PD0_FOR_32BIT_PD:
     4752                case PGMPOOLKIND_PAE_PD1_FOR_32BIT_PD:
     4753                case PGMPOOLKIND_PAE_PD2_FOR_32BIT_PD:
     4754                case PGMPOOLKIND_PAE_PD3_FOR_32BIT_PD:
     4755                case PGMPOOLKIND_PAE_PD_FOR_PAE_PD:
     4756                case PGMPOOLKIND_64BIT_PD_FOR_64BIT_PD:
     4757                case PGMPOOLKIND_64BIT_PDPT_FOR_64BIT_PDPT:
     4758                case PGMPOOLKIND_64BIT_PML4:
     4759                case PGMPOOLKIND_32BIT_PD:
     4760                case PGMPOOLKIND_PAE_PDPT:
     4761                {
     4762                    Log(("PGMPoolFlushPage: found pgm pool pages for %RGp\n", GCPhys));
     4763                    STAM_COUNTER_INC(&pPool->StatForceFlushPage);
     4764                    Assert(!pgmPoolIsPageLocked(&pVM->pgm.s, pPage));
     4765                    pgmPoolMonitorChainFlush(pPool, pPage);
     4766                    return;
     4767                }
     4768
     4769                /* ignore, no monitoring. */
     4770                case PGMPOOLKIND_32BIT_PT_FOR_32BIT_4MB:
     4771                case PGMPOOLKIND_PAE_PT_FOR_PAE_2MB:
     4772                case PGMPOOLKIND_PAE_PT_FOR_32BIT_4MB:
     4773                case PGMPOOLKIND_32BIT_PT_FOR_PHYS:
     4774                case PGMPOOLKIND_PAE_PT_FOR_PHYS:
     4775                case PGMPOOLKIND_64BIT_PDPT_FOR_PHYS:
     4776                case PGMPOOLKIND_64BIT_PD_FOR_PHYS:
     4777                case PGMPOOLKIND_EPT_PDPT_FOR_PHYS:
     4778                case PGMPOOLKIND_EPT_PD_FOR_PHYS:
     4779                case PGMPOOLKIND_EPT_PT_FOR_PHYS:
     4780                case PGMPOOLKIND_ROOT_NESTED:
     4781                case PGMPOOLKIND_PAE_PD_PHYS:
     4782                case PGMPOOLKIND_PAE_PDPT_PHYS:
     4783                case PGMPOOLKIND_32BIT_PD_PHYS:
     4784                case PGMPOOLKIND_PAE_PDPT_FOR_32BIT:
     4785                    break;
     4786
     4787                default:
     4788                    AssertFatalMsgFailed(("enmKind=%d idx=%d\n", pPage->enmKind, pPage->idx));
     4789            }
     4790        }
     4791
     4792        /* next */
     4793        i = pPage->iNext;
     4794    } while (i != NIL_PGMPOOL_IDX);
     4795#endif
     4796    return;
     4797}
    46714798
    46724799#ifdef IN_RING3
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