VirtualBox

Changeset 29201 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
May 7, 2010 12:24:54 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
61278
Message:

Shared paging updates

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/GMM.cpp

    r29086 r29201  
    399399
    400400/**
    401  * @see GMMR0CheckSharedModules
    402  */
    403 GMMR3DECL(int) GMMR3CheckSharedModules(PVM pVM)
    404 {
    405     return VMMR3CallR0(pVM, VMMR0_DO_GMM_CHECK_SHARED_MODULES, 0, NULL);
    406 }
     401 * @see GMMR0ResetSharedModules
     402 */
     403GMMR3DECL(int) GMMR3ResetSharedModules(PVM pVM)
     404{
     405    return VMMR3CallR0(pVM, VMMR0_DO_GMM_RESET_SHARED_MODULES, 0, NULL);
     406}
  • trunk/src/VBox/VMM/PGMPhys.cpp

    r28974 r29201  
    13581358    int rc = GMMR3BalloonedPages(pVM, GMMBALLOONACTION_RESET, 0);
    13591359    AssertRC(rc);
     1360
     1361#ifdef VBOX_WITH_PAGE_SHARING
     1362    /* Clear all registered shared modules. */
     1363    rc = GMMR3ResetSharedModules(pVM);
     1364    AssertRC(rc);
     1365#endif
    13601366
    13611367    /*
  • trunk/src/VBox/VMM/PGMSharedPage.cpp

    r29091 r29201  
    214214#endif
    215215}
    216 
    217 
    218 /**
    219  * Checks regsitered modules for shared pages
    220  *
    221  * @returns VBox status code.
    222  * @param   pVM                 VM handle
    223  */
    224 VMMR3DECL(int) PGMR3SharedModuleCheck(PVM pVM)
    225 {
    226 #ifdef VBOX_WITH_PAGE_SHARING
    227     return GMMR3CheckSharedModules(pVM);
    228 #else
    229     return VERR_NOT_IMPLEMENTED;
    230 #endif
    231 }
  • trunk/src/VBox/VMM/VMMR0/GMMR0.cpp

    r29168 r29201  
    618618static DECLCALLBACK(int) gmmR0TermDestroyChunk(PAVLU32NODECORE pNode, void *pvGMM);
    619619static DECLCALLBACK(int) gmmR0CleanupVMScanChunk(PAVLU32NODECORE pNode, void *pvGMM);
     620static DECLCALLBACK(int) gmmR0CleanupSharedModule(PAVLGCPTRNODECORE pNode, void *pvGVM);
    620621/*static*/ DECLCALLBACK(int) gmmR0CleanupVMDestroyChunk(PAVLU32NODECORE pNode, void *pvGVM);
    621622DECLINLINE(void) gmmR0LinkChunk(PGMMCHUNK pChunk, PGMMCHUNKFREESET pSet);
     
    805806    AssertRC(rc);
    806807    GMM_CHECK_SANITY_UPON_ENTERING(pGMM);
     808
     809#ifdef VBOX_WITH_PAGE_SHARING
     810    /* Clean up all registered shared modules. */
     811    RTAvlGCPtrDestroy(&pGVM->gmm.s.pSharedModuleTree, gmmR0CleanupSharedModule, pGVM);
     812#endif
    807813
    808814    /*
     
    34323438        if (!pRecVM)
    34333439        {
    3434             pRecVM = (PGMMSHAREDMODULEPERVM)RTMemAllocZ(RT_OFFSETOF(GMMSHAREDMODULEPERVM, aRegions[cRegions]));
     3440            pRecVM = (PGMMSHAREDMODULEPERVM)RTMemAllocZ(sizeof(*pRecVM));
    34353441            if (!pRecVM)
    34363442            {
     
    34393445                goto end;
    34403446            }
    3441 
    34423447            pRecVM->Core.Key = GCBaseAddr;
    3443             pRecVM->cRegions = cRegions;
    3444             for (unsigned i = 0; i < cRegions; i++)
    3445             {
    3446                 pRecVM->aRegions[i].GCRegionAddr      = pRegions[i].GCRegionAddr;
    3447                 pRecVM->aRegions[i].cbRegion          = pRegions[i].cbRegion;
    3448                 pRecVM->aRegions[i].u32Alignment      = 0;
    3449                 pRecVM->aRegions[i].paHCPhysPageID    = NULL; /* uninitialized. */
    3450             }
    34513448
    34523449            bool ret = RTAvlGCPtrInsert(&pGVM->gmm.s.pSharedModuleTree, &pRecVM->Core);
     
    36023599            if (pRec->cUsers == 0)
    36033600            {
    3604                 /* @todo free shared pages. */
    36053601                for (unsigned i = 0; i < pRec->cRegions; i++)
    36063602                    if (pRec->aRegions[i].paHCPhysPageID)
     
    36083604
    36093605                RTMemFree(pRec);
    3610             }
    3611         }
    3612         /* Free all the shared pages we refence here. */
    3613         for (unsigned i = 0; i < pRecVM->cRegions; i++)
    3614         {
    3615             PGMMSHAREDREGIONDESC pRegion = &pRecVM->aRegions[i];
    3616 
    3617             if (pRegion->paHCPhysPageID)
    3618             {
    3619                 unsigned cPages = pRegion->cbRegion >> PAGE_SHIFT;
    3620 
    3621                 for (unsigned j = 0; j < cPages; j++)
    3622                 {
    3623                     if (pRegion->paHCPhysPageID[j] != NIL_GMM_PAGEID)
    3624                     {
    3625                         GMMFREEPAGEDESC PageDesc;
    3626 
    3627                         PageDesc.idPage = pRegion->paHCPhysPageID[j];
    3628                         rc = gmmR0FreePages(pGMM, pGVM, 1, &PageDesc, GMMACCOUNT_BASE);
    3629                         AssertRC(rc);
    3630                     }
    3631                 }
    3632 
    3633                 RTMemFree(pRecVM->aRegions[i].paHCPhysPageID);
    36343606            }
    36353607        }
     
    36913663    AssertReturn(cPages == (pReq->aRegions[idxRegion].cbRegion >> PAGE_SHIFT), VERR_INVALID_PARAMETER);
    36923664
     3665    Log(("GMMR0SharedModuleCheckRange %s base %RGv region %d cPages %d\n", pReq->szName, pReq->GCBaseAddr, idxRegion, cPages));
     3666
    36933667    /*
    36943668     * Validate input and get the basics.
     
    37163690            goto end;
    37173691        }
    3718         PGMMSHAREDREGIONDESC pLocalRegion = &pLocalModule->aRegions[idxRegion];
    3719         if (!pLocalRegion->paHCPhysPageID)
     3692
     3693        PGMMSHAREDMODULE     pGlobalModule = pLocalModule->pGlobalModule;
     3694        PGMMSHAREDREGIONDESC pGlobalRegion = &pGlobalModule->aRegions[idxRegion];
     3695
     3696        if (!pGlobalRegion->paHCPhysPageID)
    37203697        {
    37213698            /* First time; create a page descriptor array. */
    3722             pLocalRegion->paHCPhysPageID = (uint32_t *)RTMemAlloc(cPages * sizeof(*pLocalRegion->paHCPhysPageID));
    3723             if (!pLocalRegion->paHCPhysPageID)
     3699            pGlobalRegion->paHCPhysPageID = (uint32_t *)RTMemAlloc(cPages * sizeof(*pGlobalRegion->paHCPhysPageID));
     3700            if (!pGlobalRegion->paHCPhysPageID)
    37243701            {
    37253702                AssertFailed();
     
    37293706            /* Invalidate all descriptors. */
    37303707            for (unsigned i = 0; i < cPages; i++)
    3731                 pLocalRegion->paHCPhysPageID[i] = NIL_GMM_PAGEID;
    3732         }
    3733 
    3734         PGMMSHAREDMODULE     pGlobalModule = pLocalModule->pGlobalModule;
    3735         PGMMSHAREDREGIONDESC pGlobalRegion = &pGlobalModule->aRegions[idxRegion];
    3736 
    3737         if (!pGlobalRegion->paHCPhysPageID)
    3738         {
    3739             /* First time; create a page descriptor array. */
    3740             pGlobalRegion->paHCPhysPageID = (uint32_t *)RTMemAlloc(cPages * sizeof(*pGlobalRegion->paHCPhysPageID));
    3741             if (!pGlobalRegion->paHCPhysPageID)
    3742             {
    3743                 AssertFailed();
    3744                 rc = VERR_NO_MEMORY;
    3745                 goto end;
    3746             }
    3747             /* Invalidate all descriptors. */
    3748             for (unsigned i = 0; i < cPages; i++)
    37493708                pGlobalRegion->paHCPhysPageID[i] = NIL_GMM_PAGEID;
    37503709        }
     
    37543713        {
    37553714            /* Valid page present? */
    3756             if (paPageDesc[i].uPageId != NIL_GMM_PAGEID)
     3715            if (paPageDesc[i].uHCPhysPageId != NIL_GMM_PAGEID)
    37573716            {
    37583717                /* We've seen this shared page for the first time? */
    37593718                if (pGlobalRegion->paHCPhysPageID[i] == NIL_GMM_PAGEID)
    37603719                {
    3761                     Assert(pLocalRegion->paHCPhysPageID[i] == NIL_GMM_PAGEID);
    3762 
    37633720                    /* Easy case: just change the internal page type. */
    3764                     PGMMPAGE pPage = gmmR0GetPage(pGMM, paPageDesc[i].uPageId);
     3721                    PGMMPAGE pPage = gmmR0GetPage(pGMM, paPageDesc[i].uHCPhysPageId);
    37653722                    if (!pPage)
    37663723                    {
     
    37693726                        goto end;
    37703727                    }
     3728                    Log(("New shared page guest %RGp host %RHp\n", paPageDesc[i].GCPhys, (pPage->Private.pfn << 12)));
     3729
    37713730                    Assert(paPageDesc[i].HCPhys == (pPage->Private.pfn << 12));
    37723731                    pPage->Shared.pfn     = pPage->Private.pfn;     /* same location */
     
    37753734
    37763735                    /* Keep track of these references. */
    3777                     pLocalRegion->paHCPhysPageID[i]  = paPageDesc[i].uPageId;
    3778                     pGlobalRegion->paHCPhysPageID[i] = paPageDesc[i].uPageId;
     3736                    pGlobalRegion->paHCPhysPageID[i] = paPageDesc[i].uHCPhysPageId;
    37793737                }
    37803738                else
    37813739                {
    3782                     Assert(pLocalRegion->paHCPhysPageID[i] != pGlobalRegion->paHCPhysPageID[i]);
    3783 
    3784                     PGMMPAGE pPage = gmmR0GetPage(pGMM, paPageDesc[i].uPageId);
     3740                    Assert(paPageDesc[i].uHCPhysPageId != pGlobalRegion->paHCPhysPageID[i]);
     3741
     3742                    PGMMPAGE pPage = gmmR0GetPage(pGMM, paPageDesc[i].uHCPhysPageId);
    37853743                    if (!pPage)
    37863744                    {
     
    37913749                    Assert(pPage->Common.u2State == GMM_PAGE_STATE_SHARED);
    37923750
    3793                     PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, paPageDesc[i].uPageId >> GMM_CHUNKID_SHIFT);
     3751                    Log(("Replace existing page guest %RGp host %RHp -> %RHp\n", paPageDesc[i].GCPhys, paPageDesc[i].HCPhys, (pPage->Private.pfn << 12)));
     3752
     3753                    PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, paPageDesc[i].uHCPhysPageId >> GMM_CHUNKID_SHIFT);
    37943754                    Assert(pChunk); /* can't fail as gmmR0GetPage succeeded. */
    37953755                    uint8_t *pbR3Page, *pbR3Chunk;
     
    38053765                        }
    38063766                    }
    3807                     pbR3Page = pbR3Chunk + ((paPageDesc[i].uPageId & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
     3767                    pbR3Page = pbR3Chunk + ((paPageDesc[i].uHCPhysPageId & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
    38083768
    38093769                    /* Free the old local page. */
    38103770                    GMMFREEPAGEDESC PageDesc;
    38113771
    3812                     PageDesc.idPage = pLocalRegion->paHCPhysPageID[i];
     3772                    PageDesc.idPage = paPageDesc[i].uHCPhysPageId;
    38133773                    rc = gmmR0FreePages(pGMM, pGVM, 1, &PageDesc, GMMACCOUNT_BASE);
    38143774                    AssertRC(rc);
    38153775
    38163776                    /* Pass along the new physical address & page id. */
    3817                     paPageDesc[i].HCPhys  = (pPage->Private.pfn << 12);
    3818                     paPageDesc[i].uPageId = pGlobalRegion->paHCPhysPageID[i];
    3819 
    3820                     pLocalRegion->paHCPhysPageID[i] = pGlobalRegion->paHCPhysPageID[i];
     3777                    paPageDesc[i].HCPhys        = (pPage->Private.pfn << 12);
     3778                    paPageDesc[i].uHCPhysPageId = pGlobalRegion->paHCPhysPageID[i];
    38213779                }
    38223780            }
    3823 #ifdef LOG_ENABLED
    3824             else
    3825             if (pLocalRegion->paHCPhysPageID[i] != NIL_GMM_PAGEID)
    3826             {
    3827                 /* Page was removed. */
    3828                 Log(("GMMR0SharedModuleCheckRange: page id %x not present anymore\n", pLocalRegion->paHCPhysPageID[i]));
    3829             }
    3830 #endif
    38313781        }
    38323782
     
    38403790    return rc;
    38413791}
     3792
     3793/**
     3794 * RTAvlU32Destroy callback.
     3795 *
     3796 * @returns 0
     3797 * @param   pNode   The node to destroy.
     3798 * @param   pvGVM   The GVM handle.
     3799 */
     3800static DECLCALLBACK(int) gmmR0CleanupSharedModule(PAVLGCPTRNODECORE pNode, void *pvGVM)
     3801{
     3802    PGVM pGVM = (PGVM)pvGVM;
     3803    PGMMSHAREDMODULEPERVM pRecVM = (PGMMSHAREDMODULEPERVM)pNode;
     3804
     3805    Assert(pRecVM->pGlobalModule);
     3806    if (pRecVM->pGlobalModule)
     3807    {
     3808        PGMMSHAREDMODULE pRec = pRecVM->pGlobalModule;
     3809        Assert(pRec);
     3810        Assert(pRec->cUsers);
     3811
     3812        pRec->cUsers--;
     3813        if (pRec->cUsers == 0)
     3814        {
     3815            for (unsigned i = 0; i < pRec->cRegions; i++)
     3816                if (pRec->aRegions[i].paHCPhysPageID)
     3817                    RTMemFree(pRec->aRegions[i].paHCPhysPageID);
     3818
     3819            RTMemFree(pRec);
     3820        }
     3821    }
     3822    RTMemFree(pRecVM);
     3823    return 0;
     3824}
    38423825#endif
    38433826
    38443827/**
    3845  * Checks registered modules for shared pages
     3828 * Removes all shared modules for the specified VM
    38463829 *
    38473830 * @returns VBox status code.
     
    38493832 * @param   idCpu               VCPU id
    38503833 */
    3851 GMMR0DECL(int) GMMR0CheckSharedModules(PVM pVM, VMCPUID idCpu)
     3834GMMR0DECL(int) GMMR0ResetSharedModules(PVM pVM, VMCPUID idCpu)
    38523835{
    38533836#ifdef VBOX_WITH_PAGE_SHARING
    3854     return VERR_NOT_IMPLEMENTED;
     3837    /*
     3838     * Validate input and get the basics.
     3839     */
     3840    PGMM pGMM;
     3841    GMM_GET_VALID_INSTANCE(pGMM, VERR_INTERNAL_ERROR);
     3842    PGVM pGVM;
     3843    int rc = GVMMR0ByVMAndEMT(pVM, idCpu, &pGVM);
     3844    if (RT_FAILURE(rc))
     3845        return rc;
     3846
     3847    /*
     3848     * Take the sempahore and do some more validations.
     3849     */
     3850    rc = RTSemFastMutexRequest(pGMM->Mtx);
     3851    AssertRC(rc);
     3852    if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
     3853    {
     3854        RTAvlGCPtrDestroy(&pGVM->gmm.s.pSharedModuleTree, gmmR0CleanupSharedModule, pGVM);
     3855
     3856        rc = VINF_SUCCESS;
     3857        GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
     3858    }
     3859    else
     3860        rc = VERR_INTERNAL_ERROR_5;
     3861
     3862    RTSemFastMutexRelease(pGMM->Mtx);
     3863    return rc;     
    38553864#else
    38563865    return VERR_NOT_IMPLEMENTED;
  • trunk/src/VBox/VMM/VMMR0/GMMR0Internal.h

    r29168 r29201  
    5555typedef GMMSHAREDREGIONDESC *PGMMSHAREDREGIONDESC;
    5656
     57
    5758/**
    5859 * Shared module registration info (global)
     
    9495    bool                        fCollision;
    9596    /** Alignment. */
    96     bool                        bAlignment;
    97 
    98     /** Number of regions. */
    99     unsigned                    cRegions;
    100     /** Shared region descriptor(s). */
    101     GMMSHAREDREGIONDESC         aRegions[1];
     97    bool                        bAlignment[7];
    10298} GMMSHAREDMODULEPERVM;
    10399/** Pointer to a GMMSHAREDMODULEPERVM. */
  • trunk/src/VBox/VMM/VMMR0/PGMR0.cpp

    r29168 r29201  
    366366                {
    367367                    fValidChanges = true;
    368                     paPageDesc[idxPage].uPageId = PGM_PAGE_GET_PAGEID(pPage);
    369                     paPageDesc[idxPage].HCPhys  = PGM_PAGE_GET_HCPHYS(pPage);
    370                     paPageDesc[idxPage].GCPhys  = GCPhys;
     368                    paPageDesc[idxPage].uHCPhysPageId = PGM_PAGE_GET_PAGEID(pPage);
     369                    paPageDesc[idxPage].HCPhys        = PGM_PAGE_GET_HCPHYS(pPage);
     370                    paPageDesc[idxPage].GCPhys        = GCPhys;
    371371                }
    372372                else
    373                     paPageDesc[idxPage].uPageId = NIL_GMM_PAGEID;
     373                    paPageDesc[idxPage].uHCPhysPageId = NIL_GMM_PAGEID;
    374374            }
    375375            else
    376                 paPageDesc[idxPage].uPageId = NIL_GMM_PAGEID;
     376                paPageDesc[idxPage].uHCPhysPageId = NIL_GMM_PAGEID;
    377377
    378378            idxPage++;
     
    391391            {
    392392                /* Any change for this page? */
    393                 if (paPageDesc[i].uPageId != NIL_GMM_PAGEID)
     393                if (paPageDesc[i].uHCPhysPageId != NIL_GMM_PAGEID)
    394394                {
    395395                    /** todo: maybe cache these to prevent the nth lookup. */
     
    421421                        /* Update the physical address and page id now. */
    422422                        PGM_PAGE_SET_HCPHYS(pPage, paPageDesc[idxPage].HCPhys);
    423                         PGM_PAGE_SET_PAGEID(pPage, paPageDesc[idxPage].uPageId);
     423                        PGM_PAGE_SET_PAGEID(pPage, paPageDesc[idxPage].uHCPhysPageId);
    424424                    }
    425425                    /* else nothing changed (== this page is now a shared page), so no need to flush anything. */
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r29091 r29201  
    952952
    953953        case VMMR0_DO_GMM_REGISTER_SHARED_MODULE:
     954            if (idCpu == NIL_VMCPUID)
     955                return VERR_INVALID_CPU_ID;
    954956            if (u64Arg)
    955957                return VERR_INVALID_PARAMETER;
     
    957959
    958960        case VMMR0_DO_GMM_UNREGISTER_SHARED_MODULE:
     961            if (idCpu == NIL_VMCPUID)
     962                return VERR_INVALID_CPU_ID;
    959963            if (u64Arg)
    960964                return VERR_INVALID_PARAMETER;
    961965            return GMMR0UnregisterSharedModuleReq(pVM, idCpu, (PGMMUNREGISTERSHAREDMODULEREQ)pReqHdr);
    962966
    963         case VMMR0_DO_GMM_CHECK_SHARED_MODULES:
     967        case VMMR0_DO_GMM_RESET_SHARED_MODULES:
     968            if (idCpu == NIL_VMCPUID)
     969                return VERR_INVALID_CPU_ID;
    964970            if (    u64Arg
    965971                ||  pReqHdr)
    966972                return VERR_INVALID_PARAMETER;
    967             return GMMR0CheckSharedModules(pVM, idCpu);
     973            return GMMR0ResetSharedModules(pVM, idCpu);
    968974
    969975        /*
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