PGMInternal.h revision dea1368099e5337861dd52906d4c683c447a33c4
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * PGM - Internal header file.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Copyright (C) 2006-2007 Sun Microsystems, Inc.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * available from http://www.virtualbox.org. This file is free software;
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * you can redistribute it and/or modify it under the terms of the GNU
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * General Public License (GPL) as published by the Free Software
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * additional information or have any questions.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @defgroup grp_pgm_int Internals
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @ingroup grp_pgm
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @internal
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @name PGM Compile Time Config
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Solve page is out of sync issues inside Guest Context (in PGMGC.cpp).
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * Comment it if it will break something.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Check and skip global PDEs for non-global flushes
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * Optimization for PAE page tables that are modified often
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync//#if 0 /* disabled again while debugging */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Sync N pages instead of a whole page table
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Number of pages to sync during a page fault
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * When PGMPOOL_WITH_GCPHYS_TRACKING is enabled using high values here
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * causes a lot of unnecessary extents and also is slower than taking more \#PFs.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Note that \#PFs are much more expensive in the VT-x/AMD-V case due to
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * world switch overhead, so let's sync more.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/* Chose 32 based on the compile test in #4219; 64 shows worse stats.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * 32 again shows better results than 16; slightly more overhead in the \#PF handler,
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * but ~5% fewer faults.
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync * Number of PGMPhysRead/Write cache entries (must be <= sizeof(uint64_t))
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync#define PGM_MAX_PHYSCACHE_ENTRIES_MASK (PGM_MAX_PHYSCACHE_ENTRIES-1)
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync/** @def PGMPOOL_WITH_CACHE
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * Enable agressive caching using the page pool.
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync * This requires PGMPOOL_WITH_USER_TRACKING and PGMPOOL_WITH_MONITORING.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync/** @def PGMPOOL_WITH_MIXED_PT_CR3
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync * When defined, we'll deal with 'uncachable' pages.
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync/** @def PGMPOOL_WITH_MONITORING
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * Monitor the guest pages which are shadowed.
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * When this is enabled, PGMPOOL_WITH_CACHE or PGMPOOL_WITH_GCPHYS_TRACKING must
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync * be enabled as well.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * @remark doesn't really work without caching now. (Mixed PT/CR3 change.)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @def PGMPOOL_WITH_GCPHYS_TRACKING
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Tracking the of shadow pages mapping guest physical pages.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * This is very expensive, the current cache prototype is trying to figure out
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * whether it will be acceptable with an agressive caching policy.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#if defined(PGMPOOL_WITH_CACHE) || defined(PGMPOOL_WITH_MONITORING)
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync/** @def PGMPOOL_WITH_USER_TRACKING
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * Tracking users of shadow pages. This is required for the linking of shadow page
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * tables and physical guest addresses.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#if defined(PGMPOOL_WITH_GCPHYS_TRACKING) || defined(PGMPOOL_WITH_CACHE) || defined(PGMPOOL_WITH_MONITORING)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @def PGMPOOL_CFG_MAX_GROW
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * The maximum number of pages to add to the pool in one go.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @def VBOX_STRICT_PGM_HANDLER_VIRTUAL
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Enables some extra assertions for virtual handlers (mainly phys2virt related).
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @def VBOX_WITH_NEW_LAZY_PAGE_ALLOC
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * Enables the experimental lazy page allocation code. */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync/*#define VBOX_WITH_NEW_LAZY_PAGE_ALLOC */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @def VBOX_WITH_REAL_WRITE_MONITORED_PAGES
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Enables real write monitoring of pages, i.e. mapping them read-only and
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * only making them writable when getting a write access #PF. */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync/** @name PDPT and PML4 flags.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * These are placed in the three bits available for system programs in
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * the PDPT and PML4 entries.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** The entry is a permanent one and it's must always be present.
06ea6bcf23874b662d499b3f130024c98b2dd7a6vboxsync * Never free such an entry. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Mapping (hypervisor allocated pagetable). */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync/** @name Page directory flags.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * These are placed in the three bits available for system programs in
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * the page directory entries.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Mapping (hypervisor allocated pagetable). */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Made read-only to facilitate dirty bit tracking. */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync/** @name Page flags.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * These are placed in the three bits available for system programs in
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * the page entries.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Made read-only to facilitate dirty bit tracking. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Scanned and approved by CSAM (tm).
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * NOTE: Must be identical to the one defined in CSAMInternal.h!!
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @todo Move PGM_PTFLAGS_* and PGM_PDFLAGS_* to VBox/pgm.h. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @name Defines used to indicate the shadow and guest paging in the templates.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Macro for checking if the guest is using paging.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param uGstType PGM_TYPE_*
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param uShwType PGM_TYPE_*
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @remark ASSUMES certain order of the PGM_TYPE_* values.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Macro for checking if the guest supports the NX bit.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param uGstType PGM_TYPE_*
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param uShwType PGM_TYPE_*
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @remark ASSUMES certain order of the PGM_TYPE_* values.
7e8ef90d3160234df0f254131b87af4243d79476vboxsync/** @def PGM_HCPHYS_2_PTR
7e8ef90d3160234df0f254131b87af4243d79476vboxsync * Maps a HC physical page pool address to a virtual address.
7e8ef90d3160234df0f254131b87af4243d79476vboxsync * @returns VBox status code.
7e8ef90d3160234df0f254131b87af4243d79476vboxsync * @param pVM The VM handle.
7e8ef90d3160234df0f254131b87af4243d79476vboxsync * @param HCPhys The HC physical address to map to a virtual one.
7e8ef90d3160234df0f254131b87af4243d79476vboxsync * @param ppv Where to store the virtual address. No need to cast this.
7e8ef90d3160234df0f254131b87af4243d79476vboxsync * @remark In GC this uses PGMGCDynMapHCPage(), so it will consume of the
7e8ef90d3160234df0f254131b87af4243d79476vboxsync * small page window employeed by that function. Be careful.
7e8ef90d3160234df0f254131b87af4243d79476vboxsync * @remark There is no need to assert on the result.
06ea6bcf23874b662d499b3f130024c98b2dd7a6vboxsync pgmR0DynMapHCPageInlined(&(pVM)->pgm.s, HCPhys, (void **)(ppv))
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync/** @def PGM_HCPHYS_2_PTR_BY_PGM
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Maps a HC physical page pool address to a virtual address.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @returns VBox status code.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPGM The PGM instance data.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param HCPhys The HC physical address to map to a virtual one.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param ppv Where to store the virtual address. No need to cast this.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @remark In GC this uses PGMGCDynMapHCPage(), so it will consume of the
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * small page window employeed by that function. Be careful.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @remark There is no need to assert on the result.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync# define PGM_HCPHYS_2_PTR_BY_PGM(pPGM, HCPhys, ppv) \
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync pgmR0DynMapHCPageInlined(pPGM, HCPhys, (void **)(ppv))
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync# define PGM_HCPHYS_2_PTR_BY_PGM(pPGM, HCPhys, ppv) \
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync PGM_HCPHYS_2_PTR(PGM2VM(pPGM), HCPhys, (void **)(ppv))
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @def PGM_GCPHYS_2_PTR
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Maps a GC physical page address to a virtual address.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @returns VBox status code.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pVM The VM handle.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param GCPhys The GC physical address to map to a virtual one.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param ppv Where to store the virtual address. No need to cast this.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @remark In GC this uses PGMGCDynMapGCPage(), so it will consume of the
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * small page window employeed by that function. Be careful.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @remark There is no need to assert on the result.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pgmR0DynMapGCPageInlined(&(pVM)->pgm.s, GCPhys, (void **)(ppv))
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync PGMPhysGCPhys2R3Ptr(pVM, GCPhys, 1 /* one page only */, (PRTR3PTR)(ppv)) /** @todo this isn't asserting, use PGMRamGCPhys2HCPtr! */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @def PGM_GCPHYS_2_PTR_BY_PGMCPU
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Maps a GC physical page address to a virtual address.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @returns VBox status code.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPGM Pointer to the PGM instance data.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param GCPhys The GC physical address to map to a virtual one.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param ppv Where to store the virtual address. No need to cast this.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @remark In GC this uses PGMGCDynMapGCPage(), so it will consume of the
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * small page window employeed by that function. Be careful.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @remark There is no need to assert on the result.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync# define PGM_GCPHYS_2_PTR_BY_PGMCPU(pPGM, GCPhys, ppv) \
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync pgmR0DynMapGCPageInlined(PGMCPU2PGM(pPGM), GCPhys, (void **)(ppv))
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync# define PGM_GCPHYS_2_PTR_BY_PGMCPU(pPGM, GCPhys, ppv) \
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync/** @def PGM_GCPHYS_2_PTR_EX
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Maps a unaligned GC physical page address to a virtual address.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @returns VBox status code.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pVM The VM handle.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param GCPhys The GC physical address to map to a virtual one.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param ppv Where to store the virtual address. No need to cast this.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @remark In GC this uses PGMGCDynMapGCPage(), so it will consume of the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * small page window employeed by that function. Be careful.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @remark There is no need to assert on the result.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync PGMPhysGCPhys2R3Ptr(pVM, GCPhys, 1 /* one page only */, (PRTR3PTR)(ppv)) /** @todo this isn't asserting, use PGMRamGCPhys2HCPtr! */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @def PGM_INVL_PG
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Invalidates a page.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pVCpu The VMCPU handle.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param GCVirt The virtual address of the page to invalidate.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync# define PGM_INVL_PG(pVCpu, GCVirt) ASMInvalidatePage((void *)(GCVirt))
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync# define PGM_INVL_PG(pVCpu, GCVirt) HWACCMInvalidatePage(pVCpu, (RTGCPTR)(GCVirt))
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync# define PGM_INVL_PG(pVCpu, GCVirt) HWACCMInvalidatePage(pVCpu, (RTGCPTR)(GCVirt))
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync/** @def PGM_INVL_PG_ALL_VCPU
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * Invalidates a page on all VCPUs
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * @param pVM The VM handle.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * @param GCVirt The virtual address of the page to invalidate.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt) ASMInvalidatePage((void *)(GCVirt))
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt) HWACCMInvalidatePageOnAllVCpus(pVM, (RTGCPTR)(GCVirt))
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt) HWACCMInvalidatePageOnAllVCpus(pVM, (RTGCPTR)(GCVirt))
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync/** @def PGM_INVL_BIG_PG
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync * Invalidates a 4MB page directory entry.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * @param pVCpu The VMCPU handle.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * @param GCVirt The virtual address within the page directory to invalidate.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync# define PGM_INVL_BIG_PG(pVCpu, GCVirt) ASMReloadCR3()
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync# define PGM_INVL_BIG_PG(pVCpu, GCVirt) HWACCMFlushTLB(pVCpu)
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync# define PGM_INVL_BIG_PG(pVCpu, GCVirt) HWACCMFlushTLB(pVCpu)
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync/** @def PGM_INVL_VCPU_TLBS()
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * Invalidates the TLBs of the specified VCPU
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync * @param pVCpu The VMCPU handle.
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync# define PGM_INVL_VCPU_TLBS(pVCpu) HWACCMFlushTLB(pVCpu)
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync# define PGM_INVL_VCPU_TLBS(pVCpu) HWACCMFlushTLB(pVCpu)
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync/** @def PGM_INVL_ALL_VCPU_TLBS()
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * Invalidates the TLBs of all VCPUs
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * @param pVM The VM handle.
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync# define PGM_INVL_ALL_VCPU_TLBS(pVM) HWACCMFlushTLBOnAllVCpus(pVM)
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync# define PGM_INVL_ALL_VCPU_TLBS(pVM) HWACCMFlushTLBOnAllVCpus(pVM)
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync/** Size of the GCPtrConflict array in PGMMAPPING.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * @remarks Must be a power of two. */
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * Structure for tracking GC Mappings.
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * This structure is used by linked list in both GC and HC.
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsynctypedef struct PGMMAPPING
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync /** Pointer to next entry. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Pointer to next entry. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Pointer to next entry. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Indicate whether this entry is finalized. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Start Virtual address. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Last Virtual address (inclusive). */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Range size (bytes). */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Pointer to relocation callback function. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** User argument to the callback. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Mapping description / name. For easing debugging. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Last 8 addresses that caused conflicts. */
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync /** Number of conflicts for this hypervisor mapping. */
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync /** Number of page tables. */
7e8ef90d3160234df0f254131b87af4243d79476vboxsync /** Array of page table mapping data. Each entry
7e8ef90d3160234df0f254131b87af4243d79476vboxsync * describes one page table. The array can be longer
7e8ef90d3160234df0f254131b87af4243d79476vboxsync * than the declared length.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** The HC physical address of the page table. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** The HC physical address of the first PAE page table. */
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync /** The HC physical address of the second PAE page table. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** The HC virtual address of the 32-bit page table. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** The HC virtual address of the two PAE page table. (i.e 1024 entries instead of 512) */
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync /** The RC virtual address of the 32-bit page table. */
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync /** The RC virtual address of the two PAE page table. */
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync /** The R0 virtual address of the 32-bit page table. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync /** The R0 virtual address of the two PAE page table. */
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync/** Pointer to structure for tracking GC Mappings. */
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * Physical page access handler structure.
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * This is used to keep track of physical address ranges
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * which are being monitored in some kind of way.
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync /** Access type. */
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync /** Number of pages to update. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Pointer to R3 callback function. */
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync /** User argument for R3 handlers. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Pointer to R0 callback function. */
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync /** User argument for R0 handlers. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Pointer to RC callback function. */
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync /** User argument for RC handlers. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Description / Name. For easing debugging. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Profiling of this handler. */
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync/** Pointer to a physical page access handler structure. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * Cache node for the physical addresses covered by a virtual handler.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync /** Core node for the tree based on physical ranges. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync /** Offset from this struct to the PGMVIRTHANDLER structure. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync /** Offset of the next alias relative to this one.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * Bit 0 is used for indicating whether we're in the tree.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * Bit 1 is used for indicating that we're the head node.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync/** Pointer to a phys to virtual handler structure. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync/** The bit in PGMPHYS2VIRTHANDLER::offNextAlias used to indicate that the
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * node is in the tree. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync/** The bit in PGMPHYS2VIRTHANDLER::offNextAlias used to indicate that the
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * node is in the head of an alias chain.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * The PGMPHYS2VIRTHANDLER_IN_TREE is always set if this bit is set. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync/** The mask to apply to PGMPHYS2VIRTHANDLER::offNextAlias to get the offset. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * Virtual page access handler structure.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * This is used to keep track of virtual address ranges
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * which are being monitored in some kind of way.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Core node for the tree based on virtual ranges. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Size of the range (in bytes). */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Number of cache pages. */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync /** Access type. */
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync /** Pointer to the RC callback function. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Pointer to the R3 callback function for invalidation. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Pointer to the R3 callback function. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Description / Name. For easing debugging. */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync /** Profiling of this handler. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Array of cached physical addresses for the monitored ranged. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync PGMPHYS2VIRTHANDLER aPhysToVirt[HC_ARCH_BITS == 32 ? 1 : 2];
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Pointer to a virtual page access handler structure. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Page type.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @remarks This enum has to fit in a 3-bit field (see PGMPAGE::u3Type).
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @remarks This is used in the saved state, so changes to it requires bumping
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * the saved state version.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @todo So, convert to \#defines!
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** The usual invalid zero entry. */
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync /** RAM page. (RWX) */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** MMIO2 page. (RWX) */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** MMIO2 page aliased over an MMIO page. (RWX)
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * See PGMHandlerPhysicalPageAlias(). */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Shadowed ROM. (RWX) */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** ROM page. (R-X) */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** MMIO page. (---) */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** End of valid entries. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @name Page type predicates.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync#define PGMPAGETYPE_IS_READABLE(type) ( (type) <= PGMPAGETYPE_ROM )
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGMPAGETYPE_IS_WRITEABLE(type) ( (type) <= PGMPAGETYPE_ROM_SHADOW )
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGMPAGETYPE_IS_RWX(type) ( (type) <= PGMPAGETYPE_ROM_SHADOW )
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGMPAGETYPE_IS_ROX(type) ( (type) == PGMPAGETYPE_ROM )
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGMPAGETYPE_IS_NP(type) ( (type) == PGMPAGETYPE_MMIO )
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * A Physical Guest Page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * The format of this structure is complicated because we have to fit a lot
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * of information into as few bits as possible. The format is also subject
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * to change (there is one comming up soon). Which means that for we'll be
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * using PGM_PAGE_GET_*, PGM_PAGE_IS_ and PGM_PAGE_SET_* macros for *all*
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * accesses to the structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsynctypedef struct PGMPAGE
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** The physical address and the Page ID. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Combination of:
06ea6bcf23874b662d499b3f130024c98b2dd7a6vboxsync * - [0-7]: u2HandlerPhysStateY - the physical handler state
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * (PGM_PAGE_HNDL_PHYS_STATE_*).
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * - [8-9]: u2HandlerVirtStateY - the virtual handler state
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * (PGM_PAGE_HNDL_VIRT_STATE_*).
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * - [15]: fWrittenToY - flag indicating that a write monitored page was
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * written to when set.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * - [10-14]: 5 unused bits.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @remarks Warning! All accesses to the bits are hardcoded.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @todo Change this to a union with both bitfields, u8 and u accessors.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * That'll help deal with some of the hardcoded accesses.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @todo Include uStateY and uTypeY as well so it becomes 32-bit. This
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * will make it possible to turn some of the 16-bit accesses into
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync * 32-bit ones, which may be efficient (stalls).
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** The page state.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Only 2 bits are really needed for this. */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync /** The page type (PGMPAGETYPE).
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Only 3 bits are really needed for this. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Usage tracking (page pool). */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** The number of read locks on this page. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** The number of write locks on this page. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Pointer to a physical guest page. */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync/** Pointer to a const physical guest page. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Pointer to a physical guest page pointer. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Clears the page structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync } while (0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Initializes the page structure.
06ea6bcf23874b662d499b3f130024c98b2dd7a6vboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_INIT(pPage, _HCPhys, _idPage, _uType, _uState) \
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync AssertFatal(!(SetHCPhysTmp & ~UINT64_C(0x0000fffffffff000))); \
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync (pPage)->HCPhysAndPageID = (SetHCPhysTmp << (28-12)) | ((_idPage) & UINT32_C(0x0fffffff)); \
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync } while (0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Initializes the page structure of a ZERO page.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pVM The VM handle (for getting the zero page address).
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @param uType The page type (PGMPAGETYPE).
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync PGM_PAGE_INIT((pPage), (pVM)->pgm.s.HCPhysZeroPg, NIL_GMM_PAGEID, (uType), PGM_PAGE_STATE_ZERO)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @name The Page state, PGMPAGE::uStateY.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** The zero page.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * This is a per-VM page that's never ever mapped writable. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** A allocated page.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * This is a per-VM page allocated from the page pool (or wherever
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * we get MMIO2 pages from if the type is MMIO2).
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** A allocated page that's being monitored for writes.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * The shadow page table mappings are read-only. When a write occurs, the
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * fWrittenTo member is set, the page remapped as read-write and the state
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync * moved back to allocated. */
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync/** The page is shared, aka. copy-on-write.
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync * This is a page that's shared with other VMs. */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * Gets the page state.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @returns page state (PGM_PAGE_STATE_*).
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @param pPage Pointer to the physical guest page tracking structure.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync#define PGM_PAGE_GET_STATE(pPage) ( (pPage)->uStateY )
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * Sets the page state.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @param pPage Pointer to the physical guest page tracking structure.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @param _uState The new page state.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync#define PGM_PAGE_SET_STATE(pPage, _uState) do { (pPage)->uStateY = (_uState); } while (0)
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * Gets the host physical address of the guest page.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @returns host physical address (RTHCPHYS).
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @param pPage Pointer to the physical guest page tracking structure.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync#define PGM_PAGE_GET_HCPHYS(pPage) ( ((pPage)->HCPhysAndPageID >> 28) << 12 )
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Sets the host physical address of the guest page.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param _HCPhys The new host physical address.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync AssertFatal(!(SetHCPhysTmp & ~UINT64_C(0x0000fffffffff000))); \
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync (pPage)->HCPhysAndPageID = ((pPage)->HCPhysAndPageID & UINT32_C(0x0fffffff)) \
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync } while (0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Get the Page ID.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @returns The Page ID; NIL_GMM_PAGEID if it's a ZERO page.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync#define PGM_PAGE_GET_PAGEID(pPage) ( (uint32_t)((pPage)->HCPhysAndPageID & UINT32_C(0x0fffffff)) )
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * Sets the Page ID.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync (pPage)->HCPhysAndPageID = (((pPage)->HCPhysAndPageID) & UINT64_C(0xfffffffff0000000)) \
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync } while (0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Get the Chunk ID.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @returns The Chunk ID; NIL_GMM_CHUNKID if it's a ZERO page.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_GET_CHUNKID(pPage) ( PGM_PAGE_GET_PAGEID(pPage) >> GMM_CHUNKID_SHIFT )
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync * Get the index of the page within the allocation chunk.
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync * @returns The page index.
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync#define PGM_PAGE_GET_PAGE_IN_CHUNK(pPage) ( (uint32_t)((pPage)->HCPhysAndPageID & GMM_PAGEID_IDX_MASK) )
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * Gets the page type.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @returns The page type.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Sets the page type.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param _enmType The new page type (PGMPAGETYPE).
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_SET_TYPE(pPage, _enmType) do { (pPage)->uTypeY = (_enmType); } while (0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Checks if the page is marked for MMIO.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_IS_MMIO(pPage) ( (pPage)->uTypeY == PGMPAGETYPE_MMIO )
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync * Checks if the page is backed by the ZERO page.
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync#define PGM_PAGE_IS_ZERO(pPage) ( (pPage)->uStateY == PGM_PAGE_STATE_ZERO )
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Checks if the page is backed by a SHARED page.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_IS_SHARED(pPage) ( (pPage)->uStateY == PGM_PAGE_STATE_SHARED )
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Marks the paget as written to (for GMM change monitoring).
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_SET_WRITTEN_TO(pPage) do { (pPage)->u16MiscY.au8[1] |= UINT8_C(0x80); } while (0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Clears the written-to indicator.
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_CLEAR_WRITTEN_TO(pPage) do { (pPage)->u16MiscY.au8[1] &= UINT8_C(0x7f); } while (0)
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * Checks if the page was marked as written-to.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_IS_WRITTEN_TO(pPage) ( !!((pPage)->u16MiscY.au8[1] & UINT8_C(0x80)) )
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Enabled optimized access handler tests.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * These optimizations makes ASSUMPTIONS about the state values and the u16MiscY
06ea6bcf23874b662d499b3f130024c98b2dd7a6vboxsync * layout. When enabled, the compiler should normally generate more compact
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync/** @name Physical Access Handler State values (PGMPAGE::u2HandlerPhysStateY).
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @remarks The values are assigned in order of priority, so we can calculate
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * the correct state for a page with different handlers installed.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** No handler installed. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Monitoring is temporarily disabled. */
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync/** Write access is monitored. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** All access is monitored. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Gets the physical access handler state of a page.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @returns PGM_PAGE_HNDL_PHYS_STATE_* value.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Sets the physical access handler state of a page.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param _uState The new state value.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync#define PGM_PAGE_SET_HNDL_PHYS_STATE(pPage, _uState) \
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync do { (pPage)->u16MiscY.au8[0] = (_uState); } while (0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Checks if the page has any physical access handlers, including temporariliy disabled ones.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) != PGM_PAGE_HNDL_PHYS_STATE_NONE )
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Checks if the page has any active physical access handlers.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_HAS_ACTIVE_PHYSICAL_HANDLERS(pPage) \
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) >= PGM_PAGE_HNDL_PHYS_STATE_WRITE )
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @name Virtual Access Handler State values (PGMPAGE::u2HandlerVirtStateY).
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @remarks The values are assigned in order of priority, so we can calculate
06ea6bcf23874b662d499b3f130024c98b2dd7a6vboxsync * the correct state for a page with different handlers installed.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** No handler installed. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/* 1 is reserved so the lineup is identical with the physical ones. */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync/** Write access is monitored. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** All access is monitored. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Gets the virtual access handler state of a page.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @returns PGM_PAGE_HNDL_VIRT_STATE_* value.
06ea6bcf23874b662d499b3f130024c98b2dd7a6vboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) ( (pPage)->u16MiscY.au8[1] & UINT8_C(0x03) )
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * Sets the virtual access handler state of a page.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param _uState The new state value.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_SET_HNDL_VIRT_STATE(pPage, _uState) \
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync (pPage)->u16MiscY.au8[1] = ((pPage)->u16MiscY.au8[1] & UINT8_C(0xfc)) \
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync } while (0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Checks if the page has any virtual access handlers.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync ( PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) != PGM_PAGE_HNDL_VIRT_STATE_NONE )
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync * Same as PGM_PAGE_HAS_ANY_VIRTUAL_HANDLERS - can't disable pages in
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync * virtual handlers.
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_HAS_ACTIVE_VIRTUAL_HANDLERS(pPage) \
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * Checks if the page has any access handlers, including temporarily disabled ones.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) != PGM_PAGE_HNDL_PHYS_STATE_NONE \
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync || PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) != PGM_PAGE_HNDL_VIRT_STATE_NONE )
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * Checks if the page has any active access handlers.
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * @param pPage Pointer to the physical guest page tracking structure.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) >= PGM_PAGE_HNDL_PHYS_STATE_WRITE \
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync || PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) >= PGM_PAGE_HNDL_VIRT_STATE_WRITE )
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync * Checks if the page has any active access handlers catching all accesses.
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync * @param pPage Pointer to the physical guest page tracking structure.
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync ( ( ((pPage)->u16MiscY.au8[0] | (pPage)->u16MiscY.au8[1]) & UINT8_C(0x3) ) \
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync ( PGM_PAGE_GET_HNDL_PHYS_STATE(pPage) == PGM_PAGE_HNDL_PHYS_STATE_ALL \
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync || PGM_PAGE_GET_HNDL_VIRT_STATE(pPage) == PGM_PAGE_HNDL_VIRT_STATE_ALL )
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync/** @def PGM_PAGE_GET_TRACKING
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync * Gets the packed shadow page pool tracking data associated with a guest page.
7862f4bd000f1eb6c86289f5ac2849e9cf943ca9vboxsync * @returns uint16_t containing the data.
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * @param pPage Pointer to the physical guest page tracking structure.
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync#define PGM_PAGE_GET_TRACKING(pPage) ( (pPage)->u16TrackingY )
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync/** @def PGM_PAGE_SET_TRACKING
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync * Sets the packed shadow page pool tracking data associated with a guest page.
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync * @param pPage Pointer to the physical guest page tracking structure.
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync * @param u16TrackingData The tracking data to store.
5f2b03bf7695dabd71222dba123532a3f76828c1vboxsync#define PGM_PAGE_SET_TRACKING(pPage, u16TrackingData) \
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync do { (pPage)->u16TrackingY = (u16TrackingData); } while (0)
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync/** @def PGM_PAGE_GET_TD_CREFS
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync * Gets the @a cRefs tracking data member.
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync * @returns cRefs.
907b6adfa052386a0666d5557bee9bdbc100c2e5vboxsync * @param pPage Pointer to the physical guest page tracking structure.
45655563f818c5d5bbf4b3d14aa48cbd92a871f1vboxsync ((PGM_PAGE_GET_TRACKING(pPage) >> PGMPOOL_TD_CREFS_SHIFT) & PGMPOOL_TD_CREFS_MASK)
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync/** @def PGM_PAGE_GET_TD_IDX
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync * Gets the @a idx tracking data member.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync * @returns idx.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync * @param pPage Pointer to the physical guest page tracking structure.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync ((PGM_PAGE_GET_TRACKING(pPage) >> PGMPOOL_TD_IDX_SHIFT) & PGMPOOL_TD_IDX_MASK)
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync/** Max number of locks on a page. */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync/** Get the read lock count.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync * @returns count.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync * @param pPage Pointer to the physical guest page tracking structure.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync#define PGM_PAGE_GET_READ_LOCKS(pPage) ( (pPage)->cReadLocksY )
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync/** Get the write lock count.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync * @returns count.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync * @param pPage Pointer to the physical guest page tracking structure.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync#define PGM_PAGE_GET_WRITE_LOCKS(pPage) ( (pPage)->cWriteLocksY )
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync/** Decrement the read lock counter.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync * @param pPage Pointer to the physical guest page tracking structure.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync#define PGM_PAGE_DEC_READ_LOCKS(pPage) do { --(pPage)->cReadLocksY; } while (0)
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync/** Decrement the write lock counter.
ed9d3db07648c7e3a979105c15ad752ee9ea18devboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_DEC_WRITE_LOCKS(pPage) do { --(pPage)->cWriteLocksY; } while (0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Increment the read lock counter.
d4a9d525e6f2111d462d2d96462dced6b9ec00efvboxsync * @param pPage Pointer to the physical guest page tracking structure.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync#define PGM_PAGE_INC_READ_LOCKS(pPage) do { ++(pPage)->cReadLocksY; } while (0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Increment the write lock counter.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * @param pPage Pointer to the physical guest page tracking structure.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync#define PGM_PAGE_INC_WRITE_LOCKS(pPage) do { ++(pPage)->cWriteLocksY; } while (0)
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Enables sanity checking of write monitoring using CRC-32. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * Per page live save tracking data.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync /** Number of times it has been dirtied. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync /** Whether it is currently dirty. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync /** Ignore the page.
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * This is used for pages that has been MMIO, MMIO2 or ROM pages once. We will
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * deal with these after pausing the VM and DevPCI have said it bit about
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync * remappings. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync /** Was a ZERO page last time around. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Was a SHARED page last time around. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Whether the page is/was write monitored in a previous pass. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Whether the page is/was write monitored earlier in this pass. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Bits reserved for future use. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** CRC-32 for the page. This is for internal consistency checks. */
687794577e2e35c3cae67e692a7f2130d1262a82vboxsync/** Pointer to the per page live save tracking data. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** The max value of PGMLIVESAVERAMPAGE::cDirtied. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Ram range for GC Phys to HC Phys conversion.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync * Can be used for HC Virt to GC Phys and HC Virt to HC Phys
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * conversions too, but we'll let MM handle that for now.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * This structure is used by linked lists in both GC and HC.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsynctypedef struct PGMRAMRANGE
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Start of the range. Page aligned. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Size of the range. (Page aligned of course). */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Pointer to the next RAM range - for R3. */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync /** Pointer to the next RAM range - for R0. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Pointer to the next RAM range - for RC. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** PGM_RAM_RANGE_FLAGS_* flags. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Last address in the range (inclusive). Page aligned (-1). */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Start of the HC mapping of the range. This is only used for MMIO2. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Live save per page tracking data. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** The range description. */
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync /** Pointer to self - R0 pointer. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Pointer to self - RC pointer. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Padding to make aPage aligned on sizeof(PGMPAGE). */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync uint32_t au32Alignment2[HC_ARCH_BITS == 32 ? 1 : 3];
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync /** Array of physical guest page tracking structures. */
9523921c89c66f4bececdbd5ac95aed0039eda1bvboxsync/** Pointer to Ram range for GC Phys to HC Phys conversion. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** @name PGMRAMRANGE::fFlags
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync/** The RAM range is floating around as an independent guest mapping. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Ad hoc RAM range for an ROM mapping. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Ad hoc RAM range for an MMIO mapping. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Ad hoc RAM range for an MMIO2 mapping. */
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync/** Tests if a RAM range is an ad hoc one or not.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * @param pRam The RAM range.
702a8ee2dc1de96f2f77e97135015d3e243186fdvboxsync (!!( (pRam)->fFlags & (PGM_RAM_RANGE_FLAGS_AD_HOC_ROM | PGM_RAM_RANGE_FLAGS_AD_HOC_MMIO | PGM_RAM_RANGE_FLAGS_AD_HOC_MMIO2) ) )
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * Per page tracking structure for ROM image.
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * A ROM image may have a shadow page, in which case we may have two pages
2f3883b126a405f92b19e829472f614c7352b4f9vboxsync * backing it. This structure contains the PGMPAGE for both while
typedef struct PGMROMPAGE
bool fWrittenTo;
bool fDirty;
bool fDirtiedRecently;
} LiveSave;
} PGMROMPAGE;
typedef struct PGMROMRANGE
} PGMROMRANGE;
typedef struct PGMLIVESAVEMMIO2PAGE
bool fDirty;
bool fZero;
bool fReserved;
typedef struct PGMMMIO2RANGE
bool fMapped;
bool fOverlapping;
* PGMPhysRead/Write cache entry
typedef struct PGMPHYSCACHEENTRY
* PGMPhysRead/Write cache to reduce REM memory access overhead
typedef struct PGMPHYSCACHE
} PGMPHYSCACHE;
typedef struct PGMCHUNKR3MAP
void *pv;
typedef struct PGMCHUNKR3MAPTLBE
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
typedef struct PGMCHUNKR3MAPTLB
typedef struct PGMPAGER3MAPTLBE
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
typedef struct PGMPAGER3MAPTLB
typedef struct PGMMAPSETENTRY
typedef struct PGMMAPSET
} PGMMAPSET;
#ifdef IN_RC
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 VBOX_WITH_2X_4GB_ADDR_SPACE
#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 fDirty;
/** Used to indicate that this page can't be flushed. Important for cr3 root pages or shadow pae pd pages). */
#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 PGMPOOL_WITH_MONITORING
#ifdef VBOX_WITH_STATISTICS
#if defined(IN_RC)
#if defined(IN_RC)
#if defined(IN_RC)
#define PGMPOOL_TD_IDX_SHIFT 0
typedef struct PGMTREES
} PGMTREES;
#ifdef IN_RC
# ifdef IN_RING3
typedef struct PGMMODEDATA
DECLR3CALLBACKMEMBER(int, pfnR3ShwGetPage,(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
DECLR3CALLBACKMEMBER(int, pfnR3ShwModifyPage,(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLRCCALLBACKMEMBER(int, pfnRCShwGetPage,(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
DECLRCCALLBACKMEMBER(int, pfnRCShwModifyPage,(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR0CALLBACKMEMBER(int, pfnR0ShwGetPage,(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
DECLR0CALLBACKMEMBER(int, pfnR0ShwModifyPage,(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR3CALLBACKMEMBER(int, pfnR3GstGetPage,(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
DECLR3CALLBACKMEMBER(int, pfnR3GstModifyPage,(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLRCCALLBACKMEMBER(int, pfnRCGstGetPage,(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
DECLRCCALLBACKMEMBER(int, pfnRCGstModifyPage,(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR0CALLBACKMEMBER(int, pfnR0GstGetPage,(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
DECLR0CALLBACKMEMBER(int, pfnR0GstModifyPage,(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR3CALLBACKMEMBER(int, pfnR3BthSyncCR3,(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
DECLR3CALLBACKMEMBER(int, pfnR3BthSyncPage,(PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));
DECLR3CALLBACKMEMBER(int, pfnR3BthVerifyAccessSyncPage,(PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));
#ifdef VBOX_STRICT
DECLR3CALLBACKMEMBER(unsigned, pfnR3BthAssertCR3,(PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));
DECLRCCALLBACKMEMBER(int, pfnRCBthTrap0eHandler,(PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
DECLRCCALLBACKMEMBER(int, pfnRCBthSyncCR3,(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
DECLRCCALLBACKMEMBER(int, pfnRCBthSyncPage,(PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));
DECLRCCALLBACKMEMBER(int, pfnRCBthVerifyAccessSyncPage,(PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));
#ifdef VBOX_STRICT
DECLRCCALLBACKMEMBER(unsigned, pfnRCBthAssertCR3,(PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));
DECLR0CALLBACKMEMBER(int, pfnR0BthTrap0eHandler,(PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
DECLR0CALLBACKMEMBER(int, pfnR0BthSyncCR3,(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
DECLR0CALLBACKMEMBER(int, pfnR0BthSyncPage,(PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));
DECLR0CALLBACKMEMBER(int, pfnR0BthVerifyAccessSyncPage,(PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));
#ifdef VBOX_STRICT
DECLR0CALLBACKMEMBER(unsigned, pfnR0BthAssertCR3,(PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));
typedef struct PGM
bool fRamPreAlloc;
bool fFinalizedMappings;
bool fMappingsFixed;
bool fDisableMappings;
bool fNoMorePhysWrites;
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
uint32_t c;
* @cfgm PGM/MaxRing3Chunks */
} ChunkR3Map;
} Rom,
Ram;
bool fActive;
} LiveSave;
bool volatile fErrInjHandyPages;
STAMCOUNTER StatR3DetectedConflicts; /**< R3: Number of times PGMR3MapHasConflicts() detected a conflict. */
STAMPROFILE StatR3ResolveConflict; /**< R3: pgmR3SyncPTResolveConflict() profiling (includes the entire relocation). */
STAMPROFILE StatRZSyncCR3HandlerVirtualReset; /**< RC/R0: Profiling of the virtual handler resets. */
STAMPROFILE StatRZSyncCR3HandlerVirtualUpdate; /**< RC/R0: Profiling of the virtual handler updates. */
STAMPROFILE StatR3SyncCR3HandlerVirtualUpdate; /**< R3: Profiling of the virtual handler updates. */
STAMCOUNTER StatR3PhysHandlerReset; /**< R3: The number of times PGMHandlerPhysicalReset is called. */
STAMCOUNTER StatRZPhysHandlerReset; /**< RC/R0: The number of times PGMHandlerPhysicalReset is called. */
STAMPROFILE StatRZVirtHandlerSearchByPhys; /**< RC/R0: Profiling of pgmHandlerVirtualFindByPhysAddr. */
STAMPROFILE StatR3VirtHandlerSearchByPhys; /**< R3: Profiling of pgmHandlerVirtualFindByPhysAddr. */
STAMCOUNTER StatRZPageReplaceShared; /**< RC/R0: Times a shared page has been replaced by a private one. */
STAMCOUNTER StatRZPageReplaceZero; /**< RC/R0: Times the zero page has been replaced by a private one. */
/// @todo STAMCOUNTER StatRZPageHandyAllocs; /**< RC/R0: The number of times we've executed GMMR3AllocateHandyPages. */
STAMCOUNTER StatR3PageReplaceShared; /**< R3: Times a shared page has been replaced by a private one. */
STAMCOUNTER StatR3PageReplaceZero; /**< R3: Times the zero page has been replaced by a private one. */
/// @todo STAMCOUNTER StatR3PageHandyAllocs; /**< R3: The number of times we've executed GMMR3AllocateHandyPages. */
STAMCOUNTER StatRCInvlPgConflict; /**< RC: Number of times PGMInvalidatePage() detected a mapping conflict. */
STAMCOUNTER StatRCInvlPgSyncMonCR3; /**< RC: Number of times PGMInvalidatePage() ran into PGM_SYNC_MONITOR_CR3. */
# ifdef PGMPOOL_WITH_GCPHYS_TRACKING
STAMCOUNTER StatTrackAliased; /**< The number of times switching to cRef2, i.e. the page is being shadowed by two PTs. */
STAMCOUNTER StatTrackAliasedLots; /**< The number of times we're hitting pages which has overflowed cRef2. */
} PGM;
typedef struct PGMCPU
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
bool fA20Enabled;
#ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
#ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
#ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
/** The physical addresses of the guest page directories (PAE) pointed to by apGstPagePDsHC/GC. */
#ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
/* The shadow page pool index of the user table as specified during allocation; useful for freeing root pages */
/* The index into the user table (shadowed) as specified during allocation; useful for freeing root pages. */
DECLR3CALLBACKMEMBER(int, pfnR3ShwGetPage,(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
DECLR3CALLBACKMEMBER(int, pfnR3ShwModifyPage,(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLRCCALLBACKMEMBER(int, pfnRCShwGetPage,(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
DECLRCCALLBACKMEMBER(int, pfnRCShwModifyPage,(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR0CALLBACKMEMBER(int, pfnR0ShwGetPage,(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
DECLR0CALLBACKMEMBER(int, pfnR0ShwModifyPage,(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR3CALLBACKMEMBER(int, pfnR3GstGetPage,(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
DECLR3CALLBACKMEMBER(int, pfnR3GstModifyPage,(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLRCCALLBACKMEMBER(int, pfnRCGstGetPage,(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
DECLRCCALLBACKMEMBER(int, pfnRCGstModifyPage,(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR0CALLBACKMEMBER(int, pfnR0GstGetPage,(PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
DECLR0CALLBACKMEMBER(int, pfnR0GstModifyPage,(PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
DECLR3CALLBACKMEMBER(int, pfnR3BthSyncCR3,(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
DECLR3CALLBACKMEMBER(int, pfnR3BthSyncPage,(PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));
DECLR3CALLBACKMEMBER(int, pfnR3BthVerifyAccessSyncPage,(PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));
DECLR3CALLBACKMEMBER(unsigned, pfnR3BthAssertCR3,(PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));
DECLR0CALLBACKMEMBER(int, pfnR0BthTrap0eHandler,(PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
DECLR0CALLBACKMEMBER(int, pfnR0BthSyncCR3,(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
DECLR0CALLBACKMEMBER(int, pfnR0BthSyncPage,(PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));
DECLR0CALLBACKMEMBER(int, pfnR0BthVerifyAccessSyncPage,(PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));
DECLR0CALLBACKMEMBER(unsigned, pfnR0BthAssertCR3,(PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));
DECLRCCALLBACKMEMBER(int, pfnRCBthTrap0eHandler,(PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
DECLRCCALLBACKMEMBER(int, pfnRCBthSyncCR3,(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
DECLRCCALLBACKMEMBER(int, pfnRCBthSyncPage,(PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));
DECLRCCALLBACKMEMBER(int, pfnRCBthVerifyAccessSyncPage,(PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));
DECLRCCALLBACKMEMBER(unsigned, pfnRCBthAssertCR3,(PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));
STAMCOUNTER StatR0DynMapGCPageInlMisses; /**< R0: Misses that falls back to code common with PGMDynMapHCPage. */
STAMCOUNTER StatR0DynMapHCPageInlMisses; /**< R0: Misses that falls back to code common with PGMDynMapHCPage. */
STAMCOUNTER StatR0DynMapPageSlowLoopMisses; /**< R0: Misses in the pgmR0DynMapPageSlow search loop. */
STAMPROFILE StatRZTrap0eTime2CSAM; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is CSAM. */
STAMPROFILE StatRZTrap0eTime2DirtyAndAccessed; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is dirty and/or accessed bit emulation. */
STAMPROFILE StatRZTrap0eTime2GuestTrap; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is a guest trap. */
STAMPROFILE StatRZTrap0eTime2HndPhys; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is a physical handler. */
STAMPROFILE StatRZTrap0eTime2HndVirt; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is a virtual handler. */
STAMPROFILE StatRZTrap0eTime2HndUnhandled; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is access outside the monitored areas of a monitored page. */
STAMPROFILE StatRZTrap0eTime2Misc; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is not known. */
STAMPROFILE StatRZTrap0eTime2OutOfSync; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is an out-of-sync page. */
STAMPROFILE StatRZTrap0eTime2OutOfSyncHndPhys; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is an out-of-sync physical handler page. */
STAMPROFILE StatRZTrap0eTime2OutOfSyncHndVirt; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is an out-of-sync virtual handler page. */
STAMPROFILE StatRZTrap0eTime2OutOfSyncHndObs; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is an obsolete handler page. */
STAMPROFILE StatRZTrap0eTime2SyncPT; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is lazy syncing of a PT. */
STAMCOUNTER StatRZTrap0eConflicts; /**< RC/R0: The number of times \#PF was caused by an undetected conflict. */
STAMCOUNTER StatRZTrap0eHandlersMapping; /**< RC/R0: Number of traps due to access handlers in mappings. */
STAMCOUNTER StatRZTrap0eHandlersPhysical; /**< RC/R0: Number of traps due to physical access handlers. */
STAMCOUNTER StatRZTrap0eHandlersVirtual; /**< RC/R0: Number of traps due to virtual access handlers. */
STAMCOUNTER StatRZTrap0eHandlersVirtualByPhys; /**< RC/R0: Number of traps due to virtual access handlers found by physical address. */
STAMCOUNTER StatRZTrap0eHandlersVirtualUnmarked;/**< RC/R0: Number of traps due to virtual access handlers found by virtual address (without proper physical flags). */
STAMCOUNTER StatRZTrap0eHandlersUnhandled; /**< RC/R0: Number of traps due to access outside range of monitored page(s). */
STAMCOUNTER StatRZTrap0eHandlersInvalid; /**< RC/R0: Number of traps due to access to invalid physical memory. */
STAMCOUNTER StatRZTrap0eGuestPFUnh; /**< RC/R0: Real guest #PF ending up at the end of the #PF code. */
STAMCOUNTER StatRZGuestCR3WriteHandled; /**< RC/R0: The number of times WriteHandlerCR3() was successfully called. */
STAMCOUNTER StatRZGuestCR3WriteUnhandled; /**< RC/R0: The number of times WriteHandlerCR3() was called and we had to fall back to the recompiler. */
STAMCOUNTER StatRZGuestCR3WriteConflict; /**< RC/R0: The number of times WriteHandlerCR3() was called and a conflict was detected. */
STAMCOUNTER StatRZGuestROMWriteHandled; /**< RC/R0: The number of times pgmPhysRomWriteHandler() was successfully called. */
STAMCOUNTER StatRZGuestROMWriteUnhandled; /**< RC/R0: The number of times pgmPhysRomWriteHandler() was called and we had to fall back to the recompiler */
STAMPROFILE StatRZSyncCR3Handlers; /**< RC/R0: Profiling of the PGMSyncCR3() update handler section. */
STAMCOUNTER StatRZSyncCR3DstCacheHit; /**< RC/R0: The number of times we got some kind of cache hit on a page table. */
STAMCOUNTER StatRZSyncCR3DstFreed; /**< RC/R0: The number of times we've had to free a shadow entry. */
STAMCOUNTER StatRZSyncCR3DstFreedSrcNP; /**< RC/R0: The number of times we've had to free a shadow entry for which the source entry was not present. */
STAMCOUNTER StatRZSyncCR3DstNotPresent; /**< RC/R0: The number of times we've encountered a not present shadow entry for a present guest entry. */
STAMCOUNTER StatRZSyncCR3DstSkippedGlobalPD; /**< RC/R0: The number of times a global page directory wasn't flushed. */
STAMCOUNTER StatRZSyncCR3DstSkippedGlobalPT; /**< RC/R0: The number of times a page table with only global entries wasn't flushed. */
STAMCOUNTER StatRZSyncPagePDNAs; /**< RC/R0: The number of time we've marked a PD not present from SyncPage to virtualize the accessed bit. */
STAMCOUNTER StatRZSyncPagePDOutOfSync; /**< RC/R0: The number of time we've encountered an out-of-sync PD in SyncPage. */
STAMCOUNTER StatRZAccessedPage; /**< RC/R0: The number of pages marked not present for accessed bit emulation. */
STAMPROFILE StatRZDirtyBitTracking; /**< RC/R0: Profiling the dirty bit tracking in CheckPageFault().. */
STAMCOUNTER StatRZDirtyPage; /**< RC/R0: The number of pages marked read-only for dirty bit tracking. */
STAMCOUNTER StatRZDirtyPageBig; /**< RC/R0: The number of pages marked read-only for dirty bit tracking. */
STAMCOUNTER StatRZDirtyPageTrap; /**< RC/R0: The number of traps generated for dirty bit tracking. */
STAMCOUNTER StatRZDirtyPageStale; /**< RC/R0: The number of traps generated for dirty bit tracking. (stale tlb entries) */
STAMCOUNTER StatRZDirtyTrackRealPF; /**< RC/R0: The number of real pages faults during dirty bit tracking. */
STAMCOUNTER StatRZDirtiedPage; /**< RC/R0: The number of pages marked dirty because of write accesses. */
STAMCOUNTER StatRZPageAlreadyDirty; /**< RC/R0: The number of pages already marked dirty because of write accesses. */
STAMCOUNTER StatRZInvalidatePage4KBPages; /**< RC/R0: The number of times PGMInvalidatePage() was called for a 4KB page. */
STAMCOUNTER StatRZInvalidatePage4MBPages; /**< RC/R0: The number of times PGMInvalidatePage() was called for a 4MB page. */
STAMCOUNTER StatRZInvalidatePage4MBPagesSkip; /**< RC/R0: The number of times PGMInvalidatePage() skipped a 4MB page. */
STAMCOUNTER StatRZInvalidatePagePDMappings; /**< RC/R0: The number of times PGMInvalidatePage() was called for a page directory containing mappings (no conflict). */
STAMCOUNTER StatRZInvalidatePagePDNAs; /**< RC/R0: The number of times PGMInvalidatePage() was called for a not accessed page directory. */
STAMCOUNTER StatRZInvalidatePagePDNPs; /**< RC/R0: The number of times PGMInvalidatePage() was called for a not present page directory. */
STAMCOUNTER StatRZInvalidatePagePDOutOfSync; /**< RC/R0: The number of times PGMInvalidatePage() was called for an out of sync page directory. */
STAMCOUNTER StatRZInvalidatePageSkipped; /**< RC/R0: The number of times PGMInvalidatePage() was skipped due to not present shw or pending pending SyncCR3. */
STAMCOUNTER StatRZPageOutOfSyncUser; /**< RC/R0: The number of times user page is out of sync was detected in #PF or VerifyAccessSyncPage. */
STAMCOUNTER StatRZPageOutOfSyncSupervisor; /**< RC/R0: The number of times supervisor page is out of sync was detected in in #PF or VerifyAccessSyncPage. */
STAMCOUNTER StatRZPageOutOfSyncUserWrite; /**< RC/R0: The number of times user page is out of sync was detected in #PF. */
STAMCOUNTER StatRZPageOutOfSyncSupervisorWrite; /**< RC/R0: The number of times supervisor page is out of sync was detected in in #PF. */
STAMCOUNTER StatRZFlushTLBNewCR3; /**< RC/R0: The number of times PGMFlushTLB was called with a new CR3, non-global. (switch) */
STAMCOUNTER StatRZFlushTLBNewCR3Global; /**< RC/R0: The number of times PGMFlushTLB was called with a new CR3, global. (switch) */
STAMCOUNTER StatRZFlushTLBSameCR3; /**< RC/R0: The number of times PGMFlushTLB was called with the same CR3, non-global. (flush) */
STAMCOUNTER StatRZFlushTLBSameCR3Global; /**< RC/R0: The number of times PGMFlushTLB was called with the same CR3, global. (flush) */
STAMPROFILE StatR3SyncCR3Handlers; /**< R3: Profiling of the PGMSyncCR3() update handler section. */
STAMCOUNTER StatR3SyncCR3DstFreed; /**< R3: The number of times we've had to free a shadow entry. */
STAMCOUNTER StatR3SyncCR3DstFreedSrcNP; /**< R3: The number of times we've had to free a shadow entry for which the source entry was not present. */
STAMCOUNTER StatR3SyncCR3DstNotPresent; /**< R3: The number of times we've encountered a not present shadow entry for a present guest entry. */
STAMCOUNTER StatR3SyncCR3DstSkippedGlobalPD; /**< R3: The number of times a global page directory wasn't flushed. */
STAMCOUNTER StatR3SyncCR3DstSkippedGlobalPT; /**< R3: The number of times a page table with only global entries wasn't flushed. */
STAMCOUNTER StatR3SyncCR3DstCacheHit; /**< R3: The number of times we got some kind of cache hit on a page table. */
STAMCOUNTER StatR3SyncPagePDNAs; /**< R3: The number of time we've marked a PD not present from SyncPage to virtualize the accessed bit. */
STAMCOUNTER StatR3SyncPagePDOutOfSync; /**< R3: The number of time we've encountered an out-of-sync PD in SyncPage. */
STAMCOUNTER StatR3AccessedPage; /**< R3: The number of pages marked not present for accessed bit emulation. */
STAMPROFILE StatR3DirtyBitTracking; /**< R3: Profiling the dirty bit tracking in CheckPageFault(). */
STAMCOUNTER StatR3DirtyPage; /**< R3: The number of pages marked read-only for dirty bit tracking. */
STAMCOUNTER StatR3DirtyPageBig; /**< R3: The number of pages marked read-only for dirty bit tracking. */
STAMCOUNTER StatR3DirtyTrackRealPF; /**< R3: The number of real pages faults during dirty bit tracking. */
STAMCOUNTER StatR3DirtiedPage; /**< R3: The number of pages marked dirty because of write accesses. */
STAMCOUNTER StatR3PageAlreadyDirty; /**< R3: The number of pages already marked dirty because of write accesses. */
STAMCOUNTER StatR3InvalidatePage4KBPages; /**< R3: The number of times PGMInvalidatePage() was called for a 4KB page. */
STAMCOUNTER StatR3InvalidatePage4MBPages; /**< R3: The number of times PGMInvalidatePage() was called for a 4MB page. */
STAMCOUNTER StatR3InvalidatePage4MBPagesSkip; /**< R3: The number of times PGMInvalidatePage() skipped a 4MB page. */
STAMCOUNTER StatR3InvalidatePagePDNAs; /**< R3: The number of times PGMInvalidatePage() was called for a not accessed page directory. */
STAMCOUNTER StatR3InvalidatePagePDNPs; /**< R3: The number of times PGMInvalidatePage() was called for a not present page directory. */
STAMCOUNTER StatR3InvalidatePagePDMappings; /**< R3: The number of times PGMInvalidatePage() was called for a page directory containing mappings (no conflict). */
STAMCOUNTER StatR3InvalidatePagePDOutOfSync; /**< R3: The number of times PGMInvalidatePage() was called for an out of sync page directory. */
STAMCOUNTER StatR3InvalidatePageSkipped; /**< R3: The number of times PGMInvalidatePage() was skipped due to not present shw or pending pending SyncCR3. */
STAMCOUNTER StatR3PageOutOfSyncUser; /**< R3: The number of times user page is out of sync was detected in #PF or VerifyAccessSyncPage. */
STAMCOUNTER StatR3PageOutOfSyncSupervisor; /**< R3: The number of times supervisor page is out of sync was detected in in #PF or VerifyAccessSyncPage. */
STAMCOUNTER StatR3PageOutOfSyncUserWrite; /**< R3: The number of times user page is out of sync was detected in #PF. */
STAMCOUNTER StatR3PageOutOfSyncSupervisorWrite; /**< R3: The number of times supervisor page is out of sync was detected in in #PF. */
STAMCOUNTER StatR3FlushTLBNewCR3; /**< R3: The number of times PGMFlushTLB was called with a new CR3, non-global. (switch) */
STAMCOUNTER StatR3FlushTLBNewCR3Global; /**< R3: The number of times PGMFlushTLB was called with a new CR3, global. (switch) */
STAMCOUNTER StatR3FlushTLBSameCR3; /**< R3: The number of times PGMFlushTLB was called with the same CR3, non-global. (flush) */
STAMCOUNTER StatR3FlushTLBSameCR3Global; /**< R3: The number of times PGMFlushTLB was called with the same CR3, global. (flush) */
} PGMCPU;
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)
int pgmPhysGCPhys2CCPtrInternalReadOnly(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhys, const void **ppv);
VMMDECL(int) pgmPhysRomWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
#ifdef IN_RING3
int pgmPoolAllocEx(PVM pVM, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, PGMPOOLACCESS enmAccess, uint16_t iUser, uint32_t iUserTable, PPPGMPOOLPAGE ppPage, bool fLockPage = false);
DECLINLINE(int) pgmPoolAlloc(PVM pVM, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, uint16_t iUser, uint32_t iUserTable, PPPGMPOOLPAGE ppPage, bool fLockPage = false)
return pgmPoolAllocEx(pVM, GCPhys, enmKind, PGMPOOLACCESS_DONTCARE, iUser, iUserTable, ppPage, fLockPage);
void pgmPoolTracDerefGCPhysHint(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTHCPHYS HCPhys, RTGCPHYS GCPhysHint);
#ifdef PGMPOOL_WITH_MONITORING
void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTGCPHYS GCPhysFault, CTXTYPE(RTGCPTR, RTHCPTR, RTGCPTR) pvAddress, PDISCPUSTATE pCpu);
void pgmMapClearShadowPDEs(PVM pVM, PPGMPOOLPAGE pShwPageCR3, PPGMMAPPING pMap, unsigned iOldPDE, bool fDeactivateCR3);
#ifndef IN_RC
int pgmShwSyncLongModePDPtr(PVMCPU pVCpu, RTGCPTR64 GCPtr, PX86PML4E pGstPml4e, PX86PDPE pGstPdpe, PX86PDPAE *ppPD);
return pRam;
return NULL;
return VINF_SUCCESS;
DECLINLINE(int) pgmPhysGetPageWithHintEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRamHint)
if ( !pRam
return VINF_SUCCESS;
return NULL;
DECLINLINE(int) pgmPhysGetPageAndRangeEx(PPGM pPGM, RTGCPHYS GCPhys, PPPGMPAGE ppPage, PPGMRAMRANGE *ppRam)
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
void *pv;
return pv;
void *pv;
return pv;
#ifndef IN_RC
int rc;
return rc;
DECLINLINE(int) pgmPhysPageQueryTlbeWithPage(PPGM pPGM, PPGMPAGE pPage, RTGCPHYS GCPhys, PPPGMPAGEMAPTLBE ppTlbe)
int rc;
return rc;
# ifdef IN_RING3
if (!pGuestPD)
# ifdef IN_RING3
if (!pGuestPD)
# ifdef IN_RING3
if (!pGuestPD)
return pGuestPD;
# ifdef IN_RING3
if (!pGuestPDPT)
return pGuestPDPT;
# ifdef IN_RING3
if (!pGuestPDPT)
int rc = pgmR0DynMapGCPageInlined(PGMCPU2PGM(pPGM), pGuestPDPT->a[iPdpt].u & X86_PDPE_PG_MASK, (void **)&pGuestPD);
if ( !pGuestPD
return pGuestPD;
/* returning NULL is ok if we assume it's just an invalid page of some kind emulated as all 0s. (not quite true) */
return NULL;
int rc = pgmR0DynMapGCPageInlined(PGMCPU2PGM(pPGM), pGuestPDPT->a[iPdpt].u & X86_PDPE_PG_MASK, (void **)&pGuestPD);
if ( !pGuestPD
/* returning NIL_RTGCPHYS is ok if we assume it's just an invalid page or something which we'll emulate as all 0s. (not quite true) */
return NULL;
int rc = pgmR0DynMapGCPageInlined(PGMCPU2PGM(pPGM), pGuestPDPT->a[iPdpt].u & X86_PDPE_PG_MASK, (void **)&pGuestPD);
if ( !pGuestPD
return ZeroPde;
DECLINLINE(PX86PDPAE) pgmGstGetPaePDPtr(PPGMCPU pPGM, RTGCPTR GCPtr, unsigned *piPD, PX86PDPE pPdpe)
if (pPdpe)
int rc = pgmR0DynMapGCPageInlined(PGMCPU2PGM(pPGM), pGuestPDPT->a[iPdpt].u & X86_PDPE_PG_MASK, (void **)&pGuestPD);
if ( !pGuestPD
return pGuestPD;
/* 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_RC
if (!pGuestPml4)
return pGuestPml4;
if (!pGuestPml4)
if (!pGuestPml4)
return NULL;
DECLINLINE(X86PDEPAE) pgmGstGetLongModePDEEx(PPGMCPU pPGM, RTGCPTR64 GCPtr, PX86PML4E *ppPml4e, PX86PDPE pPdpe)
return ZeroPde;
return ZeroPde;
return NULL;
DECLINLINE(PX86PDPAE) pgmGstGetLongModePDPtr(PPGMCPU pPGM, RTGCPTR64 GCPtr, PX86PML4E *ppPml4e, PX86PDPE pPdpe, unsigned *piPD)
return pPD;
if (!pShwPde)
return ZeroPde;
return NULL;
PPGMPOOLPAGE pShwPde = pgmPoolGetPage(PGMCPU2PGM(pPGM)->CTX_SUFF(pPool), pPdpt->a[iPdpt].u & X86_PDPE_PG_MASK);
return NULL;
PPGMPOOLPAGE pShwPde = pgmPoolGetPage(PGMCPU2PGM(pPGM)->CTX_SUFF(pPool), pPdpt->a[iPdpt].u & X86_PDPE_PG_MASK);
if (!pShwPde)
return ZeroPde;
#ifndef IN_RC
if (!pShwPml4)
return ZeroPml4e;
if (!pShwPml4)
return NULL;
return pPD;
return NULL;
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=%RGp, .Core.KeyLast=%RGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n",
pPhys2Virt, pPhys2Virt->Core.Key, pPhys2Virt->Core.KeyLast, pPhys2Virt->offVirtHandler, pPhys2Virt->offNextAlias));
PPGMPHYS2VIRTHANDLER pRemove = (PPGMPHYS2VIRTHANDLER)RTAvlroGCPhysRemove(&pPGM->CTX_SUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key); NOREF(pRemove);
("pPhys2Virt=%p:{.Core.Key=%RGp, .Core.KeyLast=%RGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n",
pPhys2Virt, pPhys2Virt->Core.Key, pPhys2Virt->Core.KeyLast, pPhys2Virt->offVirtHandler, pPhys2Virt->offNextAlias));
("wanted: pPhys2Virt=%p:{.Core.Key=%RGp, .Core.KeyLast=%RGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n"
" got: pRemove=%p:{.Core.Key=%RGp, .Core.KeyLast=%RGp, .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->CTX_SUFF(pTrees)->PhysToVirtHandlers, pPhys2Virt->Core.Key);
("pPhys2Virt=%p:{.Core.Key=%RGp, .Core.KeyLast=%RGp, .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} [%RGp-%RGp]\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=%RGp, .Core.KeyLast=%RGp, .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, R3STRING(pCur->pszDesc)));
#ifdef PGMPOOL_WITH_GCPHYS_TRACKING
# ifdef LOG_ENABLED
Log2(("pgmTrackDerefGCPhys: %x -> %x pPhysPage=%R[pgmpage]\n", uOrg, PGM_PAGE_GET_TRACKING(pPhysPage), pPhysPage ));
#ifdef PGMPOOL_WITH_CACHE
pPage->cModifications = 1; /* reset counter (can't use 0, or else it will be reinserted in the modified list) */
#ifdef IN_RING0