VirtualBox

source: vbox/trunk/src/VBox/VMM/MMInternal.h@ 19420

Last change on this file since 19420 was 18792, checked in by vboxsync, 16 years ago

MM,PGM: New User-kernel heap (aka MMUkHeap), use it for the PGMCHUNKR3MAP instead of the hyper heap.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 25.6 KB
Line 
1/* $Id: MMInternal.h 18792 2009-04-06 18:40:52Z vboxsync $ */
2/** @file
3 * MM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2007 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#ifndef ___MMInternal_h
23#define ___MMInternal_h
24
25#include <VBox/cdefs.h>
26#include <VBox/types.h>
27#include <VBox/sup.h>
28#include <VBox/stam.h>
29#include <iprt/avl.h>
30#include <iprt/critsect.h>
31
32
33
34/** @defgroup grp_mm_int Internals
35 * @internal
36 * @ingroup grp_mm
37 * @{
38 */
39
40
41/** @name MMR3Heap - VM Ring-3 Heap Internals
42 * @{
43 */
44
45/** @def MMR3HEAP_SIZE_ALIGNMENT
46 * The allocation size alignment of the MMR3Heap.
47 */
48#define MMR3HEAP_SIZE_ALIGNMENT 16
49
50/** @def MMR3HEAP_WITH_STATISTICS
51 * Enable MMR3Heap statistics.
52 */
53#if !defined(MMR3HEAP_WITH_STATISTICS) && defined(VBOX_WITH_STATISTICS)
54# define MMR3HEAP_WITH_STATISTICS
55#endif
56
57/**
58 * Heap statistics record.
59 * There is one global and one per allocation tag.
60 */
61typedef struct MMHEAPSTAT
62{
63 /** Core avl node, key is the tag. */
64 AVLULNODECORE Core;
65 /** Pointer to the heap the memory belongs to. */
66 struct MMHEAP *pHeap;
67#ifdef MMR3HEAP_WITH_STATISTICS
68 /** Number of allocation. */
69 uint64_t cAllocations;
70 /** Number of reallocations. */
71 uint64_t cReallocations;
72 /** Number of frees. */
73 uint64_t cFrees;
74 /** Failures. */
75 uint64_t cFailures;
76 /** Number of bytes allocated (sum). */
77 uint64_t cbAllocated;
78 /** Number of bytes freed. */
79 uint64_t cbFreed;
80 /** Number of bytes currently allocated. */
81 size_t cbCurAllocated;
82#endif
83} MMHEAPSTAT;
84/** Pointer to heap statistics record. */
85typedef MMHEAPSTAT *PMMHEAPSTAT;
86
87
88
89/**
90 * Additional heap block header for relating allocations to the VM.
91 */
92typedef struct MMHEAPHDR
93{
94 /** Pointer to the next record. */
95 struct MMHEAPHDR *pNext;
96 /** Pointer to the previous record. */
97 struct MMHEAPHDR *pPrev;
98 /** Pointer to the heap statistics record.
99 * (Where the a PVM can be found.) */
100 PMMHEAPSTAT pStat;
101 /** Size of the allocation (including this header). */
102 size_t cbSize;
103} MMHEAPHDR;
104/** Pointer to MM heap header. */
105typedef MMHEAPHDR *PMMHEAPHDR;
106
107
108/** MM Heap structure. */
109typedef struct MMHEAP
110{
111 /** Lock protecting the heap. */
112 RTCRITSECT Lock;
113 /** Heap block list head. */
114 PMMHEAPHDR pHead;
115 /** Heap block list tail. */
116 PMMHEAPHDR pTail;
117 /** Heap per tag statistics tree. */
118 PAVLULNODECORE pStatTree;
119 /** The VM handle. */
120 PUVM pUVM;
121 /** Heap global statistics. */
122 MMHEAPSTAT Stat;
123} MMHEAP;
124/** Pointer to MM Heap structure. */
125typedef MMHEAP *PMMHEAP;
126
127/** @} */
128
129
130/** @name MMUkHeap - VM User-kernel Heap Internals
131 * @{
132 */
133
134/** @def MMUKHEAP_SIZE_ALIGNMENT
135 * The allocation size alignment of the MMR3UkHeap.
136 */
137#define MMUKHEAP_SIZE_ALIGNMENT 16
138
139/** @def MMUKHEAP_WITH_STATISTICS
140 * Enable MMUkHeap statistics.
141 */
142#if !defined(MMUKHEAP_WITH_STATISTICS) && defined(VBOX_WITH_STATISTICS)
143# define MMUKHEAP_WITH_STATISTICS
144#endif
145
146
147/**
148 * Heap statistics record.
149 * There is one global and one per allocation tag.
150 */
151typedef struct MMUKHEAPSTAT
152{
153 /** Core avl node, key is the tag. */
154 AVLULNODECORE Core;
155 /** Number of allocation. */
156 uint64_t cAllocations;
157 /** Number of reallocations. */
158 uint64_t cReallocations;
159 /** Number of frees. */
160 uint64_t cFrees;
161 /** Failures. */
162 uint64_t cFailures;
163 /** Number of bytes allocated (sum). */
164 uint64_t cbAllocated;
165 /** Number of bytes freed. */
166 uint64_t cbFreed;
167 /** Number of bytes currently allocated. */
168 size_t cbCurAllocated;
169} MMUKHEAPSTAT;
170/** Pointer to heap statistics record. */
171typedef MMUKHEAPSTAT *PMMUKHEAPSTAT;
172
173/**
174 * Sub heap tracking record.
175 */
176typedef struct MMUKHEAPSUB
177{
178 /** Pointer to the next sub-heap. */
179 struct MMUKHEAPSUB *pNext;
180 /** The base address of the sub-heap. */
181 void *pv;
182 /** The size of the sub-heap. */
183 size_t cb;
184 /** The handle of the simple block pointer. */
185 RTHEAPSIMPLE hSimple;
186 /** The ring-0 address corresponding to MMUKHEAPSUB::pv. */
187 RTR0PTR pvR0;
188} MMUKHEAPSUB;
189/** Pointer to a sub-heap tracking record. */
190typedef MMUKHEAPSUB *PMMUKHEAPSUB;
191
192
193/** MM User-kernel Heap structure. */
194typedef struct MMUKHEAP
195{
196 /** Lock protecting the heap. */
197 RTCRITSECT Lock;
198 /** Head of the sub-heap LIFO. */
199 PMMUKHEAPSUB pSubHeapHead;
200 /** Heap per tag statistics tree. */
201 PAVLULNODECORE pStatTree;
202 /** The VM handle. */
203 PUVM pUVM;
204 /** Heap global statistics. */
205 MMUKHEAPSTAT Stat;
206} MMUKHEAP;
207/** Pointer to MM Heap structure. */
208typedef MMUKHEAP *PMMUKHEAP;
209
210/** @} */
211
212
213
214/** @name Hypervisor Heap Internals
215 * @{
216 */
217
218/** @def MMHYPER_HEAP_FREE_DELAY
219 * If defined, it indicates the number of frees that should be delayed.
220 */
221#if defined(DOXYGEN_RUNNING)
222# define MMHYPER_HEAP_FREE_DELAY 64
223#endif
224
225/** @def MMHYPER_HEAP_FREE_POISON
226 * If defined, it indicates that freed memory should be poisoned
227 * with the value it has.
228 */
229#if defined(VBOX_STRICT) || defined(DOXYGEN_RUNNING)
230# define MMHYPER_HEAP_FREE_POISON 0xcb
231#endif
232
233/** @def MMHYPER_HEAP_STRICT
234 * Enables a bunch of assertions in the heap code. */
235#if defined(VBOX_STRICT) || defined(DOXYGEN_RUNNING)
236# define MMHYPER_HEAP_STRICT 1
237# if 0 || defined(DOXYGEN_RUNNING)
238/** @def MMHYPER_HEAP_STRICT_FENCE
239 * Enables tail fence. */
240# define MMHYPER_HEAP_STRICT_FENCE
241/** @def MMHYPER_HEAP_STRICT_FENCE_SIZE
242 * The fence size in bytes. */
243# define MMHYPER_HEAP_STRICT_FENCE_SIZE 256
244/** @def MMHYPER_HEAP_STRICT_FENCE_U32
245 * The fence filler. */
246# define MMHYPER_HEAP_STRICT_FENCE_U32 UINT32_C(0xdeadbeef)
247# endif
248#endif
249
250/**
251 * Hypervisor heap statistics record.
252 * There is one global and one per allocation tag.
253 */
254typedef struct MMHYPERSTAT
255{
256 /** Core avl node, key is the tag.
257 * @todo The type is wrong! Get your lazy a$$ over and create that offsetted uint32_t version we need here! */
258 AVLOGCPHYSNODECORE Core;
259 /** Aligning the 64-bit fields on a 64-bit line. */
260 uint32_t u32Padding0;
261 /** Indicator for whether these statistics are registered with STAM or not. */
262 bool fRegistered;
263 /** Number of allocation. */
264 uint64_t cAllocations;
265 /** Number of frees. */
266 uint64_t cFrees;
267 /** Failures. */
268 uint64_t cFailures;
269 /** Number of bytes allocated (sum). */
270 uint64_t cbAllocated;
271 /** Number of bytes freed (sum). */
272 uint64_t cbFreed;
273 /** Number of bytes currently allocated. */
274 uint32_t cbCurAllocated;
275 /** Max number of bytes allocated. */
276 uint32_t cbMaxAllocated;
277} MMHYPERSTAT;
278/** Pointer to hypervisor heap statistics record. */
279typedef MMHYPERSTAT *PMMHYPERSTAT;
280
281/**
282 * Hypervisor heap chunk.
283 */
284typedef struct MMHYPERCHUNK
285{
286 /** Previous block in the list of all blocks.
287 * This is relative to the start of the heap. */
288 uint32_t offNext;
289 /** Offset to the previous block relative to this one. */
290 int32_t offPrev;
291 /** The statistics record this allocation belongs to (self relative). */
292 int32_t offStat;
293 /** Offset to the heap block (self relative). */
294 int32_t offHeap;
295} MMHYPERCHUNK;
296/** Pointer to a hypervisor heap chunk. */
297typedef MMHYPERCHUNK *PMMHYPERCHUNK;
298
299
300/**
301 * Hypervisor heap chunk.
302 */
303typedef struct MMHYPERCHUNKFREE
304{
305 /** Main list. */
306 MMHYPERCHUNK core;
307 /** Offset of the next chunk in the list of free nodes. */
308 uint32_t offNext;
309 /** Offset of the previous chunk in the list of free nodes. */
310 int32_t offPrev;
311 /** Size of the block. */
312 uint32_t cb;
313} MMHYPERCHUNKFREE;
314/** Pointer to a free hypervisor heap chunk. */
315typedef MMHYPERCHUNKFREE *PMMHYPERCHUNKFREE;
316
317
318/**
319 * The hypervisor heap.
320 */
321typedef struct MMHYPERHEAP
322{
323 /** The typical magic (MMHYPERHEAP_MAGIC). */
324 uint32_t u32Magic;
325 /** The heap size. (This structure is not included!) */
326 uint32_t cbHeap;
327 /** The HC ring-3 address of the heap. */
328 R3PTRTYPE(uint8_t *) pbHeapR3;
329 /** The HC ring-3 address of the shared VM strcture. */
330 PVMR3 pVMR3;
331 /** The HC ring-0 address of the heap. */
332 R0PTRTYPE(uint8_t *) pbHeapR0;
333 /** The HC ring-0 address of the shared VM strcture. */
334 PVMR0 pVMR0;
335 /** The RC address of the heap. */
336 RCPTRTYPE(uint8_t *) pbHeapRC;
337 /** The RC address of the shared VM strcture. */
338 PVMRC pVMRC;
339 /** The amount of free memory in the heap. */
340 uint32_t cbFree;
341 /** Offset of the first free chunk in the heap.
342 * The offset is relative to the start of the heap. */
343 uint32_t offFreeHead;
344 /** Offset of the last free chunk in the heap.
345 * The offset is relative to the start of the heap. */
346 uint32_t offFreeTail;
347 /** Offset of the first page aligned block in the heap.
348 * The offset is equal to cbHeap initially. */
349 uint32_t offPageAligned;
350 /** Tree of hypervisor heap statistics. */
351 AVLOGCPHYSTREE HyperHeapStatTree;
352#ifdef MMHYPER_HEAP_FREE_DELAY
353 /** Where to insert the next free. */
354 uint32_t iDelayedFree;
355 /** Array of delayed frees. Circular. Offsets relative to this structure. */
356 struct
357 {
358 /** The free caller address. */
359 RTUINTPTR uCaller;
360 /** The offset of the freed chunk. */
361 uint32_t offChunk;
362 } aDelayedFrees[MMHYPER_HEAP_FREE_DELAY];
363#else
364 /** Padding the structure to a 64-bit aligned size. */
365 uint32_t u32Padding0;
366#endif
367 /** The heap physical pages. */
368 R3PTRTYPE(PSUPPAGE) paPages;
369#if HC_ARCH_BITS == 32
370 /** Padding the structure to a 64-bit aligned size. */
371 uint32_t u32Padding1;
372#endif
373} MMHYPERHEAP;
374/** Pointer to the hypervisor heap. */
375typedef MMHYPERHEAP *PMMHYPERHEAP;
376
377/** Magic value for MMHYPERHEAP. (C. S. Lewis) */
378#define MMHYPERHEAP_MAGIC UINT32_C(0x18981129)
379
380
381/**
382 * Hypervisor heap minimum alignment (16 bytes).
383 */
384#define MMHYPER_HEAP_ALIGN_MIN 16
385
386/**
387 * The aligned size of the the MMHYPERHEAP structure.
388 */
389#define MMYPERHEAP_HDR_SIZE RT_ALIGN_Z(sizeof(MMHYPERHEAP), MMHYPER_HEAP_ALIGN_MIN * 4)
390
391/** @name Hypervisor heap chunk flags.
392 * The flags are put in the first bits of the MMHYPERCHUNK::offPrev member.
393 * These bits aren't used anyway because of the chunk minimal alignment (16 bytes).
394 * @{ */
395/** The chunk is free. (The code ASSUMES this is 0!) */
396#define MMHYPERCHUNK_FLAGS_FREE 0x0
397/** The chunk is in use. */
398#define MMHYPERCHUNK_FLAGS_USED 0x1
399/** The type mask. */
400#define MMHYPERCHUNK_FLAGS_TYPE_MASK 0x1
401/** The flag mask */
402#define MMHYPERCHUNK_FLAGS_MASK 0x1
403
404/** Checks if the chunk is free. */
405#define MMHYPERCHUNK_ISFREE(pChunk) ( (((pChunk)->offPrev) & MMHYPERCHUNK_FLAGS_TYPE_MASK) == MMHYPERCHUNK_FLAGS_FREE )
406/** Checks if the chunk is used. */
407#define MMHYPERCHUNK_ISUSED(pChunk) ( (((pChunk)->offPrev) & MMHYPERCHUNK_FLAGS_TYPE_MASK) == MMHYPERCHUNK_FLAGS_USED )
408/** Toggles FREE/USED flag of a chunk. */
409#define MMHYPERCHUNK_SET_TYPE(pChunk, type) do { (pChunk)->offPrev = ((pChunk)->offPrev & ~MMHYPERCHUNK_FLAGS_TYPE_MASK) | ((type) & MMHYPERCHUNK_FLAGS_TYPE_MASK); } while (0)
410
411/** Gets the prev offset without the flags. */
412#define MMHYPERCHUNK_GET_OFFPREV(pChunk) ((int32_t)((pChunk)->offPrev & ~MMHYPERCHUNK_FLAGS_MASK))
413/** Sets the prev offset without changing the flags. */
414#define MMHYPERCHUNK_SET_OFFPREV(pChunk, off) do { (pChunk)->offPrev = (off) | ((pChunk)->offPrev & MMHYPERCHUNK_FLAGS_MASK); } while (0)
415#if 0
416/** Clears one or more flags. */
417#define MMHYPERCHUNK_FLAGS_OP_CLEAR(pChunk, fFlags) do { ((pChunk)->offPrev) &= ~((fFlags) & MMHYPERCHUNK_FLAGS_MASK); } while (0)
418/** Sets one or more flags. */
419#define MMHYPERCHUNK_FLAGS_OP_SET(pChunk, fFlags) do { ((pChunk)->offPrev) |= ((fFlags) & MMHYPERCHUNK_FLAGS_MASK); } while (0)
420/** Checks if one is set. */
421#define MMHYPERCHUNK_FLAGS_OP_ISSET(pChunk, fFlag) (!!(((pChunk)->offPrev) & ((fFlag) & MMHYPERCHUNK_FLAGS_MASK)))
422#endif
423/** @} */
424
425/** @} */
426
427
428/** @name Page Pool Internals
429 * @{
430 */
431
432/**
433 * Page sub pool
434 *
435 * About the allocation of this structure. To keep the number of heap blocks,
436 * the number of heap calls, and fragmentation low we allocate all the data
437 * related to a MMPAGESUBPOOL node in one chunk. That means that after the
438 * bitmap (which is of variable size) comes the SUPPAGE records and then
439 * follows the lookup tree nodes. (The heap in question is the hyper heap.)
440 */
441typedef struct MMPAGESUBPOOL
442{
443 /** Pointer to next sub pool. */
444#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
445 R3PTRTYPE(struct MMPAGESUBPOOL *) pNext;
446#else
447 R3R0PTRTYPE(struct MMPAGESUBPOOL *) pNext;
448#endif
449 /** Pointer to next sub pool in the free chain.
450 * This is NULL if we're not in the free chain or at the end of it. */
451#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
452 R3PTRTYPE(struct MMPAGESUBPOOL *) pNextFree;
453#else
454 R3R0PTRTYPE(struct MMPAGESUBPOOL *) pNextFree;
455#endif
456 /** Pointer to array of lock ranges.
457 * This is allocated together with the MMPAGESUBPOOL and thus needs no freeing.
458 * It follows immediately after the bitmap.
459 * The reserved field is a pointer to this structure.
460 */
461#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
462 R3PTRTYPE(PSUPPAGE) paPhysPages;
463#else
464 R3R0PTRTYPE(PSUPPAGE) paPhysPages;
465#endif
466 /** Pointer to the first page. */
467#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
468 R3PTRTYPE(void *) pvPages;
469#else
470 R3R0PTRTYPE(void *) pvPages;
471#endif
472 /** Size of the subpool. */
473 uint32_t cPages;
474 /** Number of free pages. */
475 uint32_t cPagesFree;
476 /** The allocation bitmap.
477 * This may extend beyond the end of the defined array size.
478 */
479 uint32_t auBitmap[1];
480 /* ... SUPPAGE aRanges[1]; */
481} MMPAGESUBPOOL;
482/** Pointer to page sub pool. */
483typedef MMPAGESUBPOOL *PMMPAGESUBPOOL;
484
485/**
486 * Page pool.
487 */
488typedef struct MMPAGEPOOL
489{
490 /** List of subpools. */
491#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
492 R3PTRTYPE(PMMPAGESUBPOOL) pHead;
493#else
494 R3R0PTRTYPE(PMMPAGESUBPOOL) pHead;
495#endif
496 /** Head of subpools with free pages. */
497#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
498 R3PTRTYPE(PMMPAGESUBPOOL) pHeadFree;
499#else
500 R3R0PTRTYPE(PMMPAGESUBPOOL) pHeadFree;
501#endif
502 /** AVLPV tree for looking up HC virtual addresses.
503 * The tree contains MMLOOKUPVIRTPP records.
504 */
505#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
506 R3PTRTYPE(PAVLPVNODECORE) pLookupVirt;
507#else
508 R3R0PTRTYPE(PAVLPVNODECORE) pLookupVirt;
509#endif
510 /** Tree for looking up HC physical addresses.
511 * The tree contains MMLOOKUPPHYSHC records.
512 */
513#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
514 R3PTRTYPE(AVLHCPHYSTREE) pLookupPhys;
515#else
516 R3R0PTRTYPE(AVLHCPHYSTREE) pLookupPhys;
517#endif
518 /** Pointer to the VM this pool belongs. */
519#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
520 PVMR3 pVM;
521#else
522 R3R0PTRTYPE(PVM) pVM;
523#endif
524 /** Flag indicating the allocation method.
525 * Set: SUPLowAlloc().
526 * Clear: SUPPageAlloc() + SUPPageLock(). */
527 bool fLow;
528 /** Number of subpools. */
529 uint32_t cSubPools;
530 /** Number of pages in pool. */
531 uint32_t cPages;
532#ifdef VBOX_WITH_STATISTICS
533 /** Number of free pages in pool. */
534 uint32_t cFreePages;
535 /** Number of alloc calls. */
536 STAMCOUNTER cAllocCalls;
537 /** Number of free calls. */
538 STAMCOUNTER cFreeCalls;
539 /** Number of to phys conversions. */
540 STAMCOUNTER cToPhysCalls;
541 /** Number of to virtual conversions. */
542 STAMCOUNTER cToVirtCalls;
543 /** Number of real errors. */
544 STAMCOUNTER cErrors;
545#endif
546} MMPAGEPOOL;
547/** Pointer to page pool. */
548typedef MMPAGEPOOL *PMMPAGEPOOL;
549
550/**
551 * Lookup record for HC virtual memory in the page pool.
552 */
553typedef struct MMPPLOOKUPHCPTR
554{
555 /** The key is virtual address. */
556 AVLPVNODECORE Core;
557 /** Pointer to subpool if lookup record for a pool. */
558 struct MMPAGESUBPOOL *pSubPool;
559} MMPPLOOKUPHCPTR;
560/** Pointer to virtual memory lookup record. */
561typedef MMPPLOOKUPHCPTR *PMMPPLOOKUPHCPTR;
562
563/**
564 * Lookup record for HC physical memory.
565 */
566typedef struct MMPPLOOKUPHCPHYS
567{
568 /** The key is physical address. */
569 AVLHCPHYSNODECORE Core;
570 /** Pointer to SUPPAGE record for this physical address. */
571 PSUPPAGE pPhysPage;
572} MMPPLOOKUPHCPHYS;
573/** Pointer to physical memory lookup record. */
574typedef MMPPLOOKUPHCPHYS *PMMPPLOOKUPHCPHYS;
575
576/** @} */
577
578
579/**
580 * Hypervisor memory mapping type.
581 */
582typedef enum MMLOOKUPHYPERTYPE
583{
584 /** Invalid record. This is used for record which are incomplete. */
585 MMLOOKUPHYPERTYPE_INVALID = 0,
586 /** Mapping of locked memory. */
587 MMLOOKUPHYPERTYPE_LOCKED,
588 /** Mapping of contiguous HC physical memory. */
589 MMLOOKUPHYPERTYPE_HCPHYS,
590 /** Mapping of contiguous GC physical memory. */
591 MMLOOKUPHYPERTYPE_GCPHYS,
592 /** Mapping of MMIO2 memory. */
593 MMLOOKUPHYPERTYPE_MMIO2,
594 /** Dynamic mapping area (MMR3HyperReserve).
595 * A conversion will require to check what's in the page table for the pages. */
596 MMLOOKUPHYPERTYPE_DYNAMIC
597} MMLOOKUPHYPERTYPE;
598
599/**
600 * Lookup record for the hypervisor memory area.
601 */
602typedef struct MMLOOKUPHYPER
603{
604 /** Byte offset from the start of this record to the next.
605 * If the value is NIL_OFFSET the chain is terminated. */
606 int32_t offNext;
607 /** Offset into the hypvervisor memory area. */
608 uint32_t off;
609 /** Size of this part. */
610 uint32_t cb;
611 /** Locking type. */
612 MMLOOKUPHYPERTYPE enmType;
613 /** Type specific data */
614 union
615 {
616 /** Locked memory. */
617 struct
618 {
619 /** Host context ring-3 pointer. */
620 R3PTRTYPE(void *) pvR3;
621 /** Host context ring-0 pointer. Optional. */
622 RTR0PTR pvR0;
623 /** Pointer to an array containing the physical address of each page. */
624 R3PTRTYPE(PRTHCPHYS) paHCPhysPages;
625 } Locked;
626
627 /** Contiguous physical memory. */
628 struct
629 {
630 /** Host context ring-3 pointer. */
631 R3PTRTYPE(void *) pvR3;
632 /** Host context ring-0 pointer. Optional. */
633 RTR0PTR pvR0;
634 /** HC physical address corresponding to pvR3/pvR0. */
635 RTHCPHYS HCPhys;
636 } HCPhys;
637
638 /** Contiguous guest physical memory. */
639 struct
640 {
641 /** The memory address (Guest Context). */
642 RTGCPHYS GCPhys;
643 } GCPhys;
644
645 /** MMIO2 memory. */
646 struct
647 {
648 /** The device instance owning the MMIO2 region. */
649 PPDMDEVINSR3 pDevIns;
650 /** The region number. */
651 uint32_t iRegion;
652 /** The offset into the MMIO2 region. */
653 RTGCPHYS off;
654 } MMIO2;
655 } u;
656 /** Description. */
657 R3PTRTYPE(const char *) pszDesc;
658} MMLOOKUPHYPER;
659/** Pointer to a hypervisor memory lookup record. */
660typedef MMLOOKUPHYPER *PMMLOOKUPHYPER;
661
662
663/**
664 * Converts a MM pointer into a VM pointer.
665 * @returns Pointer to the VM structure the MM is part of.
666 * @param pMM Pointer to MM instance data.
667 */
668#define MM2VM(pMM) ( (PVM)((uint8_t *)pMM - pMM->offVM) )
669
670
671/**
672 * MM Data (part of VM)
673 */
674typedef struct MM
675{
676 /** Offset to the VM structure.
677 * See MM2VM(). */
678 RTINT offVM;
679
680 /** Set if MMR3InitPaging has been called. */
681 bool fDoneMMR3InitPaging;
682 /** Set if PGM has been initialized and we can safely call PGMR3Map(). */
683 bool fPGMInitialized;
684#if GC_ARCH_BITS == 64 || HC_ARCH_BITS == 64
685 uint32_t u32Padding1; /**< alignment padding. */
686#endif
687
688 /** Lookup list for the Hypervisor Memory Area.
689 * The offset is relative to the start of the heap.
690 * Use pHyperHeapR3, pHyperHeapR0 or pHypeRHeapRC to calculate the address.
691 */
692 RTUINT offLookupHyper;
693
694 /** The offset of the next static mapping in the Hypervisor Memory Area. */
695 RTUINT offHyperNextStatic;
696 /** The size of the HMA.
697 * Starts at 12MB and will be fixed late in the init process. */
698 RTUINT cbHyperArea;
699
700 /** Guest address of the Hypervisor Memory Area.
701 * @remarks It's still a bit open whether this should be change to RTRCPTR or
702 * remain a RTGCPTR. */
703 RTGCPTR pvHyperAreaGC;
704
705 /** The hypervisor heap (GC Ptr). */
706 RCPTRTYPE(PMMHYPERHEAP) pHyperHeapRC;
707#if HC_ARCH_BITS == 64 && GC_ARCH_BITS == 64
708 uint32_t u32Padding2;
709#endif
710
711 /** The hypervisor heap (R0 Ptr). */
712 R0PTRTYPE(PMMHYPERHEAP) pHyperHeapR0;
713#ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
714 /** Page pool - R0 Ptr. */
715 R0PTRTYPE(PMMPAGEPOOL) pPagePoolR0;
716 /** Page pool pages in low memory R0 Ptr. */
717 R0PTRTYPE(PMMPAGEPOOL) pPagePoolLowR0;
718#endif /* !VBOX_WITH_2X_4GB_ADDR_SPACE */
719
720 /** The hypervisor heap (R3 Ptr). */
721 R3PTRTYPE(PMMHYPERHEAP) pHyperHeapR3;
722 /** Page pool - R3 Ptr. */
723 R3PTRTYPE(PMMPAGEPOOL) pPagePoolR3;
724 /** Page pool pages in low memory R3 Ptr. */
725 R3PTRTYPE(PMMPAGEPOOL) pPagePoolLowR3;
726
727 /** Pointer to the dummy page.
728 * The dummy page is a paranoia thingy used for instance for pure MMIO RAM ranges
729 * to make sure any bugs will not harm whatever the system stores in the first
730 * physical page. */
731 R3PTRTYPE(void *) pvDummyPage;
732 /** Physical address of the dummy page. */
733 RTHCPHYS HCPhysDummyPage;
734
735 /** Size of the base RAM in bytes. (The CFGM RamSize value.) */
736 uint64_t cbRamBase;
737 /** The number of base RAM pages that PGM has reserved (GMM).
738 * @remarks Shadow ROMs will be counted twice (RAM+ROM), so it won't be 1:1 with
739 * what the guest sees. */
740 uint64_t cBasePages;
741 /** The number of handy pages that PGM has reserved (GMM).
742 * These are kept out of cBasePages and thus out of the saved state. */
743 uint32_t cHandyPages;
744 /** The number of shadow pages PGM has reserved (GMM). */
745 uint32_t cShadowPages;
746 /** The number of fixed pages we've reserved (GMM). */
747 uint32_t cFixedPages;
748 /** Padding. */
749 uint32_t u32Padding0;
750} MM;
751/** Pointer to MM Data (part of VM). */
752typedef MM *PMM;
753
754
755/**
756 * MM data kept in the UVM.
757 */
758typedef struct MMUSERPERVM
759{
760 /** Pointer to the MM R3 Heap. */
761 R3PTRTYPE(PMMHEAP) pHeap;
762 /** Pointer to the MM Uk Heap. */
763 R3PTRTYPE(PMMUKHEAP) pUkHeap;
764} MMUSERPERVM;
765/** Pointer to the MM data kept in the UVM. */
766typedef MMUSERPERVM *PMMUSERPERVM;
767
768
769__BEGIN_DECLS
770
771
772int mmR3UpdateReservation(PVM pVM);
773
774int mmR3PagePoolInit(PVM pVM);
775void mmR3PagePoolTerm(PVM pVM);
776
777int mmR3HeapCreateU(PUVM pUVM, PMMHEAP *ppHeap);
778void mmR3HeapDestroy(PMMHEAP pHeap);
779
780void mmR3UkHeapDestroy(PMMUKHEAP pHeap);
781int mmR3UkHeapCreateU(PUVM pUVM, PMMUKHEAP *ppHeap);
782
783
784int mmR3HyperInit(PVM pVM);
785int mmR3HyperInitPaging(PVM pVM);
786
787const char *mmR3GetTagName(MMTAG enmTag);
788
789/**
790 * Converts a pool address to a physical address.
791 * The specified allocation type must match with the address.
792 *
793 * @returns Physical address.
794 * @returns NIL_RTHCPHYS if not found or eType is not matching.
795 * @param pPool Pointer to the page pool.
796 * @param pv The address to convert.
797 * @thread The Emulation Thread.
798 */
799RTHCPHYS mmPagePoolPtr2Phys(PMMPAGEPOOL pPool, void *pv);
800
801/**
802 * Converts a pool physical address to a linear address.
803 * The specified allocation type must match with the address.
804 *
805 * @returns Physical address.
806 * @returns NULL if not found or eType is not matching.
807 * @param pPool Pointer to the page pool.
808 * @param HCPhys The address to convert.
809 * @thread The Emulation Thread.
810 */
811void *mmPagePoolPhys2Ptr(PMMPAGEPOOL pPool, RTHCPHYS HCPhys);
812
813__END_DECLS
814
815/** @} */
816
817#endif
818
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