VirtualBox

Changeset 15410 in vbox


Ignore:
Timestamp:
Dec 13, 2008 1:04:17 AM (16 years ago)
Author:
vboxsync
Message:

PGM: Deal with pgmPoolAlloc failure in MapCR3 without relying on having to clear the pool. The MapCR3 action will be postponed to SyncCR3.

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

Legend:

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

    r15404 r15410  
    28712871/** Check monitoring on next CR3 (re)load and invalidate page. */
    28722872#define PGM_SYNC_MONITOR_CR3                    RT_BIT(2)
     2873/** Check guest mapping in SyncCR3. */
     2874#define PGM_SYNC_MAP_CR3                        RT_BIT(3)
    28732875/** Clear the page pool (a light weight flush). */
    28742876#define PGM_SYNC_CLEAR_PGM_POOL                 RT_BIT(8)
  • trunk/src/VBox/VMM/PGMMap.cpp

    r14979 r15410  
    482482    /* Remap CR3 as we have just flushed the CR3 shadow PML4 in case we're in long mode. */
    483483    int rc = PGM_GST_PFN(MapCR3, pVM)(pVM, pVM->pgm.s.GCPhysCR3);
    484     AssertRC(rc);
     484    AssertRCSuccess(rc);
    485485
    486486#ifndef VBOX_WITH_PGMPOOL_PAGING_ONLY
    487487    rc = PGM_GST_PFN(MonitorCR3, pVM)(pVM, pVM->pgm.s.GCPhysCR3);
    488     AssertRC(rc);
     488    AssertRCSuccess(rc);
    489489#endif
    490490    return VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMAll/PGMAll.cpp

    r15344 r15410  
    14661466     * Always flag the necessary updates; necessary for hardware acceleration
    14671467     */
     1468    /** @todo optimize this, it shouldn't always be necessary. */
    14681469    VM_FF_SET(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL);
    14691470    if (fGlobal)
     
    14851486    if (pVM->pgm.s.GCPhysCR3 != GCPhysCR3)
    14861487    {
    1487         pVM->pgm.s.GCPhysCR3 = GCPhysCR3;
     1488        RTGCPHYS GCPhysOldCR3 = pVM->pgm.s.GCPhysCR3;
     1489        pVM->pgm.s.GCPhysCR3  = GCPhysCR3;
    14881490        rc = PGM_GST_PFN(MapCR3, pVM)(pVM, GCPhysCR3);
    1489         if (RT_SUCCESS(rc) && !pVM->pgm.s.fMappingsFixed)
     1491        if (RT_LIKELY(rc == VINF_SUCCESS))
    14901492        {
    1491             pVM->pgm.s.fSyncFlags &= ~PGM_SYNC_MONITOR_CR3;
    1492             rc = PGM_GST_PFN(MonitorCR3, pVM)(pVM, GCPhysCR3);
     1493            if (!pVM->pgm.s.fMappingsFixed)
     1494            {
     1495                pVM->pgm.s.fSyncFlags &= ~PGM_SYNC_MONITOR_CR3;
     1496                rc = PGM_GST_PFN(MonitorCR3, pVM)(pVM, GCPhysCR3);
     1497            }
    14931498        }
     1499        else
     1500        {
     1501            AssertMsg(rc == VINF_PGM_SYNC_CR3, ("%Rrc\n", rc));
     1502            Assert(VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL | VM_FF_PGM_SYNC_CR3));
     1503            pVM->pgm.s.GCPhysCR3 = GCPhysOldCR3;
     1504            pVM->pgm.s.fSyncFlags |= PGM_SYNC_MAP_CR3;
     1505            if (!pVM->pgm.s.fMappingsFixed)
     1506                pVM->pgm.s.fSyncFlags |= PGM_SYNC_MONITOR_CR3;
     1507        }
     1508
    14941509        if (fGlobal)
    14951510            STAM_COUNTER_INC(&pVM->pgm.s.CTX_MID_Z(Stat,FlushTLBNewCR3Global));
     
    15291544 *
    15301545 * @returns VBox status code.
    1531  * @retval  VINF_PGM_SYNC_CR3 if monitoring requires a CR3 sync. This can
    1532  *          safely be ignored and overridden since the FF will be set too then.
     1546 * @retval  VINF_SUCCESS.
     1547 * @retval  (If applied when not in nested mode: VINF_PGM_SYNC_CR3 if monitoring
     1548 *          requires a CR3 sync. This can safely be ignored and overridden since
     1549 *          the FF will be set too then.)
    15331550 * @param   pVM         VM handle.
    15341551 * @param   cr3         The new cr3.
     
    15591576        pVM->pgm.s.GCPhysCR3 = GCPhysCR3;
    15601577        rc = PGM_GST_PFN(MapCR3, pVM)(pVM, GCPhysCR3);
    1561     }
    1562     AssertRC(rc);
     1578        AssertRCSuccess(rc); /* Assumes VINF_PGM_SYNC_CR3 doesn't apply to nested paging. */
     1579    }
    15631580    return rc;
    15641581}
     
    15811598VMMDECL(int) PGMSyncCR3(PVM pVM, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal)
    15821599{
     1600    int rc;
     1601
    15831602    /*
    15841603     * We might be called when we shouldn't.
     
    15971616    }
    15981617
    1599     /* If global pages are not supported, then all flushes are global */
     1618    /* If global pages are not supported, then all flushes are global. */
    16001619    if (!(cr4 & X86_CR4_PGE))
    16011620        fGlobal = true;
     
    16031622             VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3), VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3_NON_GLOBAL)));
    16041623
     1624#ifdef PGMPOOL_WITH_MONITORING
     1625    /*
     1626     * The pool may have pending stuff and even require a return to ring-3 to
     1627     * clear the whole thing.
     1628     */
     1629    rc = pgmPoolSyncCR3(pVM);
     1630    if (rc != VINF_SUCCESS)
     1631        return rc;
     1632#endif
     1633
     1634    /*
     1635     * Check if we need to finish an aborted MapCR3 call (see PGMFlushTLB).
     1636     * This should be done before SyncCR3.
     1637     */
     1638    if (pVM->pgm.s.fSyncFlags & PGM_SYNC_MAP_CR3)
     1639    {
     1640        pVM->pgm.s.fSyncFlags &= ~PGM_SYNC_MAP_CR3;
     1641
     1642        RTGCPHYS GCPhysCR3Old = pVM->pgm.s.GCPhysCR3;
     1643        RTGCPHYS GCPhysCR3;
     1644        if (    pVM->pgm.s.enmGuestMode == PGMMODE_PAE
     1645            ||  pVM->pgm.s.enmGuestMode == PGMMODE_PAE_NX
     1646            ||  pVM->pgm.s.enmGuestMode == PGMMODE_AMD64
     1647            ||  pVM->pgm.s.enmGuestMode == PGMMODE_AMD64_NX)
     1648            GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_PAE_PAGE_MASK);
     1649        else
     1650            GCPhysCR3 = (RTGCPHYS)(cr3 & X86_CR3_PAGE_MASK);
     1651        pVM->pgm.s.GCPhysCR3 = GCPhysCR3;
     1652        rc = PGM_GST_PFN(MapCR3, pVM)(pVM, GCPhysCR3);
     1653#ifdef IN_RING3
     1654        if (rc == VINF_PGM_SYNC_CR3)
     1655            rc = pgmPoolSyncCR3(pVM);
     1656#else
     1657        if (rc == VINF_PGM_SYNC_CR3)
     1658        {
     1659            pVM->pgm.s.GCPhysCR3 = GCPhysCR3Old;
     1660            return rc;
     1661        }
     1662#endif
     1663        AssertRCReturn(rc, rc);
     1664        AssertRCSuccessReturn(rc, VERR_INTERNAL_ERROR);
     1665    }
     1666
    16051667    /*
    16061668     * Let the 'Bth' function do the work and we'll just keep track of the flags.
    16071669     */
    16081670    STAM_PROFILE_START(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3), a);
    1609     int rc = PGM_BTH_PFN(SyncCR3, pVM)(pVM, cr0, cr3, cr4, fGlobal);
     1671    rc = PGM_BTH_PFN(SyncCR3, pVM)(pVM, cr0, cr3, cr4, fGlobal);
    16101672    STAM_PROFILE_STOP(&pVM->pgm.s.CTX_MID_Z(Stat,SyncCR3), a);
    16111673    AssertMsg(rc == VINF_SUCCESS || rc == VINF_PGM_SYNC_CR3 || RT_FAILURE(rc), ("rc=%Rrc\n", rc));
  • trunk/src/VBox/VMM/VMMAll/PGMAllBth.h

    r15228 r15410  
    31203120#endif
    31213121
    3122 #ifdef PGMPOOL_WITH_MONITORING
    3123     int rc = pgmPoolSyncCR3(pVM);
    3124     if (rc != VINF_SUCCESS)
    3125         return rc;
    3126 #endif
    3127 
    31283122#if PGM_SHW_TYPE == PGM_TYPE_NESTED || PGM_SHW_TYPE == PGM_TYPE_EPT
    31293123    /*
    31303124     * Nested / EPT - almost no work.
    31313125     */
    3132     /** @todo check if this is really necessary */
     3126    /** @todo check if this is really necessary; the call does it as well... */
    31333127    HWACCMFlushTLB(pVM);
    31343128    return VINF_SUCCESS;
  • trunk/src/VBox/VMM/VMMAll/PGMAllGst.h

    r15404 r15410  
    423423 * CR3 is updated we simply call MapCR3 again.
    424424 *
    425  * @returns VBox status, no specials.
     425 * @returns Strict VBox status code.
     426 * @retval  VINF_SUCCESS.
     427 * @retval  VINF_PGM_SYNC_CR3 if the shadow page pool overflowed.
     428 *
    426429 * @param   pVM             VM handle.
    427430 * @param   GCPhysCR3       The physical address in the CR3 register.
     
    509512            if (!HWACCMIsNestedPagingActive(pVM))
    510513            {
     514                /*
     515                 * Update the shadow root page as well since that's not fixed.
     516                 */
     517                /** @todo Move this into PGMAllBth.h. */
    511518                PPGMPOOL pPool = pVM->pgm.s.CTX_SUFF(pPool);
    512519                if (pVM->pgm.s.CTX_SUFF(pShwAmd64CR3))
    513520                {
    514521                    /* It might have been freed already by a pool flush (see e.g. PGMR3MappingsUnfix). */
     522                    /** @todo Coordinate this better with the pool. */
    515523                    if (pVM->pgm.s.CTX_SUFF(pShwAmd64CR3)->enmKind != PGMPOOLKIND_FREE)
    516524                        pgmPoolFreeByPage(pPool, pVM->pgm.s.CTX_SUFF(pShwAmd64CR3), PGMPOOL_IDX_AMD64_CR3, pVM->pgm.s.CTX_SUFF(pShwAmd64CR3)->GCPhys >> PAGE_SHIFT);
    517                     pVM->pgm.s.CTX_SUFF(pShwAmd64CR3) = 0;
    518                     pVM->pgm.s.pShwPaePml4R3          = 0;
     525                    pVM->pgm.s.pShwAmd64CR3R3   = 0;
     526                    pVM->pgm.s.pShwAmd64CR3R0   = 0;
     527                    pVM->pgm.s.pShwPaePml4R3    = 0;
    519528#  ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
    520                     pVM->pgm.s.pShwPaePml4R0          = 0;
     529                    pVM->pgm.s.pShwPaePml4R0    = 0;
    521530#  endif
    522                     pVM->pgm.s.HCPhysShwPaePml4       = 0;
     531                    pVM->pgm.s.HCPhysShwPaePml4 = 0;
    523532                }
    524533
    525534                Assert(!(GCPhysCR3 >> (PAGE_SHIFT + 32)));
    526 l_try_again:
    527535                rc = pgmPoolAlloc(pVM, GCPhysCR3, PGMPOOLKIND_64BIT_PML4_FOR_64BIT_PML4, PGMPOOL_IDX_AMD64_CR3, GCPhysCR3 >> PAGE_SHIFT, &pVM->pgm.s.CTX_SUFF(pShwAmd64CR3));
    528536                if (rc == VERR_PGM_POOL_FLUSHED)
    529537                {
    530                     Log(("MapCR3: Flush pool and try again\n"));
    531                     Assert(pVM->pgm.s.fSyncFlags & PGM_SYNC_CLEAR_PGM_POOL);
    532                     rc = pgmPoolSyncCR3(pVM);
    533                     AssertRC(rc);
    534                     goto l_try_again;
     538                    Log(("MapCR3: PGM pool flushed -> signal sync cr3\n"));
     539                    Assert(VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
     540                    return VINF_PGM_SYNC_CR3;
    535541                }
     542                AssertRCReturn(rc, rc);
    536543#  ifdef IN_RING0
    537544                pVM->pgm.s.pShwAmd64CR3R3 = MMHyperCCToR3(pVM, pVM->pgm.s.CTX_SUFF(pShwAmd64CR3));
     
    545552#  endif
    546553                pVM->pgm.s.HCPhysShwPaePml4 = pVM->pgm.s.CTX_SUFF(pShwAmd64CR3)->Core.Key;
     554                rc = VINF_SUCCESS; /* clear it - pgmPoolAlloc returns hints. */
    547555            }
    548556# endif
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r15406 r15410  
    146146            HCPhys = pPGM->HCPhysShwPaePdpt;
    147147            break;
     148        case PGMPOOL_IDX_NESTED_ROOT:
     149            HCPhys = pPGM->HCPhysShwNestedRoot;
     150            break;
    148151        case PGMPOOL_IDX_PAE_PD:
    149152            AssertReleaseMsgFailed(("PGMPOOL_IDX_PAE_PD is not usable in VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 context\n"));
     
    153156            return NULL;
    154157    }
     158    AssertMsg(HCPhys && HCPhys != NIL_RTHCPHYS && !(PAGE_OFFSET_MASK & HCPhys), ("%RHp\n", HCPhys));
     159
    155160    void *pv;
    156161    int rc = pgmR0DynMapHCPageInlined(pPGM, HCPhys, &pv);
     
    20712076    else
    20722077    {
    2073 # ifndef IN_RC //def IN_RING3 - fixing properly in a bit...
     2078# ifdef IN_RING3 /* Don't flush in ring-0 or raw mode, it's taking too long. */
    20742079        pVM->pgm.s.fSyncFlags &= ~PGM_SYNC_CLEAR_PGM_POOL;
    20752080        pgmPoolClearAll(pVM);
     
    38103815    }
    38113816
     3817    /*
     3818     * Finally, assert the FF.
     3819     */
     3820    VM_FF_SET(pPool->CTX_SUFF(pVM), VM_FF_PGM_SYNC_CR3);
     3821
    38123822    STAM_PROFILE_STOP(&pPool->StatFlushAllInt, a);
    38133823}
     
    39673977    /*
    39683978     * Flush the pool.
     3979     *
    39693980     * If we have tracking enabled, it should be possible to come up with
    39703981     * a cheap replacement strategy...
     
    40034014    LogFlow(("pgmPoolAlloc: GCPhys=%RGp enmKind=%d iUser=%#x iUserTable=%#x\n", GCPhys, enmKind, iUser, iUserTable));
    40044015    *ppPage = NULL;
     4016    Assert(!(pVM->pgm.s.fSyncFlags & PGM_SYNC_CLEAR_PGM_POOL));
    40054017
    40064018#ifdef PGMPOOL_WITH_CACHE
  • trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp

    r15404 r15410  
    678678        {
    679679            pVMCB->guest.u64CR3             = PGMGetHyperCR3(pVM);
    680             Assert(pVMCB->guest.u64CR3);
     680            Assert(pVMCB->guest.u64CR3 || VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL));
    681681        }
    682682    }
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r15404 r15410  
    14261426        if (pVM->hwaccm.s.fNestedPaging)
    14271427        {
    1428             AssertMsg(PGMGetEPTCR3(pVM) == PGMGetHyperCR3(pVM), ("%RHp vs %RHp\n", PGMGetEPTCR3(pVM), PGMGetHyperCR3(pVM)));
     1428            AssertMsg(   PGMGetEPTCR3(pVM) == PGMGetHyperCR3(pVM)
     1429                      || VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL),
     1430                      ("%RHp vs %RHp\n", PGMGetEPTCR3(pVM), PGMGetHyperCR3(pVM)));
    14291431            pVCpu->hwaccm.s.vmx.GCPhysEPTP = PGMGetEPTCR3(pVM);
    14301432
     
    14611463        {
    14621464            val = PGMGetHyperCR3(pVM);
    1463             Assert(val);
     1465            Assert(val || VM_FF_ISPENDING(pVM, VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL));
    14641466        }
    14651467
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