VirtualBox

Changeset 14748

Show
Ignore:
Timestamp:
11/28/08 01:34:24 (1 month ago)
Author:
vboxsync
Message:

PGMR0DynMap: a couple of bugs, guard pages and PGMR0DynMapAssertIntegrity.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/include/VBox/pgm.h

    r14346 r14748  
    470470VMMR0DECL(int)      PGMR0DynMapInitVM(PVM pVM); 
    471471VMMR0DECL(void)     PGMR0DynMapTermVM(PVM pVM); 
     472VMMR0DECL(int)      PGMR0DynMapAssertIntegrity(void); 
    472473# endif 
    473474/** @} */ 
  • trunk/src/VBox/VMM/VMMR0/PGMR0DynMap.cpp

    r14674 r14748  
    5050/** The number of pages we reserve per CPU. */ 
    5151#define PGMR0DYNMAP_PAGES_PER_CPU           64 
     52/** The number of guard pages. */ 
     53#if defined(VBOX_STRICT) 
     54# define PGMR0DYNMAP_GUARD_PAGES            7 
     55#else 
     56# define PGMR0DYNMAP_GUARD_PAGES            0 
     57#endif 
     58/** The dummy physical address of guard pages. */ 
     59#define PGMR0DYNMAP_GUARD_PAGE_HCPHYS       UINT32_C(0x7777feed) 
     60/** The dummy reference count of guard pages. (Must be non-zero.) */ 
     61#define PGMR0DYNMAP_GUARD_PAGE_REF_COUNT    INT32_C(0x7777feed) 
     62#if 0 
     63/** Define this to just clear the present bit on guard pages. 
     64 * The alternative is to replace the entire PTE with an bad not-present 
     65 * PTE. Either way, XNU will screw us. :-/   */ 
     66#define PGMR0DYNMAP_GUARD_NP 
     67#endif 
     68/** The dummy PTE value for a page. */ 
     69#define PGMR0DYNMAP_GUARD_PAGE_LEGACY_PTE   X86_PTE_PG_MASK 
     70/** The dummy PTE value for a page. */ 
     71#define PGMR0DYNMAP_GUARD_PAGE_PAE_PTE      UINT64_MAX /*X86_PTE_PAE_PG_MASK*/ 
    5272/** Calcs the overload threshold. Current set at 50%. */ 
    5373#define PGMR0DYNMAP_CALC_OVERLOAD(cPages)   ((cPages) / 2) 
    5474 
     75#if 0 
    5576/* Assertions causes panics if preemption is disabled, this can be used to work aroudn that. */ 
    56 /*#define RTSpinlockAcquire(a,b) do {} while (0) 
    57 #define RTSpinlockRelease(a,b) do {} while (0) */ 
    58  
     77#define RTSpinlockAcquire(a,b) do {} while (0) 
     78#define RTSpinlockRelease(a,b) do {} while (0) 
     79#endif 
    5980 
    6081 
     
    145166    /** Whether it's 32-bit legacy or PAE/AMD64 paging mode. */ 
    146167    bool                        fLegacyMode; 
    147     /** The current load. */ 
     168    /** The current load. 
     169     * This does not include guard pages. */ 
    148170    uint32_t                    cLoad; 
    149171    /** The max load ever. 
     
    152174    /** Initialization / termination lock. */ 
    153175    RTSEMFASTMUTEX              hInitLock; 
     176    /** The number of guard pages. */ 
     177    uint32_t                    cGuardPages; 
    154178    /** The number of users (protected by hInitLock). */ 
    155179    uint32_t                    cUsers; 
     
    365389#endif 
    366390    } 
    367     else if (pThis->cMaxLoad > PGMR0DYNMAP_CALC_OVERLOAD(pThis->cPages)) 
     391    else if (pThis->cMaxLoad > PGMR0DYNMAP_CALC_OVERLOAD(pThis->cPages - pThis->cGuardPages)) 
    368392        rc = pgmR0DynMapExpand(pThis); 
    369393    if (RT_SUCCESS(rc)) 
     
    399423    { 
    400424        pVM->pgm.s.pvR0DynMapUsed = NULL; 
     425 
     426#ifdef VBOX_STRICT 
     427        PGMR0DynMapAssertIntegrity(); 
     428#endif 
    401429 
    402430        /* 
     
    455483 
    456484/** 
     485 * Shoots down the TLBs for all the cache pages, pgmR0DynMapTearDown helper. 
     486 * 
     487 * @param   idCpu           The current CPU. 
     488 * @param   pvUser1         The dynamic mapping cache instance. 
     489 * @param   pvUser2         Unused, NULL. 
     490 */ 
     491static DECLCALLBACK(void) pgmR0DynMapShootDownTlbs(RTCPUID idCpu, void *pvUser1, void *pvUser2) 
     492{ 
     493    Assert(!pvUser2); 
     494    PPGMR0DYNMAP        pThis   = (PPGMR0DYNMAP)pvUser1; 
     495    Assert(pThis == g_pPGMR0DynMap); 
     496    PPGMR0DYNMAPENTRY   paPages = pThis->paPages; 
     497    uint32_t            iPage   = pThis->cPages; 
     498    while (iPage-- > 0) 
     499        ASMInvalidatePage(paPages[iPage].pvPage); 
     500} 
     501 
     502 
     503/** 
     504 * Shoot down the TLBs for every single cache entry on all CPUs. 
     505 * 
     506 * @returns IPRT status code (RTMpOnAll). 
     507 * @param   pThis       The dynamic mapping cache instance. 
     508 */ 
     509static int pgmR0DynMapTlbShootDown(PPGMR0DYNMAP pThis) 
     510{ 
     511    int rc = RTMpOnAll(pgmR0DynMapShootDownTlbs, pThis, NULL); 
     512    AssertRC(rc); 
     513    if (RT_FAILURE(rc)) 
     514    { 
     515        uint32_t iPage = pThis->cPages; 
     516        while (iPage-- > 0) 
     517            ASMInvalidatePage(pThis->paPages[iPage].pvPage); 
     518    } 
     519    return rc; 
     520} 
     521 
     522 
     523/** 
    457524 * Calculate the new cache size based on cMaxLoad statistics. 
    458525 * 
     
    468535    RTCPUID     cCpus     = RTMpGetCount(); 
    469536    AssertReturn(cCpus > 0 && cCpus <= RTCPUSET_MAX_CPUS, 0); 
    470     uint32_t    cPages    = cCpus * PGMR0DYNMAP_PAGES_PER_CPU; 
     537    uint32_t    cPages    = cCpus * PGMR0DYNMAP_PAGES_PER_CPU; 
    471538    uint32_t    cMinPages = cCpus * (PGMR0DYNMAP_PAGES_PER_CPU / 2); 
    472539 
     
    485552    if (cPages < pThis->cPages) 
    486553        cPages = pThis->cPages; 
     554    cPages *= PGMR0DYNMAP_GUARD_PAGES + 1; 
    487555    if (cPages > PGMR0DYNMAP_MAX_PAGES) 
    488556        cPages = PGMR0DYNMAP_MAX_PAGES; 
     
    490558    if (cMinPages < pThis->cPages) 
    491559        cMinPages = pThis->cPages; 
     560    cMinPages *= PGMR0DYNMAP_GUARD_PAGES + 1; 
    492561    if (cMinPages > PGMR0DYNMAP_MAX_PAGES) 
    493562        cMinPages = PGMR0DYNMAP_MAX_PAGES; 
     
    687756            return VERR_INTERNAL_ERROR; 
    688757        } 
    689         Log(("#%d: iEntry=%4d uEntry=%#llx pvEntry=%p HCPhys=%RHp \n", i, iEntry, uEntry, pvEntry, pPgLvl->a[i].HCPhys)); 
     758        /*Log(("#%d: iEntry=%4d uEntry=%#llx pvEntry=%p HCPhys=%RHp \n", i, iEntry, uEntry, pvEntry, pPgLvl->a[i].HCPhys));*/ 
    690759    } 
    691760 
     
    697766 
    698767/** 
     768 * Sets up a guard page. 
     769 * 
     770 * @param   pThis       The dynamic mapping cache instance. 
     771 * @param   pPage       The page. 
     772 */ 
     773DECLINLINE(void) pgmR0DynMapSetupGuardPage(PPGMR0DYNMAP pThis, PPGMR0DYNMAPENTRY pPage) 
     774{ 
     775    memset(pPage->pvPage, 0xfd, PAGE_SIZE); 
     776    pPage->cRefs  = PGMR0DYNMAP_GUARD_PAGE_REF_COUNT; 
     777    pPage->HCPhys = PGMR0DYNMAP_GUARD_PAGE_HCPHYS; 
     778#ifdef PGMR0DYNMAP_GUARD_NP 
     779    ASMAtomicBitClear(pPage->uPte.pv, X86_PTE_BIT_P); 
     780#else 
     781    if (pThis->fLegacyMode) 
     782        ASMAtomicWriteU32(&pPage->uPte.pLegacy->u, PGMR0DYNMAP_GUARD_PAGE_LEGACY_PTE); 
     783    else 
     784        ASMAtomicWriteU64(&pPage->uPte.pPae->u,    PGMR0DYNMAP_GUARD_PAGE_PAE_PTE); 
     785#endif 
     786    pThis->cGuardPages++; 
     787} 
     788 
     789 
     790/** 
    699791 * Adds a new segment of the specified size. 
    700792 * 
     
    709801 
    710802    /* 
    711      * Do the array rellocation first. 
     803     * Do the array reallocations first. 
    712804     * (The pages array has to be replaced behind the spinlock of course.) 
    713805     */ 
     
    760852        PGMR0DYNMAPPGLVL    PgLvl; 
    761853        pgmR0DynMapPagingArrayInit(pThis, &PgLvl); 
    762         uint32_t            iEndPage = pThis->cPages + cPages; 
     854        uint32_t const      iEndPage = pThis->cPages + cPages; 
    763855        for (uint32_t iPage = pThis->cPages; 
    764856             iPage < iEndPage; 
     
    809901        if (RT_SUCCESS(rc)) 
    810902        { 
    811             /** @todo setup guard pages here later (strict builds should leave every 
    812              *        second page and the start/end pages not present).  */ 
     903#if PGMR0DYNMAP_GUARD_PAGES > 0 
     904            /* 
     905             * Setup guard pages. 
     906             * (Note: TLBs will be shot down later on.) 
     907             */ 
     908            uint32_t iPage = pThis->cPages; 
     909            while (iPage < iEndPage) 
     910            { 
     911                for (uint32_t iGPg = 0; iGPg < PGMR0DYNMAP_GUARD_PAGES && iPage < iEndPage; iGPg++, iPage++) 
     912                    pgmR0DynMapSetupGuardPage(pThis, &pThis->paPages[iPage]); 
     913                iPage++; /* the guarded page */ 
     914            } 
     915 
     916            /* Make sure the very last page is a guard page too. */ 
     917            iPage = iEndPage - 1; 
     918            if (pThis->paPages[iPage].cRefs != PGMR0DYNMAP_GUARD_PAGE_REF_COUNT) 
     919                pgmR0DynMapSetupGuardPage(pThis, &pThis->paPages[iPage]); 
     920#endif /* PGMR0DYNMAP_GUARD_PAGES > 0 */ 
    813921 
    814922            /* 
     
    882990    } 
    883991    Assert(ASMGetFlags() & X86_EFL_IF); 
     992 
     993#if PGMR0DYNMAP_GUARD_PAGES > 0 
     994    /* paranoia */ 
     995    if (RT_SUCCESS(rc)) 
     996        pgmR0DynMapTlbShootDown(pThis); 
     997#endif 
    884998    return rc; 
    885999} 
     
    9191033    } 
    9201034    Assert(ASMGetFlags() & X86_EFL_IF); 
     1035 
     1036#if PGMR0DYNMAP_GUARD_PAGES > 0 
     1037    /* paranoia */ 
     1038    if (RT_SUCCESS(rc)) 
     1039        pgmR0DynMapTlbShootDown(pThis); 
     1040#endif 
    9211041    return rc; 
    922 } 
    923  
    924  
    925 /** 
    926  * Shoots down the TLBs for all the cache pages, pgmR0DynMapTearDown helper. 
    927  * 
    928  * @param   idCpu           The current CPU. 
    929  * @param   pvUser1         The dynamic mapping cache instance. 
    930  * @param   pvUser2         Unused, NULL. 
    931  */ 
    932 static DECLCALLBACK(void) pgmR0DynMapShootDownTlbs(RTCPUID idCpu, void *pvUser1, void *pvUser2) 
    933 { 
    934     Assert(!pvUser2); 
    935     PPGMR0DYNMAP        pThis   = (PPGMR0DYNMAP)pvUser1; 
    936     Assert(pThis == g_pPGMR0DynMap); 
    937     PPGMR0DYNMAPENTRY   paPages = pThis->paPages; 
    938     uint32_t            iPage   = pThis->cPages; 
    939     while (iPage-- > 0) 
    940         ASMInvalidatePage(paPages[iPage].pvPage); 
    9411042} 
    9421043 
     
    9821083    /* 
    9831084     * Shoot down the TLBs on all CPUs before freeing them. 
    984      * If RTMpOnAll fails, make sure the TLBs are invalidated on the current CPU at least. 
    985      */ 
    986     int rc = RTMpOnAll(pgmR0DynMapShootDownTlbs, pThis, NULL); 
    987     AssertRC(rc); 
    988     if (RT_FAILURE(rc)) 
    989     { 
    990         iPage = pThis->cPages; 
    991         while (iPage-- > 0) 
    992             ASMInvalidatePage(paPages[iPage].pvPage); 
    993     } 
     1085     */ 
     1086    pgmR0DynMapTlbShootDown(pThis); 
    9941087 
    9951088    /* 
     
    9981091    while (pThis->pSegHead) 
    9991092    { 
     1093        int             rc; 
    10001094        PPGMR0DYNMAPSEG pSeg = pThis->pSegHead; 
    10011095        pThis->pSegHead = pSeg->pNext; 
     
    10811175        iFreePage = iPage; 
    10821176    else if (!paPages[(iPage + 1) % cPages].cRefs) 
    1083         iFreePage = iPage
     1177        iFreePage = iPage + 1
    10841178    else if (!paPages[(iPage + 2) % cPages].cRefs) 
    1085         iFreePage = iPage
     1179        iFreePage = iPage + 2
    10861180    else if (!paPages[(iPage + 3) % cPages].cRefs) 
    1087         iFreePage = iPage
     1181        iFreePage = iPage + 3
    10881182    else if (!paPages[(iPage + 4) % cPages].cRefs) 
    1089         iFreePage = iPage
     1183        iFreePage = iPage + 4
    10901184    else 
    10911185    { 
     
    10931187         * Search for an unused or matching entry. 
    10941188         */ 
    1095         iFreePage = (iPage + 5) % pThis->cPages; 
     1189        iFreePage = (iPage + 5) % cPages; 
    10961190        for (;;) 
    10971191        { 
     
    11031197            /* advance */ 
    11041198            iFreePage = (iFreePage + 1) % cPages; 
    1105             if (RT_UNLIKELY(iFreePage != iPage)) 
     1199            if (RT_UNLIKELY(iFreePage == iPage)) 
    11061200                return UINT32_MAX; 
    11071201        } 
     
    11111205     * Setup the new entry. 
    11121206     */ 
     1207    /*Log6(("pgmR0DynMapPageSlow: old - %RHp %#x %#llx\n", paPages[iFreePage].HCPhys, paPages[iFreePage].cRefs, paPages[iFreePage].uPte.pPae->u));*/ 
    11131208    paPages[iFreePage].HCPhys = HCPhys; 
    11141209    RTCpuSetFill(&paPages[iFreePage].PendingSet); 
     
    11411236 * Maps a page into the pool. 
    11421237 * 
    1143  * @returns Pointer to the mapping
     1238 * @returns Page index on success, UINT32_MAX on failure
    11441239 * @param   pThis       The dynamic mapping cache instance. 
    11451240 * @param   HCPhys      The address of the page to be mapped. 
    1146  * @param   piPage      Where to store the page index
    1147  */ 
    1148 DECLINLINE(void *) pgmR0DynMapPage(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, uint32_t *piPage) 
     1241 * @param   ppvPage      Where to the page address
     1242 */ 
     1243DECLINLINE(uint32_t) pgmR0DynMapPage(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, void **ppvPage) 
    11491244{ 
    11501245    RTSPINLOCKTMP   Tmp       = RTSPINLOCKTMP_INITIALIZER; 
     
    11811276                        { 
    11821277                            RTSpinlockRelease(pThis->hSpinlock, &Tmp); 
    1183                             return NULL
     1278                            return iPage
    11841279                        } 
    11851280                    } 
     
    12061301        if (pThis->cLoad > pThis->cMaxLoad) 
    12071302            pThis->cMaxLoad = pThis->cLoad; 
    1208         AssertMsg(pThis->cLoad <= pThis->cPages, ("%d/%d\n", pThis->cLoad, pThis->cPages)); 
     1303        AssertMsg(pThis->cLoad <= pThis->cPages - pThis->cGuardPages, ("%d/%d\n", pThis->cLoad, pThis->cPages - pThis->cGuardPages)); 
    12091304    } 
    12101305    else if (RT_UNLIKELY(cRefs <= 0)) 
     
    12121307        ASMAtomicDecS32(&paPages[iPage].cRefs); 
    12131308        RTSpinlockRelease(pThis->hSpinlock, &Tmp); 
    1214         AssertLogRelMsgFailedReturn(("cRefs=%d iPage=%p HCPhys=%RHp\n", cRefs, iPage, HCPhys), NULL); 
     1309        AssertLogRelMsgFailedReturn(("cRefs=%d iPage=%p HCPhys=%RHp\n", cRefs, iPage, HCPhys), UINT32_MAX); 
    12151310    } 
    12161311    void *pvPage = paPages[iPage].pvPage; 
     
    12311326    ASMInvalidatePage(pvPage); 
    12321327 
    1233     *piPage = iPage; 
    1234     return pvPage; 
     1328    *ppvPage = pvPage; 
     1329    return iPage; 
     1330
     1331 
     1332 
     1333/** 
     1334 * Assert the the integrity of the pool. 
     1335 * 
     1336 * @returns VBox status code. 
     1337 */ 
     1338VMMR0DECL(int) PGMR0DynMapAssertIntegrity(void) 
     1339
     1340    /* 
     1341     * Basic pool stuff that doesn't require any lock, just assumes we're a user. 
     1342     */ 
     1343    PPGMR0DYNMAP    pThis = g_pPGMR0DynMap; 
     1344    if (!pThis) 
     1345        return VINF_SUCCESS; 
     1346    AssertPtrReturn(pThis, VERR_INVALID_POINTER); 
     1347    AssertReturn(pThis->u32Magic == PGMR0DYNMAP_MAGIC, VERR_INVALID_MAGIC); 
     1348    if (!pThis->cUsers) 
     1349        return VERR_INVALID_PARAMETER; 
     1350 
     1351 
     1352    int             rc = VINF_SUCCESS; 
     1353    RTSPINLOCKTMP   Tmp = RTSPINLOCKTMP_INITIALIZER; 
     1354    RTSpinlockAcquire(pThis->hSpinlock, &Tmp); 
     1355#define CHECK_RET(expr, a) \ 
     1356    do { \ 
     1357        if (!(expr)) \ 
     1358        { \ 
     1359            RTSpinlockRelease(pThis->hSpinlock, &Tmp); \ 
     1360            AssertMsg1(#expr, __LINE__, __FILE__, __PRETTY_FUNCTION__); \ 
     1361            AssertMsg2 a; \ 
     1362            return VERR_INTERNAL_ERROR; \ 
     1363        } \ 
     1364    } while (0) 
     1365 
     1366    /* 
     1367     * Check that the PTEs are correct. 
     1368     */ 
     1369    uint32_t            cGuard      = 0; 
     1370    uint32_t            cLoad       = 0; 
     1371    PPGMR0DYNMAPENTRY   paPages     = pThis->paPages; 
     1372    uint32_t            iPage       = pThis->cPages; 
     1373    if (pThis->fLegacyMode) 
     1374    { 
     1375        PCX86PGUINT     paSavedPTEs = (PCX86PGUINT)pThis->pvSavedPTEs; NOREF(paSavedPTEs); 
     1376        while (iPage-- > 0) 
     1377        { 
     1378            CHECK_RET(!((uintptr_t)paPages[iPage].pvPage & PAGE_OFFSET_MASK), ("#%u: %p\n", iPage, paPages[iPage].pvPage)); 
     1379            if (    paPages[iPage].cRefs  == PGMR0DYNMAP_GUARD_PAGE_REF_COUNT 
     1380                &&  paPages[iPage].HCPhys == PGMR0DYNMAP_GUARD_PAGE_HCPHYS) 
     1381            { 
     1382#ifdef PGMR0DYNMAP_GUARD_NP 
     1383                CHECK_RET(paPages[iPage].uPte.pLegacy->u == (paSavedPTEs[iPage] & ~(X86PGUINT)X86_PTE_P), 
     1384                          ("#%u: %#x %#x", iPage, paPages[iPage].uPte.pLegacy->u, paSavedPTEs[iPage])); 
     1385#else 
     1386                CHECK_RET(paPages[iPage].uPte.pLegacy->u == PGMR0DYNMAP_GUARD_PAGE_LEGACY_PTE, 
     1387                          ("#%u: %#x", iPage, paPages[iPage].uPte.pLegacy->u)); 
     1388#endif 
     1389                cGuard++; 
     1390            } 
     1391            else if (paPages[iPage].HCPhys != NIL_RTHCPHYS) 
     1392            { 
     1393                CHECK_RET(!(paPages[iPage].HCPhys & PAGE_OFFSET_MASK), ("#%u: %RHp\n", iPage, paPages[iPage].HCPhys)); 
     1394                X86PGUINT uPte = (paSavedPTEs[iPage] & X86_PTE_G | X86_PTE_PAT | X86_PTE_PCD | X86_PTE_PWT) 
     1395                               | X86_PTE_P | X86_PTE_RW | X86_PTE_A | X86_PTE_D 
     1396                               | (paPages[iPage].HCPhys & X86_PTE_PAE_PG_MASK); 
     1397                CHECK_RET(paPages[iPage].uPte.pLegacy->u == uPte, 
     1398                          ("#%u: %#x %#x", iPage, paPages[iPage].uPte.pLegacy->u, uPte)); 
     1399                if (paPages[iPage].cRefs) 
     1400                    cLoad++; 
     1401            } 
     1402            else 
     1403                CHECK_RET(paPages[iPage].uPte.pLegacy->u == paSavedPTEs[iPage], 
     1404                          ("#%u: %#x %#x", iPage, paPages[iPage].uPte.pLegacy->u, paSavedPTEs[iPage])); 
     1405        } 
     1406    } 
     1407    else 
     1408    { 
     1409        PCX86PGPAEUINT  paSavedPTEs = (PCX86PGPAEUINT)pThis->pvSavedPTEs; NOREF(paSavedPTEs); 
     1410        while (iPage-- > 0) 
     1411        { 
     1412            CHECK_RET(!((uintptr_t)paPages[iPage].pvPage & PAGE_OFFSET_MASK), ("#%u: %p\n", iPage, paPages[iPage].pvPage)); 
     1413            if (    paPages[iPage].cRefs  == PGMR0DYNMAP_GUARD_PAGE_REF_COUNT 
     1414                &&  paPages[iPage].HCPhys == PGMR0DYNMAP_GUARD_PAGE_HCPHYS) 
     1415            { 
     1416#ifdef PGMR0DYNMAP_GUARD_NP 
     1417                CHECK_RET(paPages[iPage].uPte.pPae->u == (paSavedPTEs[iPage] & ~(X86PGPAEUINT)X86_PTE_P), 
     1418                          ("#%u: %#llx %#llx", iPage, paPages[iPage].uPte.pPae->u, paSavedPTEs[iPage])); 
     1419#else 
     1420                CHECK_RET(paPages[iPage].uPte.pPae->u == PGMR0DYNMAP_GUARD_PAGE_PAE_PTE, 
     1421                          ("#%u: %#llx", iPage, paPages[iPage].uPte.pPae->u)); 
     1422#endif 
     1423                cGuard++; 
     1424            } 
     1425            else if (paPages[iPage].HCPhys != NIL_RTHCPHYS) 
     1426            { 
     1427                CHECK_RET(!(paPages[iPage].HCPhys & PAGE_OFFSET_MASK), ("#%u: %RHp\n", iPage, paPages[iPage].HCPhys)); 
     1428                X86PGPAEUINT uPte = (paSavedPTEs[iPage] & X86_PTE_G | X86_PTE_PAT | X86_PTE_PCD | X86_PTE_PWT) 
     1429                                  | X86_PTE_P | X86_PTE_RW | X86_PTE_A | X86_PTE_D 
     1430                                  | (paPages[iPage].HCPhys & X86_PTE_PAE_PG_MASK); 
     1431                CHECK_RET(paPages[iPage].uPte.pPae->u == uPte, 
     1432                          ("#%u: %#llx %#llx", iPage, paPages[iPage].uPte.pLegacy->u, uPte)); 
     1433                if (paPages[iPage].cRefs) 
     1434                    cLoad++; 
     1435            } 
     1436            else 
     1437                CHECK_RET(paPages[iPage].uPte.pPae->u == paSavedPTEs[iPage], 
     1438                          ("#%u: %#llx %#llx", iPage, paPages[iPage].uPte.pPae->u, paSavedPTEs[iPage])); 
     1439        } 
     1440    } 
     1441 
     1442    CHECK_RET(cLoad == pThis->cLoad, ("%u %u\n", cLoad, pThis->cLoad)); 
     1443    CHECK_RET(cGuard == pThis->cGuardPages, ("%u %u\n", cGuard, pThis->cGuardPages)); 
     1444 
     1445#undef CHECK_RET 
     1446    RTSpinlockRelease(pThis->hSpinlock, &Tmp); 
     1447    return VINF_SUCCESS; 
    12351448} 
    12361449 
     
    12851498        } 
    12861499 
    1287         Assert(pThis->cLoad <= pThis->cPages); 
     1500        Assert(pThis->cLoad <= pThis->cPages - pThis->cGuardPages); 
    12881501        RTSpinlockRelease(pThis->hSpinlock, &Tmp); 
    12891502    } 
     
    13991612     * Map it. 
    14001613     */ 
    1401     uint32_t        iPage; 
    1402     void           *pvPage  = pgmR0DynMapPage(g_pPGMR0DynMap, HCPhys, &iPage); 
    1403     if (RT_UNLIKELY(!pvPage)) 
     1614    uint32_t const  iPage = pgmR0DynMapPage(g_pPGMR0DynMap, HCPhys, ppv); 
     1615    if (RT_UNLIKELY(iPage == UINT32_MAX)) 
    14041616    { 
    14051617        static uint32_t s_cBitched = 0; 
    14061618        if (++s_cBitched < 10) 
    1407             LogRel(("PGMDynMapHCPage: cLoad=%u/%u cPages=%u\n", 
    1408                     g_pPGMR0DynMap->cLoad, g_pPGMR0DynMap->cMaxLoad, g_pPGMR0DynMap->cPages)); 
     1619            LogRel(("PGMDynMapHCPage: cLoad=%u/%u cPages=%u cGuardPages=%u\n", 
     1620                    g_pPGMR0DynMap->cLoad, g_pPGMR0DynMap->cMaxLoad, g_pPGMR0DynMap->cPages, g_pPGMR0DynMap->cGuardPages)); 
    14091621        return VERR_PGM_DYNMAP_FAILED; 
    14101622    } 
    1411     *ppv = pvPage; 
    14121623 
    14131624    /* 
     
    14971708    PPGMMAPSET      pSet  = &pVM->aCpus[0].pgm.s.AutoSet; 
    14981709    uint32_t        i; 
     1710 
     1711    /* 
     1712     * Assert internal integrity first. 
     1713     */ 
     1714    LogRel(("Test #0\n")); 
     1715    int rc = PGMR0DynMapAssertIntegrity(); 
     1716    if (RT_FAILURE(rc)) 
     1717        return rc; 
     1718 
    14991719    void           *pvR0DynMapUsedSaved = pVM->pgm.s.pvR0DynMapUsed; 
    15001720    pVM->pgm.s.pvR0DynMapUsed = pThis; 
     
    15111731    void    *pv  = (void *)(intptr_t)-1; 
    15121732    void    *pv2 = (void *)(intptr_t)-2; 
    1513     int      rc  = PGMDynMapHCPage(pVM, cr3, &pv); 
     1733    rc           = PGMDynMapHCPage(pVM, cr3, &pv); 
    15141734    int      rc2 = PGMDynMapHCPage(pVM, cr3, &pv2); 
    15151735    ASMIntEnable(); 
     
    15181738        &&  pv == pv2) 
    15191739    { 
    1520         LogRel(("Load=%u/%u/%u Set=%u/%u\n", pThis->cLoad, pThis->cMaxLoad, pThis->cPages, pSet->cEntries, RT_ELEMENTS(pSet->aEntries))); 
     1740        LogRel(("Load=%u/%u/%u Set=%u/%u\n", pThis->cLoad, pThis->cMaxLoad, pThis->cPages - pThis->cPages, pSet->cEntries, RT_ELEMENTS(pSet->aEntries))); 
     1741        rc = PGMR0DynMapAssertIntegrity(); 
    15211742 
    15221743        /* 
     
    15541775        } 
    15551776        if (RT_SUCCESS(rc)) 
     1777            rc = PGMR0DynMapAssertIntegrity(); 
     1778        if (RT_SUCCESS(rc)) 
    15561779        { 
    15571780            /* 
     
    15771800                rc = VERR_INTERNAL_ERROR; 
    15781801            } 
    1579             LogRel(("Load=%u/%u/%u Set=%u/%u\n", pThis->cLoad, pThis->cMaxLoad, pThis->cPages, pSet->cEntries, RT_ELEMENTS(pSet->aEntries))); 
     1802            LogRel(("Load=%u/%u/%u Set=%u/%u\n", pThis->cLoad, pThis->cMaxLoad, pThis->cPages - pThis->cPages, pSet->cEntries, RT_ELEMENTS(pSet->aEntries))); 
     1803            if (RT_SUCCESS(rc)) 
     1804                rc = PGMR0DynMapAssertIntegrity(); 
    15801805            if (RT_SUCCESS(rc)) 
    15811806            { 
     
    15851810                LogRel(("Test #4\n")); 
    15861811                ASMIntDisable(); 
    1587                 for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) / 2 - 3 + 1 && RT_SUCCESS(rc) && pv2 != pv; i++) 
    1588                     rc = PGMDynMapHCPage(pVM, cr3 + PAGE_SIZE * -(i + 5), &pv2); 
     1812                for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) / 2 - 3 + 1 && pv2 != pv; i++) 
     1813                { 
     1814                    rc = PGMDynMapHCPage(pVM, cr3 - PAGE_SIZE * (i + 5), &pv2); 
     1815                    if (RT_SUCCESS(rc)) 
     1816                        rc = PGMR0DynMapAssertIntegrity(); 
     1817                    if (RT_FAILURE(rc)) 
     1818                        break; 
     1819                } 
    15891820                ASMIntEnable(); 
    15901821                if (rc == VERR_PGM_DYNMAP_FULL_SET) 
    15911822                { 
    1592                     rc = VINF_SUCCESS; 
    1593  
    15941823                    /* flush the set. */ 
     1824                    LogRel(("Test #5\n")); 
    15951825                    ASMIntDisable(); 
    15961826                    PGMDynMapMigrateAutoSet(&pVM->aCpus[0]); 
     
    15981828                    PGMDynMapStartAutoSet(&pVM->aCpus[0]); 
    15991829                    ASMIntEnable(); 
     1830 
     1831                    rc = PGMR0DynMapAssertIntegrity(); 
    16001832                } 
    16011833                else 
    16021834                { 
    1603                     LogRel(("failed(%d): rc=%Rrc, wanted %d ; pv2=%p Set=%u/%u\n", __LINE__, 
    1604                             rc, VERR_PGM_DYNMAP_FULL_SET, pv2, pSet->cEntries, RT_ELEMENTS(pSet->aEntries))); 
     1835                    LogRel(("failed(%d): rc=%Rrc, wanted %d ; pv2=%p Set=%u/%u; i=%d\n", __LINE__, 
     1836                            rc, VERR_PGM_DYNMAP_FULL_SET, pv2, pSet->cEntries, RT_ELEMENTS(pSet->aEntries), i)); 
    16051837                    if (RT_SUCCESS(rc)) rc = VERR_INTERNAL_ERROR; 
    16061838                } 
     
    16621894    ASMIntEnable(); 
    16631895 
     1896    if (RT_SUCCESS(rc)) 
     1897        rc = PGMR0DynMapAssertIntegrity(); 
     1898    else 
     1899        PGMR0DynMapAssertIntegrity(); 
     1900 
    16641901    LogRel(("Result: rc=%Rrc Load=%u/%u/%u Set=%#x/%u\n", rc, 
    1665             pThis->cLoad, pThis->cMaxLoad, pThis->cPages, pSet->cEntries, RT_ELEMENTS(pSet->aEntries))); 
     1902            pThis->cLoad, pThis->cMaxLoad, pThis->cPages - pThis->cPages, pSet->cEntries, RT_ELEMENTS(pSet->aEntries))); 
    16661903    pVM->pgm.s.pvR0DynMapUsed = pvR0DynMapUsedSaved; 
    16671904    LogRel(("pgmR0DynMapTest: ****** END ******\n")); 

© 2008 Sun Microsystems, Inc.
ContactPrivacy policy