VirtualBox

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


Ignore:
Timestamp:
May 6, 2010 11:49:48 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
61205
Message:

Shared paging updates

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

Legend:

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

    r29091 r29138  
    34143414
    34153415            pRecVM->Core.Key = GCBaseAddr;
     3416            pRecVM->cRegions = cRegions;
     3417            for (unsigned i = 0; i < cRegions; i++)
     3418            {
     3419                pRecVM->aRegions[i].GCRegionAddr      = pRegions[i].GCRegionAddr;
     3420                pRecVM->aRegions[i].cbRegion          = pRegions[i].cbRegion;
     3421                pRecVM->aRegions[i].u32Alignment      = 0;
     3422                pRecVM->aRegions[i].paHCPhysAndPageID = 0; /* uninitialized. */
     3423            }
    34163424
    34173425            bool ret = RTAvlGCPtrInsert(&pGVM->gmm.s.pSharedModuleTree, &pRecVM->Core);
     
    34483456
    34493457            for (unsigned i = 0; i < cRegions; i++)
    3450                 pRec->aRegions[i] = pRegions[i];
     3458            {
     3459                pRec->aRegions[i].GCRegionAddr      = pRegions[i].GCRegionAddr;
     3460                pRec->aRegions[i].cbRegion          = pRegions[i].cbRegion;
     3461                pRec->aRegions[i].u32Alignment      = 0;
     3462                pRec->aRegions[i].paHCPhysAndPageID = 0; /* uninitialized. */
     3463            }
    34513464
    34523465            /* Save reference. */
     
    35533566            goto end;
    35543567        }
    3555         PGMMSHAREDMODULE pRec = pRecVM->pSharedModule;
    3556         Assert(pRec);
    3557         Assert(pRec->cUsers);
    3558 
    3559         pRec->cUsers--;
    3560         if (pRec->cUsers == 0)
    3561         {
    3562             /* @todo free shared pages. */
    3563             RTMemFree(pRec);
    3564         }
     3568        /* Force pRec to go out of scope after freeing it. */
     3569        {
     3570            PGMMSHAREDMODULE pRec = pRecVM->pSharedModule;
     3571            Assert(pRec);
     3572            Assert(pRec->cUsers);
     3573
     3574            pRec->cUsers--;
     3575            if (pRec->cUsers == 0)
     3576            {
     3577                /* @todo free shared pages. */
     3578                for (unsigned i = 0; i < pRec->cRegions; i++)
     3579                    if (pRec->aRegions[i].paHCPhysAndPageID)
     3580                        RTMemFree(pRec->aRegions[i].paHCPhysAndPageID);
     3581
     3582                RTMemFree(pRec);
     3583            }
     3584        }
     3585
     3586        for (unsigned i = 0; i < pRecVM->cRegions; i++)
     3587            if (pRecVM->aRegions[i].paHCPhysAndPageID)
     3588                RTMemFree(pRecVM->aRegions[i].paHCPhysAndPageID);
    35653589        RTMemFree(pRecVM);
    35663590
     
    35993623
    36003624
     3625#ifdef VBOX_WITH_PAGE_SHARING
     3626/**
     3627 * Checks specified shared module range for changes
     3628 *
     3629 * @returns VBox status code.
     3630 * @param   pVM                 VM handle
     3631 * @param   idCpu               VCPU id
     3632 * @param   pReq                Module description
     3633 * @param   idxRegion           Region index
     3634 * @param   cPages              Number of entries in the paHCPhysAndPageID array
     3635 * @param   paHCPhysAndPageID   Host physical address and the Page ID array
     3636 */
     3637GMMR0DECL(int)  GMMR0SharedModuleCheckRange(PVM pVM, VMCPUID idCpu, PGMMREGISTERSHAREDMODULEREQ pReq, unsigned idxRegion, unsigned cPages, PRTHCPHYS paHCPhysAndPageID)
     3638{
     3639    AssertReturn(idxRegion < pReq->cRegions, VERR_INVALID_PARAMETER);
     3640    AssertReturn(cPages == (pReq->aRegions[idxRegion].cbRegion >> PAGE_SHIFT), VERR_INVALID_PARAMETER);
     3641
     3642    /*
     3643     * Validate input and get the basics.
     3644     */
     3645    PGMM pGMM;
     3646    GMM_GET_VALID_INSTANCE(pGMM, VERR_INTERNAL_ERROR);
     3647    PGVM pGVM;
     3648    int rc = GVMMR0ByVMAndEMT(pVM, idCpu, &pGVM);
     3649    if (RT_FAILURE(rc))
     3650        return rc;
     3651
     3652    /*
     3653     * Take the sempahore and do some more validations.
     3654     */
     3655    rc = RTSemFastMutexRequest(pGMM->Mtx);
     3656    AssertRC(rc);
     3657    if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
     3658    {
     3659        PGMMSHAREDMODULEPERVM pRecVM = (PGMMSHAREDMODULEPERVM)RTAvlGCPtrGet(&pGVM->gmm.s.pSharedModuleTree, pReq->GCBaseAddr);
     3660        if (!pRecVM)
     3661        {
     3662            rc = VERR_PGM_SHARED_MODULE_NOT_FOUND;
     3663            goto end;
     3664        }
     3665
     3666        for (unsigned i = 0; i < cPages; i++)
     3667        {
     3668        }
     3669
     3670        GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
     3671    }
     3672    else
     3673        rc = VERR_INTERNAL_ERROR_5;
     3674
     3675end:
     3676    RTSemFastMutexRelease(pGMM->Mtx);
     3677    return rc;
     3678}
     3679#endif
     3680
    36013681/**
    36023682 * Checks registered modules for shared pages
  • trunk/src/VBox/VMM/VMMR0/GMMR0Internal.h

    r29024 r29138  
    3535    uint32_t        cFixedPages;
    3636} GMMVMSIZES;
     37/** Pointer to a GMMVMSIZES. */
    3738typedef GMMVMSIZES *PGMMVMSIZES;
    3839
     40/**
     41 * Shared region descriptor
     42 */
     43typedef struct GMMSHAREDREGIONDESC
     44{
     45    /** Region base address. */
     46    RTGCPTR64           GCRegionAddr;
     47    /** Region size. */
     48    uint32_t            cbRegion;
     49    /** Alignment. */
     50    uint32_t            u32Alignment;
     51    /** Pointer to physical page address array. */
     52    PRTHCPHYS           paHCPhysAndPageID;
     53} GMMSHAREDREGIONDESC;
     54/** Pointer to a GMMSHAREDREGIONDESC. */
     55typedef GMMSHAREDREGIONDESC *PGMMSHAREDREGIONDESC;
    3956
    4057/**
     
    5875    char                        szVersion[GMM_SHARED_MODULE_MAX_VERSION_STRING];
    5976    /** Shared region descriptor(s). */
    60     VMMDEVSHAREDREGIONDESC      aRegions[1];
     77    GMMSHAREDREGIONDESC         aRegions[1];
    6178} GMMSHAREDMODULE;
    6279/** Pointer to a GMMSHAREDMODULE. */
     
    7693    /* Set if another VM registered a different shared module at the same base address. */
    7794    bool                        fCollision;
     95    /** Align at 8 byte boundary */
     96    bool                        abAlignment[7];
    7897
     98    /** Number of regions in the aRegions array. */
     99    unsigned                    cRegions;
     100
     101    /** Shared region descriptor(s). */
     102    GMMSHAREDREGIONDESC         aRegions[1];
    79103} GMMSHAREDMODULEPERVM;
    80104/** Pointer to a GMMSHAREDMODULEPERVM. */
  • trunk/src/VBox/VMM/VMMR0/PGMR0.cpp

    r29091 r29138  
    2727#include <VBox/err.h>
    2828#include <iprt/assert.h>
     29#include <iprt/mem.h>
    2930
    3031RT_C_DECLS_BEGIN
     
    313314{
    314315    int rc = VINF_SUCCESS;
     316    PRTHCPHYS paHCPhysAndPageID = NULL;
     317    uint32_t  cbPreviousRegion  = 0;
    315318
    316319    /*
     
    328331        Assert((pReq->aRegions[i].GCRegionAddr & 0xfff) == 0);
    329332
    330         RTGCPTR GCRegion  = pReq->aRegions[i].GCRegionAddr;
    331         uint32_t cbRegion = pReq->aRegions[i].cbRegion & ~0xfff;
     333        RTGCPTR  GCRegion  = pReq->aRegions[i].GCRegionAddr;
     334        unsigned cbRegion = pReq->aRegions[i].cbRegion & ~0xfff;
     335        unsigned idxPage = 0;
     336        bool     fValidChanges = false;
     337
     338        if (cbPreviousRegion < cbRegion)
     339        {
     340            if (paHCPhysAndPageID)
     341                RTMemFree(paHCPhysAndPageID);
     342
     343            paHCPhysAndPageID = (PRTHCPHYS)RTMemAlloc((cbRegion << PAGE_SHIFT) * sizeof(*paHCPhysAndPageID));
     344            if (!paHCPhysAndPageID)
     345            {
     346                AssertFailed();
     347                rc = VERR_NO_MEMORY;
     348                goto end;
     349            }
     350            cbPreviousRegion  = cbRegion;
     351        }
    332352
    333353        while (cbRegion)
     
    344364                    &&  !PGM_PAGE_IS_SHARED(pPage))
    345365                {
     366                    fValidChanges = true;
     367                    paHCPhysAndPageID[idxPage] = pPage->HCPhysAndPageID;
    346368                }
     369                else
     370                    paHCPhysAndPageID[idxPage] = NIL_RTHCPHYS;
    347371            }
    348 
     372            else
     373                paHCPhysAndPageID[idxPage] = NIL_RTHCPHYS;
     374
     375            idxPage++;
    349376            GCRegion += PAGE_SIZE;
    350377            cbRegion -= PAGE_SIZE;
    351378        }
    352     }
    353 
     379
     380        if (fValidChanges)
     381        {
     382            rc = GMMR0SharedModuleCheckRange(pVM, pVCpu->idCpu, pReq, i, idxPage, paHCPhysAndPageID);
     383            AssertRC(rc);
     384            if (RT_FAILURE(rc))
     385                break;
     386        }
     387    }
     388
     389end:
    354390    pgmUnlock(pVM);
     391    if (paHCPhysAndPageID)
     392        RTMemFree(paHCPhysAndPageID);
     393
    355394    return rc;
    356395}
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