VirtualBox

source: vbox/trunk/src/VBox/VMM/GMM.cpp@ 20864

Last change on this file since 20864 was 20864, checked in by vboxsync, 15 years ago

SUP,*: API cleanup.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.1 KB
Line 
1/* $Id: GMM.cpp 20864 2009-06-23 19:19:42Z vboxsync $ */
2/** @file
3 * GMM - Global Memory Manager, ring-3 request wrappers.
4 */
5
6/*
7 * Copyright (C) 2008 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#define LOG_GROUP LOG_GROUP_GMM
27#include <VBox/gmm.h>
28#include <VBox/vmm.h>
29#include <VBox/vm.h>
30#include <VBox/sup.h>
31#include <VBox/err.h>
32#include <VBox/param.h>
33
34#include <iprt/assert.h>
35#include <VBox/log.h>
36#include <iprt/mem.h>
37
38
39/**
40 * @see GMMR0InitialReservation
41 */
42GMMR3DECL(int) GMMR3InitialReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages,
43 GMMOCPOLICY enmPolicy, GMMPRIORITY enmPriority)
44{
45 GMMINITIALRESERVATIONREQ Req;
46 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
47 Req.Hdr.cbReq = sizeof(Req);
48 Req.cBasePages = cBasePages;
49 Req.cShadowPages = cShadowPages;
50 Req.cFixedPages = cFixedPages;
51 Req.enmPolicy = enmPolicy;
52 Req.enmPriority = enmPriority;
53 return VMMR3CallR0(pVM, VMMR0_DO_GMM_INITIAL_RESERVATION, 0, &Req.Hdr);
54}
55
56
57/**
58 * @see GMMR0UpdateReservation
59 */
60GMMR3DECL(int) GMMR3UpdateReservation(PVM pVM, uint64_t cBasePages, uint32_t cShadowPages, uint32_t cFixedPages)
61{
62 GMMUPDATERESERVATIONREQ Req;
63 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
64 Req.Hdr.cbReq = sizeof(Req);
65 Req.cBasePages = cBasePages;
66 Req.cShadowPages = cShadowPages;
67 Req.cFixedPages = cFixedPages;
68 return VMMR3CallR0(pVM, VMMR0_DO_GMM_UPDATE_RESERVATION, 0, &Req.Hdr);
69}
70
71
72/**
73 * Prepares a GMMR0AllocatePages request.
74 *
75 * @returns VINF_SUCCESS or VERR_NO_TMP_MEMORY.
76 * @param pVM Pointer to the shared VM structure.
77 * @param[out] ppReq Where to store the pointer to the request packet.
78 * @param cPages The number of pages that's to be allocated.
79 * @param enmAccount The account to charge.
80 */
81GMMR3DECL(int) GMMR3AllocatePagesPrepare(PVM pVM, PGMMALLOCATEPAGESREQ *ppReq, uint32_t cPages, GMMACCOUNT enmAccount)
82{
83 uint32_t cb = RT_OFFSETOF(GMMALLOCATEPAGESREQ, aPages[cPages]);
84 PGMMALLOCATEPAGESREQ pReq = (PGMMALLOCATEPAGESREQ)RTMemTmpAllocZ(cb);
85 if (!pReq)
86 return VERR_NO_TMP_MEMORY;
87
88 pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
89 pReq->Hdr.cbReq = cb;
90 pReq->enmAccount = enmAccount;
91 pReq->cPages = cPages;
92 NOREF(pVM);
93 *ppReq = pReq;
94 return VINF_SUCCESS;
95}
96
97
98/**
99 * Performs a GMMR0AllocatePages request.
100 * This will call VMSetError on failure.
101 *
102 * @returns VBox status code.
103 * @param pVM Pointer to the shared VM structure.
104 * @param pReq Pointer to the request (returned by GMMR3AllocatePagesPrepare).
105 */
106GMMR3DECL(int) GMMR3AllocatePagesPerform(PVM pVM, PGMMALLOCATEPAGESREQ pReq)
107{
108 for (unsigned i = 0; ; i++)
109 {
110 int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_ALLOCATE_PAGES, 0, &pReq->Hdr);
111 if (RT_SUCCESS(rc))
112 {
113#ifdef LOG_ENABLED
114 for (uint32_t iPage = 0; iPage < pReq->cPages; iPage++)
115 Log3(("GMMR3AllocatePagesPerform: idPage=%#x HCPhys=%RHp\n",
116 pReq->aPages[iPage].idPage, pReq->aPages[iPage].HCPhysGCPhys));
117#endif
118 return rc;
119 }
120 if (rc != VERR_GMM_SEED_ME)
121 return VMSetError(pVM, rc, RT_SRC_POS,
122 N_("GMMR0AllocatePages failed to allocate %u pages"),
123 pReq->cPages);
124 Assert(i < pReq->cPages);
125
126 /*
127 * Seed another chunk.
128 */
129 void *pvChunk;
130 rc = SUPR3PageAlloc(GMM_CHUNK_SIZE >> PAGE_SHIFT, &pvChunk);
131 if (RT_FAILURE(rc))
132 return VMSetError(pVM, rc, RT_SRC_POS,
133 N_("Out of memory (SUPR3PageAlloc) seeding a %u pages allocation request"),
134 pReq->cPages);
135
136 rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_SEED_CHUNK, (uintptr_t)pvChunk, NULL);
137 if (RT_FAILURE(rc))
138 return VMSetError(pVM, rc, RT_SRC_POS, N_("GMM seeding failed"));
139 }
140}
141
142
143/**
144 * Cleans up a GMMR0AllocatePages request.
145 * @param pReq Pointer to the request (returned by GMMR3AllocatePagesPrepare).
146 */
147GMMR3DECL(void) GMMR3AllocatePagesCleanup(PGMMALLOCATEPAGESREQ pReq)
148{
149 RTMemTmpFree(pReq);
150}
151
152
153/**
154 * Prepares a GMMR0FreePages request.
155 *
156 * @returns VINF_SUCCESS or VERR_NO_TMP_MEMORY.
157 * @param pVM Pointer to the shared VM structure.
158 * @param[out] ppReq Where to store the pointer to the request packet.
159 * @param cPages The number of pages that's to be freed.
160 * @param enmAccount The account to charge.
161 */
162GMMR3DECL(int) GMMR3FreePagesPrepare(PVM pVM, PGMMFREEPAGESREQ *ppReq, uint32_t cPages, GMMACCOUNT enmAccount)
163{
164 uint32_t cb = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[cPages]);
165 PGMMFREEPAGESREQ pReq = (PGMMFREEPAGESREQ)RTMemTmpAllocZ(cb);
166 if (!pReq)
167 return VERR_NO_TMP_MEMORY;
168
169 pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
170 pReq->Hdr.cbReq = cb;
171 pReq->enmAccount = enmAccount;
172 pReq->cPages = cPages;
173 NOREF(pVM);
174 *ppReq = pReq;
175 return VINF_SUCCESS;
176}
177
178
179/**
180 * Re-prepares a GMMR0FreePages request.
181 *
182 * @returns VINF_SUCCESS or VERR_NO_TMP_MEMORY.
183 * @param pVM Pointer to the shared VM structure.
184 * @param pReq A request buffer previously returned by
185 * GMMR3FreePagesPrepare().
186 * @param cPages The number of pages originally passed to
187 * GMMR3FreePagesPrepare().
188 * @param enmAccount The account to charge.
189 */
190GMMR3DECL(void) GMMR3FreePagesRePrep(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t cPages, GMMACCOUNT enmAccount)
191{
192 Assert(pReq->Hdr.u32Magic == SUPVMMR0REQHDR_MAGIC);
193 pReq->Hdr.cbReq = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[cPages]);
194 pReq->enmAccount = enmAccount;
195 pReq->cPages = cPages;
196 NOREF(pVM);
197}
198
199
200/**
201 * Performs a GMMR0FreePages request.
202 * This will call VMSetError on failure.
203 *
204 * @returns VBox status code.
205 * @param pVM Pointer to the shared VM structure.
206 * @param pReq Pointer to the request (returned by GMMR3FreePagesPrepare).
207 * @param cActualPages The number of pages actually freed.
208 */
209GMMR3DECL(int) GMMR3FreePagesPerform(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t cActualPages)
210{
211 /*
212 * Adjust the request if we ended up with fewer pages than anticipated.
213 */
214 if (cActualPages != pReq->cPages)
215 {
216 AssertReturn(cActualPages < pReq->cPages, VERR_INTERNAL_ERROR);
217 if (!cActualPages)
218 return VINF_SUCCESS;
219 pReq->cPages = cActualPages;
220 pReq->Hdr.cbReq = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[cActualPages]);
221 }
222
223 /*
224 * Do the job.
225 */
226 int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_FREE_PAGES, 0, &pReq->Hdr);
227 if (RT_SUCCESS(rc))
228 return rc;
229 AssertRC(rc);
230 return VMSetError(pVM, rc, RT_SRC_POS,
231 N_("GMMR0FreePages failed to free %u pages"),
232 pReq->cPages);
233}
234
235
236/**
237 * Cleans up a GMMR0FreePages request.
238 * @param pReq Pointer to the request (returned by GMMR3FreePagesPrepare).
239 */
240GMMR3DECL(void) GMMR3FreePagesCleanup(PGMMFREEPAGESREQ pReq)
241{
242 RTMemTmpFree(pReq);
243}
244
245
246/**
247 * Frees allocated pages, for bailing out on failure.
248 *
249 * This will not call VMSetError on failure but will use AssertLogRel instead.
250 *
251 * @param pVM Pointer to the shared VM structure.
252 * @param pAllocReq The allocation request to undo.
253 */
254GMMR3DECL(void) GMMR3FreeAllocatedPages(PVM pVM, GMMALLOCATEPAGESREQ const *pAllocReq)
255{
256 uint32_t cb = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[pAllocReq->cPages]);
257 PGMMFREEPAGESREQ pReq = (PGMMFREEPAGESREQ)RTMemTmpAllocZ(cb);
258 AssertLogRelReturnVoid(pReq);
259
260 pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
261 pReq->Hdr.cbReq = cb;
262 pReq->enmAccount = pAllocReq->enmAccount;
263 pReq->cPages = pAllocReq->cPages;
264 uint32_t iPage = pAllocReq->cPages;
265 while (iPage-- > 0)
266 {
267 Assert(pAllocReq->aPages[iPage].idPage != NIL_GMM_PAGEID);
268 pReq->aPages[iPage].idPage = pAllocReq->aPages[iPage].idPage;
269 }
270
271 int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_FREE_PAGES, 0, &pReq->Hdr);
272 AssertLogRelRC(rc);
273
274 RTMemTmpFree(pReq);
275}
276
277
278#if 0 /* impractical */
279GMMR3DECL(int) GMMR3BalloonedPages(PVM pVM, uint32_t cBalloonedPages, uint32_t cPagesToFree, PGMMFREEPAGEDESC paPages, bool fCompleted)
280{
281 GMMBALLOONEDPAGESREQ Req;
282 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
283 Req.Hdr.cbReq = sizeof(Req);
284
285 return VMMR3CallR0(pVM, VMMR0_DO_GMM_BALLOONED_PAGES, 0, &Req.Hdr);
286}
287#endif
288
289
290/**
291 * @see GMMR0DeflatedBalloon
292 */
293GMMR3DECL(int) GMMR3DeflatedBalloon(PVM pVM, uint32_t cPages)
294{
295 return VMMR3CallR0(pVM, VMMR0_DO_GMM_DEFLATED_BALLOON, cPages, NULL);
296}
297
298
299/**
300 * @see GMMR0MapUnmapChunk
301 */
302GMMR3DECL(int) GMMR3MapUnmapChunk(PVM pVM, uint32_t idChunkMap, uint32_t idChunkUnmap, PRTR3PTR ppvR3)
303{
304 GMMMAPUNMAPCHUNKREQ Req;
305 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
306 Req.Hdr.cbReq = sizeof(Req);
307 Req.idChunkMap = idChunkMap;
308 Req.idChunkUnmap = idChunkUnmap;
309 Req.pvR3 = NULL;
310 int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_MAP_UNMAP_CHUNK, 0, &Req.Hdr);
311 if (RT_SUCCESS(rc) && ppvR3)
312 *ppvR3 = Req.pvR3;
313 return rc;
314}
315
316
317/**
318 * @see GMMR0SeedChunk
319 */
320GMMR3DECL(int) GMMR3SeedChunk(PVM pVM, RTR3PTR pvR3)
321{
322 return VMMR3CallR0(pVM, VMMR0_DO_GMM_SEED_CHUNK, (uintptr_t)pvR3, NULL);
323}
324
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette