VirtualBox

Changeset 30488 in vbox


Ignore:
Timestamp:
Jun 29, 2010 9:02:04 AM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
63179
Message:

Debug code to find duplicate pages

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/gmm.h

    r30237 r30488  
    306306#endif
    307307
    308 
    309308/**
    310309 * Request buffer for GMMR0InitialReservationReq / VMMR0_DO_GMM_INITIAL_RESERVATION.
     
    588587GMMR0DECL(int) GMMR0UnregisterSharedModuleReq(PVM pVM, VMCPUID idCpu, PGMMUNREGISTERSHAREDMODULEREQ pReq);
    589588
     589#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
     590/**
     591 * Request buffer for GMMR0FindDuplicatePageReq / VMMR0_DO_GMM_FIND_DUPLICATE_PAGE.
     592 * @see GMMR0FindDuplicatePage.
     593 */
     594typedef struct GMMFINDDUPLICATEPAGEREQ
     595{
     596    /** The header. */
     597    SUPVMMR0REQHDR              Hdr;
     598    /** Page id. */
     599    uint32_t                    idPage;
     600    /** Duplicate flag (out) */
     601    bool                        fDuplicate;
     602} GMMFINDDUPLICATEPAGEREQ;
     603/** Pointer to a GMMR0FindDuplicatePageReq / VMMR0_DO_GMM_FIND_DUPLICATE_PAGE request buffer. */
     604typedef GMMFINDDUPLICATEPAGEREQ *PGMMFINDDUPLICATEPAGEREQ;
     605
     606GMMR0DECL(int) GMMR0FindDuplicatePageReq(PVM pVM, PGMMFINDDUPLICATEPAGEREQ pReq);
     607#endif /* VBOX_STRICT && HC_ARCH_BITS == 64 */
    590608
    591609#ifdef IN_RING3
     
    616634GMMR3DECL(int)  GMMR3CheckSharedModules(PVM pVM);
    617635GMMR3DECL(int)  GMMR3ResetSharedModules(PVM pVM);
     636
     637# if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
     638GMMR3DECL(bool) GMMR3IsDuplicatePage(PVM pVM, uint32_t idPage);
     639# endif
     640
    618641/** @} */
    619642#endif /* IN_RING3 */
  • trunk/include/VBox/pci.h

    r28800 r30488  
    462462}
    463463
     464/**
     465 * Gets the interrupt line config register.
     466 *
     467 * @returns The interrupt line.
     468 * @param   pPciDev         The PCI device.
     469 */
     470DECLINLINE(uint8_t) PCIDevGetInterruptLine(PPCIDEVICE pPciDev)
     471{
     472    return pPciDev->config[VBOX_PCI_INTERRUPT_LINE];
     473}
    464474
    465475/**
     
    475485
    476486
     487/**
     488 * Gets the interrupt pin config register.
     489 *
     490 * @returns The interrupt pin.
     491 * @param   pPciDev         The PCI device.
     492 */
     493DECLINLINE(uint8_t) PCIDevGetInterruptPin(PPCIDEVICE pPciDev)
     494{
     495    return pPciDev->config[VBOX_PCI_INTERRUPT_PIN];
     496}
     497
     498
    477499/** @} */
    478500
    479501#endif
     502
  • trunk/include/VBox/vmm.h

    r30160 r30488  
    312312    /** Call GMMR0CheckSharedModules. */
    313313    VMMR0_DO_GMM_CHECK_SHARED_MODULES,
     314    /** Call GMMR0FindDuplicatePage. */
     315    VMMR0_DO_GMM_FIND_DUPLICATE_PAGE,
    314316
    315317    /** Set a GVMM or GMM configuration value. */
  • trunk/src/VBox/VMM/GMM.cpp

    r30344 r30488  
    419419    return VMMR3CallR0(pVM, VMMR0_DO_GMM_CHECK_SHARED_MODULES, 0, NULL);
    420420}
     421
     422#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
     423/**
     424 * @see GMMR0FindDuplicatePage
     425 */
     426GMMR3DECL(bool) GMMR3IsDuplicatePage(PVM pVM, uint32_t idPage)
     427{
     428    GMMFINDDUPLICATEPAGEREQ Req;
     429    Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
     430    Req.Hdr.cbReq    = sizeof(Req);
     431    Req.idPage       = idPage;
     432    Req.fDuplicate   = false;
     433
     434    int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_FIND_DUPLICATE_PAGE, 0, &Req.Hdr);
     435    if (rc == VINF_SUCCESS)
     436        return Req.fDuplicate;
     437    else
     438        return false;
     439}
     440#endif /* VBOX_STRICT && HC_ARCH_BITS == 64 */
     441
  • trunk/src/VBox/VMM/PGM.cpp

    r30050 r30488  
    641641static DECLCALLBACK(int)  pgmR3CmdAssertCR3(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    642642# endif
     643# if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
     644static DECLCALLBACK(int)  pgmR3CmdCheckDuplicatePages(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
     645# endif
    643646static DECLCALLBACK(int)  pgmR3CmdPhysToFile(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult);
    644647#endif
     
    673676#ifdef VBOX_STRICT
    674677    { "pgmassertcr3",  0, 0,        NULL,                     0,            NULL,               0,          pgmR3CmdAssertCR3,  "",                     "Check the shadow CR3 mapping." },
     678#endif
     679#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
     680    { "pgmcheckduppages", 0, 0,     NULL,                     0,            NULL,               0,          pgmR3CmdCheckDuplicatePages,  "",           "Check for duplicate pages in all running VMs." },
    675681#endif
    676682    { "pgmsyncalways", 0, 0,        NULL,                     0,            NULL,               0,          pgmR3CmdSyncAlways, "",                     "Toggle permanent CR3 syncing." },
     
    41564162#endif /* VBOX_STRICT */
    41574163
     4164#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
     4165/**
     4166 * The '.pgmcheckduppages' command.
     4167 *
     4168 * @returns VBox status.
     4169 * @param   pCmd        Pointer to the command descriptor (as registered).
     4170 * @param   pCmdHlp     Pointer to command helper functions.
     4171 * @param   pVM         Pointer to the current VM (if any).
     4172 * @param   paArgs      Pointer to (readonly) array of arguments.
     4173 * @param   cArgs       Number of arguments in the array.
     4174 */
     4175static DECLCALLBACK(int)  pgmR3CmdCheckDuplicatePages(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
     4176{
     4177    unsigned cBallooned = 0;
     4178    unsigned cShared = 0;
     4179    unsigned cZero = 0;
     4180    unsigned cUnique = 0;
     4181    unsigned cDuplicate = 0;
     4182
     4183    pgmLock(pVM);
     4184
     4185    for (PPGMRAMRANGE pRam = pVM->pgm.s.pRamRangesR3; pRam; pRam = pRam->pNextR3)
     4186    {
     4187        PPGMPAGE    pPage  = &pRam->aPages[0];
     4188        RTGCPHYS    GCPhys = pRam->GCPhys;
     4189        uint32_t    cLeft  = pRam->cb >> PAGE_SHIFT;
     4190        while (cLeft-- > 0)
     4191        {
     4192            if (PGM_PAGE_GET_TYPE(pPage) == PGMPAGETYPE_RAM)
     4193            {
     4194                switch (PGM_PAGE_GET_STATE(pPage))
     4195                {
     4196                    case PGM_PAGE_STATE_ZERO:
     4197                        cZero++;
     4198                        break;
     4199
     4200                    case PGM_PAGE_STATE_BALLOONED:
     4201                        cBallooned++;
     4202                        break;
     4203
     4204                    case PGM_PAGE_STATE_SHARED:
     4205                        cShared++;
     4206                        break;
     4207
     4208                    case PGM_PAGE_STATE_ALLOCATED:
     4209                    case PGM_PAGE_STATE_WRITE_MONITORED:
     4210                        if (GMMR3IsDuplicatePage(pVM, PGM_PAGE_GET_PAGEID(pPage)))
     4211                            cDuplicate++;
     4212                        else
     4213                            cUnique++;
     4214
     4215                        break;
     4216
     4217                    default:
     4218                        AssertFailed();
     4219                        break;
     4220                }
     4221            }
     4222
     4223            /* next */
     4224            pPage++;
     4225            GCPhys += PAGE_SIZE;
     4226        }
     4227    }
     4228    pgmUnlock(pVM);
     4229
     4230    pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of zero pages      %x\n", cZero);
     4231    pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of ballooned pages %x\n", cBallooned);
     4232    pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of shared pages    %x\n", cShared);
     4233    pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of unique pages    %x\n", cUnique);
     4234    pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of duplicate pages %x\n", cDuplicate);
     4235    return VINF_SUCCESS;
     4236}
     4237
     4238#endif /* VBOX_STRICT && HC_ARCH_BITS == 64*/
     4239
    41584240
    41594241/**
  • trunk/src/VBox/VMM/VMMR0/GMMR0.cpp

    r30373 r30488  
    41894189#endif
    41904190}
     4191
     4192#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
     4193typedef struct
     4194{
     4195    PGVM                    pGVM;
     4196    PGMM                    pGMM;
     4197    uint8_t                *pSourcePage;
     4198    bool                    fFoundDuplicate;
     4199} GMMFINDDUPPAGEINFO, *PGMMFINDDUPPAGEINFO;
     4200
     4201/**
     4202 * RTAvlU32DoWithAll callback.
     4203 *
     4204 * @returns 0
     4205 * @param   pNode   The node to search.
     4206 * @param   pvInfo  Pointer to the input parameters
     4207 */
     4208static DECLCALLBACK(int) gmmR0FindDupPageInChunk(PAVLU32NODECORE pNode, void *pvInfo)
     4209{
     4210    PGMMCHUNK           pChunk = (PGMMCHUNK)pNode;
     4211    PGMMFINDDUPPAGEINFO pInfo = (PGMMFINDDUPPAGEINFO)pvInfo;
     4212    PGVM                pGVM = pInfo->pGVM;
     4213    PGMM                pGMM = pInfo->pGMM;
     4214    uint8_t            *pbChunk;
     4215
     4216    /* Only take chunks not mapped into this VM process; not entirely correct. */
     4217    if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk))
     4218    {
     4219        int rc = gmmR0MapChunk(pGMM, pGVM, pChunk, (PRTR3PTR)&pbChunk);
     4220        if (rc != VINF_SUCCESS)
     4221            goto end;
     4222
     4223        /*
     4224         * Look for duplicate pages
     4225         */
     4226        unsigned iPage = (GMM_CHUNK_SIZE >> PAGE_SHIFT);
     4227        while (iPage-- > 0)
     4228        {
     4229            if (GMM_PAGE_IS_PRIVATE(&pChunk->aPages[iPage]))
     4230            {
     4231                uint8_t *pbDestPage = pbChunk + (iPage  << PAGE_SHIFT);
     4232
     4233                if (!memcmp(pInfo->pSourcePage, pbDestPage, PAGE_SIZE))
     4234                {
     4235                    pInfo->fFoundDuplicate = true;
     4236                    break;
     4237                }
     4238            }
     4239        }
     4240        gmmR0UnmapChunk(pGMM, pGVM, pChunk);
     4241    }
     4242end:
     4243    if (pInfo->fFoundDuplicate)
     4244        return 1;   /* stop search */
     4245    else
     4246        return 0;
     4247}
     4248
     4249/**
     4250 * Find a duplicate of the specified page in other active VMs
     4251 *
     4252 * @returns VBox status code.
     4253 * @param   pVM                 VM handle
     4254 * @param   pReq                Request packet
     4255 */
     4256GMMR0DECL(int) GMMR0FindDuplicatePageReq(PVM pVM, PGMMFINDDUPLICATEPAGEREQ pReq)
     4257{
     4258    /*
     4259     * Validate input and pass it on.
     4260     */
     4261    AssertPtrReturn(pVM, VERR_INVALID_POINTER);
     4262    AssertPtrReturn(pReq, VERR_INVALID_POINTER);
     4263    AssertMsgReturn(pReq->Hdr.cbReq == sizeof(*pReq), ("%#x != %#x\n", pReq->Hdr.cbReq, sizeof(*pReq)), VERR_INVALID_PARAMETER);
     4264
     4265    PGMM pGMM;
     4266    GMM_GET_VALID_INSTANCE(pGMM, VERR_INTERNAL_ERROR);
     4267
     4268    /*
     4269     * Take the sempahore and do some more validations.
     4270     */
     4271    int rc = RTSemFastMutexRequest(pGMM->Mtx);
     4272    AssertRC(rc);
     4273    if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
     4274    {
     4275        PGVM pGVM;
     4276        rc = GVMMR0ByVM(pVM, &pGVM);
     4277        if (RT_FAILURE(rc))
     4278            goto end;
     4279
     4280        uint8_t  *pbChunk;
     4281        PGMMCHUNK pChunk = gmmR0GetChunk(pGMM, pReq->idPage >> GMM_CHUNKID_SHIFT);
     4282        if (!pChunk)
     4283        {
     4284            AssertFailed();
     4285            goto end;
     4286        }
     4287
     4288        if (!gmmR0IsChunkMapped(pGVM, pChunk, (PRTR3PTR)&pbChunk))
     4289        {
     4290            AssertFailed();
     4291            goto end;
     4292        }
     4293
     4294        uint8_t *pbSourcePage = pbChunk + ((pReq->idPage & GMM_PAGEID_IDX_MASK) << PAGE_SHIFT);
     4295
     4296        PGMMPAGE pPage = gmmR0GetPage(pGMM, pReq->idPage);
     4297        if (!pPage)
     4298        {
     4299            AssertFailed();
     4300            rc = VERR_PGM_PHYS_INVALID_PAGE_ID;
     4301            goto end;
     4302        }
     4303        GMMFINDDUPPAGEINFO Info;
     4304
     4305        Info.pGVM            = pGVM;
     4306        Info.pGMM            = pGMM;
     4307        Info.pSourcePage     = pbSourcePage;
     4308        Info.fFoundDuplicate = false;
     4309        RTAvlU32DoWithAll(&pGMM->pChunks, true /* fFromLeft */, gmmR0FindDupPageInChunk, pGVM);
     4310
     4311        pReq->fDuplicate = Info.fFoundDuplicate;
     4312    }
     4313    else
     4314        rc = VERR_INTERNAL_ERROR_5;
     4315
     4316end:
     4317    RTSemFastMutexRelease(pGMM->Mtx);
     4318    return rc;
     4319}
     4320
     4321#endif /* VBOX_STRICT && HC_ARCH_BITS == 64 */
     4322
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r30251 r30488  
    986986#endif
    987987
     988#if defined(VBOX_STRICT) && HC_ARCH_BITS == 64
     989        case VMMR0_DO_GMM_FIND_DUPLICATE_PAGE:
     990        {
     991            if (u64Arg)
     992                return VERR_INVALID_PARAMETER;
     993            return GMMR0FindDuplicatePageReq(pVM, (PGMMFINDDUPLICATEPAGEREQ)pReqHdr);
     994        }
     995#endif
     996
    988997        /*
    989998         * A quick GCFGM mock-up.
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