PGMInternal.h revision ec588a4ac8429a8b6c744544818b3ce3b2c75690
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * PGM - Internal header file.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * available from http://www.virtualbox.org. This file is free software;
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * you can redistribute it and/or modify it under the terms of the GNU
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * General Public License (GPL) as published by the Free Software
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * additional information or have any questions.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync#if !defined(IN_PGM_R3) && !defined(IN_PGM_R0) && !defined(IN_PGM_GC)
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @defgroup grp_pgm_int Internals
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @ingroup grp_pgm
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @internal
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @name PGM Compile Time Config
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Solve page is out of sync issues inside Guest Context (in PGMGC.cpp).
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Comment it if it will break something.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Check and skip global PDEs for non-global flushes
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Sync N pages instead of a whole page table
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Number of pages to sync during a page fault
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * When PGMPOOL_WITH_GCPHYS_TRACKING is enabled using high values here
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * causes a lot of unnecessary extents and also is slower than taking more \#PFs.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Number of PGMPhysRead/Write cache entries (must be <= sizeof(uint64_t))
cc66247640b520463f925a5533fc9e5de06aa982vboxsync#define PGM_MAX_PHYSCACHE_ENTRIES_MASK (PGM_MAX_PHYSCACHE_ENTRIES-1)
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Enable caching of PGMR3PhysRead/WriteByte/Word/Dword
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def PGMPOOL_WITH_CACHE
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Enable agressive caching using the page pool.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * This requires PGMPOOL_WITH_USER_TRACKING and PGMPOOL_WITH_MONITORING.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def PGMPOOL_WITH_MIXED_PT_CR3
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * When defined, we'll deal with 'uncachable' pages.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def PGMPOOL_WITH_MONITORING
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Monitor the guest pages which are shadowed.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * When this is enabled, PGMPOOL_WITH_CACHE or PGMPOOL_WITH_GCPHYS_TRACKING must
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * be enabled as well.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @remark doesn't really work without caching now. (Mixed PT/CR3 change.)
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def PGMPOOL_WITH_GCPHYS_TRACKING
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Tracking the of shadow pages mapping guest physical pages.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * This is very expensive, the current cache prototype is trying to figure out
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * whether it will be acceptable with an agressive caching policy.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync#if defined(PGMPOOL_WITH_CACHE) || defined(PGMPOOL_WITH_MONITORING)
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def PGMPOOL_WITH_USER_TRACKNG
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Tracking users of shadow pages. This is required for the linking of shadow page
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * tables and physical guest addresses.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync#if defined(PGMPOOL_WITH_GCPHYS_TRACKING) || defined(PGMPOOL_WITH_CACHE) || defined(PGMPOOL_WITH_MONITORING)
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def PGMPOOL_CFG_MAX_GROW
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * The maximum number of pages to add to the pool in one go.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def VBOX_STRICT_PGM_HANDLER_VIRTUAL
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Enables some extra assertions for virtual handlers (mainly phys2virt related).
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @name PDPT and PML4 flags.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * These are placed in the three bits available for system programs in
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * the PDPT and PML4 entries.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** The entry is a permanent one and it's must always be present.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Never free such an entry. */
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** Mapping (hypervisor allocated pagetable). */
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @name Page directory flags.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * These are placed in the three bits available for system programs in
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * the page directory entries.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** Mapping (hypervisor allocated pagetable). */
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** Made read-only to facilitate dirty bit tracking. */
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @name Page flags.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * These are placed in the three bits available for system programs in
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * the page entries.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** Made read-only to facilitate dirty bit tracking. */
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** Scanned and approved by CSAM (tm).
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * NOTE: Must be identical to the one defined in CSAMInternal.h!!
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @todo Move PGM_PTFLAGS_* and PGM_PDFLAGS_* to VBox/pgm.h. */
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @name Defines used to indicate the shadow and guest paging in the templates.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** Macro for checking if the guest is using paging.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param uType PGM_TYPE_*
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @remark ASSUMES certain order of the PGM_TYPE_* values.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync#define PGM_WITH_PAGING(uType) ((uType) >= PGM_TYPE_32BIT && (uType) != PGM_TYPE_NESTED)
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** Macro for checking if the guest supports the NX bit.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param uType PGM_TYPE_*
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @remark ASSUMES certain order of the PGM_TYPE_* values.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync#define PGM_WITH_NX(uType) ((uType) >= PGM_TYPE_PAE && (uType) != PGM_TYPE_NESTED)
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def PGM_HCPHYS_2_PTR
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Maps a HC physical page pool address to a virtual address.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @returns VBox status code.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param pVM The VM handle.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param HCPhys The HC physical address to map to a virtual one.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param ppv Where to store the virtual address. No need to cast this.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @remark In GC this uses PGMGCDynMapHCPage(), so it will consume of the
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * small page window employeed by that function. Be careful.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @remark There is no need to assert on the result.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync# define PGM_HCPHYS_2_PTR(pVM, HCPhys, ppv) PGMGCDynMapHCPage(pVM, HCPhys, (void **)(ppv))
cc66247640b520463f925a5533fc9e5de06aa982vboxsync# define PGM_HCPHYS_2_PTR(pVM, HCPhys, ppv) MMPagePhys2PageEx(pVM, HCPhys, (void **)(ppv))
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def PGM_GCPHYS_2_PTR
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Maps a GC physical page address to a virtual address.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @returns VBox status code.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param pVM The VM handle.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param GCPhys The GC physical address to map to a virtual one.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param ppv Where to store the virtual address. No need to cast this.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @remark In GC this uses PGMGCDynMapGCPage(), so it will consume of the
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * small page window employeed by that function. Be careful.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @remark There is no need to assert on the result.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync# define PGM_GCPHYS_2_PTR(pVM, GCPhys, ppv) PGMGCDynMapGCPage(pVM, GCPhys, (void **)(ppv))
cc66247640b520463f925a5533fc9e5de06aa982vboxsync# define PGM_GCPHYS_2_PTR(pVM, GCPhys, ppv) PGMPhysGCPhys2HCPtr(pVM, GCPhys, 1 /* one page only */, (void **)(ppv)) /** @todo this isn't asserting, use PGMRamGCPhys2HCPtr! */
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def PGM_GCPHYS_2_PTR_EX
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Maps a unaligned GC physical page address to a virtual address.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @returns VBox status code.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param pVM The VM handle.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param GCPhys The GC physical address to map to a virtual one.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param ppv Where to store the virtual address. No need to cast this.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @remark In GC this uses PGMGCDynMapGCPage(), so it will consume of the
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * small page window employeed by that function. Be careful.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @remark There is no need to assert on the result.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync# define PGM_GCPHYS_2_PTR_EX(pVM, GCPhys, ppv) PGMGCDynMapGCPageEx(pVM, GCPhys, (void **)(ppv))
cc66247640b520463f925a5533fc9e5de06aa982vboxsync# define PGM_GCPHYS_2_PTR_EX(pVM, GCPhys, ppv) PGMPhysGCPhys2HCPtr(pVM, GCPhys, 1 /* one page only */, (void **)(ppv)) /** @todo this isn't asserting, use PGMRamGCPhys2HCPtr! */
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def PGM_INVL_PG
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Invalidates a page when in GC does nothing in HC.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param GCVirt The virtual address of the page to invalidate.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync# define PGM_INVL_PG(GCVirt) ASMInvalidatePage((void *)(GCVirt))
cc66247640b520463f925a5533fc9e5de06aa982vboxsync# define PGM_INVL_PG(GCVirt) HWACCMInvalidatePage(pVM, (RTGCPTR)(GCVirt))
cc66247640b520463f925a5533fc9e5de06aa982vboxsync# define PGM_INVL_PG(GCVirt) HWACCMInvalidatePage(pVM, (RTGCPTR)(GCVirt))
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def PGM_INVL_BIG_PG
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Invalidates a 4MB page directory entry when in GC does nothing in HC.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * @param GCVirt The virtual address within the page directory to invalidate.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync# define PGM_INVL_BIG_PG(GCVirt) HWACCMFlushTLB(pVM)
cc66247640b520463f925a5533fc9e5de06aa982vboxsync# define PGM_INVL_BIG_PG(GCVirt) HWACCMFlushTLB(pVM)
cc66247640b520463f925a5533fc9e5de06aa982vboxsync/** @def PGM_INVL_GUEST_TLBS()
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Invalidates all guest TLBs.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * Structure for tracking GC Mappings.
cc66247640b520463f925a5533fc9e5de06aa982vboxsync * This structure is used by linked list in both GC and HC.
cc66247640b520463f925a5533fc9e5de06aa982vboxsynctypedef struct PGMMAPPING
cc66247640b520463f925a5533fc9e5de06aa982vboxsync /** Pointer to next entry. */
cc66247640b520463f925a5533fc9e5de06aa982vboxsync /** Pointer to next entry. */
} PGMMAPPING;
typedef struct PGMPHYSHANDLER
#ifdef VBOX_WITH_STATISTICS
typedef struct PGMPHYS2VIRTHANDLER
typedef struct PGMVIRTHANDLER
#ifdef VBOX_WITH_STATISTICS
typedef enum PGMPAGETYPE
PGMPAGETYPE_INVALID = 0,
} PGMPAGETYPE;
typedef struct PGMPAGE
} PGMPAGE;
#ifdef VBOX_WITH_NEW_PHYS_CODE
#define PGM_PAGE_STATE_ZERO 0
#define PGM_PAGE_SET_PAGEID(pPage, _idPage) do { (pPage)->HCPhys = (((pPage)->HCPhys) & UINT64_C(0x0000fffffffff000)) \
# define PGM_PAGE_GET_CHUNKID(pPage) ( (uint32_t)((pPage)->HCPhys >> (48 + (GMM_CHUNKID_SHIFT - 12)) )
# define PGM_PAGE_GET_CHUNKID(pPage) ( ( (uint32_t)((pPage)->HCPhys >> 48) << (12 - GMM_CHUNKID_SHIFT) ) \
#ifdef VBOX_WITH_NEW_PHYS_CODE
#define PGM_PAGE_HNDL_PHYS_STATE_NONE 0
#define PGM_PAGE_HAS_ANY_PHYSICAL_HANDLERS(pPage) ( (pPage)->u2HandlerPhysStateX != PGM_PAGE_HNDL_PHYS_STATE_NONE )
#define PGM_PAGE_HAS_ACTIVE_PHYSICAL_HANDLERS(pPage) ( (pPage)->u2HandlerPhysStateX >= PGM_PAGE_HNDL_PHYS_STATE_WRITE )
#define PGM_PAGE_HNDL_VIRT_STATE_NONE 0
#define PGM_PAGE_HAS_ANY_VIRTUAL_HANDLERS(pPage) ( (pPage)->u2HandlerVirtStateX != PGM_PAGE_HNDL_VIRT_STATE_NONE )
typedef struct PGMRAMRANGE
#ifdef VBOX_WITH_NEW_PHYS_CODE
/** HC virtual lookup ranges for chunks. Currently only used with MM_RAM_FLAGS_DYNAMIC_ALLOC ranges. */
/** HC virtual lookup ranges for chunks. Currently only used with MM_RAM_FLAGS_DYNAMIC_ALLOC ranges. */
#ifdef VBOX_WITH_NEW_PHYS_CODE
} PGMRAMRANGE;
(pRam->fFlags & MM_RAM_FLAGS_DYNAMIC_ALLOC) ? (RTHCPTR)((RTHCUINTPTR)CTXSUFF(pRam->pavHCChunk)[(off >> PGM_DYNAMIC_CHUNK_SHIFT)] + (off & PGM_DYNAMIC_CHUNK_OFFSET_MASK)) \
typedef struct PGMROMPAGE
} PGMROMPAGE;
typedef struct PGMROMRANGE
} PGMROMRANGE;
typedef struct PGMMMIO2RANGE
bool fMapped;
bool fOverlapping;
* PGMPhysRead/Write cache entry
typedef struct PGMPHYSCACHE_ENTRY
* PGMPhysRead/Write cache to reduce REM memory access overhead
typedef struct PGMPHYSCACHE
} PGMPHYSCACHE;
typedef struct PGMCHUNKR3MAP
void *pv;
typedef struct PGMCHUNKR3MAPTLBE
typedef struct PGMCHUNKR3MAPTLB
typedef struct PGMPAGER3MAPTLBE
typedef struct PGMPAGER3MAPTLB
#ifdef IN_GC
typedef void * PPGMPAGEMAP;
typedef void ** PPPGMPAGEMAP;
#define NIL_PGMPOOL_IDX 0
typedef struct PGMPOOLUSER
#pragma pack()
typedef struct PGMPOOLPHYSEXT
#pragma pack()
typedef enum PGMPOOLKIND
PGMPOOLKIND_INVALID = 0,
} PGMPOOLKIND;
typedef struct PGMPOOLPAGE
#ifdef PGMPOOL_WITH_USER_TRACKING
#ifdef PGMPOOL_WITH_MONITORING
#ifdef PGMPOOL_WITH_CACHE
bool fZeroed;
bool fSeenNonGlobal;
bool fMonitored;
bool fCached;
bool volatile fReusedFlushPending;
bool fCR3Mix;
#ifdef PGMPOOL_WITH_CACHE
typedef struct PGMPOOL
#ifdef PGMPOOL_WITH_USER_TRACKING
#ifdef PGMPOOL_WITH_GCPHYS_TRACKING
#ifdef PGMPOOL_WITH_CACHE
bool fCacheEnabled;
#ifdef PGMPOOL_WITH_MONITORING
#ifdef VBOX_WITH_STATISTICS
# ifdef PGMPOOL_WITH_USER_TRACKING
# ifdef PGMPOOL_WITH_GCPHYS_TRACKING
# ifdef PGMPOOL_WITH_MONITORING
# ifdef PGMPOOL_WITH_CACHE
#ifdef IN_GC
typedef struct PGMTREES
} PGMTREES;
#ifdef IN_GC
# ifdef IN_RING3
typedef struct PGMMODEDATA
DECLR3CALLBACKMEMBER(int, pfnR3ShwGetPage,(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
DECLR3CALLBACKMEMBER(int, pfnR3ShwModifyPage,(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLGCCALLBACKMEMBER(int, pfnGCShwGetPage,(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
DECLGCCALLBACKMEMBER(int, pfnGCShwModifyPage,(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR0CALLBACKMEMBER(int, pfnR0ShwGetPage,(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
DECLR0CALLBACKMEMBER(int, pfnR0ShwModifyPage,(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR3CALLBACKMEMBER(int, pfnR3GstGetPage,(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
DECLR3CALLBACKMEMBER(int, pfnR3GstModifyPage,(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLGCCALLBACKMEMBER(int, pfnGCGstGetPage,(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
DECLGCCALLBACKMEMBER(int, pfnGCGstModifyPage,(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR0CALLBACKMEMBER(int, pfnR0GstGetPage,(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
DECLR0CALLBACKMEMBER(int, pfnR0GstModifyPage,(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR3CALLBACKMEMBER(int, pfnR3BthTrap0eHandler,(PVM pVM, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
DECLR3CALLBACKMEMBER(int, pfnR3BthSyncCR3,(PVM pVM, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
DECLR3CALLBACKMEMBER(int, pfnR3BthSyncPage,(PVM pVM, X86PDE PdeSrc, RTGCUINTPTR GCPtrPage, unsigned cPages, unsigned uError));
DECLR3CALLBACKMEMBER(int, pfnR3BthVerifyAccessSyncPage,(PVM pVM, RTGCUINTPTR GCPtrPage, unsigned fFlags, unsigned uError));
#ifdef VBOX_STRICT
DECLR3CALLBACKMEMBER(unsigned, pfnR3BthAssertCR3,(PVM pVM, uint64_t cr3, uint64_t cr4, RTGCUINTPTR GCPtr, RTGCUINTPTR cb));
DECLGCCALLBACKMEMBER(int, pfnGCBthTrap0eHandler,(PVM pVM, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
DECLGCCALLBACKMEMBER(int, pfnGCBthSyncCR3,(PVM pVM, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
DECLGCCALLBACKMEMBER(int, pfnGCBthSyncPage,(PVM pVM, X86PDE PdeSrc, RTGCUINTPTR GCPtrPage, unsigned cPages, unsigned uError));
DECLGCCALLBACKMEMBER(int, pfnGCBthVerifyAccessSyncPage,(PVM pVM, RTGCUINTPTR GCPtrPage, unsigned fFlags, unsigned uError));
#ifdef VBOX_STRICT
DECLGCCALLBACKMEMBER(unsigned, pfnGCBthAssertCR3,(PVM pVM, uint64_t cr3, uint64_t cr4, RTGCUINTPTR GCPtr, RTGCUINTPTR cb));
DECLR0CALLBACKMEMBER(int, pfnR0BthTrap0eHandler,(PVM pVM, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
DECLR0CALLBACKMEMBER(int, pfnR0BthSyncCR3,(PVM pVM, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
DECLR0CALLBACKMEMBER(int, pfnR0BthSyncPage,(PVM pVM, X86PDE PdeSrc, RTGCUINTPTR GCPtrPage, unsigned cPages, unsigned uError));
DECLR0CALLBACKMEMBER(int, pfnR0BthVerifyAccessSyncPage,(PVM pVM, RTGCUINTPTR GCPtrPage, unsigned fFlags, unsigned uError));
#ifdef VBOX_STRICT
DECLR0CALLBACKMEMBER(unsigned, pfnR0BthAssertCR3,(PVM pVM, uint64_t cr3, uint64_t cr4, RTGCUINTPTR GCPtr, RTGCUINTPTR cb));
typedef struct PGM
/** The physical addresses of the guest page directories (PAE) pointed to by apGstPagePDsHC/GC. */
DECLR3CALLBACKMEMBER(int, pfnR3ShwGetPage,(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
DECLR3CALLBACKMEMBER(int, pfnR3ShwModifyPage,(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLGCCALLBACKMEMBER(int, pfnGCShwGetPage,(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
DECLGCCALLBACKMEMBER(int, pfnGCShwModifyPage,(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR0CALLBACKMEMBER(int, pfnR0ShwGetPage,(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
DECLR0CALLBACKMEMBER(int, pfnR0ShwModifyPage,(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR3CALLBACKMEMBER(int, pfnR3GstGetPage,(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
DECLR3CALLBACKMEMBER(int, pfnR3GstModifyPage,(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLGCCALLBACKMEMBER(int, pfnGCGstGetPage,(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
DECLGCCALLBACKMEMBER(int, pfnGCGstModifyPage,(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR0CALLBACKMEMBER(int, pfnR0GstGetPage,(PVM pVM, RTGCUINTPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
DECLR0CALLBACKMEMBER(int, pfnR0GstModifyPage,(PVM pVM, RTGCUINTPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR3CALLBACKMEMBER(int, pfnR3BthTrap0eHandler,(PVM pVM, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
DECLR3CALLBACKMEMBER(int, pfnR3BthSyncCR3,(PVM pVM, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
DECLR3CALLBACKMEMBER(int, pfnR3BthSyncPage,(PVM pVM, X86PDE PdeSrc, RTGCUINTPTR GCPtrPage, unsigned cPages, unsigned uError));
DECLR3CALLBACKMEMBER(int, pfnR3BthVerifyAccessSyncPage,(PVM pVM, RTGCUINTPTR GCPtrPage, unsigned fFlags, unsigned uError));
DECLR3CALLBACKMEMBER(unsigned, pfnR3BthAssertCR3,(PVM pVM, uint64_t cr3, uint64_t cr4, RTGCUINTPTR GCPtr, RTGCUINTPTR cb));
DECLR0CALLBACKMEMBER(int, pfnR0BthTrap0eHandler,(PVM pVM, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
DECLR0CALLBACKMEMBER(int, pfnR0BthSyncCR3,(PVM pVM, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
DECLR0CALLBACKMEMBER(int, pfnR0BthSyncPage,(PVM pVM, X86PDE PdeSrc, RTGCUINTPTR GCPtrPage, unsigned cPages, unsigned uError));
DECLR0CALLBACKMEMBER(int, pfnR0BthVerifyAccessSyncPage,(PVM pVM, RTGCUINTPTR GCPtrPage, unsigned fFlags, unsigned uError));
DECLR0CALLBACKMEMBER(unsigned, pfnR0BthAssertCR3,(PVM pVM, uint64_t cr3, uint64_t cr4, RTGCUINTPTR GCPtr, RTGCUINTPTR cb));
DECLGCCALLBACKMEMBER(int, pfnGCBthTrap0eHandler,(PVM pVM, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
DECLGCCALLBACKMEMBER(int, pfnGCBthSyncCR3,(PVM pVM, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
DECLGCCALLBACKMEMBER(int, pfnGCBthSyncPage,(PVM pVM, X86PDE PdeSrc, RTGCUINTPTR GCPtrPage, unsigned cPages, unsigned uError));
DECLGCCALLBACKMEMBER(int, pfnGCBthVerifyAccessSyncPage,(PVM pVM, RTGCUINTPTR GCPtrPage, unsigned fFlags, unsigned uError));
DECLGCCALLBACKMEMBER(unsigned, pfnGCBthAssertCR3,(PVM pVM, uint64_t cr3, uint64_t cr4, RTGCUINTPTR GCPtr, RTGCUINTPTR cb));
bool fMappingsFixed;
bool fDisableMappings;
bool fNoMorePhysWrites;
bool fPhysCacheFlushPending;
uint32_t c;
* @cfgm PGM/MaxRing3Chunks */
} ChunkR3Map;
#ifdef VBOX_WITH_STATISTICS
STAMPROFILE StatTrap0eDirtyAndAccessedBits; /**< Profiling of the Trap0eHandler body when the cause is dirty and/or accessed bit emulation. */
STAMPROFILE StatTrap0eGuestTrap; /**< Profiling of the Trap0eHandler body when the cause is a guest trap. */
STAMPROFILE StatTrap0eHndPhys; /**< Profiling of the Trap0eHandler body when the cause is a physical handler. */
STAMPROFILE StatTrap0eHndVirt; /**< Profiling of the Trap0eHandler body when the cause is a virtual handler. */
STAMPROFILE StatTrap0eHndUnhandled; /**< Profiling of the Trap0eHandler body when the cause is access outside the monitored areas of a monitored page. */
STAMPROFILE StatTrap0eMisc; /**< Profiling of the Trap0eHandler body when the cause is not known. */
STAMPROFILE StatTrap0eOutOfSync; /**< Profiling of the Trap0eHandler body when the cause is an out-of-sync page. */
STAMPROFILE StatTrap0eOutOfSyncHndPhys; /**< Profiling of the Trap0eHandler body when the cause is an out-of-sync physical handler page. */
STAMPROFILE StatTrap0eOutOfSyncHndVirt; /**< Profiling of the Trap0eHandler body when the cause is an out-of-sync virtual handler page. */
STAMPROFILE StatTrap0eOutOfSyncObsHnd; /**< Profiling of the Trap0eHandler body when the cause is an obsolete handler page. */
STAMPROFILE StatTrap0eSyncPT; /**< Profiling of the Trap0eHandler body when the cause is lazy syncing of a PT. */
STAMCOUNTER StatGCTrap0eConflicts; /**< GC: The number of times \#PF was caused by an undetected conflict. */
/** GC: The number of times PGMGCInvalidatePage() was called for a page directory containing mappings (no conflict). */
/** HC: The number of times PGMGCInvalidatePage() was skipped due to not present shw or pending pending SyncCR3. */
/** GC: The number of times pgmGCGuestPDWriteHandler() was called and we had to fall back to the recompiler. */
/** GC: Number of traps due to virtual access handlers found by virtual address (without proper physical flags). */
/** GC: The number of times pgmGCGuestROMWriteHandler() was called and we had to fall back to the recompiler */
/** HC: The number of times PGMR3InvalidatePage() was called for a page directory containing mappings (no conflict). */
/** HC: The number of times PGMR3InvalidatePage() was skipped due to not present shw or pending pending SyncCR3. */
/** GC: The number of time we've marked a PD not present from SyncPage to virtualize the accessed bit. */
/** HC: The number of time we've marked a PD not present from SyncPage to virtualize the accessed bit. */
STAMPROFILE StatGCSyncCR3Handlers; /**< GC: Profiling of the PGMSyncCR3() update handler section. */
STAMPROFILE StatGCSyncCR3HandlerVirtualUpdate; /**< GC: Profiling of the virtual handler updates. */
STAMCOUNTER StatGCSyncCR3DstFreed; /**< GC: The number of times we've had to free a shadow entry. */
STAMCOUNTER StatGCSyncCR3DstFreedSrcNP; /**< GC: The number of times we've had to free a shadow entry for which the source entry was not present. */
STAMCOUNTER StatGCSyncCR3DstNotPresent; /**< GC: The number of times we've encountered a not present shadow entry for a present guest entry. */
STAMCOUNTER StatGCSyncCR3DstSkippedGlobalPD; /**< GC: The number of times a global page directory wasn't flushed. */
STAMCOUNTER StatGCSyncCR3DstSkippedGlobalPT; /**< GC: The number of times a page table with only global entries wasn't flushed. */
STAMCOUNTER StatGCSyncCR3DstCacheHit; /**< GC: The number of times we got some kind of cache hit on a page table. */
STAMPROFILE StatHCSyncCR3Handlers; /**< HC: Profiling of the PGMSyncCR3() update handler section. */
STAMPROFILE StatHCSyncCR3HandlerVirtualUpdate; /**< HC: Profiling of the virtual handler updates. */
STAMCOUNTER StatHCSyncCR3DstFreed; /**< HC: The number of times we've had to free a shadow entry. */
STAMCOUNTER StatHCSyncCR3DstFreedSrcNP; /**< HC: The number of times we've had to free a shadow entry for which the source entry was not present. */
STAMCOUNTER StatHCSyncCR3DstNotPresent; /**< HC: The number of times we've encountered a not present shadow entry for a present guest entry. */
STAMCOUNTER StatHCSyncCR3DstSkippedGlobalPD; /**< HC: The number of times a global page directory wasn't flushed. */
STAMCOUNTER StatHCSyncCR3DstSkippedGlobalPT; /**< HC: The number of times a page table with only global entries wasn't flushed. */
STAMCOUNTER StatHCSyncCR3DstCacheHit; /**< HC: The number of times we got some kind of cache hit on a page table. */
# ifdef PGMPOOL_WITH_GCPHYS_TRACKING
PGMGCDECL(int) pgmGCGuestPDWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, void *pvFault, RTGCPHYS GCPhysFault, void *pvUser);
PGMDECL(int) pgmPhysRomWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, void *pvFault, RTGCPHYS GCPhysFault, void *pvUser);
int pgmR3SyncPTResolveConflict(PVM pVM, PPGMMAPPING pMapping, PX86PD pPDSrc, RTGCPTR GCPtrOldMapping);
void pgmR3MapRelocate(PVM pVM, PPGMMAPPING pMapping, RTGCPTR GCPtrOldMapping, RTGCPTR GCPtrNewMapping);
int pgmHandlerVirtualFindByPhysAddr(PVM pVM, RTGCPHYS GCPhys, PPGMVIRTHANDLER *ppVirt, unsigned *piPage);
# define pgmHandlerVirtualDumpPhysPages(a) do { } while (0)
#ifdef IN_RING3
#ifndef VBOX_WITH_NEW_PHYS_CODE
#ifdef IN_GC
int pgmPoolAlloc(PVM pVM, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, uint16_t iUser, uint32_t iUserTable, PPPGMPOOLPAGE ppPage);
#ifdef PGMPOOL_WITH_MONITORING
# ifdef IN_RING3
void pgmPoolMonitorChainChanging(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTGCPHYS GCPhysFault, RTHCPTR pvAddress, PDISCPUSTATE pCpu);
void pgmPoolMonitorChainChanging(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTGCPHYS GCPhysFault, RTGCPTR pvAddress, PDISCPUSTATE pCpu);
return pRam;
return NULL;
#ifndef VBOX_WITH_NEW_PHYS_CODE
#ifdef IN_RING3
return rc;
return VINF_SUCCESS;
DECLINLINE(int) pgmPhysGetPageWithHintEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRamHint)
if ( !pRam
#ifndef VBOX_WITH_NEW_PHYS_CODE
#ifdef IN_RING3
return rc;
return VINF_SUCCESS;
return NULL;
DECLINLINE(int) pgmPhysGetPageAndRangeEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRam)
#ifndef VBOX_WITH_NEW_PHYS_CODE
#ifdef IN_RING3
return rc;
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
#ifndef IN_GC
int rc;
return rc;
#ifndef VBOX_WITH_NEW_PHYS_CODE
return rc;
*pHCPtr = (RTHCPTR)((RTHCUINTPTR)CTXSUFF(pRam->pavHCChunk)[iChunk] + (off & PGM_DYNAMIC_CHUNK_OFFSET_MASK));
return VINF_SUCCESS;
return VINF_SUCCESS;
DECLINLINE(int) pgmRamGCPhys2HCPtrWithRange(PVM pVM, PPGMRAMRANGE pRam, RTGCPHYS GCPhys, PRTHCPTR pHCPtr)
#ifdef IN_RING3
return rc;
*pHCPtr = (RTHCPTR)((RTHCUINTPTR)CTXSUFF(pRam->pavHCChunk)[idx] + (off & PGM_DYNAMIC_CHUNK_OFFSET_MASK));
return VINF_SUCCESS;
return VINF_SUCCESS;
DECLINLINE(int) pgmRamGCPhys2HCPtrAndHCPhysWithFlags(PPGM pPGM, RTGCPHYS GCPhys, PRTHCPTR pHCPtr, PRTHCPHYS pHCPhys)
return rc;
*pHCPtr = (RTHCPTR)((RTHCUINTPTR)CTXSUFF(pRam->pavHCChunk)[idx] + (off & PGM_DYNAMIC_CHUNK_OFFSET_MASK));
return VINF_SUCCESS;
return VINF_SUCCESS;
*pHCPtr = 0;
return rc;
return VINF_SUCCESS;
DECLINLINE(int) pgmRamFlagsClearByGCPhysWithHint(PPGM pPGM, RTGCPHYS GCPhys, unsigned fFlags, PPGMRAMRANGE *ppRamHint)
return rc;
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
DECLINLINE(int) pgmRamFlagsSetByGCPhysWithHint(PPGM pPGM, RTGCPHYS GCPhys, unsigned fFlags, PPGMRAMRANGE *ppRamHint)
return rc;
return VINF_SUCCESS;
int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), CTXSUFF(pPGM->pGstPaePDPT)->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
return pPD;
/* returning NIL_RTGCPHYS is ok if we assume it's just an invalid page of some kind emulated as all 0s. */
return NULL;
int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), CTXSUFF(pPGM->pGstPaePDPT)->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
/* returning NIL_RTGCPHYS is ok if we assume it's just an invalid page or something which we'll emulate as all 0s. */
return NULL;
int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), CTXSUFF(pPGM->pGstPaePDPT)->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
return 0ULL;
int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), CTXSUFF(pPGM->pGstPaePDPT)->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
return pPD;
/* returning NIL_RTGCPHYS is ok if we assume it's just an invalid page of some kind emulated as all 0s. */
return NULL;
#ifndef IN_GC
AssertFailed();
return NULL;
return NULL;
DECLINLINE(uint64_t) pgmGstGetLongModePDE(PPGM pPGM, RTGCUINTPTR64 GCPtr, PX86PML4E *ppPml4e, PX86PDPE pPdpe)
AssertFailed();
return 0ULL;
AssertFailed();
return 0ULL;
return 0ULL;
int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPGM->pGstPaePML4HC->a[iPml4e].u & X86_PML4E_PG_MASK, &pPdptTemp);
AssertFailed();
return 0ULL;
AssertFailed();
return 0ULL;
return 0ULL;
int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPGM->pGstPaePML4HC->a[iPml4e].u & X86_PML4E_PG_MASK, &pPdptTemp);
AssertFailed();
return NULL;
AssertFailed();
return NULL;
return NULL;
DECLINLINE(PX86PDPAE) pgmGstGetLongModePDPtr(PPGM pPGM, RTGCUINTPTR64 GCPtr, PX86PML4E *ppPml4e, PX86PDPE pPdpe, unsigned *piPD)
AssertFailed();
return 0ULL;
AssertFailed();
return 0ULL;
return pPD;
return 0ULL;
AssertFailed();
return 0ULL;
AssertFailed();
return 0ULL;
return pPD;
return 0ULL;
return pPage
return PGM_PAGE_HNDL_PHYS_STATE_WRITE;
case PGMPHYSHANDLERTYPE_MMIO:
return PGM_PAGE_HNDL_PHYS_STATE_ALL;
case PGMVIRTHANDLERTYPE_WRITE:
return PGM_PAGE_HNDL_VIRT_STATE_WRITE;
case PGMVIRTHANDLERTYPE_ALL:
return PGM_PAGE_HNDL_VIRT_STATE_ALL;
("pPhys2Virt=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n",
pPhys2Virt, pPhys2Virt->Core.Key, pPhys2Virt->Core.KeyLast, pPhys2Virt->offVirtHandler, pPhys2Virt->offNextAlias));
PPGMPHYS2VIRTHANDLER pRemove = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysRemove(&pPGM->CTXSUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key); NOREF(pRemove);
("pPhys2Virt=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n",
pPhys2Virt, pPhys2Virt->Core.Key, pPhys2Virt->Core.KeyLast, pPhys2Virt->offVirtHandler, pPhys2Virt->offNextAlias));
("wanted: pPhys2Virt=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n"
" got: pRemove=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n",
pPhys2Virt, pPhys2Virt->Core.Key, pPhys2Virt->Core.KeyLast, pPhys2Virt->offVirtHandler, pPhys2Virt->offNextAlias,
pRemove, pRemove->Core.Key, pRemove->Core.KeyLast, pRemove->offVirtHandler, pRemove->offNextAlias));
PPGMPHYS2VIRTHANDLER pNext = (PPGMPHYS2VIRTHANDLER)((intptr_t)pPhys2Virt + (pPhys2Virt->offNextAlias & PGMPHYS2VIRTHANDLER_OFF_MASK));
PPGMPHYS2VIRTHANDLER pPrev = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysGet(&pPGM->CTXSUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key);
("pPhys2Virt=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32} pPrev=%p\n",
pPhys2Virt, pPhys2Virt->Core.Key, pPhys2Virt->Core.KeyLast, pPhys2Virt->offVirtHandler, pPhys2Virt->offNextAlias, pPrev));
PPGMPHYS2VIRTHANDLER pNext = (PPGMPHYS2VIRTHANDLER)((intptr_t)pPrev + (pPrev->offNextAlias & PGMPHYS2VIRTHANDLER_OFF_MASK));
LogFlow(("pgmHandlerVirtualClearPage: removed %p:{.offNextAlias=%#RX32} from alias chain. prev %p:{.offNextAlias=%#RX32} [%VGp-%VGp]\n",
pPhys2Virt, pPhys2Virt->offNextAlias, pPrev, pPrev->offNextAlias, pPhys2Virt->Core.Key, pPhys2Virt->Core.KeyLast));
PPGMPHYS2VIRTHANDLER pNewNext = (PPGMPHYS2VIRTHANDLER)((intptr_t)pPhys2Virt + (pPhys2Virt->offNextAlias & PGMPHYS2VIRTHANDLER_OFF_MASK));
("pPhys2Virt=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32} pPrev=%p\n",
pPhys2Virt, pPhys2Virt->Core.Key, pPhys2Virt->Core.KeyLast, pPhys2Virt->offVirtHandler, pPhys2Virt->offNextAlias, pPrev));
pPhys2Virt->Core.Key, pPhys2Virt->Core.KeyLast, pPhys2Virt->offNextAlias, HCSTRING(pCur->pszDesc)));
PPGMPOOLPAGE pPage = (PPGMPOOLPAGE)RTAvloHCPhysGet(&pPool->HCPhysTree, HCPhys & X86_PTE_PAE_PG_MASK);
AssertFatalMsg(pPage && pPage->enmKind != PGMPOOLKIND_FREE, ("HCPhys=%VHp pPage=%p type=%d\n", HCPhys, pPage, (pPage) ? pPage->enmKind : 0));
return pPage;
#ifdef PGMPOOL_WITH_GCPHYS_TRACKING
#ifdef LOG_ENABLED
#ifdef PGMPOOL_WITH_CACHE
* @todo inline in PGMInternal.h!
#ifdef IN_RING0