VirtualBox

Changeset 18291 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Mar 26, 2009 5:11:07 AM (16 years ago)
Author:
vboxsync
Message:

PGM: Map PGMRAMRANGES above 4GB outside HMA (see defect). Changed PGMR3MapPT to take a flag indicating whether PGMR3UnmapPT will be used; this way we can select a more optimal allocation function for the ram ranges. PGMMapResolveConflicts: Walk the list correctly after reloc. pgmMapClearShadowPDEs: Don't clear PGM_PLXFLAGS_MAPPING when we shouldn't (odd PAE cases).

File:
1 edited

Legend:

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

    r17667 r18291  
    268268            case PGMMODE_PAE_NX:
    269269            {
    270                 PX86PDPT  pShwPdpt;
    271                 PX86PDPAE pShwPaePd;
    272                 const unsigned iPdPt = iNewPDE / 256;
    273                 unsigned iPDE = iNewPDE * 2 % 512;
    274 
    275                 pShwPdpt  = pgmShwGetPaePDPTPtr(&pVM->pgm.s);
     270                const unsigned  iPdPt     = iNewPDE / 256;
     271                unsigned        iPDE      = iNewPDE * 2 % 512;
     272                PX86PDPT        pShwPdpt  = pgmShwGetPaePDPTPtr(&pVM->pgm.s);
    276273                Assert(pShwPdpt);
    277274#ifdef IN_RC    /* Lock mapping to prevent it from being reused during pgmShwSyncPaePDPtr. */
    278275                PGMDynLockHCPage(pVM, (uint8_t *)pShwPdpt);
    279276#endif
    280                 pShwPaePd = pgmShwGetPaePDPtr(&pVM->pgm.s, (iPdPt << X86_PDPT_SHIFT));
     277                PX86PDPAE       pShwPaePd = pgmShwGetPaePDPtr(&pVM->pgm.s, (iPdPt << X86_PDPT_SHIFT));
    281278                if (!pShwPaePd)
    282279                {
     
    312309                    pgmPoolLockPage(pVM->pgm.s.CTX_SUFF(pPool), pPoolPagePd);
    313310                }
    314 # ifdef VBOX_STRICT
    315                 else 
     311#ifdef VBOX_STRICT
     312                else
    316313                if (pShwPaePd->a[iPDE].u & PGM_PDFLAGS_MAPPING)
    317314                {
     
    321318                    AssertFatalMsg((pShwPaePd->a[iPDE+1].u & X86_PDE_PG_MASK) == pMap->aPTs[i].HCPhysPaePT1, ("%RX64 vs %RX64\n", pShwPaePd->a[iPDE+1].u & X86_PDE_PG_MASK, pMap->aPTs[i].HCPhysPaePT1));
    322319                }
    323 # endif
     320#endif
    324321                if (    pShwPaePd->a[iPDE].n.u1Present
    325322                    &&  !(pShwPaePd->a[iPDE].u & PGM_PDFLAGS_MAPPING))
     
    364361}
    365362
     363
    366364/**
    367365 * Clears all PDEs involved with the mapping in the shadow page table.
    368366 *
    369  * @param   pVM         The VM handle.
    370  * @param   pShwPageCR3 CR3 root page
    371  * @param   pMap        Pointer to the mapping in question.
    372  * @param   iOldPDE     The index of the 32-bit PDE corresponding to the base of the mapping.
    373  */
    374 void pgmMapClearShadowPDEs(PVM pVM, PPGMPOOLPAGE pShwPageCR3, PPGMMAPPING pMap, unsigned iOldPDE)
    375 {
    376     Log(("pgmMapClearShadowPDEs old pde %x (cPTs=%x) (mappings enabled %d)\n", iOldPDE, pMap->cPTs, pgmMapAreMappingsEnabled(&pVM->pgm.s)));
     367 * @param   pVM             The VM handle.
     368 * @param   pShwPageCR3     CR3 root page
     369 * @param   pMap            Pointer to the mapping in question.
     370 * @param   iOldPDE         The index of the 32-bit PDE corresponding to the base of the mapping.
     371 * @param   fDeactivateCR3  Set if it's pgmMapDeactivateCR3 calling.
     372 */
     373void pgmMapClearShadowPDEs(PVM pVM, PPGMPOOLPAGE pShwPageCR3, PPGMMAPPING pMap, unsigned iOldPDE, bool fDeactivateCR3)
     374{
     375    Log(("pgmMapClearShadowPDEs: old pde %x (cPTs=%x) (mappings enabled %d) fDeactivateCR3=%RTbool\n", iOldPDE, pMap->cPTs, pgmMapAreMappingsEnabled(&pVM->pgm.s), fDeactivateCR3));
    377376
    378377    if (!pgmMapAreMappingsEnabled(&pVM->pgm.s))
     
    415414            case PGMMODE_PAE_NX:
    416415            {
    417                 PX86PDPT  pShwPdpt = NULL;
    418                 PX86PDPAE pShwPaePd = NULL;
    419 
    420                 const unsigned iPdpt = iOldPDE / 256;         /* iOldPDE * 2 / 512; iOldPDE is in 4 MB pages */
    421                 unsigned iPDE = iOldPDE * 2 % 512;
    422                 pShwPdpt  = (PX86PDPT)PGMPOOL_PAGE_2_PTR_BY_PGM(&pVM->pgm.s, pShwPageCR3);
    423                 pShwPaePd = pgmShwGetPaePDPtr(&pVM->pgm.s, pShwPdpt, (iPdpt << X86_PDPT_SHIFT));
     416                const unsigned  iPdpt     = iOldPDE / 256;      /* iOldPDE * 2 / 512; iOldPDE is in 4 MB pages */
     417                unsigned        iPDE      = iOldPDE * 2 % 512;
     418                PX86PDPT        pShwPdpt  = (PX86PDPT)PGMPOOL_PAGE_2_PTR_BY_PGM(&pVM->pgm.s, pShwPageCR3);
     419                PX86PDPAE       pShwPaePd = pgmShwGetPaePDPtr(&pVM->pgm.s, pShwPdpt, (iPdpt << X86_PDPT_SHIFT));
    424420
    425421                /* Clear the PGM_PDFLAGS_MAPPING flag for the page directory pointer entry. (legacy PAE guest mode) */
    426                 pShwPdpt->a[iPdpt].u &= ~PGM_PLXFLAGS_MAPPING;
    427 
     422                if (fDeactivateCR3)
     423                    pShwPdpt->a[iPdpt].u &= ~PGM_PLXFLAGS_MAPPING;
     424                else if (pShwPdpt->a[iPdpt].u & PGM_PLXFLAGS_MAPPING)
     425                {
     426                    /* See if there are any other mappings here. This is suboptimal code. */
     427                    pShwPdpt->a[iPdpt].u &= ~PGM_PLXFLAGS_MAPPING;
     428                    for (PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings); pCur; pCur = pCur->CTX_SUFF(pNext))
     429                        if (    pCur != pMap
     430                            &&  (   (pCur->GCPtr >> X86_PDPT_SHIFT) == iPdpt
     431                                 || (pCur->GCPtrLast >> X86_PDPT_SHIFT) == iPdpt))
     432                        {
     433                            pShwPdpt->a[iPdpt].u |= PGM_PLXFLAGS_MAPPING;
     434                            break;
     435                        }
     436                }
    428437                if (pCurrentShwPdpt)
    429438                {
     
    474483 * @param   iPDE        The index of the 32-bit PDE corresponding to the base of the mapping.
    475484 */
    476 void pgmMapCheckShadowPDEs(PVM pVM, PPGMPOOLPAGE pShwPageCR3, PPGMMAPPING pMap, unsigned iPDE)
     485static void pgmMapCheckShadowPDEs(PVM pVM, PPGMPOOLPAGE pShwPageCR3, PPGMMAPPING pMap, unsigned iPDE)
    477486{
    478487    Assert(pShwPageCR3);
    479488
    480     unsigned i = pMap->cPTs;
     489    uint32_t i = pMap->cPTs;
    481490    PGMMODE  enmShadowMode = PGMGetShadowMode(pVM);
    482491
     
    486495        iPDE--;
    487496
    488         switch(enmShadowMode)
     497        switch (enmShadowMode)
    489498        {
    490499            case PGMMODE_32_BIT:
     
    494503
    495504                AssertMsg(pShw32BitPd->a[iPDE].u == (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | (uint32_t)pMap->aPTs[i].HCPhysPT),
    496                           ("Expected %x vs %x\n", pShw32BitPd->a[iPDE].u, (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | (uint32_t)pMap->aPTs[i].HCPhysPT)));
     505                          ("Expected %x vs %x; iPDE=%#x %RGv %s\n",
     506                           pShw32BitPd->a[iPDE].u,  (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | (uint32_t)pMap->aPTs[i].HCPhysPT),
     507                           iPDE, pMap->GCPtr, R3STRING(pMap->pszDesc) ));
    497508                break;
    498509            }
     
    501512            case PGMMODE_PAE_NX:
    502513            {
    503                 PX86PDPT  pPdpt = NULL;
    504                 PX86PDPAE pShwPaePd = NULL;
    505 
    506                 const unsigned iPD = iPDE / 256;         /* iPDE * 2 / 512; iPDE is in 4 MB pages */
    507                 unsigned iPaePDE = iPDE * 2 % 512;
    508                 pPdpt     = (PX86PDPT)PGMPOOL_PAGE_2_PTR_BY_PGM(&pVM->pgm.s, pShwPageCR3);
    509                 pShwPaePd = pgmShwGetPaePDPtr(&pVM->pgm.s, pPdpt, (iPD << X86_PDPT_SHIFT));
     514                const unsigned  iPD       = iPDE / 256;         /* iPDE * 2 / 512; iPDE is in 4 MB pages */
     515                unsigned        iPaePDE   = iPDE * 2 % 512;
     516                PX86PDPT        pPdpt     = (PX86PDPT)PGMPOOL_PAGE_2_PTR_BY_PGM(&pVM->pgm.s, pShwPageCR3);
     517                PX86PDPAE       pShwPaePd = pgmShwGetPaePDPtr(&pVM->pgm.s, pPdpt, (iPD << X86_PDPT_SHIFT));
    510518                AssertFatal(pShwPaePd);
    511519
    512520                AssertMsg(pShwPaePd->a[iPaePDE].u == (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | pMap->aPTs[i].HCPhysPaePT0),
    513                          ("Expected %RX64 vs %RX64\n", pShwPaePd->a[iPDE].u, (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | (uint32_t)pMap->aPTs[i].HCPhysPaePT0)));
     521                          ("Expected %RX64 vs %RX64; iPDE=%#x iPD=%#x iPaePDE=%#x %RGv %s\n",
     522                           pShwPaePd->a[iPDE].u,     (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | pMap->aPTs[i].HCPhysPaePT0),
     523                           iPDE, iPD, iPaePDE, pMap->GCPtr, R3STRING(pMap->pszDesc) ));
    514524
    515525                iPaePDE++;
     
    517527
    518528                AssertMsg(pShwPaePd->a[iPaePDE].u == (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | pMap->aPTs[i].HCPhysPaePT1),
    519                          ("Expected %RX64 vs %RX64\n", pShwPaePd->a[iPDE].u, (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | (uint32_t)pMap->aPTs[i].HCPhysPaePT1)));
    520 
    521                 Assert(pPdpt->a[iPD].u & PGM_PLXFLAGS_MAPPING);
     529                          ("Expected %RX64 vs %RX64; iPDE=%#x iPD=%#x iPaePDE=%#x %RGv %s\n",
     530                           pShwPaePd->a[iPDE].u,     (PGM_PDFLAGS_MAPPING | X86_PDE_P | X86_PDE_A | X86_PDE_RW | X86_PDE_US | pMap->aPTs[i].HCPhysPaePT1),
     531                           iPDE, iPD, iPaePDE, pMap->GCPtr, R3STRING(pMap->pszDesc) ));
     532
     533                AssertMsg(pPdpt->a[iPD].u & PGM_PLXFLAGS_MAPPING,
     534                          ("%RX64; iPD=%#x iPDE=%#x iPaePDE=%#x %RGv %s\n",
     535                           pPdpt->a[iPD].u,
     536                           iPDE, iPD, iPaePDE, pMap->GCPtr, R3STRING(pMap->pszDesc) ));
    522537                break;
    523538            }
     
    530545}
    531546
     547
    532548/**
    533549 * Check the hypervisor mappings in the active CR3.
     
    558574
    559575#ifndef IN_RING0
     576
    560577/**
    561578 * Apply the hypervisor mappings to the active CR3.
     
    573590        return VINF_SUCCESS;
    574591
    575     /* @note A log flush (in RC) can cause problems when called from MapCR3 (inconsistent state will trigger assertions). */
    576     Log4(("PGMMapActivateAll fixed mappings=%d\n", pVM->pgm.s.fMappingsFixed));
     592    /* Note. A log flush (in RC) can cause problems when called from MapCR3 (inconsistent state will trigger assertions). */
     593    Log4(("pgmMapActivateCR3: fixed mappings=%d idxShwPageCR3=%#x\n", pVM->pgm.s.fMappingsFixed, pShwPageCR3 ? pShwPageCR3->idx : NIL_PGMPOOL_IDX));
    577594
    578595    Assert(pShwPageCR3 && pShwPageCR3 == pVM->pgm.s.CTX_SUFF(pShwPageCR3));
     
    584601    {
    585602        unsigned iPDE = pCur->GCPtr >> X86_PD_SHIFT;
    586 
    587603        pgmMapSetShadowPDEs(pVM, pCur, iPDE);
    588604    }
     
    607623
    608624    Assert(pShwPageCR3);
     625    Log4(("pgmMapDeactivateCR3: fixed mappings=%d idxShwPageCR3=%#x\n", pVM->pgm.s.fMappingsFixed, pShwPageCR3 ? pShwPageCR3->idx : NIL_PGMPOOL_IDX));
    609626
    610627    /*
     
    614631    {
    615632        unsigned iPDE = pCur->GCPtr >> X86_PD_SHIFT;
    616 
    617         pgmMapClearShadowPDEs(pVM, pShwPageCR3, pCur, iPDE);
     633        pgmMapClearShadowPDEs(pVM, pShwPageCR3, pCur, iPDE, true /*fDeactivateCR3*/);
    618634    }
    619635    return VINF_SUCCESS;
    620636}
     637
    621638
    622639/**
     
    711728}
    712729
     730
    713731/**
    714732 * Checks and resolves (ring 3 only) guest conflicts with VMM GC mappings.
     
    728746    Assert(enmGuestMode <= PGMMODE_PAE_NX);
    729747
    730     /*
    731      * Iterate mappings.
    732      */
    733748    if (enmGuestMode == PGMMODE_32_BIT)
    734749    {
     
    739754        Assert(pPD);
    740755
    741         for (PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings); pCur; pCur = pCur->CTX_SUFF(pNext))
     756        /*
     757         * Iterate mappings.
     758         */
     759        for (PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings); pCur; )
    742760        {
    743             unsigned iPDE = pCur->GCPtr >> X86_PD_SHIFT;
    744             unsigned iPT = pCur->cPTs;
     761            PPGMMAPPING pNext = pCur->CTX_SUFF(pNext);
     762            unsigned    iPDE  = pCur->GCPtr >> X86_PD_SHIFT;
     763            unsigned    iPT   = pCur->cPTs;
    745764            while (iPT-- > 0)
    746765            {
    747766                if (    pPD->a[iPDE + iPT].n.u1Present /** @todo PGMGstGetPDE. */
    748                     &&  (pVM->fRawR0Enabled || pPD->a[iPDE + iPT].n.u1User))
     767                    &&  (   pVM->fRawR0Enabled
     768                         || pPD->a[iPDE + iPT].n.u1User))
    749769                {
    750770                    STAM_COUNTER_INC(&pVM->pgm.s.StatR3DetectedConflicts);
     
    753773                    Log(("PGMHasMappingConflicts: Conflict was detected at %08RX32 for mapping %s (32 bits)\n"
    754774                         "                        iPDE=%#x iPT=%#x PDE=%RGp.\n",
    755                         (iPT + iPDE) << X86_PD_SHIFT, pCur->pszDesc,
    756                         iPDE, iPT, pPD->a[iPDE + iPT].au32[0]));
     775                         (iPT + iPDE) << X86_PD_SHIFT, pCur->pszDesc,
     776                         iPDE, iPT, pPD->a[iPDE + iPT].au32[0]));
    757777                    int rc = pgmR3SyncPTResolveConflict(pVM, pCur, pPD, iPDE << X86_PD_SHIFT);
    758778                    AssertRCReturn(rc, rc);
    759 
    760                     /*
    761                      * Update pCur.
    762                      */
    763                     pCur = pVM->pgm.s.CTX_SUFF(pMappings);
    764                     while (pCur && pCur->GCPtr < (iPDE << X86_PD_SHIFT))
    765                         pCur = pCur->CTX_SUFF(pNext);
    766779                    break;
    767780#else
    768781                    Log(("PGMHasMappingConflicts: Conflict was detected at %08RX32 for mapping (32 bits)\n"
    769782                         "                        iPDE=%#x iPT=%#x PDE=%RGp.\n",
    770                         (iPT + iPDE) << X86_PD_SHIFT,
    771                         iPDE, iPT, pPD->a[iPDE + iPT].au32[0]));
     783                         (iPT + iPDE) << X86_PD_SHIFT,
     784                         iPDE, iPT, pPD->a[iPDE + iPT].au32[0]));
    772785                    return VINF_PGM_SYNC_CR3;
    773786#endif
    774787                }
    775788            }
    776             if (!pCur)
    777                 break;
     789            pCur = pNext;
    778790        }
    779791    }
     
    781793             || enmGuestMode == PGMMODE_PAE_NX)
    782794    {
    783         for (PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings); pCur; pCur = pCur->CTX_SUFF(pNext))
     795        /*
     796         * Iterate mappings.
     797         */
     798        for (PPGMMAPPING pCur = pVM->pgm.s.CTX_SUFF(pMappings); pCur;)
    784799        {
    785             RTGCPTR   GCPtr = pCur->GCPtr;
    786 
    787             unsigned  iPT = pCur->cb >> X86_PD_PAE_SHIFT;
     800            PPGMMAPPING pNext = pCur->CTX_SUFF(pNext);
     801            RTGCPTR     GCPtr = pCur->GCPtr;
     802            unsigned    iPT  = pCur->cb >> X86_PD_PAE_SHIFT;
    788803            while (iPT-- > 0)
    789804            {
     
    797812                    Log(("PGMHasMappingConflicts: Conflict was detected at %RGv for mapping %s (PAE)\n"
    798813                         "                        PDE=%016RX64.\n",
    799                         GCPtr, pCur->pszDesc, Pde.u));
     814                         GCPtr, pCur->pszDesc, Pde.u));
    800815                    int rc = pgmR3SyncPTResolveConflictPAE(pVM, pCur, pCur->GCPtr);
    801816                    AssertRCReturn(rc, rc);
    802 
    803                     /*
    804                      * Update pCur.
    805                      */
    806                     pCur = pVM->pgm.s.CTX_SUFF(pMappings);
    807                     while (pCur && pCur->GCPtr < GCPtr)
    808                         pCur = pCur->CTX_SUFF(pNext);
    809817                    break;
    810818#else
    811819                    Log(("PGMHasMappingConflicts: Conflict was detected at %RGv for mapping (PAE)\n"
    812820                         "                        PDE=%016RX64.\n",
    813                         GCPtr, Pde.u));
     821                         GCPtr, Pde.u));
    814822                    return VINF_PGM_SYNC_CR3;
    815823#endif
     
    817825                GCPtr += (1 << X86_PD_PAE_SHIFT);
    818826            }
    819             if (!pCur)
    820                 break;
     827            pCur = pNext;
    821828        }
    822829    }
     
    824831        AssertFailed();
    825832
     833    Assert(!PGMMapHasConflicts(pVM));
    826834    return VINF_SUCCESS;
    827835}
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