VirtualBox

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

Last change on this file since 16560 was 14597, checked in by vboxsync, 16 years ago

Added R0 address to MMR3HyperMapHCPhys and made the MMHyperXToR0 use pvR0 for HCPhys and Locked more strickly.

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

© 2023 Oracle
ContactPrivacy policyTerms of Use