Logo Search packages:      
Sourcecode: virtualbox-ose version File versions

gmm.h

Go to the documentation of this file.
/** @file
 * GMM - The Global Memory Manager.
 */

/*
 * Copyright (C) 2007 Sun Microsystems, Inc.
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * 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.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
 * Clara, CA 95054 USA or visit http://www.sun.com if you need
 * additional information or have any questions.
 */

#ifndef ___VBox_gmm_h
#define ___VBox_gmm_h

#include <VBox/types.h>
#include <VBox/gvmm.h>
#include <VBox/sup.h>

RT_C_DECLS_BEGIN

/** @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
# define GMMR0DECL(type)    DECLEXPORT(type) VBOXCALL
#else
00057 # define GMMR0DECL(type)    DECLIMPORT(type) VBOXCALL
#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
# define GMMR3DECL(type)    DECLEXPORT(type) VBOXCALL
#else
00074 # define GMMR3DECL(type)    DECLIMPORT(type) VBOXCALL
#endif


/** The chunk shift. (2^20 = 1 MB) */
00079 #define GMM_CHUNK_SHIFT                 20
/** The allocation chunk size. */
00081 #define GMM_CHUNK_SIZE                  (1U << GMM_CHUNK_SHIFT)
/** The allocation chunk size in pages. */
00083 #define GMM_CHUNK_NUM_PAGES             (1U << (GMM_CHUNK_SHIFT - PAGE_SHIFT))
/** The shift factor for converting a page id into a chunk id. */
00085 #define GMM_CHUNKID_SHIFT               (GMM_CHUNK_SHIFT - PAGE_SHIFT)
/** The last valid Chunk ID value. */
00087 #define GMM_CHUNKID_LAST                (GMM_PAGEID_LAST >> GMM_CHUNKID_SHIFT)
/** 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. */
00091 #define GMM_PAGEID_LAST                 (RT_BIT_32(28) - 1)
/** Mask out the page index from the Page ID. */
00093 #define GMM_PAGEID_IDX_MASK             ((1U << GMM_CHUNKID_SHIFT) - 1)
/** The NIL Chunk ID value. */
00095 #define NIL_GMM_CHUNKID                 0
/** The NIL Page ID value. */
00097 #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
# define GMM_GCPHYS_LAST            UINT64_C(0x00000fffffff0000)    /* 2^44 (16TB) - 0x10000 */
#else
00120 # define GMM_GCPHYS_LAST            UINT64_C(0x0000000fffff0000)    /* 2^36 (64GB) - 0x10000 */
#endif

/**
 * Over-commitment policy.
 */
00126 typedef enum GMMOCPOLICY
{
    /** The usual invalid 0 value. */
00129     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. */
00133     GMMOCPOLICY_NO_OC,
    /** to-be-determined. */
00135     GMMOCPOLICY_TBD,
    /** The end of the valid policy range. */
00137     GMMOCPOLICY_END,
    /** The usual 32-bit hack. */
00139     GMMOCPOLICY_32BIT_HACK = 0x7fffffff
} GMMOCPOLICY;

/**
 * VM / Memory priority.
 */
00145 typedef enum GMMPRIORITY
{
    /** The usual invalid 0 value. */
00148     GMMPRIORITY_INVALID = 0,
    /** High.
     * When ballooning, ask these VMs last.
     * When running out of memory, try not to interrupt these VMs. */
00152     GMMPRIORITY_HIGH,
    /** Normal.
     * When ballooning, don't wait to ask these.
     * When running out of memory, pause, save and/or kill these VMs. */
00156     GMMPRIORITY_NORMAL,
    /** Low.
     * When ballooning, maximize these first.
     * When running out of memory, save or kill these VMs. */
00160     GMMPRIORITY_LOW,
    /** The end of the valid priority range. */
00162     GMMPRIORITY_END,
    /** The custom 32-bit type blowup. */
00164     GMMPRIORITY_32BIT_HACK = 0x7fffffff
} GMMPRIORITY;


/**
 * GMM Memory Accounts.
 */
00171 typedef enum GMMACCOUNT
{
    /** The customary invalid zero entry. */
00174     GMMACCOUNT_INVALID = 0,
    /** Account with the base allocations. */
00176     GMMACCOUNT_BASE,
    /** Account with the shadow allocations. */
00178     GMMACCOUNT_SHADOW,
    /** Account with the fixed allocations. */
00180     GMMACCOUNT_FIXED,
    /** The end of the valid values. */
00182     GMMACCOUNT_END,
    /** The usual 32-bit value to finish it off. */
00184     GMMACCOUNT_32BIT_HACK = 0x7fffffff
} GMMACCOUNT;


/**
 * A page descriptor for use when freeing pages.
 * See GMMR0FreePages, GMMR0BalloonedPages.
 */
00192 typedef struct GMMFREEPAGEDESC
{
    /** The Page ID of the page to be freed. */
00195     uint32_t idPage;
} GMMFREEPAGEDESC;
/** Pointer to a page descriptor for freeing pages. */
00198 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.
 */
00207 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).
     */
00225     RTHCPHYS                    HCPhysGCPhys;

    /** 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.
     */
00237     uint32_t                    idPage;

    /** 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.
     */
00250     uint32_t                    idSharedPage;
} GMMPAGEDESC;
AssertCompileSize(GMMPAGEDESC, 16);
/** Pointer to a page allocation. */
00254 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
# define GMM_GCPHYS_UNSHAREABLE     UINT64_C(0x00000fffffff1000)
#else
00261 # define GMM_GCPHYS_UNSHAREABLE     UINT64_C(0x0000000fffff1000)
#endif

GMMR0DECL(int)  GMMR0Init(void);
GMMR0DECL(void) GMMR0Term(void);
GMMR0DECL(void) GMMR0InitPerVMData(PGVM pGVM);
GMMR0DECL(void) GMMR0CleanupVM(PGVM pGVM);
GMMR0DECL(int)  GMMR0InitialReservation(PVM pVM, VMCPUID idCpu, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages,
                                        GMMOCPOLICY enmPolicy, GMMPRIORITY enmPriority);
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)  GMMR0FreePages(PVM pVM, VMCPUID idCpu, uint32_t cPages, PGMMFREEPAGEDESC paPages, GMMACCOUNT enmAccount);
GMMR0DECL(int)  GMMR0BalloonedPages(PVM pVM, VMCPUID idCpu, uint32_t cBalloonedPages, uint32_t cPagesToFree, PGMMFREEPAGEDESC paPages, bool fCompleted);
GMMR0DECL(int)  GMMR0DeflatedBalloon(PVM pVM, VMCPUID idCpu, uint32_t cPages);
GMMR0DECL(int)  GMMR0MapUnmapChunk(PVM pVM, VMCPUID idCpu, uint32_t idChunkMap, uint32_t idChunkUnmap, PRTR3PTR ppvR3);
GMMR0DECL(int)  GMMR0SeedChunk(PVM pVM, VMCPUID idCpu, RTR3PTR pvR3);



/**
 * Request buffer for GMMR0InitialReservationReq / VMMR0_DO_GMM_INITIAL_RESERVATION.
 * @see GMMR0InitialReservation
 */
00285 typedef struct GMMINITIALRESERVATIONREQ
{
    /** The header. */
00288     SUPVMMR0REQHDR  Hdr;
00289     uint64_t        cBasePages;         /**< @see GMMR0InitialReservation */
00290     uint32_t        cShadowPages;       /**< @see GMMR0InitialReservation */
00291     uint32_t        cFixedPages;        /**< @see GMMR0InitialReservation */
00292     GMMOCPOLICY     enmPolicy;          /**< @see GMMR0InitialReservation */
00293     GMMPRIORITY     enmPriority;        /**< @see GMMR0InitialReservation */
} GMMINITIALRESERVATIONREQ;
/** Pointer to a GMMR0InitialReservationReq / VMMR0_DO_GMM_INITIAL_RESERVATION request buffer. */
00296 typedef GMMINITIALRESERVATIONREQ *PGMMINITIALRESERVATIONREQ;

GMMR0DECL(int)  GMMR0InitialReservationReq(PVM pVM, VMCPUID idCpu, PGMMINITIALRESERVATIONREQ pReq);


/**
 * Request buffer for GMMR0UpdateReservationReq / VMMR0_DO_GMM_UPDATE_RESERVATION.
 * @see GMMR0UpdateReservation
 */
00305 typedef struct GMMUPDATERESERVATIONREQ
{
    /** The header. */
00308     SUPVMMR0REQHDR  Hdr;
00309     uint64_t        cBasePages;         /**< @see GMMR0UpdateReservation */
00310     uint32_t        cShadowPages;       /**< @see GMMR0UpdateReservation */
00311     uint32_t        cFixedPages;        /**< @see GMMR0UpdateReservation */
} GMMUPDATERESERVATIONREQ;
/** Pointer to a GMMR0InitialReservationReq / VMMR0_DO_GMM_INITIAL_RESERVATION request buffer. */
00314 typedef GMMUPDATERESERVATIONREQ *PGMMUPDATERESERVATIONREQ;

GMMR0DECL(int)  GMMR0UpdateReservationReq(PVM pVM, VMCPUID idCpu, PGMMUPDATERESERVATIONREQ pReq);


/**
 * Request buffer for GMMR0AllocatePagesReq / VMMR0_DO_GMM_ALLOCATE_PAGES.
 * @see GMMR0AllocatePages.
 */
00323 typedef struct GMMALLOCATEPAGESREQ
{
    /** The header. */
00326     SUPVMMR0REQHDR  Hdr;
    /** The account to charge the allocation to. */
00328     GMMACCOUNT      enmAccount;
    /** The number of pages to allocate. */
00330     uint32_t        cPages;
    /** Array of page descriptors. */
00332     GMMPAGEDESC     aPages[1];
} GMMALLOCATEPAGESREQ;
/** Pointer to a GMMR0AllocatePagesReq / VMMR0_DO_GMM_ALLOCATE_PAGES request buffer. */
00335 typedef GMMALLOCATEPAGESREQ *PGMMALLOCATEPAGESREQ;

GMMR0DECL(int)  GMMR0AllocatePagesReq(PVM pVM, VMCPUID idCpu, PGMMALLOCATEPAGESREQ pReq);


/**
 * Request buffer for GMMR0FreePagesReq / VMMR0_DO_GMM_FREE_PAGES.
 * @see GMMR0FreePages.
 */
00344 typedef struct GMMFREEPAGESREQ
{
    /** The header. */
00347     SUPVMMR0REQHDR  Hdr;
    /** The account this relates to. */
00349     GMMACCOUNT      enmAccount;
    /** The number of pages to free. */
00351     uint32_t        cPages;
    /** Array of free page descriptors. */
00353     GMMFREEPAGEDESC aPages[1];
} GMMFREEPAGESREQ;
/** Pointer to a GMMR0FreePagesReq / VMMR0_DO_GMM_FREE_PAGES request buffer. */
00356 typedef GMMFREEPAGESREQ *PGMMFREEPAGESREQ;

GMMR0DECL(int)  GMMR0FreePagesReq(PVM pVM, VMCPUID idCpu, PGMMFREEPAGESREQ pReq);


/**
 * Request buffer for GMMR0BalloonedPagesReq / VMMR0_DO_GMM_BALLOONED_PAGES.
 * @see GMMR0BalloonedPages.
 */
00365 typedef struct GMMBALLOONEDPAGESREQ
{
    /** The header. */
00368     SUPVMMR0REQHDR  Hdr;
    /** The number of ballooned pages. */
00370     uint32_t        cBalloonedPages;
    /** The number of pages to free. */
00372     uint32_t        cPagesToFree;
    /** Whether the ballooning request is completed or more pages are still to come. */
00374     bool            fCompleted;
    /** Array of free page descriptors. */
00376     GMMFREEPAGEDESC aPages[1];
} GMMBALLOONEDPAGESREQ;
/** Pointer to a GMMR0BalloonedPagesReq / VMMR0_DO_GMM_BALLOONED_PAGES request buffer. */
00379 typedef GMMBALLOONEDPAGESREQ *PGMMBALLOONEDPAGESREQ;

GMMR0DECL(int)  GMMR0BalloonedPagesReq(PVM pVM, VMCPUID idCpu, PGMMBALLOONEDPAGESREQ pReq);


/**
 * Request buffer for GMMR0MapUnmapChunkReq / VMMR0_DO_GMM_MAP_UNMAP_CHUNK.
 * @see GMMR0MapUnmapChunk
 */
00388 typedef struct GMMMAPUNMAPCHUNKREQ
{
    /** The header. */
00391     SUPVMMR0REQHDR  Hdr;
    /** The chunk to map, NIL_GMM_CHUNKID if unmap only. (IN) */
00393     uint32_t        idChunkMap;
    /** The chunk to unmap, NIL_GMM_CHUNKID if map only. (IN) */
00395     uint32_t        idChunkUnmap;
    /** Where the mapping address is returned. (OUT) */
00397     RTR3PTR         pvR3;
} GMMMAPUNMAPCHUNKREQ;
/** Pointer to a GMMR0MapUnmapChunkReq / VMMR0_DO_GMM_MAP_UNMAP_CHUNK request buffer. */
00400 typedef GMMMAPUNMAPCHUNKREQ *PGMMMAPUNMAPCHUNKREQ;

GMMR0DECL(int)  GMMR0MapUnmapChunkReq(PVM pVM, VMCPUID idCpu, PGMMMAPUNMAPCHUNKREQ pReq);


#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,
                                        GMMOCPOLICY enmPolicy, GMMPRIORITY enmPriority);
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)  GMMR3AllocatePagesPerform(PVM pVM, PGMMALLOCATEPAGESREQ pReq);
GMMR3DECL(void) GMMR3AllocatePagesCleanup(PGMMALLOCATEPAGESREQ pReq);
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)  GMMR3FreePagesPerform(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t cActualPages);
GMMR3DECL(void) GMMR3FreePagesCleanup(PGMMFREEPAGESREQ pReq);
GMMR3DECL(void) GMMR3FreeAllocatedPages(PVM pVM, GMMALLOCATEPAGESREQ const *pAllocReq);
GMMR3DECL(int)  GMMR3DeflatedBalloon(PVM pVM, uint32_t cPages);
GMMR3DECL(int)  GMMR3MapUnmapChunk(PVM pVM, uint32_t idChunkMap, uint32_t idChunkUnmap, PRTR3PTR ppvR3);
GMMR3DECL(int)  GMMR3SeedChunk(PVM pVM, RTR3PTR pvR3);
/** @} */
#endif /* IN_RING3 */

/** @} */

RT_C_DECLS_END

#endif


Generated by  Doxygen 1.6.0   Back to index