gmm.h revision 530c5ad6ea29dc5dc7a512482d3257faafdb2812
/** @file
* GMM - The Global Memory Manager.
*/
/*
* Copyright (C) 2007-2010 Oracle Corporation
*
* This file is part of VirtualBox Open Source Edition (OSE), as
* available from http://www.virtualbox.org. This file is free software;
* General Public License (GPL) as published by the Free Software
* Foundation, in version 2 as it comes in the "COPYING" file of the
* VirtualBox OSE distribution. VirtualBox OSE is distributed in the
* hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
*
* The contents of this file may alternatively be used under the terms
* of the Common Development and Distribution License Version 1.0
* (CDDL) only, as it comes in the "COPYING.CDDL" file of the
* VirtualBox OSE distribution, in which case the provisions of the
* CDDL are applicable instead of those of the GPL.
*
* You may elect to license modified versions of this file under the
* terms and conditions of either the GPL or the CDDL or both.
*/
#ifndef ___VBox_vmm_gmm_h
#define ___VBox_vmm_gmm_h
/** @defgroup grp_gmm GMM - The Global Memory Manager
* @{
*/
/** @def IN_GMM_R0
* Used to indicate whether we're inside the same link module as the ring 0
* part of the Global Memory Manager or not.
*/
#ifdef DOXYGEN_RUNNING
# define IN_GMM_R0
#endif
/** @def GMMR0DECL
* Ring 0 GMM export or import declaration.
* @param type The return type of the function declaration.
*/
#ifdef IN_GMM_R0
#else
#endif
/** @def IN_GMM_R3
* Used to indicate whether we're inside the same link module as the ring 3
* part of the Global Memory Manager or not.
*/
#ifdef DOXYGEN_RUNNING
# define IN_GMM_R3
#endif
/** @def GMMR3DECL
* Ring 3 GMM export or import declaration.
* @param type The return type of the function declaration.
*/
#ifdef IN_GMM_R3
#else
#endif
/** The chunk shift. (2^21 = 2 MB) */
#define GMM_CHUNK_SHIFT 21
/** The allocation chunk size. */
/** The allocation chunk size in pages. */
/** The shift factor for converting a page id into a chunk id. */
/** The last valid Chunk ID value. */
/** The last valid Page ID value.
* The current limit is 2^28 - 1, or almost 1TB if you like.
* The constraints are currently dictated by PGMPAGE. */
/** Mask out the page index from the Page ID. */
/** The NIL Chunk ID value. */
#define NIL_GMM_CHUNKID 0
/** The NIL Page ID value. */
#define NIL_GMM_PAGEID 0
#if 0 /* wrong - these are guest page pfns and not page ids! */
/** Special Page ID used by unassigned pages. */
#define GMM_PAGEID_UNASSIGNED 0x0fffffffU
/** Special Page ID used by unsharable pages.
* Like MMIO2, shadow and heap. This is for later, obviously. */
#define GMM_PAGEID_UNSHARABLE 0x0ffffffeU
/** The end of the valid Page IDs. This is the first special one. */
#define GMM_PAGEID_END 0x0ffffff0U
#endif
/** @def GMM_GCPHYS_LAST
* The last of the valid guest physical address as it applies to GMM pages.
*
* This must reflect the constraints imposed by the RTGCPHYS type and
* the guest page frame number used internally in GMMPAGE.
*
* @note Note this corresponds to GMM_PAGE_PFN_LAST. */
#if HC_ARCH_BITS == 64
#else
#endif
/**
* Over-commitment policy.
*/
typedef enum GMMOCPOLICY
{
/** The usual invalid 0 value. */
GMMOCPOLICY_INVALID = 0,
/** No over-commitment, fully backed.
* The GMM guarantees that it will be able to allocate all of the
* guest RAM for a VM with OC policy. */
/** to-be-determined. */
/** The end of the valid policy range. */
/** The usual 32-bit hack. */
GMMOCPOLICY_32BIT_HACK = 0x7fffffff
} GMMOCPOLICY;
/**
* VM / Memory priority.
*/
typedef enum GMMPRIORITY
{
/** The usual invalid 0 value. */
GMMPRIORITY_INVALID = 0,
/** High.
* When ballooning, ask these VMs last.
* When running out of memory, try not to interrupt these VMs. */
/** Normal.
* When ballooning, don't wait to ask these.
/** Low.
* When ballooning, maximize these first.
* When running out of memory, save or kill these VMs. */
/** The end of the valid priority range. */
/** The custom 32-bit type blowup. */
GMMPRIORITY_32BIT_HACK = 0x7fffffff
} GMMPRIORITY;
/**
* GMM Memory Accounts.
*/
typedef enum GMMACCOUNT
{
/** The customary invalid zero entry. */
GMMACCOUNT_INVALID = 0,
/** Account with the base allocations. */
/** Account with the shadow allocations. */
/** Account with the fixed allocations. */
/** The end of the valid values. */
/** The usual 32-bit value to finish it off. */
GMMACCOUNT_32BIT_HACK = 0x7fffffff
} GMMACCOUNT;
/**
* Balloon actions.
*/
typedef enum
{
/** Invalid zero entry. */
/** Inflate the balloon. */
/** Deflate the balloon. */
/** Puncture the balloon because of VM reset. */
/** End of the valid actions. */
/** hack forcing the size of the enum to 32-bits. */
GMMBALLOONACTION_MAKE_32BIT_HACK = 0x7fffffff
/**
* A page descriptor for use when freeing pages.
* See GMMR0FreePages, GMMR0BalloonedPages.
*/
typedef struct GMMFREEPAGEDESC
{
/** The Page ID of the page to be freed. */
/** Pointer to a page descriptor for freeing pages. */
typedef GMMFREEPAGEDESC *PGMMFREEPAGEDESC;
/**
* A page descriptor for use when updating and allocating pages.
*
* This is a bit complicated because we want to do as much as possible
* with the same structure.
*/
typedef struct GMMPAGEDESC
{
/** The physical address of the page.
*
* @input GMMR0AllocateHandyPages expects the guest physical address
* to update the GMMPAGE structure with. Pass GMM_GCPHYS_UNSHAREABLE
* when appropriate and NIL_RTHCPHYS when the page wasn't used
* for any specific guest address.
*
* GMMR0AllocatePage expects the guest physical address to put in
* the GMMPAGE structure for the page it allocates for this entry.
* Pass NIL_RTHCPHYS and GMM_GCPHYS_UNSHAREABLE as above.
*
* @output The host physical address of the allocated page.
* NIL_RTHCPHYS on allocation failure.
*
* ASSUMES: sizeof(RTHCPHYS) >= sizeof(RTGCPHYS).
*/
/** The Page ID.
*
* @intput GMMR0AllocateHandyPages expects the Page ID of the page to
* update here. NIL_GMM_PAGEID means no page should be updated.
*
* GMMR0AllocatePages requires this to be initialized to
* NIL_GMM_PAGEID currently.
*
* @output The ID of the page, NIL_GMM_PAGEID if the allocation failed.
*/
/** The Page ID of the shared page was replaced by this page.
*
* @input GMMR0AllocateHandyPages expects this to indicate a shared
* page that has been replaced by this page and should have its
* reference counter decremented and perhaps be freed up. Use
* NIL_GMM_PAGEID if no shared page was involved.
*
* All other APIs expects NIL_GMM_PAGEID here.
*
* @output All APIs sets this to NIL_GMM_PAGEID.
*/
} GMMPAGEDESC;
/** Pointer to a page allocation. */
typedef GMMPAGEDESC *PGMMPAGEDESC;
/** GMMPAGEDESC::HCPhysGCPhys value that indicates that the page is unsharable.
* @note This corresponds to GMM_PAGE_PFN_UNSHAREABLE. */
#if HC_ARCH_BITS == 64
#else
#endif
/**
* The allocation sizes.
*/
typedef struct GMMVMSIZES
{
/** The number of pages of base memory.
* This is the sum of RAM, ROMs and handy pages. */
/** The number of pages for the shadow pool. (Can be squeezed for memory.) */
/** The number of pages for fixed allocations like MMIO2 and the hyper heap. */
} GMMVMSIZES;
/** Pointer to a GMMVMSIZES. */
typedef GMMVMSIZES *PGMMVMSIZES;
/**
* GMM VM statistics.
*/
typedef struct GMMVMSTATS
{
/** The reservations. */
/** The actual allocations.
* This includes both private and shared page allocations. */
/** The current number of private pages. */
/** The current number of shared pages. */
/** The current number of ballooned pages. */
/** The max number of pages that can be ballooned. */
/** The number of pages we've currently requested the guest to give us.
* This is 0 if no pages currently requested. */
/** The number of pages the guest has given us in response to the request.
* This is not reset on request completed and may be used in later decisions. */
/** The number of pages we've currently requested the guest to take back. */
/** The number of shareable module tracked by this VM. */
/** The current over-commitment policy. */
/** The VM priority for arbitrating VMs in low and out of memory situation.
* Like which VMs to start squeezing first. */
/** Whether ballooning is enabled or not. */
bool fBallooningEnabled;
/** Whether shared paging is enabled or not. */
bool fSharedPagingEnabled;
/** Whether the VM is allowed to allocate memory or not.
* This is used when the reservation update request fails or when the VM has
bool fMayAllocate;
/** Explicit alignment. */
bool afReserved[1];
} GMMVMSTATS;
/**
* The GMM statistics.
*/
typedef struct GMMSTATS
{
/** The maximum number of pages we're allowed to allocate
* (GMM::cMaxPages). */
/** The number of pages that has been reserved (GMM::cReservedPages). */
/** The number of pages that we have over-committed in reservations
* (GMM::cOverCommittedPages). */
/** The number of actually allocated (committed if you like) pages
* (GMM::cAllocatedPages). */
/** The number of pages that are shared. A subset of cAllocatedPages.
* (GMM::cSharedPages) */
/** The number of pages that are actually shared between VMs.
* (GMM:cDuplicatePages) */
/** The number of pages that are shared that has been left behind by
* VMs not doing proper cleanups (GMM::cLeftBehindSharedPages). */
/** The number of current ballooned pages (GMM::cBalloonedPages). */
/** The number of allocation chunks (GMM::cChunks). */
/** The number of freed chunks ever (GMM::cFreedChunks). */
/** The number of shareable modules (GMM:cShareableModules). */
/** Space reserved for later. */
/** Statistics for the specified VM. (Zero filled if not requested.) */
} GMMSTATS;
/** Pointer to the GMM statistics. */
/** Const pointer to the GMM statistics. */
typedef const GMMSTATS *PCGMMSTATS;
GMMR0DECL(int) GMMR0InitialReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages,
GMMR0DECL(int) GMMR0UpdateReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages);
GMMR0DECL(int) GMMR0AllocateHandyPages(PVM pVM, VMCPUID idCpu, uint32_t cPagesToUpdate, uint32_t cPagesToAlloc, PGMMPAGEDESC paPages);
GMMR0DECL(int) GMMR0AllocatePages(PVM pVM, VMCPUID idCpu, uint32_t cPages, PGMMPAGEDESC paPages, GMMACCOUNT enmAccount);
GMMR0DECL(int) GMMR0AllocateLargePage(PVM pVM, VMCPUID idCpu, uint32_t cbPage, uint32_t *pIdPage, RTHCPHYS *pHCPhys);
GMMR0DECL(int) GMMR0FreePages(PVM pVM, VMCPUID idCpu, uint32_t cPages, PGMMFREEPAGEDESC paPages, GMMACCOUNT enmAccount);
GMMR0DECL(int) GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, GMMBALLOONACTION enmAction, uint32_t cBalloonedPages);
GMMR0DECL(int) GMMR0MapUnmapChunk(PVM pVM, uint32_t idChunkMap, uint32_t idChunkUnmap, PRTR3PTR ppvR3);
GMMR0DECL(int) GMMR0RegisterSharedModule(PVM pVM, VMCPUID idCpu, VBOXOSFAMILY enmGuestOS, char *pszModuleName, char *pszVersion,
struct VMMDEVSHAREDREGIONDESC *pRegions);
GMMR0DECL(int) GMMR0UnregisterSharedModule(PVM pVM, VMCPUID idCpu, char *pszModuleName, char *pszVersion, RTGCPTR GCBaseAddr, uint32_t cbModule);
/**
* Request buffer for GMMR0InitialReservationReq / VMMR0_DO_GMM_INITIAL_RESERVATION.
* @see GMMR0InitialReservation
*/
typedef struct GMMINITIALRESERVATIONREQ
{
/** The header. */
/** Pointer to a GMMR0InitialReservationReq / VMMR0_DO_GMM_INITIAL_RESERVATION request buffer. */
/**
* Request buffer for GMMR0UpdateReservationReq / VMMR0_DO_GMM_UPDATE_RESERVATION.
* @see GMMR0UpdateReservation
*/
typedef struct GMMUPDATERESERVATIONREQ
{
/** The header. */
/** Pointer to a GMMR0InitialReservationReq / VMMR0_DO_GMM_INITIAL_RESERVATION request buffer. */
/**
* Request buffer for GMMR0AllocatePagesReq / VMMR0_DO_GMM_ALLOCATE_PAGES.
* @see GMMR0AllocatePages.
*/
typedef struct GMMALLOCATEPAGESREQ
{
/** The header. */
/** The account to charge the allocation to. */
/** The number of pages to allocate. */
/** Array of page descriptors. */
/** Pointer to a GMMR0AllocatePagesReq / VMMR0_DO_GMM_ALLOCATE_PAGES request buffer. */
typedef GMMALLOCATEPAGESREQ *PGMMALLOCATEPAGESREQ;
/**
* Request buffer for GMMR0FreePagesReq / VMMR0_DO_GMM_FREE_PAGES.
* @see GMMR0FreePages.
*/
typedef struct GMMFREEPAGESREQ
{
/** The header. */
/** The account this relates to. */
/** The number of pages to free. */
/** Array of free page descriptors. */
/** Pointer to a GMMR0FreePagesReq / VMMR0_DO_GMM_FREE_PAGES request buffer. */
typedef GMMFREEPAGESREQ *PGMMFREEPAGESREQ;
/**
* Request buffer for GMMR0BalloonedPagesReq / VMMR0_DO_GMM_BALLOONED_PAGES.
* @see GMMR0BalloonedPages.
*/
typedef struct GMMBALLOONEDPAGESREQ
{
/** The header. */
/** The number of ballooned pages. */
/** Inflate or deflate the balloon. */
/** Pointer to a GMMR0BalloonedPagesReq / VMMR0_DO_GMM_BALLOONED_PAGES request buffer. */
typedef GMMBALLOONEDPAGESREQ *PGMMBALLOONEDPAGESREQ;
/**
* Request buffer for GMMR0QueryHypervisorMemoryStatsReq / VMMR0_DO_GMM_QUERY_VMM_MEM_STATS.
* @see GMMR0QueryHypervisorMemoryStatsReq.
*/
typedef struct GMMMEMSTATSREQ
{
/** The header. */
/** The number of allocated pages (out). */
/** The number of free pages (out). */
/** The number of ballooned pages (out). */
/** The number of shared pages (out). */
/** Maximum nr of pages (out). */
/** Pointer to a GMMR0QueryHypervisorMemoryStatsReq / VMMR0_DO_GMM_QUERY_HYPERVISOR_MEM_STATS request buffer. */
typedef GMMMEMSTATSREQ *PGMMMEMSTATSREQ;
/**
* Request buffer for GMMR0MapUnmapChunkReq / VMMR0_DO_GMM_MAP_UNMAP_CHUNK.
* @see GMMR0MapUnmapChunk
*/
typedef struct GMMMAPUNMAPCHUNKREQ
{
/** The header. */
/** The chunk to map, NIL_GMM_CHUNKID if unmap only. (IN) */
/** The chunk to unmap, NIL_GMM_CHUNKID if map only. (IN) */
/** Where the mapping address is returned. (OUT) */
/** Pointer to a GMMR0MapUnmapChunkReq / VMMR0_DO_GMM_MAP_UNMAP_CHUNK request buffer. */
typedef GMMMAPUNMAPCHUNKREQ *PGMMMAPUNMAPCHUNKREQ;
/**
* Request buffer for GMMR0FreeLargePageReq / VMMR0_DO_GMM_FREE_LARGE_PAGE.
* @see GMMR0FreeLargePage.
*/
typedef struct GMMFREELARGEPAGEREQ
{
/** The header. */
/** The Page ID. */
/** Pointer to a GMMR0FreePagesReq / VMMR0_DO_GMM_FREE_PAGES request buffer. */
typedef GMMFREELARGEPAGEREQ *PGMMFREELARGEPAGEREQ;
/** Maximum length of the shared module name string. */
#define GMM_SHARED_MODULE_MAX_NAME_STRING 128
/** Maximum length of the shared module version string. */
#define GMM_SHARED_MODULE_MAX_VERSION_STRING 16
/**
* Request buffer for GMMR0RegisterSharedModuleReq / VMMR0_DO_GMM_REGISTER_SHARED_MODULE.
* @see GMMR0RegisterSharedModule.
*/
typedef struct GMMREGISTERSHAREDMODULEREQ
{
/** The header. */
/** Shared module size. */
/** Number of included region descriptors */
/** Base address of the shared module. */
/** Guest OS type. */
/** return code. */
/** Module name */
/** Module version */
/** Shared region descriptor(s). */
/** Pointer to a GMMR0RegisterSharedModuleReq / VMMR0_DO_GMM_REGISTER_SHARED_MODULE request buffer. */
GMMR0DECL(int) GMMR0RegisterSharedModuleReq(PVM pVM, VMCPUID idCpu, PGMMREGISTERSHAREDMODULEREQ pReq);
/**
* Shared region descriptor
*/
typedef struct GMMSHAREDREGIONDESC
{
/** Region base address. */
/** Region size. */
/** Alignment. */
/** Pointer to physical GMM page ID array. */
/** Pointer to a GMMSHAREDREGIONDESC. */
typedef GMMSHAREDREGIONDESC *PGMMSHAREDREGIONDESC;
/**
* Shared module registration info (global)
*/
typedef struct GMMSHAREDMODULE
{
/** Tree node. */
/** Shared module size. */
/** Number of included region descriptors */
/** Number of users (VMs). */
/** Guest OS family type. */
/** Module name */
/** Module version */
/** Shared region descriptor(s). */
/** Pointer to a GMMSHAREDMODULE. */
typedef GMMSHAREDMODULE *PGMMSHAREDMODULE;
/**
* Page descriptor for GMMR0SharedModuleCheckRange
*/
typedef struct GMMSHAREDPAGEDESC
{
/** GC Physical address (in) */
/** Align at 8 byte boundary. */
/** Pointer to a GMMSHAREDPAGEDESC. */
typedef GMMSHAREDPAGEDESC *PGMMSHAREDPAGEDESC;
GMMR0DECL(int) GMMR0SharedModuleCheckPage(PGVM pGVM, PGMMSHAREDMODULE pModule, unsigned idxRegion, unsigned idxPage,
/**
* Request buffer for GMMR0UnregisterSharedModuleReq / VMMR0_DO_GMM_UNREGISTER_SHARED_MODULE.
* @see GMMR0UnregisterSharedModule.
*/
typedef struct GMMUNREGISTERSHAREDMODULEREQ
{
/** The header. */
/** Shared module size. */
/** Align at 8 byte boundary. */
/** Base address of the shared module. */
/** Module name */
/** Module version */
/** Pointer to a GMMR0UnregisterSharedModuleReq / VMMR0_DO_GMM_UNREGISTER_SHARED_MODULE request buffer. */
GMMR0DECL(int) GMMR0UnregisterSharedModuleReq(PVM pVM, VMCPUID idCpu, PGMMUNREGISTERSHAREDMODULEREQ pReq);
/**
* Request buffer for GMMR0FindDuplicatePageReq / VMMR0_DO_GMM_FIND_DUPLICATE_PAGE.
* @see GMMR0FindDuplicatePage.
*/
typedef struct GMMFINDDUPLICATEPAGEREQ
{
/** The header. */
/** Page id. */
/** Duplicate flag (out) */
bool fDuplicate;
/** Pointer to a GMMR0FindDuplicatePageReq / VMMR0_DO_GMM_FIND_DUPLICATE_PAGE request buffer. */
#endif /* VBOX_STRICT && HC_ARCH_BITS == 64 */
/**
* Request buffer for GMMR0QueryStatisticsReq / VMMR0_DO_GMM_QUERY_STATISTICS.
* @see GMMR0QueryStatistics.
*/
typedef struct GMMQUERYSTATISTICSSREQ
{
/** The header. */
/** The support driver session. */
/** The statistics. */
/** Pointer to a GMMR0QueryStatisticsReq / VMMR0_DO_GMM_QUERY_STATISTICS
* request buffer. */
/**
* Request buffer for GMMR0ResetStatisticsReq / VMMR0_DO_GMM_RESET_STATISTICS.
* @see GMMR0ResetStatistics.
*/
typedef struct GMMRESETSTATISTICSSREQ
{
/** The header. */
/** The support driver session. */
/** The statistics to reset.
* Any non-zero entry will be reset (if permitted). */
/** Pointer to a GMMR0ResetStatisticsReq / VMMR0_DO_GMM_RESET_STATISTICS
* request buffer. */
#ifdef IN_RING3
/** @defgroup grp_gmm_r3 The Global Memory Manager Ring-3 API Wrappers
* @ingroup grp_gmm
* @{
*/
GMMR3DECL(int) GMMR3InitialReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages,
GMMR3DECL(int) GMMR3UpdateReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages);
GMMR3DECL(int) GMMR3AllocatePagesPrepare(PVM pVM, PGMMALLOCATEPAGESREQ *ppReq, uint32_t cPages, GMMACCOUNT enmAccount);
GMMR3DECL(int) GMMR3FreePagesPrepare(PVM pVM, PGMMFREEPAGESREQ *ppReq, uint32_t cPages, GMMACCOUNT enmAccount);
GMMR3DECL(void) GMMR3FreePagesRePrep(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t cPages, GMMACCOUNT enmAccount);
GMMR3DECL(int) GMMR3MapUnmapChunk(PVM pVM, uint32_t idChunkMap, uint32_t idChunkUnmap, PRTR3PTR ppvR3);
GMMR3DECL(int) GMMR3QueryHypervisorMemoryStats(PVM pVM, uint64_t *pcTotalAllocPages, uint64_t *pcTotalFreePages, uint64_t *pcTotalBalloonPages, uint64_t *puTotalBalloonSize);
GMMR3DECL(int) GMMR3QueryMemoryStats(PVM pVM, uint64_t *pcAllocPages, uint64_t *pcMaxPages, uint64_t *pcBalloonPages);
# endif
/** @} */
#endif /* IN_RING3 */
/** @} */
#endif