PGMSharedPage.cpp revision 37bbf8d2728e3d798119c54a8fde51a02808ac47
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * PGM - Page Manager and Monitor, Shared page handling
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * Copyright (C) 2006-2010 Oracle Corporation
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * available from http://www.virtualbox.org. This file is free software;
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * you can redistribute it and/or modify it under the terms of the GNU
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * General Public License (GPL) as published by the Free Software
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync/*******************************************************************************
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync* Header Files *
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync*******************************************************************************/
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync/* Keep a copy of all registered shared modules for the .pgmcheckduppages debugger command. */
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsyncstatic PGMMREGISTERSHAREDMODULEREQ pSharedModules[512] = {0};
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsyncstatic unsigned cSharedModules = 0;
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * Registers a new shared module for the VM
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * @returns VBox status code.
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * @param pVM VM handle
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * @param enmGuestOS Guest OS type
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * @param pszModuleName Module name
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * @param pszVersion Module version
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * @param GCBaseAddr Module base address
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * @param cbModule Module size
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * @param cRegions Number of shared region descriptors
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync * @param pRegions Shared region(s)
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsyncVMMR3DECL(int) PGMR3SharedModuleRegister(PVM pVM, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion, RTGCPTR GCBaseAddr, uint32_t cbModule,
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync unsigned cRegions, VMMDEVSHAREDREGIONDESC *pRegions)
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync Log(("PGMR3SharedModuleRegister family=%d name=%s version=%s base=%RGv size=%x cRegions=%d\n", enmGuestOS, pszModuleName, pszVersion, GCBaseAddr, cbModule, cRegions));
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync /* Sanity check. */
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync AssertReturn(cRegions < VMMDEVSHAREDREGIONDESC_MAX, VERR_INVALID_PARAMETER);
4fedcd2da6f840dbadee84e579f146ad0f1fde22vboxsync pReq = (PGMMREGISTERSHAREDMODULEREQ)RTMemAllocZ(RT_OFFSETOF(GMMREGISTERSHAREDMODULEREQ, aRegions[cRegions]));
for (unsigned i = 0; i < cRegions; i++)
return VERR_BUFFER_OVERFLOW;
for (unsigned i = 0; i < cSharedModules; i++)
*ppSharedModule = (PGMMREGISTERSHAREDMODULEREQ)RTMemAllocZ(RT_OFFSETOF(GMMREGISTERSHAREDMODULEREQ, aRegions[cRegions]));
Assert(rc == VINF_SUCCESS || rc == VINF_PGM_SHARED_MODULE_COLLISION || rc == VINF_PGM_SHARED_MODULE_ALREADY_REGISTERED);
return rc;
return VINF_SUCCESS;
return VERR_NOT_IMPLEMENTED;
VMMR3DECL(int) PGMR3SharedModuleUnregister(PVM pVM, char *pszModuleName, char *pszVersion, RTGCPTR GCBaseAddr, uint32_t cbModule)
#ifdef VBOX_WITH_PAGE_SHARING
Log(("PGMR3SharedModuleUnregister name=%s version=%s base=%RGv size=%x\n", pszModuleName, pszVersion, GCBaseAddr, cbModule));
return VERR_BUFFER_OVERFLOW;
for (unsigned i = 0; i < cSharedModules; i++)
return rc;
return VERR_NOT_IMPLEMENTED;
#ifdef VBOX_WITH_PAGE_SHARING
static DECLCALLBACK(VBOXSTRICTRC) pgmR3SharedModuleRegRendezvous(PVM pVM, PVMCPU pVCpu, void *pvUser)
/* Execute on the VCPU that issued the original request to make sure we're in the right cr3 context. */
return VINF_SUCCESS;
return rc;
/* We must stall other VCPUs as we'd otherwise have to send IPI flush commands for every single change we make. */
int rc = VMMR3EmtRendezvous(pVM, VMMEMTRENDEZVOUS_FLAGS_TYPE_ONE_BY_ONE, pgmR3SharedModuleRegRendezvous, &idCpu);
#ifdef VBOX_WITH_PAGE_SHARING
/* Queue the actual registration as we are under the IOM lock right now. Perform this operation on the way out. */
return VMR3ReqCallNoWait(pVM, VMCPUID_ANY_QUEUE, (PFNRT)pgmR3CheckSharedModulesHelper, 2, pVM, VMMGetCpuId(pVM));
return VERR_NOT_IMPLEMENTED;
VMMR3DECL(int) PGMR3SharedModuleGetPageState(PVM pVM, RTGCPTR GCPtrPage, bool *pfShared, uint64_t *puPageFlags)
switch (rc)
case VINF_SUCCESS:
if (pPage)
case VERR_PAGE_NOT_PRESENT:
*pfShared = false;
*puPageFlags = 0;
return rc;
return VERR_NOT_IMPLEMENTED;
DECLCALLBACK(int) pgmR3CmdCheckDuplicatePages(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
unsigned cBallooned = 0;
unsigned cShared = 0;
unsigned cZero = 0;
unsigned cUnique = 0;
unsigned cDuplicate = 0;
unsigned cAllocZero = 0;
unsigned cPages = 0;
while (cLeft-- > 0)
case PGM_PAGE_STATE_ZERO:
cZero++;
case PGM_PAGE_STATE_BALLOONED:
cBallooned++;
case PGM_PAGE_STATE_SHARED:
cShared++;
case PGM_PAGE_STATE_ALLOCATED:
const void *pvPage;
cAllocZero++;
cDuplicate++;
cUnique++;
AssertFailed();
pPage++;
cPages++;
pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of alloczero pages %08x (%d MB)\n", cAllocZero, cAllocZero / 256);
pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of ballooned pages %08x (%d MB)\n", cBallooned, cBallooned / 256);
pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Number of duplicate pages %08x (%d MB)\n", cDuplicate, cDuplicate / 256);
return VINF_SUCCESS;
DECLCALLBACK(int) pgmR3CmdShowSharedModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs, PDBGCVAR pResult)
if (pSharedModules[i])
pCmdHlp->pfnPrintf(pCmdHlp, NULL, "Shared module %s (%s):\n", pSharedModules[i]->szName, pSharedModules[i]->szVersion);
pCmdHlp->pfnPrintf(pCmdHlp, NULL, "--- Region %d: base %RGv size %x\n", j, pSharedModules[i]->aRegions[j].GCRegionAddr, pSharedModules[i]->aRegions[j].cbRegion);
while (i < cSharedModules);
return VINF_SUCCESS;