VirtualBox

Changeset 29209 in vbox for trunk/src


Ignore:
Timestamp:
May 7, 2010 1:16:53 PM (15 years ago)
Author:
vboxsync
Message:

More shared paging updates

Location:
trunk/src/VBox/VMM/VMMR0
Files:
2 edited

Legend:

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

    r29201 r29209  
    35023502                &&  !strcmp(pGlobalModule->szVersion, pszVersion))
    35033503            {
    3504                 Assert(!pRecVM->fCollision);
    3505 
    35063504                /* Save reference. */
    35073505                pRecVM->pGlobalModule = pGlobalModule;
     3506                if (    fNewModule
     3507                    ||  pRecVM->fCollision == true) /* colliding module unregistered and new one registerd since the last check */
     3508                    pGlobalModule->cUsers++;
     3509
    35083510                pRecVM->fCollision    = false;
    3509                 if (fNewModule)
    3510                     pGlobalModule->cUsers++;
    35113511                rc = VINF_SUCCESS;
    35123512            }
     
    35903590            goto end;
    35913591        }
    3592         /* Force pRec to go out of scope after freeing it. */
     3592        /* Remove reference to global shared module. */
     3593        if (!pRecVM->fCollision)
    35933594        {
    35943595            PGMMSHAREDMODULE pRec = pRecVM->pGlobalModule;
    35953596            Assert(pRec);
    3596             Assert(pRec->cUsers);
    3597 
    3598             pRec->cUsers--;
    3599             if (pRec->cUsers == 0)
     3597
     3598            if (pRec)   /* paranoia */
    36003599            {
    3601                 for (unsigned i = 0; i < pRec->cRegions; i++)
    3602                     if (pRec->aRegions[i].paHCPhysPageID)
    3603                         RTMemFree(pRec->aRegions[i].paHCPhysPageID);
    3604 
    3605                 RTMemFree(pRec);
     3600                Assert(pRec->cUsers);
     3601                pRec->cUsers--;
     3602                if (pRec->cUsers == 0)
     3603                {
     3604                    /* Free the ranges, but leave the pages intact as there might still be references; they will be cleared by the COW mechanism. */
     3605                    for (unsigned i = 0; i < pRec->cRegions; i++)
     3606                        if (pRec->aRegions[i].paHCPhysPageID)
     3607                            RTMemFree(pRec->aRegions[i].paHCPhysPageID);
     3608
     3609                    RTMemFree(pRec);
     3610                }
    36063611            }
    3607         }
     3612            else
     3613                rc = VERR_PGM_SHARED_MODULE_REGISTRATION_INCONSISTENCY;
     3614        }
     3615        else
     3616            Assert(!pRecVM->pGlobalModule);
     3617
    36083618        RTMemFree(pRecVM);
    36093619
     
    37383748                else
    37393749                {
     3750                    uint8_t  *pbLocalPage, *pbSharedPage;
     3751                    uint8_t  *pbChunk;
     3752                    PGMMCHUNK pChunk;
     3753
    37403754                    Assert(paPageDesc[i].uHCPhysPageId != pGlobalRegion->paHCPhysPageID[i]);
    37413755
    3742                     PGMMPAGE pPage = gmmR0GetPage(pGMM, paPageDesc[i].uHCPhysPageId);
     3756                    /* Get the shared page source. */
     3757                    PGMMPAGE pPage = gmmR0GetPage(pGMM, pGlobalRegion->paHCPhysPageID[i]);
    37433758                    if (!pPage)
    37443759                    {
     
    37513766                    Log(("Replace existing page guest %RGp host %RHp -> %RHp\n", paPageDesc[i].GCPhys, paPageDesc[i].HCPhys, (pPage->Private.pfn << 12)));
    37523767
    3753                     PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, paPageDesc[i].uHCPhysPageId >> GMM_CHUNKID_SHIFT);
     3768                    /* Calculate the virtual address of the local page. */
     3769                    pChunk = gmmR0GetChunk(pGMM, paPageDesc[i].uHCPhysPageId >> GMM_CHUNKID_SHIFT);
     3770                    if (pChunk)
     3771                    {
     3772                        if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk))
     3773                        {
     3774                            AssertFailed();
     3775                            rc = VERR_PGM_PHYS_INVALID_PAGE_ID;
     3776                            goto end;
     3777                        }
     3778                        pbLocalPage = pbChunk + ((paPageDesc[i].uHCPhysPageId & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
     3779                    }
     3780                    else
     3781                    {
     3782                        AssertFailed();
     3783                        rc = VERR_PGM_PHYS_INVALID_PAGE_ID;
     3784                        goto end;
     3785                    }
     3786                   
     3787                    /* Calculate the virtual address of the shared page. */
     3788                    pChunk = gmmR0GetChunk(pGMM, pGlobalRegion->paHCPhysPageID[i] >> GMM_CHUNKID_SHIFT);
    37543789                    Assert(pChunk); /* can't fail as gmmR0GetPage succeeded. */
    3755                     uint8_t *pbR3Page, *pbR3Chunk;
    37563790
    37573791                    /* Get the virtual address of the physical page; map the chunk into the VM process if not already done. */
    3758                     if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbR3Chunk))
     3792                    if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk))
    37593793                    {
    3760                         rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pbR3Chunk);
     3794                        rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk);
    37613795                        if (rc != VINF_SUCCESS)
    37623796                        {
     
    37653799                        }
    37663800                    }
    3767                     pbR3Page = pbR3Chunk + ((paPageDesc[i].uHCPhysPageId & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
     3801                    pbSharedPage = pbChunk + ((pGlobalRegion->paHCPhysPageID[i] & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
     3802
     3803                    /** todo write ASMMemComparePage. */
     3804                    if (memcmp(pbSharedPage, pbLocalPage, PAGE_SIZE))
     3805                    {
     3806                        Log(("Unexpected differences found between local and shared page; skip\n"));
     3807                        continue;
     3808                    }
    37683809
    37693810                    /* Free the old local page. */
     
    37733814                    rc = gmmR0FreePages(pGMM, pGVM, 1, &PageDesc, GMMACCOUNT_BASE);
    37743815                    AssertRC(rc);
     3816
     3817                    /* Increase reference count. */
     3818                    pPage->Shared.cRefs++;
    37753819
    37763820                    /* Pass along the new physical address & page id. */
  • trunk/src/VBox/VMM/VMMR0/PGMR0.cpp

    r29201 r29209  
    342342                RTMemFree(paPageDesc);
    343343
    344             paPageDesc = (PGMMSHAREDPAGEDESC)RTMemAlloc((cbRegion << PAGE_SHIFT) * sizeof(*paPageDesc));
     344            paPageDesc = (PGMMSHAREDPAGEDESC)RTMemAlloc((cbRegion >> PAGE_SHIFT) * sizeof(*paPageDesc));
    345345            if (!paPageDesc)
    346346            {
     
    359359            rc = PGMGstGetPage(pVCpu, GCRegion, &GCPhys, &fFlags);
    360360            if (    rc == VINF_SUCCESS
    361                 &&  !(fFlags & X86_PTE_RW))
     361                &&  !(fFlags & X86_PTE_RW)) /* important as we make assumptions about this below! */
    362362            {
    363363                PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys);
     
    387387            if (RT_FAILURE(rc))
    388388                break;
    389 
     389               
    390390            for (unsigned i = 0; i < idxPage; i++)
    391391            {
     
    394394                {
    395395                    /** todo: maybe cache these to prevent the nth lookup. */
    396                     PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPageDesc[idxPage].GCPhys);
     396                    PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPageDesc[i].GCPhys);
    397397                    if (!pPage)
    398398                    {
     
    404404                    Assert(!PGM_PAGE_IS_SHARED(pPage));
    405405
    406                     if (paPageDesc[idxPage].HCPhys != PGM_PAGE_GET_HCPHYS(pPage))
     406                    if (paPageDesc[i].HCPhys != PGM_PAGE_GET_HCPHYS(pPage))
    407407                    {
    408408                        bool fFlush = false;
    409409
    410                         /* Page was replaced by an existing shared version of it; dereference the page first. */
    411                         rc = pgmPoolTrackUpdateGCPhys(pVM, paPageDesc[idxPage].GCPhys, pPage, true /* clear the entries */, &fFlush);
     410                        /* Page was replaced by an existing shared version of it; clear all references first. */
     411                        rc = pgmPoolTrackUpdateGCPhys(pVM, paPageDesc[i].GCPhys, pPage, true /* clear the entries */, &fFlush);
    412412                        if (RT_FAILURE(rc))
    413413                        {
     
    420420
    421421                        /* Update the physical address and page id now. */
    422                         PGM_PAGE_SET_HCPHYS(pPage, paPageDesc[idxPage].HCPhys);
    423                         PGM_PAGE_SET_PAGEID(pPage, paPageDesc[idxPage].uHCPhysPageId);
     422                        PGM_PAGE_SET_HCPHYS(pPage, paPageDesc[i].HCPhys);
     423                        PGM_PAGE_SET_PAGEID(pPage, paPageDesc[i].uHCPhysPageId);
    424424                    }
    425425                    /* else nothing changed (== this page is now a shared page), so no need to flush anything. */
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