PGMInternal.h revision 3ec8f688113b92e4f31a8d9fda15a30f6d2b6d90
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * PGM - Internal header file.
8c6fb701605a315f86160241e36fa643f8158ddevboxsync * Copyright (C) 2006-2010 Oracle Corporation
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * available from http://www.virtualbox.org. This file is free software;
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * you can redistribute it and/or modify it under the terms of the GNU
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * General Public License (GPL) as published by the Free Software
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @defgroup grp_pgm_int Internals
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @ingroup grp_pgm
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @internal
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @name PGM Compile Time Config
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Indicates that there are no guest mappings to care about.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Currently on raw-mode related code uses mappings, i.e. RC and R3 code.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync#if defined(IN_RING0) || !defined(VBOX_WITH_RAW_MODE)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Check and skip global PDEs for non-global flushes
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Optimization for PAE page tables that are modified often
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync//#if 0 /* disabled again while debugging */
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Large page support enabled only on 64 bits hosts; applies to nested paging only.
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * Enables optimizations for MMIO handlers that exploits X86_TRAP_PF_RSVD and
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * VMX_EXIT_EPT_MISCONFIG.
f44e23b1649344fbcc0e91b8699965f13d3bc4f7vboxsync * Chunk unmapping code activated on 32-bit hosts for > 1.5/2 GB guest memory support
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_WITH_LARGE_ADDRESS_SPACE_ON_32_BIT_HOST
f44e23b1649344fbcc0e91b8699965f13d3bc4f7vboxsync * Sync N pages instead of a whole page table
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Number of pages to sync during a page fault
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * When PGMPOOL_WITH_GCPHYS_TRACKING is enabled using high values here
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * causes a lot of unnecessary extents and also is slower than taking more \#PFs.
e1efbeea1e5e1e63cc2be01c582cec73bc58e839vboxsync * Note that \#PFs are much more expensive in the VT-x/AMD-V case due to
e1efbeea1e5e1e63cc2be01c582cec73bc58e839vboxsync * world switch overhead, so let's sync more.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/* Chose 32 based on the compile test in #4219; 64 shows worse stats.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * 32 again shows better results than 16; slightly more overhead in the \#PF handler,
142a193b7c7ba74914c647ad7ec4d3dc88c03208vboxsync * but ~5% fewer faults.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Number of PGMPhysRead/Write cache entries (must be <= sizeof(uint64_t))
8c6fb701605a315f86160241e36fa643f8158ddevboxsync#define PGM_MAX_PHYSCACHE_ENTRIES_MASK (PGM_MAX_PHYSCACHE_ENTRIES-1)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGMPOOL_CFG_MAX_GROW
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * The maximum number of pages to add to the pool in one go.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def VBOX_STRICT_PGM_HANDLER_VIRTUAL
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Enables some extra assertions for virtual handlers (mainly phys2virt related).
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def VBOX_WITH_NEW_LAZY_PAGE_ALLOC
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Enables the experimental lazy page allocation code. */
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/*#define VBOX_WITH_NEW_LAZY_PAGE_ALLOC */
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def VBOX_WITH_REAL_WRITE_MONITORED_PAGES
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Enables real write monitoring of pages, i.e. mapping them read-only and
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * only making them writable when getting a write access #PF. */
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @name PDPT and PML4 flags.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * These are placed in the three bits available for system programs in
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * the PDPT and PML4 entries.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** The entry is a permanent one and it's must always be present.
46d187d353685ef44f46d06582d0d69291e0f75evboxsync * Never free such an entry. */
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** Mapping (hypervisor allocated pagetable). */
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @name Page directory flags.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * These are placed in the three bits available for system programs in
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * the page directory entries.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** Mapping (hypervisor allocated pagetable). */
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** Made read-only to facilitate dirty bit tracking. */
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @name Page flags.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * These are placed in the three bits available for system programs in
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * the page entries.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** Made read-only to facilitate dirty bit tracking. */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync/** Scanned and approved by CSAM (tm).
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsync * NOTE: Must be identical to the one defined in CSAMInternal.h!!
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @todo Move PGM_PTFLAGS_* and PGM_PDFLAGS_* to VBox/vmm/pgm.h. */
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @name Defines used to indicate the shadow and guest paging in the templates.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** Macro for checking if the guest is using paging.
142a193b7c7ba74914c647ad7ec4d3dc88c03208vboxsync * @param uGstType PGM_TYPE_*
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param uShwType PGM_TYPE_*
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @remark ASSUMES certain order of the PGM_TYPE_* values.
6f17b5db855742e2cf9d2902a53b58c020f6bba9vboxsync/** Macro for checking if the guest supports the NX bit.
6f17b5db855742e2cf9d2902a53b58c020f6bba9vboxsync * @param uGstType PGM_TYPE_*
8c6fb701605a315f86160241e36fa643f8158ddevboxsync * @param uShwType PGM_TYPE_*
8c6fb701605a315f86160241e36fa643f8158ddevboxsync * @remark ASSUMES certain order of the PGM_TYPE_* values.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGM_HCPHYS_2_PTR
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Maps a HC physical page pool address to a virtual address.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @returns VBox status code.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pVM The VM handle.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pVCpu The current CPU.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param HCPhys The HC physical address to map to a virtual one.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param ppv Where to store the virtual address. No need to cast
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @remark Use with care as we don't have so much dynamic mapping space in
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * ring-0 on 32-bit darwin and in RC.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @remark There is no need to assert on the result.
f44e23b1649344fbcc0e91b8699965f13d3bc4f7vboxsync#if defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) || defined(IN_RC)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_HCPHYS_2_PTR(pVM, pVCpu, HCPhys, ppv) \
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync pgmRZDynMapHCPageInlined(pVCpu, HCPhys, (void **)(ppv) RTLOG_COMMA_SRC_POS)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_HCPHYS_2_PTR(pVM, pVCpu, HCPhys, ppv) \
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGM_GCPHYS_2_PTR_V2
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Maps a GC physical page address to a virtual address.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @returns VBox status code.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pVM The VM handle.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pVCpu The current CPU.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param GCPhys The GC physical address to map to a virtual one.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param ppv Where to store the virtual address. No need to cast this.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @remark Use with care as we don't have so much dynamic mapping space in
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * ring-0 on 32-bit darwin and in RC.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @remark There is no need to assert on the result.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync#if defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0) || defined(IN_RC)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_GCPHYS_2_PTR_V2(pVM, pVCpu, GCPhys, ppv) \
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync pgmRZDynMapGCPageV2Inlined(pVM, pVCpu, GCPhys, (void **)(ppv) RTLOG_COMMA_SRC_POS)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_GCPHYS_2_PTR_V2(pVM, pVCpu, GCPhys, ppv) \
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync PGMPhysGCPhys2R3Ptr(pVM, GCPhys, 1 /* one page only */, (PRTR3PTR)(ppv)) /** @todo this isn't asserting, use PGMRamGCPhys2HCPtr! */
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGM_GCPHYS_2_PTR
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Maps a GC physical page address to a virtual address.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @returns VBox status code.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pVM The VM handle.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param GCPhys The GC physical address to map to a virtual one.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param ppv Where to store the virtual address. No need to cast this.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @remark Use with care as we don't have so much dynamic mapping space in
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * ring-0 on 32-bit darwin and in RC.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @remark There is no need to assert on the result.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync#define PGM_GCPHYS_2_PTR(pVM, GCPhys, ppv) PGM_GCPHYS_2_PTR_V2(pVM, VMMGetCpu(pVM), GCPhys, ppv)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGM_GCPHYS_2_PTR_BY_VMCPU
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Maps a GC physical page address to a virtual address.
407e4f581d7a567b1b8fe0af00b2be49df2a2af0vboxsync * @returns VBox status code.
407e4f581d7a567b1b8fe0af00b2be49df2a2af0vboxsync * @param pVCpu The current CPU.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param GCPhys The GC physical address to map to a virtual one.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param ppv Where to store the virtual address. No need to cast this.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @remark Use with care as we don't have so much dynamic mapping space in
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * ring-0 on 32-bit darwin and in RC.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @remark There is no need to assert on the result.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync#define PGM_GCPHYS_2_PTR_BY_VMCPU(pVCpu, GCPhys, ppv) PGM_GCPHYS_2_PTR_V2((pVCpu)->CTX_SUFF(pVM), pVCpu, GCPhys, ppv)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGM_GCPHYS_2_PTR_EX
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Maps a unaligned GC physical page address to a virtual address.
f339edb4ba0e574e342ab15370e695f2a7f5fb25vboxsync * @returns VBox status code.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pVM The VM handle.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param GCPhys The GC physical address to map to a virtual one.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param ppv Where to store the virtual address. No need to cast this.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @remark Use with care as we don't have so much dynamic mapping space in
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * ring-0 on 32-bit darwin and in RC.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @remark There is no need to assert on the result.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync pgmRZDynMapGCPageOffInlined(VMMGetCpu(pVM), GCPhys, (void **)(ppv) RTLOG_COMMA_SRC_POS)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync PGMPhysGCPhys2R3Ptr(pVM, GCPhys, 1 /* one page only */, (PRTR3PTR)(ppv)) /** @todo this isn't asserting, use PGMRamGCPhys2HCPtr! */
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGM_DYNMAP_UNUSED_HINT
de0f1c1251cc9a7d80f9ebeb8f03fb2989fd6cd0vboxsync * Hints to the dynamic mapping code in RC and R0/darwin that the specified page
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * is no longer used.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * For best effect only apply this to the page that was mapped most recently.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pVCpu The current CPU.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pvPage The pool page.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_DYNMAP_UNUSED_HINT(pVCpu, pvPage) pgmRZDynMapUnusedHint(pVCpu, pvPage, RT_SRC_POS)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_DYNMAP_UNUSED_HINT(pVCpu, pvPage) pgmRZDynMapUnusedHint(pVCpu, pvPage)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_DYNMAP_UNUSED_HINT(pVCpu, pvPage) do {} while (0)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGM_DYNMAP_UNUSED_HINT_VM
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Hints to the dynamic mapping code in RC and R0/darwin that the specified page
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * is no longer used.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * For best effect only apply this to the page that was mapped most recently.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pVM The VM handle.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pvPage The pool page.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync#define PGM_DYNMAP_UNUSED_HINT_VM(pVM, pvPage) PGM_DYNMAP_UNUSED_HINT(VMMGetCpu(pVM), pvPage)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGM_INVL_PG
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Invalidates a page.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pVCpu The VMCPU handle.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param GCVirt The virtual address of the page to invalidate.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_INVL_PG(pVCpu, GCVirt) ASMInvalidatePage((void *)(uintptr_t)(GCVirt))
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_INVL_PG(pVCpu, GCVirt) HWACCMInvalidatePage(pVCpu, (RTGCPTR)(GCVirt))
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_INVL_PG(pVCpu, GCVirt) HWACCMInvalidatePage(pVCpu, (RTGCPTR)(GCVirt))
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGM_INVL_PG_ALL_VCPU
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Invalidates a page on all VCPUs
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pVM The VM handle.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param GCVirt The virtual address of the page to invalidate.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt) ASMInvalidatePage((void *)(uintptr_t)(GCVirt))
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt) HWACCMInvalidatePageOnAllVCpus(pVM, (RTGCPTR)(GCVirt))
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_INVL_PG_ALL_VCPU(pVM, GCVirt) HWACCMInvalidatePageOnAllVCpus(pVM, (RTGCPTR)(GCVirt))
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGM_INVL_BIG_PG
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Invalidates a 4MB page directory entry.
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * @param pVCpu The VMCPU handle.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param GCVirt The virtual address within the page directory to invalidate.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_INVL_BIG_PG(pVCpu, GCVirt) ASMReloadCR3()
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_INVL_BIG_PG(pVCpu, GCVirt) HWACCMFlushTLB(pVCpu)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_INVL_BIG_PG(pVCpu, GCVirt) HWACCMFlushTLB(pVCpu)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGM_INVL_VCPU_TLBS()
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Invalidates the TLBs of the specified VCPU
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pVCpu The VMCPU handle.
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_INVL_VCPU_TLBS(pVCpu) HWACCMFlushTLB(pVCpu)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync# define PGM_INVL_VCPU_TLBS(pVCpu) HWACCMFlushTLB(pVCpu)
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync/** @def PGM_INVL_ALL_VCPU_TLBS()
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * Invalidates the TLBs of all VCPUs
1ace73711fa06807748eff26632c7273a1f7c2dbvboxsync * @param pVM The VM handle.
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync# define PGM_INVL_ALL_VCPU_TLBS(pVM) HWACCMFlushTLBOnAllVCpus(pVM)
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync# define PGM_INVL_ALL_VCPU_TLBS(pVM) HWACCMFlushTLBOnAllVCpus(pVM)
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync/** @name Safer Shadow PAE PT/PTE
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync * For helping avoid misinterpreting invalid PAE/AMD64 page table entries as
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync * For making sure that u1Present and X86_PTE_P checks doesn't mistake
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync * invalid entries for present.
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync * @sa X86PTEPAE.
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync /** Unsigned integer view */
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync /* Not other views. */
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync# define PGMSHWPTEPAE_IS_P(Pte) ( ((Pte).uCareful & (X86_PTE_P | X86_PTE_PAE_MBZ_MASK_NX)) == X86_PTE_P )
f4ccb18a71e0e531719734918583f84fbc72ebfevboxsync# define PGMSHWPTEPAE_IS_RW(Pte) ( !!((Pte).uCareful & X86_PTE_RW))
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync# define PGMSHWPTEPAE_IS_US(Pte) ( !!((Pte).uCareful & X86_PTE_US))
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync# define PGMSHWPTEPAE_IS_A(Pte) ( !!((Pte).uCareful & X86_PTE_A))
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync# define PGMSHWPTEPAE_IS_D(Pte) ( !!((Pte).uCareful & X86_PTE_D))
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync# define PGMSHWPTEPAE_IS_TRACK_DIRTY(Pte) ( !!((Pte).uCareful & PGM_PTFLAGS_TRACK_DIRTY) )
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsync# define PGMSHWPTEPAE_IS_P_RW(Pte) ( ((Pte).uCareful & (X86_PTE_P | X86_PTE_RW | X86_PTE_PAE_MBZ_MASK_NX)) == (X86_PTE_P | X86_PTE_RW) )
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync# define PGMSHWPTEPAE_GET_LOG(Pte) ( (Pte).uCareful )
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync# define PGMSHWPTEPAE_GET_HCPHYS(Pte) ( (Pte).uCareful & X86_PTE_PAE_PG_MASK )
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync# define PGMSHWPTEPAE_GET_U(Pte) ( (Pte).uCareful ) /**< Use with care. */
f4ccb18a71e0e531719734918583f84fbc72ebfevboxsync# define PGMSHWPTEPAE_SET(Pte, uVal) do { (Pte).uCareful = (uVal); } while (0)
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync# define PGMSHWPTEPAE_SET2(Pte, Pte2) do { (Pte).uCareful = (Pte2).uCareful; } while (0)
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync# define PGMSHWPTEPAE_ATOMIC_SET(Pte, uVal) do { ASMAtomicWriteU64(&(Pte).uCareful, (uVal)); } while (0)
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync# define PGMSHWPTEPAE_ATOMIC_SET2(Pte, Pte2) do { ASMAtomicWriteU64(&(Pte).uCareful, (Pte2).uCareful); } while (0)
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync# define PGMSHWPTEPAE_SET_RO(Pte) do { (Pte).uCareful &= ~(X86PGPAEUINT)X86_PTE_RW; } while (0)
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsync# define PGMSHWPTEPAE_SET_RW(Pte) do { (Pte).uCareful |= X86_PTE_RW; } while (0)
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync * For making sure that u1Present and X86_PTE_P checks doesn't mistake
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync * invalid entries for present.
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync * @sa X86PTPAE.
771761cda2c81e899526a0dce22c8cd2510fff82vboxsynctypedef struct PGMSHWPTPAE
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync# define PGMSHWPTEPAE_IS_P(Pte) ( (Pte).n.u1Present )
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync# define PGMSHWPTEPAE_IS_RW(Pte) ( (Pte).n.u1Write )
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync# define PGMSHWPTEPAE_IS_A(Pte) ( (Pte).n.u1Accessed )
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync# define PGMSHWPTEPAE_IS_TRACK_DIRTY(Pte) ( !!((Pte).u & PGM_PTFLAGS_TRACK_DIRTY) )
f4ccb18a71e0e531719734918583f84fbc72ebfevboxsync# define PGMSHWPTEPAE_IS_P_RW(Pte) ( ((Pte).u & (X86_PTE_P | X86_PTE_RW)) == (X86_PTE_P | X86_PTE_RW) )
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync# define PGMSHWPTEPAE_GET_HCPHYS(Pte) ( (Pte).u & X86_PTE_PAE_PG_MASK )
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync# define PGMSHWPTEPAE_GET_U(Pte) ( (Pte).u ) /**< Use with care. */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync# define PGMSHWPTEPAE_SET(Pte, uVal) do { (Pte).u = (uVal); } while (0)
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsync# define PGMSHWPTEPAE_SET2(Pte, Pte2) do { (Pte).u = (Pte2).u; } while (0)
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync# define PGMSHWPTEPAE_ATOMIC_SET(Pte, uVal) do { ASMAtomicWriteU64(&(Pte).u, (uVal)); } while (0)
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync# define PGMSHWPTEPAE_ATOMIC_SET2(Pte, Pte2) do { ASMAtomicWriteU64(&(Pte).u, (Pte2).u); } while (0)
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync# define PGMSHWPTEPAE_SET_RO(Pte) do { (Pte).u &= ~(X86PGPAEUINT)X86_PTE_RW; } while (0)
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync# define PGMSHWPTEPAE_SET_RW(Pte) do { (Pte).u |= X86_PTE_RW; } while (0)
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync/** Pointer to a shadow PAE PTE. */
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync/** Pointer to a const shadow PAE PTE. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync/** Pointer to a shadow PAE page table. */
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync/** Pointer to a const shadow PAE page table. */
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync/** Size of the GCPtrConflict array in PGMMAPPING.
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync * @remarks Must be a power of two. */
9a08dd6ed47cffa9cacbb9d53db1ce71d04db61fvboxsync * Structure for tracking GC Mappings.
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync * This structure is used by linked list in both GC and HC.
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsynctypedef struct PGMMAPPING
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync /** Pointer to next entry. */
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync /** Pointer to next entry. */
f4ccb18a71e0e531719734918583f84fbc72ebfevboxsync /** Pointer to next entry. */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync /** Indicate whether this entry is finalized. */
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsync /** Start Virtual address. */
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync /** Last Virtual address (inclusive). */
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync /** Range size (bytes). */
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync /** Pointer to relocation callback function. */
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync /** User argument to the callback. */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync /** Mapping description / name. For easing debugging. */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync /** Last 8 addresses that caused conflicts. */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync /** Number of conflicts for this hypervisor mapping. */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync /** Number of page tables. */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync /** Array of page table mapping data. Each entry
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * describes one page table. The array can be longer
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * than the declared length.
efbdd9fc22305720d20be7cc37b4f45f43146b09vboxsync /** The HC physical address of the page table. */
f339edb4ba0e574e342ab15370e695f2a7f5fb25vboxsync /** The HC physical address of the first PAE page table. */
907ba2c9b3d1821f95be17115ecad9fe8a2cae02vboxsync /** The HC physical address of the second PAE page table. */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync /** The HC virtual address of the 32-bit page table. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** The HC virtual address of the two PAE page table. (i.e 1024 entries instead of 512) */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** The RC virtual address of the 32-bit page table. */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync /** The RC virtual address of the two PAE page table. */
407e4f581d7a567b1b8fe0af00b2be49df2a2af0vboxsync /** The R0 virtual address of the 32-bit page table. */
3b58b08293698f7f081b5558c52e80741a4a6763vboxsync /** The R0 virtual address of the two PAE page table. */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync/** Pointer to structure for tracking GC Mappings. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync * Physical page access handler structure.
ea17f2e36383176db94ff3608f628a1e7432fa60vboxsync * This is used to keep track of physical address ranges
8c6fb701605a315f86160241e36fa643f8158ddevboxsync * which are being monitored in some kind of way.
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** Access type. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** Number of pages to update. */
efbdd9fc22305720d20be7cc37b4f45f43146b09vboxsync /** Set if we have pages that have been aliased. */
771761cda2c81e899526a0dce22c8cd2510fff82vboxsync /** Set if we have pages that have temporarily been disabled. */
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync /** Pointer to R3 callback function. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** User argument for R3 handlers. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** Pointer to R0 callback function. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** User argument for R0 handlers. */
f4ccb18a71e0e531719734918583f84fbc72ebfevboxsync /** Pointer to RC callback function. */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync /** User argument for RC handlers. */
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsync /** Description / Name. For easing debugging. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** Profiling of this handler. */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync/** Pointer to a physical page access handler structure. */
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync * Cache node for the physical addresses covered by a virtual handler.
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync /** Core node for the tree based on physical ranges. */
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync /** Offset from this struct to the PGMVIRTHANDLER structure. */
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync /** Offset of the next alias relative to this one.
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync * Bit 0 is used for indicating whether we're in the tree.
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync * Bit 1 is used for indicating that we're the head node.
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync/** Pointer to a phys to virtual handler structure. */
f4ccb18a71e0e531719734918583f84fbc72ebfevboxsync/** The bit in PGMPHYS2VIRTHANDLER::offNextAlias used to indicate that the
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync * node is in the tree. */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync/** The bit in PGMPHYS2VIRTHANDLER::offNextAlias used to indicate that the
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsync * node is in the head of an alias chain.
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync * The PGMPHYS2VIRTHANDLER_IN_TREE is always set if this bit is set. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync/** The mask to apply to PGMPHYS2VIRTHANDLER::offNextAlias to get the offset. */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync * Virtual page access handler structure.
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync * This is used to keep track of virtual address ranges
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync * which are being monitored in some kind of way.
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync /** Core node for the tree based on virtual ranges. */
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync /** Size of the range (in bytes). */
76800c2d8e954bb5249d2d30f4af41c6ea03ad5evboxsync /** Number of cache pages. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** Access type. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** Pointer to the RC callback function. */
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync /** Pointer to the R3 callback function for invalidation. */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync /** Pointer to the R3 callback function. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** Description / Name. For easing debugging. */
9a08dd6ed47cffa9cacbb9d53db1ce71d04db61fvboxsync /** Profiling of this handler. */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync /** Array of cached physical addresses for the monitored ranged. */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync PGMPHYS2VIRTHANDLER aPhysToVirt[HC_ARCH_BITS == 32 ? 1 : 2];
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync/** Pointer to a virtual page access handler structure. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync/** @name Page type predicates.
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync#define PGMPAGETYPE_IS_READABLE(type) ( (type) <= PGMPAGETYPE_ROM )
9a08dd6ed47cffa9cacbb9d53db1ce71d04db61fvboxsync#define PGMPAGETYPE_IS_WRITEABLE(type) ( (type) <= PGMPAGETYPE_ROM_SHADOW )
f4ccb18a71e0e531719734918583f84fbc72ebfevboxsync#define PGMPAGETYPE_IS_RWX(type) ( (type) <= PGMPAGETYPE_ROM_SHADOW )
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync#define PGMPAGETYPE_IS_ROX(type) ( (type) == PGMPAGETYPE_ROM )
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync#define PGMPAGETYPE_IS_NP(type) ( (type) == PGMPAGETYPE_MMIO )
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync * A Physical Guest Page tracking structure.
ae9aaa62489b8ace9ce2a0a15f0b2f7d3be340c6vboxsync * The format of this structure is complicated because we have to fit a lot
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync * of information into as few bits as possible. The format is also subject
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync * to change (there is one coming up soon). Which means that for we'll be
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync * using PGM_PAGE_GET_*, PGM_PAGE_IS_ and PGM_PAGE_SET_* macros for *all*
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsync * accesses to the structure.
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsynctypedef struct PGMPAGE
1d258b8772ee104b5fab3d1743eabc2f5cfe2fa4vboxsync /** Bit field. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** The physical address and the Page ID. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** 7:0 - The physical handler state
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync * (PGM_PAGE_HNDL_PHYS_STATE_*). */
f4ccb18a71e0e531719734918583f84fbc72ebfevboxsync /*uint32_t u6Reserved : 6;*/
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync /** 9:8 - The physical handler state
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync * (PGM_PAGE_HNDL_VIRT_STATE_*). */
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsync /** 10 - Indicator of dirty page for fault tolerance
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync * tracking. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** 12:11 - Currently unused. */
f4ccb18a71e0e531719734918583f84fbc72ebfevboxsync /** 14:13 - Paging structure needed to map the page
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync * (PGM_PAGE_PDE_TYPE_*). */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync /** 15 - Flag indicating that a write monitored page was written
af8ba507921d1f8c4e22a120b24de396b08e19efvboxsync * to when set. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** 18:16 - The page state. */
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync /** 21:19 - The page type (PGMPAGETYPE). */
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync /** 31:22 - PTE index for usage tracking (page pool). */
6e3cc82d5d5effda92c9fec18b870d54386f99favboxsync /** Usage tracking (page pool). */
76800c2d8e954bb5249d2d30f4af41c6ea03ad5evboxsync /** The number of read locks on this page. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** The number of write locks on this page. */
9a08dd6ed47cffa9cacbb9d53db1ce71d04db61fvboxsync /** 64-bit integer view. */
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync /** 16-bit view. */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync /** 16-bit view. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync /** 8-bit view. */
13b516eac15d19e108e587a9d9ecc85e1961ac6dvboxsync/** Pointer to a physical guest page. */
2ebf77e955a41ebc4eaa4a0d2a9aaf05540d2e4dvboxsync/** Pointer to a const physical guest page. */
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync/** Pointer to a physical guest page pointer. */
7bff28e0cedd8656acd24b420759649184d8cf00vboxsync * Clears the page structure.
8dc3361c3de6b4f38230d57c547ab74b713f6ff1vboxsync * @param a_pPage Pointer to the physical guest page tracking structure.
(a_pPage)->u1.bit.HCPhysAndPageID = (SetHCPhysTmp << (28-12)) | ((a_idPage) & UINT32_C(0x0fffffff)); \
PGM_PAGE_INIT((a_pPage), (a_pVM)->pgm.s.HCPhysZeroPg, NIL_GMM_PAGEID, (a_uType), PGM_PAGE_STATE_ZERO)
#define PGM_PAGE_STATE_ZERO 0
#define PGM_PAGE_SET_STATE(a_pPage, a_uState) do { (a_pPage)->u1.bit.uStateY = (a_uState); } while (0)
#define PGM_PAGE_GET_PAGEID(a_pPage) ( (uint32_t)((a_pPage)->u1.bit.HCPhysAndPageID & UINT32_C(0x0fffffff)) )
(a_pPage)->u1.bit.HCPhysAndPageID = (((a_pPage)->u1.bit.HCPhysAndPageID) & UINT64_C(0xfffffffff0000000)) \
#define PGM_PAGE_GET_PAGE_IN_CHUNK(a_pPage) ( (uint32_t)((a_pPage)->u1.bit.HCPhysAndPageID & GMM_PAGEID_IDX_MASK) )
#define PGM_PAGE_SET_TYPE(a_pPage, a_enmType) do { (a_pPage)->u1.bit.uTypeY = (a_enmType); } while (0)
#define PGM_PAGE_SET_PTE_INDEX(a_pPage, a_iPte) do { (a_pPage)->u1.bit.u10PteIdx = (a_iPte); } while (0)
#define PGM_PAGE_PDE_TYPE_DONTCARE 0
/** Can use a page directory entry to map the continuous range - temporarily disabled (by page monitoring). */
#define PGM_PAGE_HNDL_PHYS_STATE_NONE 0
#define PGM_PAGE_HNDL_VIRT_STATE_NONE 0
# define PGMLIVESAVERAMPAGE_WITH_CRC32
typedef struct PGMLIVESAVERAMPAGE
#define PGM_USE_RAMRANGE_SEARCH_TREES
typedef struct PGMRAMRANGE
} PGMRAMRANGE;
(!!( (pRam)->fFlags & (PGM_RAM_RANGE_FLAGS_AD_HOC_ROM | PGM_RAM_RANGE_FLAGS_AD_HOC_MMIO | PGM_RAM_RANGE_FLAGS_AD_HOC_MMIO2) ) )
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 PGMRCDYNMAPENTRY
struct PGMRCDYNMAPENTRY_PPTE
} uPte;
* paDynPageMap* PGM members. However, it has to be defined in PGMInternal.h
typedef struct PGMRCDYNMAP
} PGMRCDYNMAP;
typedef struct PGMMAPSETENTRY
#ifndef IN_RC
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
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). */
typedef struct PGMPOOL
bool fCacheEnabled;
#ifdef VBOX_WITH_STATISTICS
#ifdef VBOX_WITH_STATISTICS
# define PGMPOOL_PAGE_2_PTR(a_pVM, a_pPage) pgmPoolMapPageInlined((a_pVM), (a_pPage) RTLOG_COMMA_SRC_POS)
# define PGMPOOL_PAGE_2_PTR_V2(a_pVM, a_pVCpu, a_pPage) pgmPoolMapPageV2Inlined((a_pVM), (a_pVCpu), (a_pPage) RTLOG_COMMA_SRC_POS)
#define PGMPOOL_TD_IDX_SHIFT 0
typedef struct PGMTREES
} PGMTREES;
typedef struct PGMPTWALKCORE
bool fSucceeded;
bool fNotPresent;
bool fBadPhysAddr;
bool fRsvdError;
bool fBigPage;
bool fGigantPage;
bool fEffectiveUS;
bool fEffectiveRW;
bool fEffectiveNX;
typedef struct PGMPTWALKGSTAMD64
typedef struct PGMPTWALKGSTPAE
typedef struct PGMPTWALKGST32BIT
#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, uint32_t fOpFlags));
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, uint32_t fOpFlags));
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, uint32_t fOpFlags));
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, 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, bool *pfLockTaken));
DECLRCCALLBACKMEMBER(int, pfnRCBthSyncCR3,(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
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, bool *pfLockTaken));
DECLR0CALLBACKMEMBER(int, pfnR0BthSyncCR3,(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
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));
#ifdef VBOX_WITH_STATISTICS
typedef struct PGMSTATS
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. */
STAMCOUNTER StatR3PhysHandlerLookupHits; /**< R3: Number of cache hits when looking up physical handlers. */
STAMCOUNTER StatR3PhysHandlerLookupMisses; /**< R3: Number of cache misses when looking up physical handlers. */
STAMCOUNTER StatRZPhysHandlerLookupHits; /**< RC/R0: Number of cache hits when lookup up physical handlers. */
STAMCOUNTER StatRZPhysHandlerLookupMisses; /**< RC/R0: Number of cache misses when looking up physical handlers */
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. */
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. */
} PGMSTATS;
typedef struct PGM
bool fRamPreAlloc;
bool fNestedPaging;
bool fNoMorePhysWrites;
bool fPciPassthrough;
bool fFinalizedMappings;
bool fMappingsFixed;
bool fMappingsFixedRestored;
bool fMappingsDisabled;
* @todo The plan of keeping PGMRCDYNMAP private to PGMRZDynMap.cpp didn't
#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
uint32_t c;
* @cfgm PGM/MaxRing3Chunks */
} ChunkR3Map;
} Rom,
Ram;
bool fActive;
} LiveSave;
bool volatile fErrInjHandyPages;
uint32_t cAllPages; /**< The total number of pages. (Should be Private + Shared + Zero + Pure MMIO.) */
#ifdef VBOX_WITH_STATISTICS
} PGM;
typedef struct PGMCPUSTATS
STAMCOUNTER StatR0NpMiscfgSyncPage; /**< R0: SyncPage calls from PGMR0Trap0eHandlerNPMisconfig(). */
STAMPROFILE StatRZTrap0eTime2Ballooned; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is read access to a ballooned page. */
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 StatRZTrap0eTime2InvalidPhys; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is access to an invalid physical guest address. */
STAMPROFILE StatRZTrap0eTime2MakeWritable; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is a page that needed to be made writable. */
STAMPROFILE StatRZTrap0eTime2Mapping; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is the guest mappings. */
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. */
STAMPROFILE StatRZTrap0eTime2WPEmulation; /**< RC/R0: Profiling of the Trap0eHandler body when the cause is CR0.WP emulation. */
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 StatRZTrap0eHandlersPhysAll; /**< RC/R0: Number of traps due to physical all-access handlers. */
STAMCOUNTER StatRZTrap0eHandlersPhysAllOpt; /**< RC/R0: Number of the physical all-access handler traps using the optimization. */
STAMCOUNTER StatRZTrap0eHandlersPhysWrite; /**< RC/R0: Number of traps due to write-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 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 */
STAMCOUNTER StatRZDynMapPageSlowLoopMisses; /**< RZ: Misses in the pgmR0DynMapPageSlow search loop. */
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 StatRZPageOutOfSyncBallloon; /**< RC/R0: The number of times a ballooned page was accessed (read). */
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 StatR3PageOutOfSyncBallloon; /**< R3: The number of times a ballooned page was accessed (read). */
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) */
} PGMCPUSTATS;
typedef struct PGMCPU
bool fA20Enabled;
bool fNoExecuteEnabled;
#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, uint32_t fOpFlags));
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, uint32_t fOpFlags));
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, uint32_t fOpFlags));
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, 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, bool *pfLockTaken));
DECLR0CALLBACKMEMBER(int, pfnR0BthSyncCR3,(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
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, bool *pfLockTaken));
DECLRCCALLBACKMEMBER(int, pfnRCBthSyncCR3,(PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
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));
} PGMCPU;
int pgmR3SyncPTResolveConflict(PVM pVM, PPGMMAPPING pMapping, PX86PD pPDSrc, RTGCPTR GCPtrOldMapping);
void pgmHandlerPhysicalResetAliasedPage(PVM pVM, PPGMPAGE pPage, RTGCPHYS GCPhysPage, bool fDoAccounting);
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) pgmPhysHandlerRedirectToHC(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
VMMDECL(int) pgmPhysRomWriteHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
int pgmPhysFreePage(PVM pVM, PGMMFREEPAGESREQ pReq, uint32_t *pcPendingPages, PPGMPAGE pPage, RTGCPHYS GCPhys);
#ifdef IN_RING3
DECLCALLBACK(VBOXSTRICTRC) pgmR3PoolClearAllRendezvous(PVM pVM, PVMCPU pVCpu, void *fpvFlushRemTbl);
int pgmRZDynMapGCPageCommon(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, void **ppv RTLOG_COMMA_SRC_POS_DECL);
# ifdef LOG_ENABLED
int pgmPoolAllocEx(PVM pVM, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, PGMPOOLACCESS enmAccess, uint16_t iUser,
DECLINLINE(int) pgmPoolAlloc(PVM pVM, RTGCPHYS GCPhys, PGMPOOLKIND enmKind, uint16_t iUser, uint32_t iUserTable,
return pgmPoolAllocEx(pVM, GCPhys, enmKind, PGMPOOLACCESS_DONTCARE, iUser, iUserTable, false, ppPage);
int pgmPoolFlushPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage, bool fFlush = true /* DO NOT USE false UNLESS YOU KNOWN WHAT YOU'RE DOING!! */);
int pgmPoolTrackUpdateGCPhys(PVM pVM, RTGCPHYS GCPhysPage, PPGMPAGE pPhysPage, bool fFlushPTEs, bool *pfFlushTLBs);
void pgmPoolTracDerefGCPhysHint(PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTHCPHYS HCPhys, RTGCPHYS GCPhysHint, uint16_t iPte);
uint16_t pgmPoolTrackPhysExtAddref(PVM pVM, PPGMPAGE pPhysPage, uint16_t u16, uint16_t iShwPT, uint16_t iPte);
void pgmPoolTrackPhysExtDerefGCPhys(PPGMPOOL pPool, PPGMPOOLPAGE pPoolPage, PPGMPAGE pPhysPage, uint16_t iPte);
void pgmPoolMonitorChainChanging(PVMCPU pVCpu, PPGMPOOL pPool, PPGMPOOLPAGE pPage, RTGCPHYS GCPhysFault, CTXTYPE(RTGCPTR, RTHCPTR, RTGCPTR) pvAddress, unsigned cbWrite);
void pgmMapClearShadowPDEs(PVM pVM, PPGMPOOLPAGE pShwPageCR3, PPGMMAPPING pMap, unsigned iOldPDE, bool fDeactivateCR3);
int pgmShwSyncNestedPageLocked(PVMCPU pVCpu, RTGCPHYS GCPhysFault, uint32_t cPages, PGMMODE enmShwPagingMode);
DECLCALLBACK(int) pgmR3CmdCheckDuplicatePages(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);
DECLCALLBACK(int) pgmR3CmdShowSharedModules(PCDBGCCMD pCmd, PDBGCCMDHLP pCmdHlp, PVM pVM, PCDBGCVAR paArgs, unsigned cArgs);