VirtualBox

Changeset 20135 in vbox


Ignore:
Timestamp:
May 29, 2009 7:44:12 AM (16 years ago)
Author:
vboxsync
Message:

Prevent reuse of cached larged pages with different access attributes.

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

Legend:

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

    r20129 r20135  
    15811581
    15821582
     1583typedef enum
     1584{
     1585    PGMPOOLACCESS_DONTCARE = 0,
     1586    PGMPOOLACCESS_USER_RW,
     1587    PGMPOOLACCESS_USER_R,
     1588    PGMPOOLACCESS_SUPERVISOR_RW,
     1589    PGMPOOLACCESS_SUPERVISOR_R
     1590} PGMPOOLACCESS;
     1591
    15831592/**
    15841593 * The tracking data for a page in the pool.
     
    16011610    /** The kind of page we're shadowing. (This is really a PGMPOOLKIND enum.) */
    16021611    uint8_t             enmKind;
    1603     uint8_t             bPadding;
     1612    /** The subkind of page we're shadowing. (This is really a PGMPOOLACCESS enum.) */
     1613    uint8_t             enmAccess;
    16041614    /** The index of this page. */
    16051615    uint16_t            idx;
     
    29592969int             pgmR0DynMapHCPageCommon(PVM pVM, PPGMMAPSET pSet, RTHCPHYS HCPhys, void **ppv);
    29602970#endif
    2961 int             pgmPoolAlloc(PVM pVM, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, uint16_t iUser, uint32_t iUserTable, PPPGMPOOLPAGE ppPage);
     2971int             pgmPoolAllocEx(PVM pVM, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, PGMPOOLACCESS enmAccess, uint16_t iUser, uint32_t iUserTable, PPPGMPOOLPAGE ppPage);
     2972
     2973DECLINLINE(int) pgmPoolAlloc(PVM pVM, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, uint16_t iUser, uint32_t iUserTable, PPPGMPOOLPAGE ppPage)
     2974{
     2975    return pgmPoolAllocEx(pVM, GCPhys, enmKind, PGMPOOLACCESS_DONTCARE, iUser, iUserTable, ppPage);
     2976}
     2977
    29622978void            pgmPoolFree(PVM pVM, RTHCPHYS HCPhys, uint16_t iUser, uint32_t iUserTable);
    29632979void            pgmPoolFreeByPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage, uint16_t iUser, uint32_t iUserTable);
  • trunk/src/VBox/VMM/PGMPhys.cpp

    r20129 r20135  
    32333233            else
    32343234            {
    3235                 /* Temporariliy disabled phycial handler(s), since the recompiler
    3236                    doesn't get notified when it's reset we'll have to pretend its
     3235                /* Temporarily disabled physical handler(s), since the recompiler
     3236                   doesn't get notified when it's reset we'll have to pretend it's
    32373237                   operating normally. */
    32383238                if (pgmHandlerPhysicalIsAll(pVM, GCPhys))
     
    32663266            *ppv = (void *)((uintptr_t)pTlbe->pv | (GCPhys & PAGE_OFFSET_MASK));
    32673267            /** @todo mapping/locking hell; this isn't horribly efficient since
    3268              *        pgmPhysPageLoadIntoTlb will repeate the lookup we've done here. */
     3268             *        pgmPhysPageLoadIntoTlb will repeat the lookup we've done here. */
    32693269
    32703270            Log6(("PGMR3PhysTlbGCPhys2Ptr: GCPhys=%RGp rc=%Rrc pPage=%R[pgmpage] *ppv=%p\n", GCPhys, rc, pPage, *ppv));
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r20129 r20135  
    11881188    if (PdeSrc.n.u1Present)
    11891189    {
     1190# ifndef PGM_WITHOUT_MAPPING
    11901191        if (PdeDst.u & PGM_PDFLAGS_MAPPING)
    11911192        {
     
    11991200            pgmUnlock(pVM);
    12001201        }
    1201         else if (   PdeSrc.n.u1User != PdeDst.n.u1User
    1202                  || (!PdeSrc.n.u1Write && PdeDst.n.u1Write))
     1202        else
     1203# endif /* !PGM_WITHOUT_MAPPING */
     1204        if (   PdeSrc.n.u1User != PdeDst.n.u1User
     1205            || (!PdeSrc.n.u1Write && PdeDst.n.u1Write))
    12031206        {
    12041207            /*
     
    25892592        else
    25902593        {
     2594            PGMPOOLACCESS enmAccess;
     2595
    25912596            GCPhys = GST_GET_PDE_BIG_PG_GCPHYS(PdeSrc);
    25922597# if PGM_SHW_TYPE == PGM_TYPE_PAE && PGM_GST_TYPE == PGM_TYPE_32BIT
     
    25942599            GCPhys |= GCPtrPage & (1 << X86_PD_PAE_SHIFT);
    25952600# endif
    2596             rc = pgmPoolAlloc(pVM, GCPhys, BTH_PGMPOOLKIND_PT_FOR_BIG, pShwPde->idx,      iPDDst, &pShwPage);
     2601            /* Determine the right kind of large page to avoid incorrect cached entry reuse. */
     2602            if (PdeSrc.n.u1User)
     2603            {
     2604                if (PdeSrc.n.u1Write)
     2605                    enmAccess = PGMPOOLACCESS_USER_RW;
     2606                else
     2607                    enmAccess = PGMPOOLACCESS_USER_R;
     2608            }
     2609            else
     2610            {
     2611                if (PdeSrc.n.u1Write)
     2612                    enmAccess = PGMPOOLACCESS_SUPERVISOR_RW;
     2613                else
     2614                    enmAccess = PGMPOOLACCESS_SUPERVISOR_R;
     2615            }
     2616            rc = pgmPoolAllocEx(pVM, GCPhys, BTH_PGMPOOLKIND_PT_FOR_BIG, enmAccess, pShwPde->idx, iPDDst, &pShwPage);
    25972617        }
    25982618        if (rc == VINF_SUCCESS)
     
    33313351#endif /* PGM_GST_TYPE != PGM_TYPE_32BIT */
    33323352}
    3333 
    3334 
    3335 #if PGM_GST_TYPE == PGM_TYPE_32BIT || PGM_GST_TYPE == PGM_TYPE_PAE || PGM_GST_TYPE == PGM_TYPE_AMD64
    3336 # if PGM_SHW_TYPE == PGM_TYPE_32BIT || PGM_SHW_TYPE == PGM_TYPE_PAE || PGM_SHW_TYPE == PGM_TYPE_AMD64
    3337 /**
    3338  * Figures out which kind of shadow page this guest PDE warrants.
    3339  *
    3340  * @returns Shadow page kind.
    3341  * @param   pPdeSrc     The guest PDE in question.
    3342  * @param   cr4         The current guest cr4 value.
    3343  */
    3344 DECLINLINE(PGMPOOLKIND) PGM_BTH_NAME(CalcPageKind)(const GSTPDE *pPdeSrc, uint32_t cr4)
    3345 {
    3346 #  if PMG_GST_TYPE == PGM_TYPE_AMD64
    3347     if (!pPdeSrc->n.u1Size)
    3348 #  else
    3349     if (!pPdeSrc->n.u1Size || !(cr4 & X86_CR4_PSE))
    3350 #  endif
    3351         return BTH_PGMPOOLKIND_PT_FOR_PT;
    3352     //switch (pPdeSrc->u & (X86_PDE4M_RW | X86_PDE4M_US /*| X86_PDE4M_PAE_NX*/))
    3353     //{
    3354     //    case 0:
    3355     //      return BTH_PGMPOOLKIND_PT_FOR_BIG_RO;
    3356     //    case X86_PDE4M_RW:
    3357     //      return BTH_PGMPOOLKIND_PT_FOR_BIG_RW;
    3358     //    case X86_PDE4M_US:
    3359     //      return BTH_PGMPOOLKIND_PT_FOR_BIG_US;
    3360     //    case X86_PDE4M_RW | X86_PDE4M_US:
    3361     //      return BTH_PGMPOOLKIND_PT_FOR_BIG_RW_US;
    3362 #  if 0
    3363     //    case X86_PDE4M_PAE_NX:
    3364     //      return BTH_PGMPOOLKIND_PT_FOR_BIG_NX;
    3365     //    case X86_PDE4M_RW | X86_PDE4M_PAE_NX:
    3366     //      return BTH_PGMPOOLKIND_PT_FOR_BIG_RW_NX;
    3367     //    case X86_PDE4M_US | X86_PDE4M_PAE_NX:
    3368     //      return BTH_PGMPOOLKIND_PT_FOR_BIG_US_NX;
    3369     //    case X86_PDE4M_RW | X86_PDE4M_US | X86_PDE4M_PAE_NX:
    3370     //      return BTH_PGMPOOLKIND_PT_FOR_BIG_RW_US_NX;
    3371 #  endif
    3372             return BTH_PGMPOOLKIND_PT_FOR_BIG;
    3373     //}
    3374 }
    3375 # endif
    3376 #endif
    33773353
    33783354#undef MY_STAM_COUNTER_INC
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r20058 r20135  
    14291429 * @param   ppPage      Where to store the pointer to the page.
    14301430 */
    1431 static int pgmPoolCacheAlloc(PPGMPOOL pPool, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, uint16_t iUser, uint32_t iUserTable, PPPGMPOOLPAGE ppPage)
     1431static int pgmPoolCacheAlloc(PPGMPOOL pPool, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, PGMPOOLACCESS enmAccess, uint16_t iUser, uint32_t iUserTable, PPPGMPOOLPAGE ppPage)
    14321432{
    14331433#ifndef IN_RC
     
    14471447            if (pPage->GCPhys == GCPhys)
    14481448            {
    1449                 if ((PGMPOOLKIND)pPage->enmKind == enmKind)
     1449                if (    (PGMPOOLKIND)pPage->enmKind == enmKind
     1450                    &&  (PGMPOOLACCESS)pPage->enmAccess == enmAccess)
    14501451                {
    14511452                    /* Put it at the start of the use list to make sure pgmPoolTrackAddUser
     
    14651466                }
    14661467
    1467                 /*
    1468                  * The kind is different. In some cases we should now flush the page
    1469                  * as it has been reused, but in most cases this is normal remapping
    1470                  * of PDs as PT or big pages using the GCPhys field in a slightly
    1471                  * different way than the other kinds.
    1472                  */
    1473                 if (pgmPoolCacheReusedByKind((PGMPOOLKIND)pPage->enmKind, enmKind))
     1468                if ((PGMPOOLKIND)pPage->enmKind != enmKind)
    14741469                {
    1475                     STAM_COUNTER_INC(&pPool->StatCacheKindMismatches);
    1476                     pgmPoolFlushPage(pPool, pPage);
    1477                     PGM_INVL_VCPU_TLBS(VMMGetCpu(pVM)); /* see PT handler. */
    1478                     break;
     1470                    /*
     1471                     * The kind is different. In some cases we should now flush the page
     1472                     * as it has been reused, but in most cases this is normal remapping
     1473                     * of PDs as PT or big pages using the GCPhys field in a slightly
     1474                     * different way than the other kinds.
     1475                     */
     1476                    if (pgmPoolCacheReusedByKind((PGMPOOLKIND)pPage->enmKind, enmKind))
     1477                    {
     1478                        STAM_COUNTER_INC(&pPool->StatCacheKindMismatches);
     1479                        pgmPoolFlushPage(pPool, pPage);
     1480                        PGM_INVL_VCPU_TLBS(VMMGetCpu(pVM)); /* see PT handler. */
     1481                        break;
     1482                    }
    14791483                }
    14801484            }
     
    39163920    pPool->iFreeHead = pPage->idx;
    39173921    pPage->enmKind = PGMPOOLKIND_FREE;
     3922    pPage->enmAccess = PGMPOOLACCESS_DONTCARE;
    39183923    pPage->GCPhys = NIL_RTGCPHYS;
    39193924    pPage->fReusedFlushPending = false;
     
    40184023#endif
    40194024}
    4020 
    40214025
    40224026/**
     
    40354039 *                      shadow PT is covering.
    40364040 * @param   enmKind     The kind of mapping.
     4041 * @param   enmAccess   Access type for the mapping (only relevant for big pages)
    40374042 * @param   iUser       The shadow page pool index of the user table.
    40384043 * @param   iUserTable  The index into the user table (shadowed).
    40394044 * @param   ppPage      Where to store the pointer to the page. NULL is stored here on failure.
    40404045 */
    4041 int pgmPoolAlloc(PVM pVM, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, uint16_t iUser, uint32_t iUserTable, PPPGMPOOLPAGE ppPage)
     4046int pgmPoolAllocEx(PVM pVM, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, PGMPOOLACCESS enmAccess, uint16_t iUser, uint32_t iUserTable, PPPGMPOOLPAGE ppPage)
    40424047{
    40434048    PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
     
    40544059    if (pPool->fCacheEnabled)
    40554060    {
    4056         int rc2 = pgmPoolCacheAlloc(pPool, GCPhys, enmKind, iUser, iUserTable, ppPage);
     4061        int rc2 = pgmPoolCacheAlloc(pPool, GCPhys, enmKind, enmAccess, iUser, iUserTable, ppPage);
    40574062        if (RT_SUCCESS(rc2))
    40584063        {
     
    40944099    pPool->cUsedPages++;                /* physical handler registration / pgmPoolTrackFlushGCPhysPTsSlow requirement. */
    40954100    pPage->enmKind = enmKind;
     4101    pPage->enmAccess = enmAccess;
    40964102    pPage->GCPhys = GCPhys;
    40974103    pPage->fSeenNonGlobal = false;      /* Set this to 'true' to disable this feature. */
     
    41174123    {
    41184124        pPool->cUsedPages--;
    4119         pPage->enmKind = PGMPOOLKIND_FREE;
    4120         pPage->GCPhys = NIL_RTGCPHYS;
    4121         pPage->iNext = pPool->iFreeHead;
    4122         pPool->iFreeHead = pPage->idx;
     4125        pPage->enmKind      = PGMPOOLKIND_FREE;
     4126        pPage->enmAccess    = PGMPOOLACCESS_DONTCARE;
     4127        pPage->GCPhys       = NIL_RTGCPHYS;
     4128        pPage->iNext        = pPool->iFreeHead;
     4129        pPool->iFreeHead    = pPage->idx;
    41234130        pgmUnlock(pVM);
    41244131        STAM_PROFILE_ADV_STOP(&pPool->StatAlloc, a);
     
    42444251        pPage->cModifications = 0;
    42454252#endif
    4246         pPage->GCPhys    = NIL_RTGCPHYS;
    4247         pPage->enmKind   = PGMPOOLKIND_FREE;
     4253        pPage->GCPhys     = NIL_RTGCPHYS;
     4254        pPage->enmKind    = PGMPOOLKIND_FREE;
     4255        pPage->enmAccess  = PGMPOOLACCESS_DONTCARE;
    42484256        Assert(pPage->idx == i);
    4249         pPage->iNext     = i + 1;
    4250         pPage->fZeroed   = false;       /* This could probably be optimized, but better safe than sorry. */
     4257        pPage->iNext      = i + 1;
     4258        pPage->fZeroed    = false;       /* This could probably be optimized, but better safe than sorry. */
    42514259        pPage->fSeenNonGlobal = false;
    4252         pPage->fMonitored= false;
    4253         pPage->fCached   = false;
     4260        pPage->fMonitored = false;
     4261        pPage->fCached    = false;
    42544262        pPage->fReusedFlushPending = false;
    42554263#ifdef PGMPOOL_WITH_USER_TRACKING
    4256         pPage->iUserHead = NIL_PGMPOOL_USER_INDEX;
     4264        pPage->iUserHead  = NIL_PGMPOOL_USER_INDEX;
    42574265#else
    4258         pPage->fCR3Mix = false;
     4266        pPage->fCR3Mix    = false;
    42594267#endif
    42604268#ifdef PGMPOOL_WITH_CACHE
    4261         pPage->iAgeNext  = NIL_PGMPOOL_IDX;
    4262         pPage->iAgePrev  = NIL_PGMPOOL_IDX;
    4263 #endif
    4264         pPage->cLocked   = 0;
     4269        pPage->iAgeNext   = NIL_PGMPOOL_IDX;
     4270        pPage->iAgePrev   = NIL_PGMPOOL_IDX;
     4271#endif
     4272        pPage->cLocked    = 0;
    42654273    }
    42664274    pPool->aPages[pPool->cCurPages - 1].iNext = NIL_PGMPOOL_IDX;
  • trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp

    r20087 r20135  
    649649    GEN_CHECK_OFF(PGMPOOLPAGE, pvPageR3);
    650650    GEN_CHECK_OFF(PGMPOOLPAGE, enmKind);
    651     GEN_CHECK_OFF(PGMPOOLPAGE, bPadding);
     651    GEN_CHECK_OFF(PGMPOOLPAGE, enmAccess);
    652652    GEN_CHECK_OFF(PGMPOOLPAGE, idx);
    653653    GEN_CHECK_OFF(PGMPOOLPAGE, iNext);
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