VirtualBox

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

Last change on this file since 74795 was 69474, checked in by vboxsync, 7 years ago

*: scm updates - header files should have 'svn:keywords=Id Revision' too (doesn't mean they have to use them).

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

© 2023 Oracle
ContactPrivacy policyTerms of Use