VirtualBox

Changeset 55910 in vbox


Ignore:
Timestamp:
May 18, 2015 1:36:19 PM (10 years ago)
Author:
vboxsync
Message:

pgmPoolAccessHandler: Make use of the enmOrigin to detect device writes and increase the write size to 16, doing proper splitting in the manner of pgmPoolAccessPfHandlerSimple.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r55909 r55910  
    13791379             GCPhys, pPage, pPage->Core.Key, pPage->idx, pPage->GCPhys, pPage->enmKind));
    13801380
    1381     NOREF(pvBuf); NOREF(enmAccessType); NOREF(enmOrigin);
    1382 
    1383     /*
    1384      * We don't have to be very sophisticated about this since there are relativly few calls here.
    1385      * However, we must try our best to detect any non-cpu accesses (disk / networking).
     1381    NOREF(pvBuf); NOREF(enmAccessType);
     1382
     1383    /*
     1384     * Make sure the pool page wasn't modified by a different CPU.
    13861385     */
    13871386    pgmLock(pVM);
    1388     if (PHYS_PAGE_ADDRESS(GCPhys) != PHYS_PAGE_ADDRESS(pPage->GCPhys))
    1389     {
    1390         /* Pool page changed while we were waiting for the lock; ignore. */
     1387    if (PHYS_PAGE_ADDRESS(GCPhys) == PHYS_PAGE_ADDRESS(pPage->GCPhys))
     1388    {
     1389        Assert(pPage->enmKind != PGMPOOLKIND_FREE);
     1390
     1391        /* The max modification count before flushing depends on the context and page type. */
     1392#ifdef IN_RING3
     1393        uint16_t const cMaxModifications = 96; /* it's cheaper here, right? */
     1394#else
     1395        uint16_t cMaxModifications;
     1396        if (    pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_PAE_PT
     1397            ||  pPage->enmKind == PGMPOOLKIND_PAE_PT_FOR_32BIT_PT)
     1398            cMaxModifications = 4;
     1399        else
     1400            cMaxModifications = 24;
     1401# ifdef IN_RC
     1402        cMaxModifications *= 2; /* traps are cheaper than exists. */
     1403# endif
     1404#endif
     1405
     1406        /*
     1407         * We don't have to be very sophisticated about this since there are relativly few calls here.
     1408         * However, we must try our best to detect any non-cpu accesses (disk / networking).
     1409         */
     1410        if (   (   pPage->cModifications < cMaxModifications
     1411                || pgmPoolIsPageLocked(pPage) )
     1412            && enmOrigin != PGMACCESSORIGIN_DEVICE
     1413            && cbBuf <= 16)
     1414        {
     1415            /* Clear the shadow entry. */
     1416            if (!pPage->cModifications++)
     1417                pgmPoolMonitorModifiedInsert(pPool, pPage);
     1418
     1419            if (cbBuf <= 8)
     1420                pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhys, pvBuf, (uint32_t)cbBuf);
     1421            else
     1422            {
     1423                pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhys, pvBuf, 8);
     1424                pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhys + 8, (uint8_t *)pvBuf + 8, (uint32_t)cbBuf - 8);
     1425            }
     1426        }
     1427        else
     1428        {
     1429            /* ASSUME that VERR_PGM_POOL_CLEARED can be ignored here and that FFs will deal with it in due time. */
     1430            pgmPoolMonitorChainFlush(pPool, pPage);
     1431        }
     1432
     1433        STAM_PROFILE_STOP_EX(&pPool->StatMonitorR3, &pPool->StatMonitorR3FlushPage, a);
     1434    }
     1435    else
    13911436        Log(("CPU%d: PGM_ALL_CB_DECL pgm pool page for %RGp changed (to %RGp) while waiting!\n", pVCpu->idCpu, PHYS_PAGE_ADDRESS(GCPhys), PHYS_PAGE_ADDRESS(pPage->GCPhys)));
    1392         pgmUnlock(pVM);
    1393         return VINF_PGM_HANDLER_DO_DEFAULT;
    1394     }
    1395 
    1396     Assert(pPage->enmKind != PGMPOOLKIND_FREE);
    1397 /** @todo we can do better than this now.   */
    1398     if (   (   pPage->cModifications < 96 /* it's cheaper here. */
    1399             || pgmPoolIsPageLocked(pPage) )
    1400         && cbBuf <= 4)
    1401     {
    1402         /* Clear the shadow entry. */
    1403         if (!pPage->cModifications++)
    1404             pgmPoolMonitorModifiedInsert(pPool, pPage);
    1405         /** @todo r=bird: making unsafe assumption about not crossing entries here! */
    1406         pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhys, pvBuf, 0 /* unknown write size */);
    1407         STAM_PROFILE_STOP(&pPool->StatMonitorR3, a);
    1408     }
    1409     else
    1410     {
    1411         pgmPoolMonitorChainFlush(pPool, pPage); /* ASSUME that VERR_PGM_POOL_CLEARED can be ignored here and that FFs will deal with it in due time. */
    1412         STAM_PROFILE_STOP_EX(&pPool->StatMonitorR3, &pPool->StatMonitorR3FlushPage, a);
    1413     }
    14141437    pgmUnlock(pVM);
    14151438    return VINF_PGM_HANDLER_DO_DEFAULT;
    14161439}
    1417 
    1418 
    14191440
    14201441
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