VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/MMHyper.cpp@ 93661

Last change on this file since 93661 was 93620, checked in by vboxsync, 3 years ago

VMM/MMHyper: Removed unused code. bugref:10093

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 23.2 KB
Line 
1/* $Id: MMHyper.cpp 93620 2022-02-06 09:43:00Z vboxsync $ */
2/** @file
3 * MM - Memory Manager - Hypervisor Memory Area.
4 */
5
6/*
7 * Copyright (C) 2006-2022 Oracle Corporation
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
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_MM_HYPER
23#include <VBox/vmm/pgm.h>
24#include <VBox/vmm/mm.h>
25#include <VBox/vmm/hm.h>
26#include <VBox/vmm/dbgf.h>
27#include "MMInternal.h"
28#include <VBox/vmm/vm.h>
29#include <VBox/vmm/gvm.h>
30#include <VBox/err.h>
31#include <VBox/param.h>
32#include <VBox/log.h>
33#include <iprt/alloc.h>
34#include <iprt/assert.h>
35#include <iprt/string.h>
36
37
38/*********************************************************************************************************************************
39* Internal Functions *
40*********************************************************************************************************************************/
41static int mmR3HyperMap(PVM pVM, const size_t cb, const char *pszDesc, PRTGCPTR pGCPtr, PMMLOOKUPHYPER *ppLookup);
42static int mmR3HyperHeapCreate(PVM pVM, const size_t cb, PMMHYPERHEAP *ppHeap, PRTR0PTR pR0PtrHeap);
43static int mmR3HyperHeapMap(PVM pVM, PMMHYPERHEAP pHeap, PRTGCPTR ppHeapGC);
44static DECLCALLBACK(void) mmR3HyperInfoHma(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
45static int MMR3HyperMapPages(PVM pVM, void *pvR3, RTR0PTR pvR0, size_t cHostPages, PCSUPPAGE paPages,
46 const char *pszDesc, PRTGCPTR pGCPtr);
47
48
49/**
50 * Determin the default heap size.
51 *
52 * @returns The heap size in bytes.
53 * @param pVM The cross context VM structure.
54 */
55static uint32_t mmR3HyperComputeHeapSize(PVM pVM)
56{
57 /** @todo Redo after moving allocations off the hyper heap. */
58
59 /*
60 * Gather parameters.
61 */
62 bool fCanUseLargerHeap = true;
63 //bool fCanUseLargerHeap;
64 //int rc = CFGMR3QueryBoolDef(CFGMR3GetChild(CFGMR3GetRoot(pVM), "MM"), "CanUseLargerHeap", &fCanUseLargerHeap, false);
65 //AssertStmt(RT_SUCCESS(rc), fCanUseLargerHeap = false);
66
67 uint64_t cbRam;
68 int rc = CFGMR3QueryU64(CFGMR3GetRoot(pVM), "RamSize", &cbRam);
69 AssertStmt(RT_SUCCESS(rc), cbRam = _1G);
70
71 /*
72 * We need to keep saved state compatibility if raw-mode is an option,
73 * so lets filter out that case first.
74 */
75 if ( !fCanUseLargerHeap
76 && VM_IS_RAW_MODE_ENABLED(pVM)
77 && cbRam < 16*_1G64)
78 return 1280 * _1K;
79
80 /*
81 * Calculate the heap size.
82 */
83 uint32_t cbHeap = _1M;
84
85 /* The newer chipset may have more devices attached, putting additional
86 pressure on the heap. */
87 if (fCanUseLargerHeap)
88 cbHeap += _1M;
89
90 /* More CPUs means some extra memory usage. */
91 if (pVM->cCpus > 1)
92 cbHeap += pVM->cCpus * _64K;
93
94 /* Lots of memory means extra memory consumption as well (pool). */
95 if (cbRam > 16*_1G64)
96 cbHeap += _2M; /** @todo figure out extactly how much */
97
98 return RT_ALIGN(cbHeap, _256K);
99}
100
101
102/**
103 * Initializes the hypervisor related MM stuff without
104 * calling down to PGM.
105 *
106 * PGM is not initialized at this point, PGM relies on
107 * the heap to initialize.
108 *
109 * @returns VBox status code.
110 */
111int mmR3HyperInit(PVM pVM)
112{
113 LogFlow(("mmR3HyperInit:\n"));
114
115 /*
116 * Decide Hypervisor mapping in the guest context
117 * And setup various hypervisor area and heap parameters.
118 */
119 pVM->mm.s.pvHyperAreaGC = (RTGCPTR)MM_HYPER_AREA_ADDRESS;
120 pVM->mm.s.cbHyperArea = MM_HYPER_AREA_MAX_SIZE;
121 AssertRelease(RT_ALIGN_T(pVM->mm.s.pvHyperAreaGC, 1 << X86_PD_SHIFT, RTGCPTR) == pVM->mm.s.pvHyperAreaGC);
122 Assert(pVM->mm.s.pvHyperAreaGC < 0xff000000);
123
124 /** @todo @bugref{1865}, @bugref{3202}: Change the cbHyperHeap default
125 * depending on whether VT-x/AMD-V is enabled or not! Don't waste
126 * precious kernel space on heap for the PATM.
127 */
128 PCFGMNODE pMM = CFGMR3GetChild(CFGMR3GetRoot(pVM), "MM");
129 uint32_t cbHyperHeap;
130 int rc = CFGMR3QueryU32Def(pMM, "cbHyperHeap", &cbHyperHeap, mmR3HyperComputeHeapSize(pVM));
131 AssertLogRelRCReturn(rc, rc);
132
133 cbHyperHeap = RT_ALIGN_32(cbHyperHeap, GUEST_PAGE_SIZE);
134 LogRel(("MM: cbHyperHeap=%#x (%u)\n", cbHyperHeap, cbHyperHeap));
135
136 /*
137 * Allocate the hypervisor heap.
138 *
139 * (This must be done before we start adding memory to the
140 * hypervisor static area because lookup records are allocated from it.)
141 */
142 rc = mmR3HyperHeapCreate(pVM, cbHyperHeap, &pVM->mm.s.pHyperHeapR3, &pVM->mm.s.pHyperHeapR0);
143 if (RT_SUCCESS(rc))
144 {
145 /*
146 * Map the VM structure into the hypervisor space.
147 * Note! Keeping the mappings here for now in case someone is using
148 * MMHyperR3ToR0 or similar.
149 */
150 AssertCompileSizeAlignment(VM, HOST_PAGE_SIZE);
151 AssertCompileSizeAlignment(VMCPU, HOST_PAGE_SIZE);
152 AssertCompileSizeAlignment(GVM, HOST_PAGE_SIZE);
153 AssertCompileSizeAlignment(GVMCPU, HOST_PAGE_SIZE);
154 AssertRelease(pVM->cbSelf == sizeof(VM));
155 AssertRelease(pVM->cbVCpu == sizeof(VMCPU));
156/** @todo get rid of this (don't dare right now because of
157 * possible MMHyperYYToXX use on the VM structure.) */
158 RTGCPTR GCPtr;
159 if (SUPR3IsDriverless())
160 GCPtr = _1G;
161 else
162 {
163 Assert(GUEST_PAGE_SHIFT == HOST_PAGE_SHIFT);
164 rc = MMR3HyperMapPages(pVM, pVM, pVM->pVMR0ForCall, sizeof(VM) >> HOST_PAGE_SHIFT, pVM->paVMPagesR3, "VM", &GCPtr);
165 uint32_t offPages = RT_UOFFSETOF_DYN(GVM, aCpus) >> HOST_PAGE_SHIFT; /* (Using the _DYN variant avoids -Winvalid-offset) */
166 for (uint32_t idCpu = 0; idCpu < pVM->cCpus && RT_SUCCESS(rc); idCpu++, offPages += sizeof(GVMCPU) >> HOST_PAGE_SHIFT)
167 {
168 PVMCPU pVCpu = pVM->apCpusR3[idCpu];
169 RTGCPTR GCPtrIgn;
170 rc = MMR3HyperMapPages(pVM, pVCpu, pVM->pVMR0ForCall + offPages * HOST_PAGE_SIZE,
171 sizeof(VMCPU) >> HOST_PAGE_SHIFT, &pVM->paVMPagesR3[offPages], "VMCPU", &GCPtrIgn);
172 }
173 }
174 if (RT_SUCCESS(rc))
175 {
176 pVM->pVMRC = (RTRCPTR)GCPtr;
177 for (VMCPUID i = 0; i < pVM->cCpus; i++)
178 pVM->apCpusR3[i]->pVMRC = pVM->pVMRC;
179
180 /*
181 * Map the heap into the hypervisor space.
182 */
183 rc = mmR3HyperHeapMap(pVM, pVM->mm.s.pHyperHeapR3, &GCPtr);
184 if (RT_SUCCESS(rc))
185 {
186 pVM->mm.s.pHyperHeapRC = (RTRCPTR)GCPtr;
187 Assert(pVM->mm.s.pHyperHeapRC == GCPtr);
188
189 /*
190 * Register info handlers.
191 */
192 DBGFR3InfoRegisterInternal(pVM, "hma", "Show the layout of the Hypervisor Memory Area.", mmR3HyperInfoHma);
193
194 LogFlow(("mmR3HyperInit: returns VINF_SUCCESS\n"));
195 return VINF_SUCCESS;
196 }
197 /* Caller will do proper cleanup. */
198 }
199 }
200
201 LogFlow(("mmR3HyperInit: returns %Rrc\n", rc));
202 return rc;
203}
204
205
206/**
207 * Cleans up the hypervisor heap.
208 *
209 * @returns VBox status code.
210 */
211int mmR3HyperTerm(PVM pVM)
212{
213 if (pVM->mm.s.pHyperHeapR3)
214 PDMR3CritSectDelete(pVM, &pVM->mm.s.pHyperHeapR3->Lock);
215
216 return VINF_SUCCESS;
217}
218
219
220/**
221 * Finalizes the HMA mapping (obsolete).
222 *
223 * This is called later during init, most (all) HMA allocations should be done
224 * by the time this function is called.
225 *
226 * @returns VBox status code.
227 */
228VMMR3DECL(int) MMR3HyperInitFinalize(PVM pVM)
229{
230 LogFlow(("MMR3HyperInitFinalize:\n"));
231
232 /*
233 * Initialize the hyper heap critical section.
234 */
235 int rc = PDMR3CritSectInit(pVM, &pVM->mm.s.pHyperHeapR3->Lock, RT_SRC_POS, "MM-HYPER");
236 AssertRC(rc);
237
238 pVM->mm.s.fPGMInitialized = true;
239
240 LogFlow(("MMR3HyperInitFinalize: returns VINF_SUCCESS\n"));
241 return VINF_SUCCESS;
242}
243
244
245/**
246 * Maps locked R3 virtual memory into the hypervisor region in the GC.
247 *
248 * @return VBox status code.
249 *
250 * @param pVM The cross context VM structure.
251 * @param pvR3 The ring-3 address of the memory, must be page aligned.
252 * @param pvR0 The ring-0 address of the memory, must be page aligned. (optional)
253 * @param cHostPages The number of host pages.
254 * @param paPages The page descriptors.
255 * @param pszDesc Mapping description.
256 * @param pGCPtr Where to store the GC address corresponding to pvR3.
257 */
258static int MMR3HyperMapPages(PVM pVM, void *pvR3, RTR0PTR pvR0, size_t cHostPages, PCSUPPAGE paPages,
259 const char *pszDesc, PRTGCPTR pGCPtr)
260{
261 LogFlow(("MMR3HyperMapPages: pvR3=%p pvR0=%p cHostPages=%zu paPages=%p pszDesc=%p:{%s} pGCPtr=%p\n",
262 pvR3, pvR0, cHostPages, paPages, pszDesc, pszDesc, pGCPtr));
263
264 /*
265 * Validate input.
266 */
267 AssertPtrReturn(pvR3, VERR_INVALID_POINTER);
268 AssertPtrReturn(paPages, VERR_INVALID_POINTER);
269 AssertReturn(cHostPages > 0, VERR_PAGE_COUNT_OUT_OF_RANGE);
270 AssertReturn(cHostPages <= VBOX_MAX_ALLOC_PAGE_COUNT, VERR_PAGE_COUNT_OUT_OF_RANGE);
271 AssertPtrReturn(pszDesc, VERR_INVALID_POINTER);
272 AssertReturn(*pszDesc, VERR_INVALID_PARAMETER);
273 AssertPtrReturn(pGCPtr, VERR_INVALID_PARAMETER);
274 AssertReturn(GUEST_PAGE_SIZE == HOST_PAGE_SIZE, VERR_NOT_SUPPORTED);
275
276 /*
277 * Add the memory to the hypervisor area.
278 */
279 RTGCPTR GCPtr;
280 PMMLOOKUPHYPER pLookup;
281 int rc = mmR3HyperMap(pVM, cHostPages << HOST_PAGE_SHIFT, pszDesc, &GCPtr, &pLookup);
282 if (RT_SUCCESS(rc))
283 {
284 /*
285 * Copy the physical page addresses and tell PGM about them.
286 */
287 PRTHCPHYS paHCPhysPages = (PRTHCPHYS)MMR3HeapAlloc(pVM, MM_TAG_MM, sizeof(RTHCPHYS) * cHostPages);
288 if (paHCPhysPages)
289 {
290 bool const fDriverless = SUPR3IsDriverless();
291 for (size_t i = 0; i < cHostPages; i++)
292 {
293 AssertReleaseMsgReturn( ( paPages[i].Phys != 0
294 && paPages[i].Phys != NIL_RTHCPHYS
295 && !(paPages[i].Phys & HOST_PAGE_OFFSET_MASK))
296 || fDriverless,
297 ("i=%#zx Phys=%RHp %s\n", i, paPages[i].Phys, pszDesc),
298 VERR_INTERNAL_ERROR);
299 paHCPhysPages[i] = paPages[i].Phys;
300 }
301
302 pLookup->enmType = MMLOOKUPHYPERTYPE_LOCKED;
303 pLookup->u.Locked.pvR3 = pvR3;
304 pLookup->u.Locked.pvR0 = pvR0;
305 pLookup->u.Locked.paHCPhysPages = paHCPhysPages;
306
307 /* done. */
308 *pGCPtr = GCPtr;
309 return rc;
310 }
311 /* Don't care about failure clean, we're screwed if this fails anyway. */
312 }
313
314 return rc;
315}
316
317
318/**
319 * Adds memory to the hypervisor memory arena.
320 *
321 * @return VBox status code.
322 * @param pVM The cross context VM structure.
323 * @param cb Size of the memory. Will be rounded up to nearest page.
324 * @param pszDesc The description of the memory.
325 * @param pGCPtr Where to store the GC address.
326 * @param ppLookup Where to store the pointer to the lookup record.
327 * @remark We assume the threading structure of VBox imposes natural
328 * serialization of most functions, this one included.
329 */
330static int mmR3HyperMap(PVM pVM, const size_t cb, const char *pszDesc, PRTGCPTR pGCPtr, PMMLOOKUPHYPER *ppLookup)
331{
332 /*
333 * Validate input.
334 */
335 const uint32_t cbAligned = RT_ALIGN_32(cb, GUEST_PAGE_SIZE);
336 AssertReturn(cbAligned >= cb, VERR_INVALID_PARAMETER);
337 if (pVM->mm.s.offHyperNextStatic + cbAligned >= pVM->mm.s.cbHyperArea) /* don't use the last page, it's a fence. */
338 {
339 AssertMsgFailed(("Out of static mapping space in the HMA! offHyperAreaGC=%x cbAligned=%x cbHyperArea=%x\n",
340 pVM->mm.s.offHyperNextStatic, cbAligned, pVM->mm.s.cbHyperArea));
341 return VERR_NO_MEMORY;
342 }
343
344 /*
345 * Allocate lookup record.
346 */
347 PMMLOOKUPHYPER pLookup;
348 int rc = MMHyperAlloc(pVM, sizeof(*pLookup), 1, MM_TAG_MM, (void **)&pLookup);
349 if (RT_SUCCESS(rc))
350 {
351 /*
352 * Initialize it and insert it.
353 */
354 pLookup->offNext = pVM->mm.s.offLookupHyper;
355 pLookup->cb = cbAligned;
356 pLookup->off = pVM->mm.s.offHyperNextStatic;
357 pVM->mm.s.offLookupHyper = (uint8_t *)pLookup - (uint8_t *)pVM->mm.s.pHyperHeapR3;
358 if (pLookup->offNext != (int32_t)NIL_OFFSET)
359 pLookup->offNext -= pVM->mm.s.offLookupHyper;
360 pLookup->enmType = MMLOOKUPHYPERTYPE_INVALID;
361 memset(&pLookup->u, 0xff, sizeof(pLookup->u));
362 pLookup->pszDesc = pszDesc;
363
364 /* Mapping. */
365 *pGCPtr = pVM->mm.s.pvHyperAreaGC + pVM->mm.s.offHyperNextStatic;
366 pVM->mm.s.offHyperNextStatic += cbAligned;
367
368 /* Return pointer. */
369 *ppLookup = pLookup;
370 }
371
372 AssertRC(rc);
373 LogFlow(("mmR3HyperMap: returns %Rrc *pGCPtr=%RGv\n", rc, *pGCPtr));
374 return rc;
375}
376
377
378/**
379 * Allocates a new heap.
380 *
381 * @returns VBox status code.
382 * @param pVM The cross context VM structure.
383 * @param cb The size of the new heap.
384 * @param ppHeap Where to store the heap pointer on successful return.
385 * @param pR0PtrHeap Where to store the ring-0 address of the heap on
386 * success.
387 */
388static int mmR3HyperHeapCreate(PVM pVM, const size_t cb, PMMHYPERHEAP *ppHeap, PRTR0PTR pR0PtrHeap)
389{
390 /*
391 * Allocate the hypervisor heap.
392 */
393 const uint32_t cbAligned = RT_ALIGN_32(cb, RT_MAX(GUEST_PAGE_SIZE, HOST_PAGE_SIZE));
394 AssertReturn(cbAligned >= cb, VERR_INVALID_PARAMETER);
395 uint32_t const cHostPages = cbAligned >> HOST_PAGE_SHIFT;
396 PSUPPAGE paPages = (PSUPPAGE)MMR3HeapAlloc(pVM, MM_TAG_MM, cHostPages * sizeof(paPages[0]));
397 if (!paPages)
398 return VERR_NO_MEMORY;
399 void *pv;
400 RTR0PTR pvR0 = NIL_RTR0PTR;
401 int rc = SUPR3PageAllocEx(cHostPages,
402 0 /*fFlags*/,
403 &pv,
404 &pvR0,
405 paPages);
406 if (RT_SUCCESS(rc))
407 {
408 Assert((pvR0 != NIL_RTR0PTR && !(HOST_PAGE_OFFSET_MASK & pvR0)) || SUPR3IsDriverless());
409 memset(pv, 0, cbAligned);
410
411 /*
412 * Initialize the heap and first free chunk.
413 */
414 PMMHYPERHEAP pHeap = (PMMHYPERHEAP)pv;
415 pHeap->u32Magic = MMHYPERHEAP_MAGIC;
416 pHeap->pbHeapR3 = (uint8_t *)pHeap + MMYPERHEAP_HDR_SIZE;
417 pHeap->pbHeapR0 = pvR0 + MMYPERHEAP_HDR_SIZE;
418 //pHeap->pbHeapRC = 0; // set by mmR3HyperHeapMap()
419 pHeap->pVMR3 = pVM;
420 pHeap->pVMR0 = pVM->pVMR0ForCall;
421 pHeap->pVMRC = pVM->pVMRC;
422 pHeap->cbHeap = cbAligned - MMYPERHEAP_HDR_SIZE;
423 pHeap->cbFree = pHeap->cbHeap - sizeof(MMHYPERCHUNK);
424 //pHeap->offFreeHead = 0;
425 //pHeap->offFreeTail = 0;
426 pHeap->offPageAligned = pHeap->cbHeap;
427 //pHeap->HyperHeapStatTree = 0;
428 pHeap->paPages = paPages;
429
430 PMMHYPERCHUNKFREE pFree = (PMMHYPERCHUNKFREE)pHeap->pbHeapR3;
431 pFree->cb = pHeap->cbFree;
432 //pFree->core.offNext = 0;
433 MMHYPERCHUNK_SET_TYPE(&pFree->core, MMHYPERCHUNK_FLAGS_FREE);
434 pFree->core.offHeap = -(int32_t)MMYPERHEAP_HDR_SIZE;
435 //pFree->offNext = 0;
436 //pFree->offPrev = 0;
437
438 STAMR3Register(pVM, &pHeap->cbHeap, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, "/MM/HyperHeap/cbHeap", STAMUNIT_BYTES, "The heap size.");
439 STAMR3Register(pVM, &pHeap->cbFree, STAMTYPE_U32, STAMVISIBILITY_ALWAYS, "/MM/HyperHeap/cbFree", STAMUNIT_BYTES, "The free space.");
440
441 *ppHeap = pHeap;
442 *pR0PtrHeap = pvR0;
443 return VINF_SUCCESS;
444 }
445 AssertMsgFailed(("SUPR3PageAllocEx(%d,,,,) -> %Rrc\n", cbAligned >> HOST_PAGE_SHIFT, rc));
446
447 *ppHeap = NULL;
448 return rc;
449}
450
451
452/**
453 * Allocates a new heap.
454 */
455static int mmR3HyperHeapMap(PVM pVM, PMMHYPERHEAP pHeap, PRTGCPTR ppHeapGC)
456{
457 Assert(RT_ALIGN_Z(pHeap->cbHeap + MMYPERHEAP_HDR_SIZE, GUEST_PAGE_SIZE) == pHeap->cbHeap + MMYPERHEAP_HDR_SIZE);
458 Assert(RT_ALIGN_Z(pHeap->cbHeap + MMYPERHEAP_HDR_SIZE, HOST_PAGE_SIZE) == pHeap->cbHeap + MMYPERHEAP_HDR_SIZE);
459 Assert(pHeap->pbHeapR0);
460 Assert(pHeap->paPages);
461 int rc = MMR3HyperMapPages(pVM,
462 pHeap,
463 pHeap->pbHeapR0 - MMYPERHEAP_HDR_SIZE,
464 (pHeap->cbHeap + MMYPERHEAP_HDR_SIZE) >> HOST_PAGE_SHIFT,
465 pHeap->paPages,
466 "Heap", ppHeapGC);
467 if (RT_SUCCESS(rc))
468 {
469 pHeap->pVMRC = pVM->pVMRC;
470 pHeap->pbHeapRC = *ppHeapGC + MMYPERHEAP_HDR_SIZE;
471
472 /* We won't need these any more. */
473 MMR3HeapFree(pHeap->paPages);
474 pHeap->paPages = NULL;
475 }
476 return rc;
477}
478
479
480/**
481 * Info handler for 'hma', it dumps the list of lookup records for the hypervisor memory area.
482 *
483 * @param pVM The cross context VM structure.
484 * @param pHlp Callback functions for doing output.
485 * @param pszArgs Argument string. Optional and specific to the handler.
486 */
487static DECLCALLBACK(void) mmR3HyperInfoHma(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
488{
489 NOREF(pszArgs);
490
491 pHlp->pfnPrintf(pHlp, "Hypervisor Memory Area (HMA) Layout: Base %RGv, 0x%08x bytes\n",
492 pVM->mm.s.pvHyperAreaGC, pVM->mm.s.cbHyperArea);
493
494 PMMLOOKUPHYPER pLookup = (PMMLOOKUPHYPER)((uint8_t *)pVM->mm.s.pHyperHeapR3 + pVM->mm.s.offLookupHyper);
495 for (;;)
496 {
497 switch (pLookup->enmType)
498 {
499 case MMLOOKUPHYPERTYPE_LOCKED:
500 pHlp->pfnPrintf(pHlp, "%RGv-%RGv %RHv %RHv LOCKED %-*s %s\n",
501 pLookup->off + pVM->mm.s.pvHyperAreaGC,
502 pLookup->off + pVM->mm.s.pvHyperAreaGC + pLookup->cb,
503 pLookup->u.Locked.pvR3,
504 pLookup->u.Locked.pvR0,
505 sizeof(RTHCPTR) * 2, "",
506 pLookup->pszDesc);
507 break;
508
509 case MMLOOKUPHYPERTYPE_HCPHYS:
510 pHlp->pfnPrintf(pHlp, "%RGv-%RGv %RHv %RHv HCPHYS %RHp %s\n",
511 pLookup->off + pVM->mm.s.pvHyperAreaGC,
512 pLookup->off + pVM->mm.s.pvHyperAreaGC + pLookup->cb,
513 pLookup->u.HCPhys.pvR3,
514 pLookup->u.HCPhys.pvR0,
515 pLookup->u.HCPhys.HCPhys,
516 pLookup->pszDesc);
517 break;
518
519 case MMLOOKUPHYPERTYPE_GCPHYS:
520 pHlp->pfnPrintf(pHlp, "%RGv-%RGv %*s GCPHYS %RGp%*s %s\n",
521 pLookup->off + pVM->mm.s.pvHyperAreaGC,
522 pLookup->off + pVM->mm.s.pvHyperAreaGC + pLookup->cb,
523 sizeof(RTHCPTR) * 2 * 2 + 1, "",
524 pLookup->u.GCPhys.GCPhys, RT_ABS((int)(sizeof(RTHCPHYS) - sizeof(RTGCPHYS))) * 2, "",
525 pLookup->pszDesc);
526 break;
527
528 case MMLOOKUPHYPERTYPE_MMIO2:
529 pHlp->pfnPrintf(pHlp, "%RGv-%RGv %*s MMIO2 %RGp%*s %s\n",
530 pLookup->off + pVM->mm.s.pvHyperAreaGC,
531 pLookup->off + pVM->mm.s.pvHyperAreaGC + pLookup->cb,
532 sizeof(RTHCPTR) * 2 * 2 + 1, "",
533 pLookup->u.MMIO2.off, RT_ABS((int)(sizeof(RTHCPHYS) - sizeof(RTGCPHYS))) * 2, "",
534 pLookup->pszDesc);
535 break;
536
537 case MMLOOKUPHYPERTYPE_DYNAMIC:
538 pHlp->pfnPrintf(pHlp, "%RGv-%RGv %*s DYNAMIC %*s %s\n",
539 pLookup->off + pVM->mm.s.pvHyperAreaGC,
540 pLookup->off + pVM->mm.s.pvHyperAreaGC + pLookup->cb,
541 sizeof(RTHCPTR) * 2 * 2 + 1, "",
542 sizeof(RTHCPTR) * 2, "",
543 pLookup->pszDesc);
544 break;
545
546 default:
547 AssertMsgFailed(("enmType=%d\n", pLookup->enmType));
548 break;
549 }
550
551 /* next */
552 if ((unsigned)pLookup->offNext == NIL_OFFSET)
553 break;
554 pLookup = (PMMLOOKUPHYPER)((uint8_t *)pLookup + pLookup->offNext);
555 }
556}
557
558
559#if 0
560/**
561 * Re-allocates memory from the hyper heap.
562 *
563 * @returns VBox status code.
564 * @param pVM The cross context VM structure.
565 * @param pvOld The existing block of memory in the hyper heap to
566 * re-allocate (can be NULL).
567 * @param cbOld Size of the existing block.
568 * @param uAlignmentNew Required memory alignment in bytes. Values are
569 * 0,8,16,32 and GUEST_PAGE_SIZE. 0 -> default
570 * alignment, i.e. 8 bytes.
571 * @param enmTagNew The statistics tag.
572 * @param cbNew The required size of the new block.
573 * @param ppv Where to store the address to the re-allocated
574 * block.
575 *
576 * @remarks This does not work like normal realloc() on failure, the memory
577 * pointed to by @a pvOld is lost if there isn't sufficient space on
578 * the hyper heap for the re-allocation to succeed.
579*/
580VMMR3DECL(int) MMR3HyperRealloc(PVM pVM, void *pvOld, size_t cbOld, unsigned uAlignmentNew, MMTAG enmTagNew, size_t cbNew,
581 void **ppv)
582{
583 if (!pvOld)
584 return MMHyperAlloc(pVM, cbNew, uAlignmentNew, enmTagNew, ppv);
585
586 if (!cbNew && pvOld)
587 return MMHyperFree(pVM, pvOld);
588
589 if (cbOld == cbNew)
590 return VINF_SUCCESS;
591
592 size_t cbData = RT_MIN(cbNew, cbOld);
593 void *pvTmp = RTMemTmpAlloc(cbData);
594 if (RT_UNLIKELY(!pvTmp))
595 {
596 MMHyperFree(pVM, pvOld);
597 return VERR_NO_TMP_MEMORY;
598 }
599 memcpy(pvTmp, pvOld, cbData);
600
601 int rc = MMHyperFree(pVM, pvOld);
602 if (RT_SUCCESS(rc))
603 {
604 rc = MMHyperAlloc(pVM, cbNew, uAlignmentNew, enmTagNew, ppv);
605 if (RT_SUCCESS(rc))
606 {
607 Assert(cbData <= cbNew);
608 memcpy(*ppv, pvTmp, cbData);
609 }
610 }
611 else
612 AssertMsgFailed(("Failed to free hyper heap block pvOld=%p cbOld=%u\n", pvOld, cbOld));
613
614 RTMemTmpFree(pvTmp);
615 return rc;
616}
617#endif
618
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