VirtualBox

Changeset 38955 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Oct 6, 2011 12:23:39 PM (13 years ago)
Author:
vboxsync
Message:

pgmR3PhysChunkMap: Make sure we don't unmap the chunk we just added.

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

Legend:

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

    r38953 r38955  
    10631063        STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,ChunkR3MapTlbHits));
    10641064        pMap = pTlbe->pChunk;
     1065        AssertPtr(pMap->pv);
    10651066    }
    10661067    else
     
    10721073         */
    10731074        pMap = (PPGMCHUNKR3MAP)RTAvlU32Get(&pVM->pgm.s.ChunkR3Map.pTree, idChunk);
    1074         if (!pMap)
     1075        if (pMap)
     1076            AssertPtr(pMap->pv);
     1077        else
    10751078        {
    10761079#ifdef IN_RING0
     
    10841087                return rc;
    10851088#endif
     1089            AssertPtr(pMap->pv);
    10861090        }
    10871091
  • trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp

    r38953 r38955  
    37693769static DECLCALLBACK(int) pgmR3PhysChunkUnmapCandidateCallback(PAVLU32NODECORE pNode, void *pvUser)
    37703770{
    3771     PPGMCHUNKR3MAP pChunk = (PPGMCHUNKR3MAP)pNode;
    3772     PPGMR3PHYSCHUNKUNMAPCB pArg = (PPGMR3PHYSCHUNKUNMAPCB)pvUser;
    3773 
    3774     if (    pChunk->iAge
    3775         &&  !pChunk->cRefs
    3776         &&  pArg->iLastAge < pChunk->iAge)
    3777     {
    3778         /*
    3779          * Check that it's not in any of the TLBs.
    3780          */
    3781         PVM pVM = pArg->pVM;
    3782         for (unsigned i = 0; i < RT_ELEMENTS(pVM->pgm.s.ChunkR3Map.Tlb.aEntries); i++)
    3783             if (pVM->pgm.s.ChunkR3Map.Tlb.aEntries[i].pChunk == pChunk)
    3784             {
    3785                 pChunk = NULL;
    3786                 break;
    3787             }
    3788         if (pChunk)
    3789             for (unsigned i = 0; i < RT_ELEMENTS(pVM->pgm.s.PhysTlbHC.aEntries); i++)
    3790                 if (pVM->pgm.s.PhysTlbHC.aEntries[i].pMap == pChunk)
    3791                 {
    3792                     pChunk = NULL;
    3793                     break;
    3794                 }
    3795         if (pChunk)
    3796         {
    3797             pArg->pChunk = pChunk;
    3798             pArg->iLastAge = pChunk->iAge;
    3799         }
    3800     }
     3771    PPGMCHUNKR3MAP          pChunk = (PPGMCHUNKR3MAP)pNode;
     3772    PPGMR3PHYSCHUNKUNMAPCB  pArg   = (PPGMR3PHYSCHUNKUNMAPCB)pvUser;
     3773
     3774    /*
     3775     * Check for locks and age.
     3776     */
     3777    if (pChunk->cRefs)
     3778        return 0;
     3779    if (!pChunk->iAge)
     3780        return 0;
     3781    if (pArg->iLastAge >= pChunk->iAge)
     3782        return 0;
     3783
     3784    /*
     3785     * Check that it's not in any of the TLBs.
     3786     */
     3787    PVM pVM = pArg->pVM;
     3788    if (   pVM->pgm.s.ChunkR3Map.Tlb.aEntries[PGM_CHUNKR3MAPTLB_IDX(pChunk->Core.Key)].idChunk
     3789        == pChunk->Core.Key)
     3790    {
     3791        pChunk = NULL;
     3792        return 0;
     3793    }
     3794#ifdef VBOX_STRICT
     3795    for (unsigned i = 0; i < RT_ELEMENTS(pVM->pgm.s.ChunkR3Map.Tlb.aEntries); i++)
     3796    {
     3797        Assert(pVM->pgm.s.ChunkR3Map.Tlb.aEntries[i].pChunk != pChunk);
     3798        Assert(pVM->pgm.s.ChunkR3Map.Tlb.aEntries[i].idChunk != pChunk->Core.Key);
     3799    }
     3800#endif
     3801
     3802    for (unsigned i = 0; i < RT_ELEMENTS(pVM->pgm.s.PhysTlbHC.aEntries); i++)
     3803        if (pVM->pgm.s.PhysTlbHC.aEntries[i].pMap == pChunk)
     3804            return 0;
     3805
     3806    pArg->pChunk   = pChunk;
     3807    pArg->iLastAge = pChunk->iAge;
    38013808    return 0;
    38023809}
     
    38383845    if (Args.pChunk)
    38393846    {
     3847        Assert(Args.pChunk->cRefs == 0);
     3848        Assert(Args.pChunk->cPermRefs == 0);
    38403849        STAM_PROFILE_STOP(&pVM->pgm.s.CTX_SUFF(pStats)->StatChunkFindCandidate, a);
    38413850        return Args.pChunk->Core.Key;
     
    38453854    return INT32_MAX;
    38463855}
     3856
    38473857
    38483858/**
     
    38663876    {
    38673877        /* Flush the pgm pool cache; call the internal rendezvous handler as we're already in a rendezvous handler here. */
    3868         /* todo: also not really efficient to unmap a chunk that contains PD or PT pages. */
     3878        /** @todo also not really efficient to unmap a chunk that contains PD
     3879         *  or PT pages. */
    38693880        pgmR3PoolClearAllRendezvous(pVM, &pVM->aCpus[0], NULL /* no need to flush the REM TLB as we already did that above */);
    38703881
     
    38743885        GMMMAPUNMAPCHUNKREQ Req;
    38753886        Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
    3876         Req.Hdr.cbReq = sizeof(Req);
    3877         Req.pvR3 = NULL;
    3878         Req.idChunkMap = NIL_GMM_CHUNKID;
     3887        Req.Hdr.cbReq    = sizeof(Req);
     3888        Req.pvR3         = NULL;
     3889        Req.idChunkMap   = NIL_GMM_CHUNKID;
    38793890        Req.idChunkUnmap = pgmR3PhysChunkFindUnmapCandidate(pVM);
    3880 
    38813891        if (Req.idChunkUnmap != INT32_MAX)
    38823892        {
     
    38863896            if (RT_SUCCESS(rc))
    38873897            {
    3888                 /* remove the unmapped one. */
     3898                /*
     3899                 * Remove the unmapped one.
     3900                 */
    38893901                PPGMCHUNKR3MAP pUnmappedChunk = (PPGMCHUNKR3MAP)RTAvlU32Remove(&pVM->pgm.s.ChunkR3Map.pTree, Req.idChunkUnmap);
    38903902                AssertRelease(pUnmappedChunk);
    3891                 pUnmappedChunk->pv = NULL;
     3903                AssertRelease(!pUnmappedChunk->cRefs);
     3904                AssertRelease(!pUnmappedChunk->cPermRefs);
     3905                pUnmappedChunk->pv       = NULL;
    38923906                pUnmappedChunk->Core.Key = UINT32_MAX;
    38933907#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
     
    38993913                pVM->pgm.s.cUnmappedChunks++;
    39003914
    3901                 /* Flush dangling PGM pointers (R3 & R0 ptrs to GC physical addresses) */
    3902                 /* todo: we should not flush chunks which include cr3 mappings. */
     3915                /*
     3916                 * Flush dangling PGM pointers (R3 & R0 ptrs to GC physical addresses).
     3917                 */
     3918                /** todo: we should not flush chunks which include cr3 mappings. */
    39033919                for (VMCPUID idCpu = 0; idCpu < pVM->cCpus; idCpu++)
    39043920                {
     
    39934009    if (RT_SUCCESS(rc))
    39944010    {
    3995         /*
    3996          * Update the tree.
    3997          */
    3998         /* insert the new one. */
    3999         AssertPtr(Req.pvR3);
    4000         pChunk->pv = Req.pvR3;
    4001         bool fRc = RTAvlU32Insert(&pVM->pgm.s.ChunkR3Map.pTree, &pChunk->Core);
    4002         AssertRelease(fRc);
    4003         pVM->pgm.s.ChunkR3Map.c++;
    4004         pVM->pgm.s.cMappedChunks++;
    4005 
    40064011        /*
    40074012         * If we're running out of virtual address space, then we should
     
    40214026         *        map+unmap as one kernel call without any rendezvous or
    40224027         *        other precautions. */
    4023         if (pVM->pgm.s.ChunkR3Map.c >= pVM->pgm.s.ChunkR3Map.cMax)
     4028        if (pVM->pgm.s.ChunkR3Map.c + 1 >= pVM->pgm.s.ChunkR3Map.cMax)
    40244029        {
    40254030            switch (VMR3GetState(pVM))
     
    40434048            }
    40444049        }
     4050
     4051        /*
     4052         * Update the tree.  We must do this after any unmapping to make sure
     4053         * the chunk we're going to return isn't unmapped by accident.
     4054         */
     4055        /* insert the new one. */
     4056        AssertPtr(Req.pvR3);
     4057        pChunk->pv = Req.pvR3;
     4058        bool fRc = RTAvlU32Insert(&pVM->pgm.s.ChunkR3Map.pTree, &pChunk->Core);
     4059        AssertRelease(fRc);
     4060        pVM->pgm.s.ChunkR3Map.c++;
     4061        pVM->pgm.s.cMappedChunks++;
    40454062    }
    40464063    else
  • trunk/src/VBox/VMM/include/PGMInline.h

    r37354 r38955  
    491491        STAM_COUNTER_INC(&pVM->pgm.s.CTX_SUFF(pStats)->CTX_MID_Z(Stat,PageMapTlbHits));
    492492        rc = VINF_SUCCESS;
     493        AssertPtr(pTlbe->pv);
     494        Assert(!pTlbe->pMap || RT_VALID_PTR(pTlbe->pMap->pv));
    493495    }
    494496    else
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