GMM.cpp revision 30868e719f5a45ec4689ecb2616767cb1fd02c28
db69d5d53cbffd6cc7419807e767792eef3bc593Automatic Updater/* $Id$ */
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews/** @file
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * GMM - Global Memory Manager, ring-3 request wrappers.
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater */
4c1132f34493327abc632196f5876a89aa573687Bob Halley
4c1132f34493327abc632196f5876a89aa573687Bob Halley/*
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Copyright (C) 2008 Sun Microsystems, Inc.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews *
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * This file is part of VirtualBox Open Source Edition (OSE), as
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * available from http://www.virtualbox.org. This file is free software;
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * you can redistribute it and/or modify it under the terms of the GNU
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * General Public License (GPL) as published by the Free Software
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Foundation, in version 2 as it comes in the "COPYING" file of the
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews *
9c3531d72aeaad6c5f01efe6a1c82023e1379e4dDavid Lawrence * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
f41f183f628a148860a6d1f0070208cddd45b0c6Bob Halley * Clara, CA 95054 USA or visit http://www.sun.com if you need
f41f183f628a148860a6d1f0070208cddd45b0c6Bob Halley * additional information or have any questions.
f41f183f628a148860a6d1f0070208cddd45b0c6Bob Halley */
f41f183f628a148860a6d1f0070208cddd45b0c6Bob Halley
9a2127f8335bad323451d7825119cd9f72e32464Mark Andrews
9a2127f8335bad323451d7825119cd9f72e32464Mark Andrews/*******************************************************************************
9a2127f8335bad323451d7825119cd9f72e32464Mark Andrews* Header Files *
9a2127f8335bad323451d7825119cd9f72e32464Mark Andrews*******************************************************************************/
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley#define LOG_GROUP LOG_GROUP_GMM
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley#include <VBox/gmm.h>
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley#include <VBox/vmm.h>
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley#include <VBox/vm.h>
c2bc56dc65b4b103a5600565680eb5f33fa4c90bMark Andrews#include <VBox/sup.h>
51917258dbb23cfe6069ae1cf2b7fc5aefc1e0c2Bob Halley#include <VBox/err.h>
c6b3c1984caa362359862e063e7b70dfb306db7eMark Andrews#include <VBox/param.h>
155a0ce6e3c9cef51b63789c34d83d9143ce01fdMark Andrews
494576ce20cfd98d74955698cf8f7b37dce2f740Mark Andrews#include <iprt/assert.h>
494576ce20cfd98d74955698cf8f7b37dce2f740Mark Andrews#include <VBox/log.h>
6d5dcd0dc9bdbd679282b1ffc47987d24c3a1346Bob Halley#include <iprt/mem.h>
12178c86525332bb0ab66155feb61fbf32eca6acEvan Hunt
155a0ce6e3c9cef51b63789c34d83d9143ce01fdMark Andrews
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley/**
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley * @see GMMR0InitialReservation
b6d52ee5bea1b9d9074698e693b49ce96edff47bMark Andrews */
b6d52ee5bea1b9d9074698e693b49ce96edff47bMark AndrewsGMMR3DECL(int) GMMR3InitialReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages,
b6d52ee5bea1b9d9074698e693b49ce96edff47bMark Andrews GMMOCPOLICY enmPolicy, GMMPRIORITY enmPriority)
b6d52ee5bea1b9d9074698e693b49ce96edff47bMark Andrews{
c45abd11bb68005d8a5c56c14b16f4184c3e057dMichael Graff GMMINITIALRESERVATIONREQ Req;
c45abd11bb68005d8a5c56c14b16f4184c3e057dMichael Graff Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
a685d9c3b608eb768d237f20e8e8b1c5d3902146David Lawrence Req.Hdr.cbReq = sizeof(Req);
feb08cecf318bba330437cfcb725f48d999804d8James Brister Req.cBasePages = cBasePages;
76117ff568dc788ed24937cfea916a18db285960Mark Andrews Req.cShadowPages = cShadowPages;
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews Req.cFixedPages = cFixedPages;
76117ff568dc788ed24937cfea916a18db285960Mark Andrews Req.enmPolicy = enmPolicy;
76117ff568dc788ed24937cfea916a18db285960Mark Andrews Req.enmPriority = enmPriority;
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews return VMMR3CallR0(pVM, VMMR0_DO_GMM_INITIAL_RESERVATION, 0, &Req.Hdr);
76117ff568dc788ed24937cfea916a18db285960Mark Andrews}
65c4736d9c0ebc6d9b1d991593b55566909da9cdBrian Wellington
fc80027fb54b501cdd88461bf879d078259e0226David Lawrence
d0eb2cc33c5db3366a16b1cb0abcca6ec7c8ee3cTatuya JINMEI 神明達哉/**
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson * @see GMMR0UpdateReservation
911ed0d3bee586b3bec42cb6c376d5cc6c0e1e24Brian Wellington */
e334405421979688f2d838805ac67ee47bd62976Mark AndrewsGMMR3DECL(int) GMMR3UpdateReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages)
e334405421979688f2d838805ac67ee47bd62976Mark Andrews{
e334405421979688f2d838805ac67ee47bd62976Mark Andrews GMMUPDATERESERVATIONREQ Req;
911ed0d3bee586b3bec42cb6c376d5cc6c0e1e24Brian Wellington Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt Req.Hdr.cbReq = sizeof(Req);
28479307225582ad0b2e11441d85fcf5169551d0Mark Andrews Req.cBasePages = cBasePages;
28b863e609ff2d97b78663b46894494cfa2ea411Mark Andrews Req.cShadowPages = cShadowPages;
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews Req.cFixedPages = cFixedPages;
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews return VMMR3CallR0(pVM, VMMR0_DO_GMM_UPDATE_RESERVATION, 0, &Req.Hdr);
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews}
3916872f379457fe344afb02398a009701c5016aEvan Hunt
ce1f5b8d0ae5936fd187c1f414ff12a7e3b0aa37Andreas Gustafsson
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉/**
5c6762838c9e423753723ec2a963164e3d66ac32Mark Andrews * Prepares a GMMR0AllocatePages request.
5c6762838c9e423753723ec2a963164e3d66ac32Mark Andrews *
5c6762838c9e423753723ec2a963164e3d66ac32Mark Andrews * @returns VINF_SUCCESS or VERR_NO_TMP_MEMORY.
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley * @param pVM Pointer to the shared VM structure.
fc80027fb54b501cdd88461bf879d078259e0226David Lawrence * @param[out] ppReq Where to store the pointer to the request packet.
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews * @param cPages The number of pages that's to be allocated.
37dee1ff94960a61243f611c0f87f8c316815c53Mark Andrews * @param enmAccount The account to charge.
76117ff568dc788ed24937cfea916a18db285960Mark Andrews */
76117ff568dc788ed24937cfea916a18db285960Mark AndrewsGMMR3DECL(int) GMMR3AllocatePagesPrepare(PVM pVM, PGMMALLOCATEPAGESREQ *ppReq, uint32_t cPages, GMMACCOUNT enmAccount)
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews{
494576ce20cfd98d74955698cf8f7b37dce2f740Mark Andrews uint32_t cb = RT_OFFSETOF(GMMALLOCATEPAGESREQ, aPages[cPages]);
76117ff568dc788ed24937cfea916a18db285960Mark Andrews PGMMALLOCATEPAGESREQ pReq = (PGMMALLOCATEPAGESREQ)RTMemTmpAllocZ(cb);
494576ce20cfd98d74955698cf8f7b37dce2f740Mark Andrews if (!pReq)
d0eb2cc33c5db3366a16b1cb0abcca6ec7c8ee3cTatuya JINMEI 神明達哉 return VERR_NO_TMP_MEMORY;
6017f424ee3c02d7f22132c77576ea38542fa949Andreas Gustafsson
911ed0d3bee586b3bec42cb6c376d5cc6c0e1e24Brian Wellington pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
e334405421979688f2d838805ac67ee47bd62976Mark Andrews pReq->Hdr.cbReq = cb;
cfb1587eb9a6dc6d1d36ea0344e1b20068b81e88Evan Hunt pReq->enmAccount = enmAccount;
911ed0d3bee586b3bec42cb6c376d5cc6c0e1e24Brian Wellington pReq->cPages = cPages;
6098d364b690cb9dabf96e9664c4689c8559bd2eMark Andrews NOREF(pVM);
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews *ppReq = pReq;
3cd88f71b01833d5c2474638854dfa5c4244a22aBrian Wellington return VINF_SUCCESS;
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews}
87708bde16713bc02ff2598f4a82f98c699a2f2dMark Andrews
ce1f5b8d0ae5936fd187c1f414ff12a7e3b0aa37Andreas Gustafsson
307d2084502eddc7ce921e5ce439aec3531d90e0Tatuya JINMEI 神明達哉/**
18d110413cf6416eb339c169b99159d09f690da1Brian Wellington * Performs a GMMR0AllocatePages request.
494576ce20cfd98d74955698cf8f7b37dce2f740Mark Andrews * This will call VMSetError on failure.
4fd3e3482c7e4ce01e2cf28f13e0152c8e50d746Mark Andrews *
494576ce20cfd98d74955698cf8f7b37dce2f740Mark Andrews * @returns VBox status code.
4fd3e3482c7e4ce01e2cf28f13e0152c8e50d746Mark Andrews * @param pVM Pointer to the shared VM structure.
4fd3e3482c7e4ce01e2cf28f13e0152c8e50d746Mark Andrews * @param pReq Pointer to the request (returned by GMMR3AllocatePagesPrepare).
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley */
d2b5fe92a4755ce67f2dd6050955782b4fd6b3f3Mark AndrewsGMMR3DECL(int) GMMR3AllocatePagesPerform(PVM pVM, PGMMALLOCATEPAGESREQ pReq)
d2b5fe92a4755ce67f2dd6050955782b4fd6b3f3Mark Andrews{
d2b5fe92a4755ce67f2dd6050955782b4fd6b3f3Mark Andrews for (unsigned i = 0; ; i++)
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley {
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_ALLOCATE_PAGES, 0, &pReq->Hdr);
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley if (RT_SUCCESS(rc))
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews {
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley#ifdef LOG_ENABLED
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley for (uint32_t iPage = 0; iPage < pReq->cPages; iPage++)
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley Log3(("GMMR3AllocatePagesPerform: idPage=%#x HCPhys=%RHp\n",
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley pReq->aPages[iPage].idPage, pReq->aPages[iPage].HCPhysGCPhys));
139154bd9894495042f4e748f554e9c8b98b7598Bob Halley#endif
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley return rc;
193738b819e3c699f9edd18864a6810fcfcec855Andreas Gustafsson }
fd35453765c6494d077edca44f4d998af5fd4cfaDavid Lawrence if (rc != VERR_GMM_SEED_ME)
fd35453765c6494d077edca44f4d998af5fd4cfaDavid Lawrence return VMSetError(pVM, rc, RT_SRC_POS,
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley N_("GMMR0AllocatePages failed to allocate %u pages"),
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley pReq->cPages);
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews Assert(i < pReq->cPages);
9f7d51ee3290e2a064d71016a6bd555b47134a7cMark Andrews
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley /*
881702c9c0079cd48a45054fd90d043f3a8b7e11Mark Andrews * Seed another chunk.
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley */
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley void *pvChunk;
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley rc = SUPR3PageAlloc(GMM_CHUNK_SIZE >> PAGE_SHIFT, &pvChunk);
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley if (RT_FAILURE(rc))
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley return VMSetError(pVM, rc, RT_SRC_POS,
922e6a3c2ac4ef900dd9dc99f0cc137f18372583Andreas Gustafsson N_("Out of memory (SUPR3PageAlloc) seeding a %u pages allocation request"),
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley pReq->cPages);
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley
74cb99072c4b0ebd2ccafcfa284288fa760f7a1aMark Andrews rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_SEED_CHUNK, (uintptr_t)pvChunk, NULL);
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley if (RT_FAILURE(rc))
4880900113e4d0f17884f3fbdbf4c302e3f9ea91Bob Halley return VMSetError(pVM, rc, RT_SRC_POS, N_("GMM seeding failed"));
fd35453765c6494d077edca44f4d998af5fd4cfaDavid Lawrence }
c8a42d6d81ff2fd9ad7fac94d4b85323554493c0Bob Halley}
4fd3e3482c7e4ce01e2cf28f13e0152c8e50d746Mark Andrews
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
6ef838d427c1ea858d2f09194a369134babf8b98Mark Andrews/**
6ef838d427c1ea858d2f09194a369134babf8b98Mark Andrews * Cleans up a GMMR0AllocatePages request.
6ef838d427c1ea858d2f09194a369134babf8b98Mark Andrews * @param pReq Pointer to the request (returned by GMMR3AllocatePagesPrepare).
6ef838d427c1ea858d2f09194a369134babf8b98Mark Andrews */
6d831cd0baf7dd2c133f7f9cbf295f3d80cf63a7David LawrenceGMMR3DECL(void) GMMR3AllocatePagesCleanup(PGMMALLOCATEPAGESREQ pReq)
6d831cd0baf7dd2c133f7f9cbf295f3d80cf63a7David Lawrence{
dac2799ea19735503a4d27f517d821aea210e594Andreas Gustafsson RTMemTmpFree(pReq);
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley}
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
6d7585b3e948dd31bf78321d83ac0e024f44a71bMark Andrews
6d5dcd0dc9bdbd679282b1ffc47987d24c3a1346Bob Halley/**
6d7585b3e948dd31bf78321d83ac0e024f44a71bMark Andrews * Prepares a GMMR0FreePages request.
6d7585b3e948dd31bf78321d83ac0e024f44a71bMark Andrews *
6d5dcd0dc9bdbd679282b1ffc47987d24c3a1346Bob Halley * @returns VINF_SUCCESS or VERR_NO_TMP_MEMORY.
6d7585b3e948dd31bf78321d83ac0e024f44a71bMark Andrews * @param pVM Pointer to the shared VM structure.
1471a520e59ac12b413afa8d8b3158a87af97aa6Bob Halley * @param[out] ppReq Where to store the pointer to the request packet.
1471a520e59ac12b413afa8d8b3158a87af97aa6Bob Halley * @param cPages The number of pages that's to be freed.
1471a520e59ac12b413afa8d8b3158a87af97aa6Bob Halley * @param enmAccount The account to charge.
94a3bcd132e515b4baa0884ba9dd0f361d2e17bcMark Andrews */
1471a520e59ac12b413afa8d8b3158a87af97aa6Bob HalleyGMMR3DECL(int) GMMR3FreePagesPrepare(PVM pVM, PGMMFREEPAGESREQ *ppReq, uint32_t cPages, GMMACCOUNT enmAccount)
1471a520e59ac12b413afa8d8b3158a87af97aa6Bob Halley{
4fd3e3482c7e4ce01e2cf28f13e0152c8e50d746Mark Andrews uint32_t cb = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[cPages]);
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews PGMMFREEPAGESREQ pReq = (PGMMFREEPAGESREQ)RTMemTmpAllocZ(cb);
6d5dcd0dc9bdbd679282b1ffc47987d24c3a1346Bob Halley if (!pReq)
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews return VERR_NO_TMP_MEMORY;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
118394ef2ec7cef253c55359a3d70d202ddc2fa0Mark Andrews pReq->Hdr.cbReq = cb;
bb556a9bf3a15c7160fa4f1b71773ce12b1bedf6Bob Halley pReq->enmAccount = enmAccount;
64e41159a919b0711321fe688ca5da4f4d1b7d80Bob Halley pReq->cPages = cPages;
1471a520e59ac12b413afa8d8b3158a87af97aa6Bob Halley NOREF(pVM);
1471a520e59ac12b413afa8d8b3158a87af97aa6Bob Halley *ppReq = pReq;
1471a520e59ac12b413afa8d8b3158a87af97aa6Bob Halley return VINF_SUCCESS;
fe37278859bce157001cca14cdfa3a761b0d5012Mark Andrews}
1471a520e59ac12b413afa8d8b3158a87af97aa6Bob Halley
494576ce20cfd98d74955698cf8f7b37dce2f740Mark Andrews
798c83548f89091e3994ca5a9c8c7e9caaf89d10Mark Andrews/**
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews * Re-prepares a GMMR0FreePages request.
289ae548d52bc8f982d9823af64cafda7bd92232Mark Andrews *
* @returns VINF_SUCCESS or VERR_NO_TMP_MEMORY.
* @param pVM Pointer to the shared VM structure.
* @param pReq A request buffer previously returned by
* GMMR3FreePagesPrepare().
* @param cPages The number of pages originally passed to
* GMMR3FreePagesPrepare().
* @param enmAccount The account to charge.
*/
GMMR3DECL(void) GMMR3FreePagesRePrep(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t cPages, GMMACCOUNT enmAccount)
{
Assert(pReq->Hdr.u32Magic == SUPVMMR0REQHDR_MAGIC);
pReq->Hdr.cbReq = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[cPages]);
pReq->enmAccount = enmAccount;
pReq->cPages = cPages;
NOREF(pVM);
}
/**
* Performs a GMMR0FreePages request.
* This will call VMSetError on failure.
*
* @returns VBox status code.
* @param pVM Pointer to the shared VM structure.
* @param pReq Pointer to the request (returned by GMMR3FreePagesPrepare).
* @param cActualPages The number of pages actually freed.
*/
GMMR3DECL(int) GMMR3FreePagesPerform(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t cActualPages)
{
/*
* Adjust the request if we ended up with fewer pages than anticipated.
*/
if (cActualPages != pReq->cPages)
{
AssertReturn(cActualPages < pReq->cPages, VERR_INTERNAL_ERROR);
if (!cActualPages)
return VINF_SUCCESS;
pReq->cPages = cActualPages;
pReq->Hdr.cbReq = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[cActualPages]);
}
/*
* Do the job.
*/
int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_FREE_PAGES, 0, &pReq->Hdr);
if (RT_SUCCESS(rc))
return rc;
AssertRC(rc);
return VMSetError(pVM, rc, RT_SRC_POS,
N_("GMMR0FreePages failed to free %u pages"),
pReq->cPages);
}
/**
* Cleans up a GMMR0FreePages request.
* @param pReq Pointer to the request (returned by GMMR3FreePagesPrepare).
*/
GMMR3DECL(void) GMMR3FreePagesCleanup(PGMMFREEPAGESREQ pReq)
{
RTMemTmpFree(pReq);
}
/**
* Frees allocated pages, for bailing out on failure.
*
* This will not call VMSetError on failure but will use AssertLogRel instead.
*
* @param pVM Pointer to the shared VM structure.
* @param pAllocReq The allocation request to undo.
*/
GMMR3DECL(void) GMMR3FreeAllocatedPages(PVM pVM, GMMALLOCATEPAGESREQ const *pAllocReq)
{
uint32_t cb = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[pAllocReq->cPages]);
PGMMFREEPAGESREQ pReq = (PGMMFREEPAGESREQ)RTMemTmpAllocZ(cb);
AssertLogRelReturnVoid(pReq);
pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
pReq->Hdr.cbReq = cb;
pReq->enmAccount = pAllocReq->enmAccount;
pReq->cPages = pAllocReq->cPages;
uint32_t iPage = pAllocReq->cPages;
while (iPage-- > 0)
{
Assert(pAllocReq->aPages[iPage].idPage != NIL_GMM_PAGEID);
pReq->aPages[iPage].idPage = pAllocReq->aPages[iPage].idPage;
}
int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_FREE_PAGES, 0, &pReq->Hdr);
AssertLogRelRC(rc);
RTMemTmpFree(pReq);
}
#if 0 /* impractical */
GMMR3DECL(int) GMMR3BalloonedPages(PVM pVM, uint32_t cBalloonedPages, uint32_t cPagesToFree, PGMMFREEPAGEDESC paPages, bool fCompleted)
{
GMMBALLOONEDPAGESREQ Req;
Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
Req.Hdr.cbReq = sizeof(Req);
return VMMR3CallR0(pVM, VMMR0_DO_GMM_BALLOONED_PAGES, 0, &Req.Hdr);
}
#endif
/**
* @see GMMR0DeflatedBalloon
*/
GMMR3DECL(int) GMMR3DeflatedBalloon(PVM pVM, uint32_t cPages)
{
return VMMR3CallR0(pVM, VMMR0_DO_GMM_DEFLATED_BALLOON, cPages, NULL);
}
/**
* @see GMMR0MapUnmapChunk
*/
GMMR3DECL(int) GMMR3MapUnmapChunk(PVM pVM, uint32_t idChunkMap, uint32_t idChunkUnmap, PRTR3PTR ppvR3)
{
GMMMAPUNMAPCHUNKREQ Req;
Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
Req.Hdr.cbReq = sizeof(Req);
Req.idChunkMap = idChunkMap;
Req.idChunkUnmap = idChunkUnmap;
Req.pvR3 = NULL;
int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_MAP_UNMAP_CHUNK, 0, &Req.Hdr);
if (RT_SUCCESS(rc) && ppvR3)
*ppvR3 = Req.pvR3;
return rc;
}
/**
* @see GMMR0FreeLargePage
*/
GMMR3DECL(int) GMMR3FreeLargePage(PVM pVM, uint32_t idPage)
{
GMMFREELARGEPAGEREQ Req;
Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
Req.Hdr.cbReq = sizeof(Req);
Req.idPage = idPage;
return VMMR3CallR0(pVM, VMMR0_DO_GMM_FREE_LARGE_PAGE, 0, &Req.Hdr);
}
/**
* @see GMMR0SeedChunk
*/
GMMR3DECL(int) GMMR3SeedChunk(PVM pVM, RTR3PTR pvR3)
{
return VMMR3CallR0(pVM, VMMR0_DO_GMM_SEED_CHUNK, (uintptr_t)pvR3, NULL);
}