- Timestamp:
- May 7, 2010 1:16:53 PM (15 years ago)
- Location:
- trunk/src/VBox/VMM/VMMR0
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMR0/GMMR0.cpp
r29201 r29209 3502 3502 && !strcmp(pGlobalModule->szVersion, pszVersion)) 3503 3503 { 3504 Assert(!pRecVM->fCollision);3505 3506 3504 /* Save reference. */ 3507 3505 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 3508 3510 pRecVM->fCollision = false; 3509 if (fNewModule)3510 pGlobalModule->cUsers++;3511 3511 rc = VINF_SUCCESS; 3512 3512 } … … 3590 3590 goto end; 3591 3591 } 3592 /* Force pRec to go out of scope after freeing it. */ 3592 /* Remove reference to global shared module. */ 3593 if (!pRecVM->fCollision) 3593 3594 { 3594 3595 PGMMSHAREDMODULE pRec = pRecVM->pGlobalModule; 3595 3596 Assert(pRec); 3596 Assert(pRec->cUsers); 3597 3598 pRec->cUsers--; 3599 if (pRec->cUsers == 0) 3597 3598 if (pRec) /* paranoia */ 3600 3599 { 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 } 3606 3611 } 3607 } 3612 else 3613 rc = VERR_PGM_SHARED_MODULE_REGISTRATION_INCONSISTENCY; 3614 } 3615 else 3616 Assert(!pRecVM->pGlobalModule); 3617 3608 3618 RTMemFree(pRecVM); 3609 3619 … … 3738 3748 else 3739 3749 { 3750 uint8_t *pbLocalPage, *pbSharedPage; 3751 uint8_t *pbChunk; 3752 PGMMCHUNK pChunk; 3753 3740 3754 Assert(paPageDesc[i].uHCPhysPageId != pGlobalRegion->paHCPhysPageID[i]); 3741 3755 3742 PGMMPAGE pPage = gmmR0GetPage(pGMM, paPageDesc[i].uHCPhysPageId); 3756 /* Get the shared page source. */ 3757 PGMMPAGE pPage = gmmR0GetPage(pGMM, pGlobalRegion->paHCPhysPageID[i]); 3743 3758 if (!pPage) 3744 3759 { … … 3751 3766 Log(("Replace existing page guest %RGp host %RHp -> %RHp\n", paPageDesc[i].GCPhys, paPageDesc[i].HCPhys, (pPage->Private.pfn << 12))); 3752 3767 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); 3754 3789 Assert(pChunk); /* can't fail as gmmR0GetPage succeeded. */ 3755 uint8_t *pbR3Page, *pbR3Chunk;3756 3790 3757 3791 /* 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)&pb R3Chunk))3792 if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk)) 3759 3793 { 3760 rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pb R3Chunk);3794 rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk); 3761 3795 if (rc != VINF_SUCCESS) 3762 3796 { … … 3765 3799 } 3766 3800 } 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 } 3768 3809 3769 3810 /* Free the old local page. */ … … 3773 3814 rc = gmmR0FreePages(pGMM, pGVM, 1, &PageDesc, GMMACCOUNT_BASE); 3774 3815 AssertRC(rc); 3816 3817 /* Increase reference count. */ 3818 pPage->Shared.cRefs++; 3775 3819 3776 3820 /* Pass along the new physical address & page id. */ -
trunk/src/VBox/VMM/VMMR0/PGMR0.cpp
r29201 r29209 342 342 RTMemFree(paPageDesc); 343 343 344 paPageDesc = (PGMMSHAREDPAGEDESC)RTMemAlloc((cbRegion <<PAGE_SHIFT) * sizeof(*paPageDesc));344 paPageDesc = (PGMMSHAREDPAGEDESC)RTMemAlloc((cbRegion >> PAGE_SHIFT) * sizeof(*paPageDesc)); 345 345 if (!paPageDesc) 346 346 { … … 359 359 rc = PGMGstGetPage(pVCpu, GCRegion, &GCPhys, &fFlags); 360 360 if ( rc == VINF_SUCCESS 361 && !(fFlags & X86_PTE_RW)) 361 && !(fFlags & X86_PTE_RW)) /* important as we make assumptions about this below! */ 362 362 { 363 363 PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, GCPhys); … … 387 387 if (RT_FAILURE(rc)) 388 388 break; 389 389 390 390 for (unsigned i = 0; i < idxPage; i++) 391 391 { … … 394 394 { 395 395 /** todo: maybe cache these to prevent the nth lookup. */ 396 PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPageDesc[i dxPage].GCPhys);396 PPGMPAGE pPage = pgmPhysGetPage(&pVM->pgm.s, paPageDesc[i].GCPhys); 397 397 if (!pPage) 398 398 { … … 404 404 Assert(!PGM_PAGE_IS_SHARED(pPage)); 405 405 406 if (paPageDesc[i dxPage].HCPhys != PGM_PAGE_GET_HCPHYS(pPage))406 if (paPageDesc[i].HCPhys != PGM_PAGE_GET_HCPHYS(pPage)) 407 407 { 408 408 bool fFlush = false; 409 409 410 /* Page was replaced by an existing shared version of it; dereference the pagefirst. */411 rc = pgmPoolTrackUpdateGCPhys(pVM, paPageDesc[i dxPage].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); 412 412 if (RT_FAILURE(rc)) 413 413 { … … 420 420 421 421 /* Update the physical address and page id now. */ 422 PGM_PAGE_SET_HCPHYS(pPage, paPageDesc[i dxPage].HCPhys);423 PGM_PAGE_SET_PAGEID(pPage, paPageDesc[i dxPage].uHCPhysPageId);422 PGM_PAGE_SET_HCPHYS(pPage, paPageDesc[i].HCPhys); 423 PGM_PAGE_SET_PAGEID(pPage, paPageDesc[i].uHCPhysPageId); 424 424 } 425 425 /* 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.