Changeset 29201 in vbox for trunk/src/VBox/VMM
- Timestamp:
- May 7, 2010 12:24:54 PM (15 years ago)
- svn:sync-xref-src-repo-rev:
- 61278
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/GMM.cpp
r29086 r29201 399 399 400 400 /** 401 * @see GMMR0 CheckSharedModules402 */ 403 GMMR3DECL(int) GMMR3 CheckSharedModules(PVM pVM)404 { 405 return VMMR3CallR0(pVM, VMMR0_DO_GMM_ CHECK_SHARED_MODULES, 0, NULL);406 } 401 * @see GMMR0ResetSharedModules 402 */ 403 GMMR3DECL(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 1358 1358 int rc = GMMR3BalloonedPages(pVM, GMMBALLOONACTION_RESET, 0); 1359 1359 AssertRC(rc); 1360 1361 #ifdef VBOX_WITH_PAGE_SHARING 1362 /* Clear all registered shared modules. */ 1363 rc = GMMR3ResetSharedModules(pVM); 1364 AssertRC(rc); 1365 #endif 1360 1366 1361 1367 /* -
trunk/src/VBox/VMM/PGMSharedPage.cpp
r29091 r29201 214 214 #endif 215 215 } 216 217 218 /**219 * Checks regsitered modules for shared pages220 *221 * @returns VBox status code.222 * @param pVM VM handle223 */224 VMMR3DECL(int) PGMR3SharedModuleCheck(PVM pVM)225 {226 #ifdef VBOX_WITH_PAGE_SHARING227 return GMMR3CheckSharedModules(pVM);228 #else229 return VERR_NOT_IMPLEMENTED;230 #endif231 } -
trunk/src/VBox/VMM/VMMR0/GMMR0.cpp
r29168 r29201 618 618 static DECLCALLBACK(int) gmmR0TermDestroyChunk(PAVLU32NODECORE pNode, void *pvGMM); 619 619 static DECLCALLBACK(int) gmmR0CleanupVMScanChunk(PAVLU32NODECORE pNode, void *pvGMM); 620 static DECLCALLBACK(int) gmmR0CleanupSharedModule(PAVLGCPTRNODECORE pNode, void *pvGVM); 620 621 /*static*/ DECLCALLBACK(int) gmmR0CleanupVMDestroyChunk(PAVLU32NODECORE pNode, void *pvGVM); 621 622 DECLINLINE(void) gmmR0LinkChunk(PGMMCHUNK pChunk, PGMMCHUNKFREESET pSet); … … 805 806 AssertRC(rc); 806 807 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 807 813 808 814 /* … … 3432 3438 if (!pRecVM) 3433 3439 { 3434 pRecVM = (PGMMSHAREDMODULEPERVM)RTMemAllocZ( RT_OFFSETOF(GMMSHAREDMODULEPERVM, aRegions[cRegions]));3440 pRecVM = (PGMMSHAREDMODULEPERVM)RTMemAllocZ(sizeof(*pRecVM)); 3435 3441 if (!pRecVM) 3436 3442 { … … 3439 3445 goto end; 3440 3446 } 3441 3442 3447 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 }3451 3448 3452 3449 bool ret = RTAvlGCPtrInsert(&pGVM->gmm.s.pSharedModuleTree, &pRecVM->Core); … … 3602 3599 if (pRec->cUsers == 0) 3603 3600 { 3604 /* @todo free shared pages. */3605 3601 for (unsigned i = 0; i < pRec->cRegions; i++) 3606 3602 if (pRec->aRegions[i].paHCPhysPageID) … … 3608 3604 3609 3605 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);3634 3606 } 3635 3607 } … … 3691 3663 AssertReturn(cPages == (pReq->aRegions[idxRegion].cbRegion >> PAGE_SHIFT), VERR_INVALID_PARAMETER); 3692 3664 3665 Log(("GMMR0SharedModuleCheckRange %s base %RGv region %d cPages %d\n", pReq->szName, pReq->GCBaseAddr, idxRegion, cPages)); 3666 3693 3667 /* 3694 3668 * Validate input and get the basics. … … 3716 3690 goto end; 3717 3691 } 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) 3720 3697 { 3721 3698 /* First time; create a page descriptor array. */ 3722 p LocalRegion->paHCPhysPageID = (uint32_t *)RTMemAlloc(cPages * sizeof(*pLocalRegion->paHCPhysPageID));3723 if (!p LocalRegion->paHCPhysPageID)3699 pGlobalRegion->paHCPhysPageID = (uint32_t *)RTMemAlloc(cPages * sizeof(*pGlobalRegion->paHCPhysPageID)); 3700 if (!pGlobalRegion->paHCPhysPageID) 3724 3701 { 3725 3702 AssertFailed(); … … 3729 3706 /* Invalidate all descriptors. */ 3730 3707 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++)3749 3708 pGlobalRegion->paHCPhysPageID[i] = NIL_GMM_PAGEID; 3750 3709 } … … 3754 3713 { 3755 3714 /* Valid page present? */ 3756 if (paPageDesc[i].u PageId != NIL_GMM_PAGEID)3715 if (paPageDesc[i].uHCPhysPageId != NIL_GMM_PAGEID) 3757 3716 { 3758 3717 /* We've seen this shared page for the first time? */ 3759 3718 if (pGlobalRegion->paHCPhysPageID[i] == NIL_GMM_PAGEID) 3760 3719 { 3761 Assert(pLocalRegion->paHCPhysPageID[i] == NIL_GMM_PAGEID);3762 3763 3720 /* Easy case: just change the internal page type. */ 3764 PGMMPAGE pPage = gmmR0GetPage(pGMM, paPageDesc[i].u PageId);3721 PGMMPAGE pPage = gmmR0GetPage(pGMM, paPageDesc[i].uHCPhysPageId); 3765 3722 if (!pPage) 3766 3723 { … … 3769 3726 goto end; 3770 3727 } 3728 Log(("New shared page guest %RGp host %RHp\n", paPageDesc[i].GCPhys, (pPage->Private.pfn << 12))); 3729 3771 3730 Assert(paPageDesc[i].HCPhys == (pPage->Private.pfn << 12)); 3772 3731 pPage->Shared.pfn = pPage->Private.pfn; /* same location */ … … 3775 3734 3776 3735 /* 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; 3779 3737 } 3780 3738 else 3781 3739 { 3782 Assert(p LocalRegion->paHCPhysPageID[i]!= pGlobalRegion->paHCPhysPageID[i]);3783 3784 PGMMPAGE pPage = gmmR0GetPage(pGMM, paPageDesc[i].u PageId);3740 Assert(paPageDesc[i].uHCPhysPageId != pGlobalRegion->paHCPhysPageID[i]); 3741 3742 PGMMPAGE pPage = gmmR0GetPage(pGMM, paPageDesc[i].uHCPhysPageId); 3785 3743 if (!pPage) 3786 3744 { … … 3791 3749 Assert(pPage->Common.u2State == GMM_PAGE_STATE_SHARED); 3792 3750 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); 3794 3754 Assert(pChunk); /* can't fail as gmmR0GetPage succeeded. */ 3795 3755 uint8_t *pbR3Page, *pbR3Chunk; … … 3805 3765 } 3806 3766 } 3807 pbR3Page = pbR3Chunk + ((paPageDesc[i].u PageId & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);3767 pbR3Page = pbR3Chunk + ((paPageDesc[i].uHCPhysPageId & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT); 3808 3768 3809 3769 /* Free the old local page. */ 3810 3770 GMMFREEPAGEDESC PageDesc; 3811 3771 3812 PageDesc.idPage = p LocalRegion->paHCPhysPageID[i];3772 PageDesc.idPage = paPageDesc[i].uHCPhysPageId; 3813 3773 rc = gmmR0FreePages(pGMM, pGVM, 1, &PageDesc, GMMACCOUNT_BASE); 3814 3774 AssertRC(rc); 3815 3775 3816 3776 /* 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]; 3821 3779 } 3822 3780 } 3823 #ifdef LOG_ENABLED3824 else3825 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 #endif3831 3781 } 3832 3782 … … 3840 3790 return rc; 3841 3791 } 3792 3793 /** 3794 * RTAvlU32Destroy callback. 3795 * 3796 * @returns 0 3797 * @param pNode The node to destroy. 3798 * @param pvGVM The GVM handle. 3799 */ 3800 static 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 } 3842 3825 #endif 3843 3826 3844 3827 /** 3845 * Checks registered modules for shared pages3828 * Removes all shared modules for the specified VM 3846 3829 * 3847 3830 * @returns VBox status code. … … 3849 3832 * @param idCpu VCPU id 3850 3833 */ 3851 GMMR0DECL(int) GMMR0 CheckSharedModules(PVM pVM, VMCPUID idCpu)3834 GMMR0DECL(int) GMMR0ResetSharedModules(PVM pVM, VMCPUID idCpu) 3852 3835 { 3853 3836 #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; 3855 3864 #else 3856 3865 return VERR_NOT_IMPLEMENTED; -
trunk/src/VBox/VMM/VMMR0/GMMR0Internal.h
r29168 r29201 55 55 typedef GMMSHAREDREGIONDESC *PGMMSHAREDREGIONDESC; 56 56 57 57 58 /** 58 59 * Shared module registration info (global) … … 94 95 bool fCollision; 95 96 /** 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]; 102 98 } GMMSHAREDMODULEPERVM; 103 99 /** Pointer to a GMMSHAREDMODULEPERVM. */ -
trunk/src/VBox/VMM/VMMR0/PGMR0.cpp
r29168 r29201 366 366 { 367 367 fValidChanges = true; 368 paPageDesc[idxPage].u PageId = 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; 371 371 } 372 372 else 373 paPageDesc[idxPage].u PageId = NIL_GMM_PAGEID;373 paPageDesc[idxPage].uHCPhysPageId = NIL_GMM_PAGEID; 374 374 } 375 375 else 376 paPageDesc[idxPage].u PageId = NIL_GMM_PAGEID;376 paPageDesc[idxPage].uHCPhysPageId = NIL_GMM_PAGEID; 377 377 378 378 idxPage++; … … 391 391 { 392 392 /* Any change for this page? */ 393 if (paPageDesc[i].u PageId != NIL_GMM_PAGEID)393 if (paPageDesc[i].uHCPhysPageId != NIL_GMM_PAGEID) 394 394 { 395 395 /** todo: maybe cache these to prevent the nth lookup. */ … … 421 421 /* Update the physical address and page id now. */ 422 422 PGM_PAGE_SET_HCPHYS(pPage, paPageDesc[idxPage].HCPhys); 423 PGM_PAGE_SET_PAGEID(pPage, paPageDesc[idxPage].u PageId);423 PGM_PAGE_SET_PAGEID(pPage, paPageDesc[idxPage].uHCPhysPageId); 424 424 } 425 425 /* 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 952 952 953 953 case VMMR0_DO_GMM_REGISTER_SHARED_MODULE: 954 if (idCpu == NIL_VMCPUID) 955 return VERR_INVALID_CPU_ID; 954 956 if (u64Arg) 955 957 return VERR_INVALID_PARAMETER; … … 957 959 958 960 case VMMR0_DO_GMM_UNREGISTER_SHARED_MODULE: 961 if (idCpu == NIL_VMCPUID) 962 return VERR_INVALID_CPU_ID; 959 963 if (u64Arg) 960 964 return VERR_INVALID_PARAMETER; 961 965 return GMMR0UnregisterSharedModuleReq(pVM, idCpu, (PGMMUNREGISTERSHAREDMODULEREQ)pReqHdr); 962 966 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; 964 970 if ( u64Arg 965 971 || pReqHdr) 966 972 return VERR_INVALID_PARAMETER; 967 return GMMR0 CheckSharedModules(pVM, idCpu);973 return GMMR0ResetSharedModules(pVM, idCpu); 968 974 969 975 /*
Note:
See TracChangeset
for help on using the changeset viewer.