VirtualBox

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

Last change on this file since 18004 was 17432, checked in by vboxsync, 16 years ago

PGM,GMM: Filling in missing bits and fixing some bugs.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.8 KB
Line 
1/* $Id: GMM.cpp 17432 2009-03-06 02:04:24Z 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 return rc;
113 if (rc != VERR_GMM_SEED_ME)
114 return VMSetError(pVM, rc, RT_SRC_POS,
115 N_("GMMR0AllocatePages failed to allocate %u pages"),
116 pReq->cPages);
117 Assert(i < pReq->cPages);
118
119 /*
120 * Seed another chunk.
121 */
122 void *pvChunk;
123 rc = SUPPageAlloc(GMM_CHUNK_SIZE >> PAGE_SHIFT, &pvChunk);
124 if (RT_FAILURE(rc))
125 return VMSetError(pVM, rc, RT_SRC_POS,
126 N_("Out of memory (SUPPageAlloc) seeding a %u pages allocation request"),
127 pReq->cPages);
128
129 rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_SEED_CHUNK, (uintptr_t)pvChunk, NULL);
130 if (RT_FAILURE(rc))
131 return VMSetError(pVM, rc, RT_SRC_POS, N_("GMM seeding failed"));
132 }
133}
134
135
136/**
137 * Cleans up a GMMR0AllocatePages request.
138 * @param pReq Pointer to the request (returned by GMMR3AllocatePagesPrepare).
139 */
140GMMR3DECL(void) GMMR3AllocatePagesCleanup(PGMMALLOCATEPAGESREQ pReq)
141{
142 RTMemTmpFree(pReq);
143}
144
145
146/**
147 * Prepares a GMMR0FreePages request.
148 *
149 * @returns VINF_SUCCESS or VERR_NO_TMP_MEMORY.
150 * @param pVM Pointer to the shared VM structure.
151 * @param[out] ppReq Where to store the pointer to the request packet.
152 * @param cPages The number of pages that's to be freed.
153 * @param enmAccount The account to charge.
154 */
155GMMR3DECL(int) GMMR3FreePagesPrepare(PVM pVM, PGMMFREEPAGESREQ *ppReq, uint32_t cPages, GMMACCOUNT enmAccount)
156{
157 uint32_t cb = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[cPages]);
158 PGMMFREEPAGESREQ pReq = (PGMMFREEPAGESREQ)RTMemTmpAllocZ(cb);
159 if (!pReq)
160 return VERR_NO_TMP_MEMORY;
161
162 pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
163 pReq->Hdr.cbReq = cb;
164 pReq->enmAccount = enmAccount;
165 pReq->cPages = cPages;
166 NOREF(pVM);
167 *ppReq = pReq;
168 return VINF_SUCCESS;
169}
170
171
172/**
173 * Re-prepares a GMMR0FreePages request.
174 *
175 * @returns VINF_SUCCESS or VERR_NO_TMP_MEMORY.
176 * @param pVM Pointer to the shared VM structure.
177 * @param pReq A request buffer previously returned by
178 * GMMR3FreePagesPrepare().
179 * @param cPages The number of pages originally passed to
180 * GMMR3FreePagesPrepare().
181 * @param enmAccount The account to charge.
182 */
183GMMR3DECL(void) GMMR3FreePagesRePrep(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t cPages, GMMACCOUNT enmAccount)
184{
185 Assert(pReq->Hdr.u32Magic == SUPVMMR0REQHDR_MAGIC);
186 pReq->Hdr.cbReq = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[cPages]);
187 pReq->enmAccount = enmAccount;
188 pReq->cPages = cPages;
189 NOREF(pVM);
190}
191
192
193/**
194 * Performs a GMMR0FreePages request.
195 * This will call VMSetError on failure.
196 *
197 * @returns VBox status code.
198 * @param pVM Pointer to the shared VM structure.
199 * @param pReq Pointer to the request (returned by GMMR3FreePagesPrepare).
200 * @param cActualPages The number of pages actually freed.
201 */
202GMMR3DECL(int) GMMR3FreePagesPerform(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t cActualPages)
203{
204 /*
205 * Adjust the request if we ended up with fewer pages than anticipated.
206 */
207 if (cActualPages != pReq->cPages)
208 {
209 AssertReturn(cActualPages < pReq->cPages, VERR_INTERNAL_ERROR);
210 if (!cActualPages)
211 return VINF_SUCCESS;
212 pReq->cPages = cActualPages;
213 pReq->Hdr.cbReq = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[cActualPages]);
214 }
215
216 /*
217 * Do the job.
218 */
219 int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_FREE_PAGES, 0, &pReq->Hdr);
220 if (RT_SUCCESS(rc))
221 return rc;
222 AssertRC(rc);
223 return VMSetError(pVM, rc, RT_SRC_POS,
224 N_("GMMR0FreePages failed to free %u pages"),
225 pReq->cPages);
226}
227
228
229/**
230 * Cleans up a GMMR0FreePages request.
231 * @param pReq Pointer to the request (returned by GMMR3FreePagesPrepare).
232 */
233GMMR3DECL(void) GMMR3FreePagesCleanup(PGMMFREEPAGESREQ pReq)
234{
235 RTMemTmpFree(pReq);
236}
237
238
239/**
240 * Frees allocated pages, for bailing out on failure.
241 *
242 * This will not call VMSetError on failure but will use AssertLogRel instead.
243 *
244 * @param pVM Pointer to the shared VM structure.
245 * @param pAllocReq The allocation request to undo.
246 */
247GMMR3DECL(void) GMMR3FreeAllocatedPages(PVM pVM, GMMALLOCATEPAGESREQ const *pAllocReq)
248{
249 uint32_t cb = RT_OFFSETOF(GMMFREEPAGESREQ, aPages[pAllocReq->cPages]);
250 PGMMFREEPAGESREQ pReq = (PGMMFREEPAGESREQ)RTMemTmpAllocZ(cb);
251 AssertLogRelReturnVoid(pReq);
252
253 pReq->Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
254 pReq->Hdr.cbReq = cb;
255 pReq->enmAccount = pAllocReq->enmAccount;
256 pReq->cPages = pAllocReq->cPages;
257 uint32_t iPage = pAllocReq->cPages;
258 while (iPage-- > 0)
259 {
260 Assert(pAllocReq->aPages[iPage].idPage != NIL_GMM_PAGEID);
261 pReq->aPages[iPage].idPage = pAllocReq->aPages[iPage].idPage;
262 }
263
264 int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_FREE_PAGES, 0, &pReq->Hdr);
265 AssertLogRelRC(rc);
266
267 RTMemTmpFree(pReq);
268}
269
270
271#if 0 /* impractical */
272GMMR3DECL(int) GMMR3BalloonedPages(PVM pVM, uint32_t cBalloonedPages, uint32_t cPagesToFree, PGMMFREEPAGEDESC paPages, bool fCompleted)
273{
274 GMMBALLOONEDPAGESREQ Req;
275 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
276 Req.Hdr.cbReq = sizeof(Req);
277
278 return VMMR3CallR0(pVM, VMMR0_DO_GMM_BALLOONED_PAGES, 0, &Req.Hdr);
279}
280#endif
281
282
283/**
284 * @see GMMR0DeflatedBalloon
285 */
286GMMR3DECL(int) GMMR3DeflatedBalloon(PVM pVM, uint32_t cPages)
287{
288 return VMMR3CallR0(pVM, VMMR0_DO_GMM_DEFLATED_BALLOON, cPages, NULL);
289}
290
291
292/**
293 * @see GMMR0MapUnmapChunk
294 */
295GMMR3DECL(int) GMMR3MapUnmapChunk(PVM pVM, uint32_t idChunkMap, uint32_t idChunkUnmap, PRTR3PTR ppvR3)
296{
297 GMMMAPUNMAPCHUNKREQ Req;
298 Req.Hdr.u32Magic = SUPVMMR0REQHDR_MAGIC;
299 Req.Hdr.cbReq = sizeof(Req);
300 Req.idChunkMap = idChunkMap;
301 Req.idChunkUnmap = idChunkUnmap;
302 Req.pvR3 = NULL;
303 int rc = VMMR3CallR0(pVM, VMMR0_DO_GMM_MAP_UNMAP_CHUNK, 0, &Req.Hdr);
304 if (RT_SUCCESS(rc) && ppvR3)
305 *ppvR3 = Req.pvR3;
306 return rc;
307}
308
309
310/**
311 * @see GMMR0SeedChunk
312 */
313GMMR3DECL(int) GMMR3SeedChunk(PVM pVM, RTR3PTR pvR3)
314{
315 return VMMR3CallR0(pVM, VMMR0_DO_GMM_SEED_CHUNK, (uintptr_t)pvR3, NULL);
316}
317
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