VirtualBox

Changeset 82975 in vbox for trunk/src/VBox/VMM/VMMR0


Ignore:
Timestamp:
Feb 4, 2020 12:35:27 PM (5 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
135984
Message:

VMM/GMMR0: Use the chunk list rather than the AVL tree in GMMR0FindDuplicatePageReq to look for duplicate pages. This will restricts the AVL tree to lookups and make it simpler to protect. bugref:9627

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/GMMR0.cpp

    r82968 r82975  
    53545354
    53555355/**
    5356  * RTAvlU32DoWithAll callback.
    5357  *
    5358  * @returns 0
    5359  * @param   pNode       The node to search.
    5360  * @param   pvUser      Pointer to the input argument packet.
    5361  */
    5362 static DECLCALLBACK(int) gmmR0FindDupPageInChunk(PAVLU32NODECORE pNode, void *pvUser)
    5363 {
    5364     PGMMCHUNK           pChunk = (PGMMCHUNK)pNode;
    5365     GMMFINDDUPPAGEINFO *pArgs  = (GMMFINDDUPPAGEINFO *)pvUser;
    5366     PGVM                pGVM   = pArgs->pGVM;
    5367     PGMM                pGMM   = pArgs->pGMM;
    5368     uint8_t            *pbChunk;
    5369 
     5356 * Worker for GMMR0FindDuplicatePageReq.
     5357 *
     5358 * @returns true if duplicate, false if not.
     5359 */
     5360static bool gmmR0FindDupPageInChunk(PGMM pGMM, PGVM pGVM, PGMMCHUNK pChunk, uint8_t const *pbSourcePage)
     5361{
     5362    bool fFoundDuplicate = false;
    53705363    /* Only take chunks not mapped into this VM process; not entirely correct. */
     5364    uint8_t *pbChunk;
    53715365    if (!gmmR0IsChunkMapped(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk))
    53725366    {
     
    53775371             * Look for duplicate pages
    53785372             */
    5379             unsigned iPage = (GMM_CHUNK_SIZE >> PAGE_SHIFT);
     5373            uintptr_t iPage = (GMM_CHUNK_SIZE >> PAGE_SHIFT);
    53805374            while (iPage-- > 0)
    53815375            {
     
    53835377                {
    53845378                    uint8_t *pbDestPage = pbChunk + (iPage  << PAGE_SHIFT);
    5385 
    5386                     if (!memcmp(pArgs->pSourcePage, pbDestPage, PAGE_SIZE))
     5379                    if (!memcmp(pbSourcePage, pbDestPage, PAGE_SIZE))
    53875380                    {
    5388                         pArgs->fFoundDuplicate = true;
     5381                        fFoundDuplicate = true;
    53895382                        break;
    53905383                    }
     
    53945387        }
    53955388    }
    5396     return pArgs->fFoundDuplicate; /* (stops search if true) */
     5389    return fFoundDuplicate;
    53975390}
    53985391
     
    54365429                if (pPage)
    54375430                {
     5431                    /*
     5432                     * Walk the chunks
     5433                     */
    54385434                    GMMFINDDUPPAGEINFO Args;
    54395435                    Args.pGVM            = pGVM;
     
    54415437                    Args.pSourcePage     = pbSourcePage;
    54425438                    Args.fFoundDuplicate = false;
    5443                     RTAvlU32DoWithAll(&pGMM->pChunks, true /* fFromLeft */, gmmR0FindDupPageInChunk, &Args);
    5444 
    5445                     pReq->fDuplicate = Args.fFoundDuplicate;
     5439
     5440                    PGMMCHUNK pChunk;
     5441                    pReq->fDuplicate = false;
     5442                    RTListForEach(&pGMM->ChunkList, pChunk, GMMCHUNK, ListNode)
     5443                    {
     5444                        if (gmmR0FindDupPageInChunk(pGMM, pGVM, pChunk, pbSourcePage))
     5445                        {
     5446                            pReq->fDuplicate = true;
     5447                            break;
     5448                        }
     5449                    }
    54465450                }
    54475451                else
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette