VirtualBox

Changeset 22600 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Aug 31, 2009 12:19:56 PM (15 years ago)
Author:
vboxsync
Message:

Removed unnecessary EPT invlpg calls.
Invalidate the page who's R/W attribute was changed.

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

Legend:

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

    r22510 r22600  
    343343#endif
    344344
    345 /** @def PGM_INVL_PG
     345/** @def PGM_INVL_PG_ALL_VCPU
    346346 * Invalidates a page on all VCPUs
    347347 *
     
    350350 */
    351351#ifdef IN_RC
    352 # define PGM_INVL_ALL_VCPU_PG(pVM, GCVirt)      ASMInvalidatePage((void *)(GCVirt))
     352# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt)      ASMInvalidatePage((void *)(GCVirt))
    353353#elif defined(IN_RING0)
    354 # define PGM_INVL_ALL_VCPU_PG(pVM, GCVirt)      HWACCMInvalidatePageOnAllVCpus(pVM, (RTGCPTR)(GCVirt))
     354# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt)      HWACCMInvalidatePageOnAllVCpus(pVM, (RTGCPTR)(GCVirt))
    355355#else
    356 # define PGM_INVL_ALL_VCPU_PG(pVM, GCVirt)      HWACCMInvalidatePageOnAllVCpus(pVM, (RTGCPTR)(GCVirt))
     356# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt)      HWACCMInvalidatePageOnAllVCpus(pVM, (RTGCPTR)(GCVirt))
    357357#endif
    358358
     
    16801680#ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT
    16811681    uint32_t            idxDirty;
     1682    RTGCPTR             pvDirtyFault;
    16821683#else
    16831684    uint32_t            bPadding2;
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r22473 r22600  
    838838                       /*
    839839                        * Page was successfully synced, return to guest.
     840                        * First invalidate the page as it might be in the TLB.
    840841                        */
     842#   if PGM_SHW_TYPE == PGM_TYPE_EPT
     843                        HWACCMInvalidatePhysPage(pVM, (RTGCPHYS)pvFault);
     844#   else
     845                        PGM_INVL_PG_ALL_VCPU(pVM, pvFault);
     846#   endif
    841847#   ifdef VBOX_STRICT
    842848                        RTGCPHYS GCPhys;
     
    14831489            PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
    14841490            PX86PTPAE pGstPT;
    1485            
     1491
    14861492            pGstPT = (PX86PTPAE)&pPool->aDirtyPages[pShwPage->idxDirty][0];
    14871493            pGstPT->a[iPTDst].u = PteSrc.u;
  • trunk/src/VBox/VMM/VMMAll/PGMAllHandler.cpp

    r20808 r22600  
    926926            PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, PGM_PAGE_HNDL_PHYS_STATE_DISABLED);
    927927            pgmUnlock(pVM);
    928 #ifndef IN_RC
    929             HWACCMInvalidatePhysPage(pVM, GCPhysPage);
    930 #endif
    931928            return VINF_SUCCESS;
    932929        }
     
    10481045
    10491046            pgmUnlock(pVM);
    1050 #ifndef IN_RC
    1051             HWACCMInvalidatePhysPage(pVM, GCPhysPage);
    1052 #endif
    10531047            return VINF_SUCCESS;
    10541048        }
     
    11501144            LogFlow(("PGMHandlerPhysicalPageAliasHC: => %R[pgmpage]\n", pPage));
    11511145            pgmUnlock(pVM);
    1152 #ifndef IN_RC
    1153             HWACCMInvalidatePhysPage(pVM, GCPhysPage);
    1154 #endif
    11551146            return VINF_SUCCESS;
    11561147        }
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r22537 r22600  
    11711171        pPage->pvLastAccessHandlerFault = pvFault;
    11721172        pPage->cLastAccessHandlerCount  = pVCpu->pgm.s.cPoolAccessHandler;
    1173         if (pPage->cModifications > cMaxModifications)
     1173        if (pPage->cModifications >= cMaxModifications)
    11741174        {
    11751175            STAM_COUNTER_INC(&pPool->CTX_MID_Z(StatMonitor,FlushReinit));
     
    11851185     */
    11861186    bool fReused = false;
     1187    bool fNotReusedNotForking = false;
    11871188    if (    (   pPage->cModifications < cMaxModifications   /** @todo #define */ /** @todo need to check that it's not mapping EIP. */ /** @todo adjust this! */
    11881189             || pgmPoolIsPageLocked(&pVM->pgm.s, pPage)
     
    12761277        Log4(("pgmPoolAccessHandler: eax=%#x ecx=%#x edi=%#x esi=%#x rip=%RGv opcode=%d prefix=%#x\n",
    12771278              pRegFrame->eax, pRegFrame->ecx, pRegFrame->edi, pRegFrame->esi, (RTGCPTR)pRegFrame->rip, pDis->pCurInstr->opcode, pDis->prefix));
     1279        fNotReusedNotForking = true;
    12781280    }
    12791281
     
    12821284     * leads to pgm pool trashing and an excessive amount of write faults due to page monitoring.
    12831285     */
    1284     if (    !fReused
     1286    if (    pPage->cModifications >= cMaxModifications
    12851287        &&  !fForcedFlush
    12861288        &&  pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT
    1287         &&  pPage->cModifications >= cMaxModifications)
     1289        &&  (   fNotReusedNotForking
     1290             || (   !pgmPoolMonitorIsReused(pVM, pVCpu, pRegFrame, pDis, pvFault)
     1291                 && !pgmPoolMonitorIsForking(pPool, pDis, GCPhysFault & PAGE_OFFSET_MASK))
     1292            )
     1293       )
    12881294    {
    12891295        Assert(!pgmPoolIsPageLocked(&pVM->pgm.s, pPage));
     
    13191325        }
    13201326
    1321         /* Temporarily allow write access to the page table again. */
    1322         rc = PGMHandlerPhysicalPageTempOff(pVM, pPage->GCPhys, pPage->GCPhys);
    1323         if (rc == VINF_SUCCESS)
    1324         {
    1325             rc = PGMShwModifyPage(pVCpu, pvFault, 1, X86_PTE_RW, ~(uint64_t)X86_PTE_RW);
    1326             AssertMsg(rc == VINF_SUCCESS
    1327                       /* In the SMP case the page table might be removed while we wait for the PGM lock in the trap handler. */
    1328                       ||  rc == VERR_PAGE_TABLE_NOT_PRESENT
    1329                       ||  rc == VERR_PAGE_NOT_PRESENT,
    1330                       ("PGMShwModifyPage -> GCPtr=%RGv rc=%d\n", pvFault, rc));
    1331 
    1332             pgmPoolAddDirtyPage(pVM, pPool, pPage);
    1333  
    1334             STAM_PROFILE_STOP(&pVM->pgm.s.CTX_SUFF(pPool)->CTX_SUFF_Z(StatMonitor), a);
    1335             pgmUnlock(pVM);
    1336             return rc;
     1327        /* The flushing above might fail for locked pages, so double check. */
     1328        if (    pPage->iMonitoredNext == NIL_PGMPOOL_IDX
     1329            &&  pPage->iMonitoredPrev == NIL_PGMPOOL_IDX)
     1330        {
     1331            /* Temporarily allow write access to the page table again. */
     1332            rc = PGMHandlerPhysicalPageTempOff(pVM, pPage->GCPhys, pPage->GCPhys);
     1333            if (rc == VINF_SUCCESS)
     1334            {
     1335                rc = PGMShwModifyPage(pVCpu, pvFault, 1, X86_PTE_RW, ~(uint64_t)X86_PTE_RW);
     1336                AssertMsg(rc == VINF_SUCCESS
     1337                        /* In the SMP case the page table might be removed while we wait for the PGM lock in the trap handler. */
     1338                        ||  rc == VERR_PAGE_TABLE_NOT_PRESENT
     1339                        ||  rc == VERR_PAGE_NOT_PRESENT,
     1340                        ("PGMShwModifyPage -> GCPtr=%RGv rc=%d\n", pvFault, rc));
     1341
     1342                pgmPoolAddDirtyPage(pVM, pPool, pPage);
     1343                pPage->pvDirtyFault = pvFault;
     1344     
     1345                STAM_PROFILE_STOP(&pVM->pgm.s.CTX_SUFF(pPool)->CTX_SUFF_Z(StatMonitor), a);
     1346                pgmUnlock(pVM);
     1347                return rc;
     1348            }
    13371349        }
    13381350    }
     
    13591371# ifdef PGMPOOL_WITH_OPTIMIZED_DIRTY_PT
    13601372/**
     1373 * Check references to guest physical memory in a PAE / PAE page table.
     1374 *
     1375 * @param   pPool       The pool.
     1376 * @param   pPage       The page.
     1377 * @param   pShwPT      The shadow page table (mapping of the page).
     1378 * @param   pGstPT      The guest page table.
     1379 */
     1380DECLINLINE(void) pgmPoolTrackCheckPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PTPAE pShwPT, PCX86PTPAE pGstPT)
     1381{
     1382    for (unsigned i = 0; i < RT_ELEMENTS(pShwPT->a); i++)
     1383    {
     1384        if (pShwPT->a[i].n.u1Present)
     1385        {
     1386            RTHCPHYS HCPhys = -1;
     1387            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        }
     1390    }
     1391}
     1392
     1393/**
    13611394 * Clear references to guest physical memory in a PAE / PAE page table.
    13621395 *
     
    13661399 * @param   pShwPT      The shadow page table (mapping of the page).
    13671400 * @param   pGstPT      The guest page table.
    1368  * @param   pGstPT      The old cached guest page table.
     1401 * @param   pOldGstPT   The old cached guest page table.
    13691402 */
    13701403DECLINLINE(unsigned) pgmPoolTrackFlushPTPaePae(PPGMPOOL pPool, PPGMPOOLPAGE pPage, PX86PTPAE pShwPT, PCX86PTPAE pGstPT, PCX86PTPAE pOldGstPT)
     
    14461479    pPage->fDirty         = false;
    14471480
     1481#ifdef VBOX_STRICT
     1482    uint64_t fFlags = 0;
     1483    rc = PGMShwGetPage(VMMGetCpu(pVM), pPage->pvDirtyFault, &fFlags, NULL);
     1484    AssertMsg(      (rc == VINF_SUCCESS && !(fFlags & X86_PTE_RW))
     1485                /* In the SMP case the page table might be removed while we wait for the PGM lock in the trap handler. */
     1486                ||  rc == VERR_PAGE_TABLE_NOT_PRESENT
     1487                ||  rc == VERR_PAGE_NOT_PRESENT,
     1488                ("PGMShwGetPage -> GCPtr=%RGv rc=%d flags=%RX64\n", pPage->pvDirtyFault, rc, fFlags));
     1489#endif
     1490
    14481491    /* This page is likely to be modified again, so reduce the nr of modifications just a bit here. */
    14491492    Assert(pPage->cModifications);
     
    14631506}
    14641507
     1508# ifndef IN_RING3
    14651509/**
    14661510 * Add a new dirty page
     
    14761520    Assert(PGMIsLocked(pVM));
    14771521    AssertCompile(RT_ELEMENTS(pPool->aIdxDirtyPages) == 8 || RT_ELEMENTS(pPool->aIdxDirtyPages) == 16);
    1478 
    1479     if (pPage->fDirty)
    1480         return;
     1522    Assert(!pPage->fDirty);
    14811523
    14821524    idxFree = pPool->idxFreeDirtyPage;
     
    14891531    AssertMsg(pPool->aIdxDirtyPages[idxFree] == NIL_PGMPOOL_IDX, ("idxFree=%d cDirtyPages=%d\n", idxFree, pPool->cDirtyPages));
    14901532
     1533    Log(("Add dirty page %RGp (slot=%d)\n", pPage->GCPhys, idxFree));
     1534
    14911535    /* Make a copy of the guest page table as we require valid GCPhys addresses when removing
    14921536     * references to physical pages. (the HCPhys linear lookup is *extremely* expensive!)
    14931537     */
     1538    void *pvShw = PGMPOOL_PAGE_2_LOCKED_PTR(pPool->CTX_SUFF(pVM), pPage);
    14941539    void *pvGst;
    14951540    int rc = PGM_GCPHYS_2_PTR(pPool->CTX_SUFF(pVM), pPage->GCPhys, &pvGst); AssertReleaseRC(rc);
    14961541    memcpy(&pPool->aDirtyPages[idxFree][0], pvGst, PAGE_SIZE);
     1542    pgmPoolTrackCheckPTPaePae(pPool, pPage, (PX86PTPAE)pvShw, (PCX86PTPAE)pvGst);
    14971543
    14981544    STAM_COUNTER_INC(&pPool->StatDirtyPage);
    1499     Log(("Mark dirty page %RGp (slot=%d)\n", pPage->GCPhys, idxFree));
    15001545    pPage->fDirty                  = true;
    15011546    pPage->idxDirty                = idxFree;
     
    15231568    return;
    15241569}
    1525 
     1570# endif /* !IN_RING3 */
    15261571
    15271572/**
     
    31433188    {
    31443189# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    3145         /* Start a subset here because pgmPoolTrackFlushGCPhysPTsSlow kill the pool otherwise. */
     3190        /* Start a subset here because pgmPoolTrackFlushGCPhysPTsSlow kills the pool otherwise. */
    31463191        uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu);
    31473192# endif
  • trunk/src/VBox/VMM/VMMAll/PGMAllShw.h

    r20374 r22600  
    367367                HWACCMInvalidatePhysPage(pVM, (RTGCPHYS)GCPtr);
    368368# else
    369                 PGM_INVL_ALL_VCPU_PG(pVM, GCPtr);
     369                PGM_INVL_PG_ALL_VCPU(pVM, GCPtr);
    370370# endif
    371371            }
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