PGMInternal.h revision 24625dd0a909bb53fe84c52b22d35798b14995af
2N/A * PGM - Internal header file. 2N/A * Copyright (C) 2006-2007 Sun Microsystems, Inc. 2N/A * This file is part of VirtualBox Open Source Edition (OSE), as 2N/A * you can redistribute it and/or modify it under the terms of the GNU 2N/A * General Public License (GPL) as published by the Free Software 2N/A * Foundation, in version 2 as it comes in the "COPYING" file of the 2N/A * VirtualBox OSE distribution. VirtualBox OSE is distributed in the 2N/A * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. 2N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa 2N/A * additional information or have any questions. 2N/A#
error "Not in PGM! This is an internal header!" /** @defgroup grp_pgm_int Internals /** @name PGM Compile Time Config * Solve page is out of sync issues inside Guest Context (in PGMGC.cpp). * Comment it if it will break something. * Virtualize the dirty bit * This also makes a half-hearted attempt at the accessed bit. For full * accessed bit virtualization define PGM_SYNC_ACCESSED_BIT. * Fully virtualize the accessed bit. * @remark This requires SYNC_DIRTY_ACCESSED_BITS to be defined! * Check and skip global PDEs for non-global flushes * Sync N pages instead of a whole page table * Number of pages to sync during a page fault * When PGMPOOL_WITH_GCPHYS_TRACKING is enabled using high values here * causes a lot of unnecessary extents and also is slower than taking more \#PFs. #
error "PGM_SYNC_ACCESSED_BIT requires PGM_SYNC_DIRTY_BIT!"/** @def PGMPOOL_WITH_CACHE * Enable agressive caching using the page pool. * This requires PGMPOOL_WITH_USER_TRACKING and PGMPOOL_WITH_MONITORING. /** @def PGMPOOL_WITH_MIXED_PT_CR3 * When defined, we'll deal with 'uncachable' pages. /** @def PGMPOOL_WITH_MONITORING * Monitor the guest pages which are shadowed. * When this is enabled, PGMPOOL_WITH_CACHE or PGMPOOL_WITH_GCPHYS_TRACKING must * @remark doesn't really work without caching now. (Mixed PT/CR3 change.) /** @def PGMPOOL_WITH_GCPHYS_TRACKING * Tracking the of shadow pages mapping guest physical pages. * This is very expensive, the current cache prototype is trying to figure out * whether it will be acceptable with an agressive caching policy. /** @def PGMPOOL_WITH_USER_TRACKNG * Tracking users of shadow pages. This is required for the linking of shadow page * tables and physical guest addresses. /** @def PGMPOOL_CFG_MAX_GROW * The maximum number of pages to add to the pool in one go. /** @def VBOX_STRICT_PGM_HANDLER_VIRTUAL * Enables some extra assertions for virtual handlers (mainly phys2virt related). /** @name PDPT and PML4 flags. * These are placed in the three bits available for system programs in * the PDPT and PML4 entries. /** The entry is a permanent one and it's must always be present. * Never free such an entry. */ /** Mapping (hypervisor allocated pagetable). */ /** @name Page directory flags. * These are placed in the three bits available for system programs in * the page directory entries. /** Mapping (hypervisor allocated pagetable). */ /** Made read-only to facilitate dirty bit tracking. */ * These are placed in the three bits available for system programs in /** Made read-only to facilitate dirty bit tracking. */ /** Scanned and approved by CSAM (tm). * @todo Move PGM_PTFLAGS_* and PGM_PDFLAGS_* to VBox/pgm.h. */ /** @name Defines used to indicate the shadow and guest paging in the templates. /** Macro for checking if the guest is using paging. * @param uType PGM_TYPE_* * @remark ASSUMES certain order of the PGM_TYPE_* values. /** Macro for checking if the guest supports the NX bit. * @param uType PGM_TYPE_* * @remark ASSUMES certain order of the PGM_TYPE_* values. /** @def PGM_HCPHYS_2_PTR * Maps a HC physical page pool address to a virtual address. * @returns VBox status code. * @param pVM The VM handle. * @param HCPhys The HC physical address to map to a virtual one. * @param ppv Where to store the virtual address. No need to cast this. * @remark In GC this uses PGMGCDynMapHCPage(), so it will consume of the * small page window employeed by that function. Be careful. * @remark There is no need to assert on the result. /** @def PGM_GCPHYS_2_PTR * Maps a GC physical page address to a virtual address. * @returns VBox status code. * @param pVM The VM handle. * @param GCPhys The GC physical address to map to a virtual one. * @param ppv Where to store the virtual address. No need to cast this. * @remark In GC this uses PGMGCDynMapGCPage(), so it will consume of the * small page window employeed by that function. Be careful. * @remark There is no need to assert on the result. /** @def PGM_GCPHYS_2_PTR_EX * Maps a unaligned GC physical page address to a virtual address. * @returns VBox status code. * @param pVM The VM handle. * @param GCPhys The GC physical address to map to a virtual one. * @param ppv Where to store the virtual address. No need to cast this. * @remark In GC this uses PGMGCDynMapGCPage(), so it will consume of the * small page window employeed by that function. Be careful. * @remark There is no need to assert on the result. * Invalidates a page when in GC does nothing in HC. * @param GCVirt The virtual address of the page to invalidate. * Invalidates a 4MB page directory entry when in GC does nothing in HC. * @param GCVirt The virtual address within the page directory to invalidate. /** @def PGM_INVL_GUEST_TLBS() * Invalidates all guest TLBs. * Structure for tracking GC Mappings. * This structure is used by linked list in both GC and HC. /** Pointer to next entry. */ /** Pointer to next entry. */ /** Pointer to next entry. */ /** Start Virtual address. */ /** Last Virtual address (inclusive). */ /** Range size (bytes). */ /** Pointer to relocation callback function. */ /** User argument to the callback. */ /** Mapping description / name. For easing debugging. */ /** Number of page tables. */ /** Array of page table mapping data. Each entry * describes one page table. The array can be longer * than the declared length. /** The HC physical address of the page table. */ /** The HC physical address of the first PAE page table. */ /** The HC physical address of the second PAE page table. */ /** The HC virtual address of the 32-bit page table. */ /** The HC virtual address of the two PAE page table. (i.e 1024 entries instead of 512) */ /** The GC virtual address of the 32-bit page table. */ /** The GC virtual address of the two PAE page table. */ /** The GC virtual address of the 32-bit page table. */ /** The GC virtual address of the two PAE page table. */ /** Pointer to structure for tracking GC Mappings. */ * Physical page access handler structure. * This is used to keep track of physical address ranges * which are being monitored in some kind of way. /** Number of pages to update. */ /** Pointer to R3 callback function. */ /** User argument for R3 handlers. */ /** Pointer to R0 callback function. */ /** User argument for R0 handlers. */ /** Pointer to GC callback function. */ /** User argument for GC handlers. */ /** Description / Name. For easing debugging. */ /** Profiling of this handler. */ /** Pointer to a physical page access handler structure. */ * Cache node for the physical addresses covered by a virtual handler. /** Core node for the tree based on physical ranges. */ /** Offset from this struct to the PGMVIRTHANDLER structure. */ /** Offset of the next alias relative to this one. * Bit 0 is used for indicating whether we're in the tree. * Bit 1 is used for indicating that we're the head node. /** Pointer to a phys to virtual handler structure. */ /** The bit in PGMPHYS2VIRTHANDLER::offNextAlias used to indicate that the * node is in the tree. */ /** The bit in PGMPHYS2VIRTHANDLER::offNextAlias used to indicate that the * node is in the head of an alias chain. * The PGMPHYS2VIRTHANDLER_IN_TREE is always set if this bit is set. */ /** The mask to apply to PGMPHYS2VIRTHANDLER::offNextAlias to get the offset. */ * Virtual page access handler structure. * This is used to keep track of virtual address ranges * which are being monitored in some kind of way. /** Core node for the tree based on virtual ranges. */ /** Number of cache pages. */ /** Number of cache pages. */ /** @todo The next two members are redundant. It adds some readability though. */ /** Start of the range. */ /** End of the range (exclusive). */ /** Size of the range (in bytes). */ /** Pointer to the GC callback function. */ /** Pointer to the HC callback function for invalidation. */ /** Pointer to the HC callback function. */ /** Description / Name. For easing debugging. */ /** Profiling of this handler. */ /** Array of cached physical addresses for the monitored ranged. */ /** Pointer to a virtual page access handler structure. */ * @remarks This enum has to fit in a 3-bit field (see PGMPAGE::u3Type). * @todo convert to \#defines. /** The usual invalid zero entry. */ /** Shadowed ROM. (RWX) */ /** End of valid entries. */ /** @name Page type predicates. * A Physical Guest Page tracking structure. * The format of this structure is complicated because we have to fit a lot * of information into as few bits as possible. The format is also subject * to change (there is one comming up soon). Which means that for we'll be * using PGM_PAGE_GET_*, PGM_PAGE_IS_ and PGM_PAGE_SET_* macros for *all* * accessess to the structure. /** The physical address and a whole lot of other stuff. All bits are used! */ /** Flag indicating that a write monitored page was written to when set. */ * @todo Merge with HCPhys once we've liberated HCPhys of its stuff. * The HCPhys will be 100% static. */ /** The page type (PGMPAGETYPE). */ /** The physical handler state (PGM_PAGE_HNDL_PHYS_STATE*) */ /** The virtual handler state (PGM_PAGE_HNDL_VIRT_STATE*) */ /** Pointer to a physical guest page. */ /** Pointer to a const physical guest page. */ /** Pointer to a physical guest page pointer. */ * Clears the page structure. * @param pPage Pointer to the physical guest page tracking structure. * Initializes the page structure. * @param pPage Pointer to the physical guest page tracking structure. /*(pPage)->u3Type = (_uType); - later */ \
* Initializes the page structure of a ZERO page. * @param pPage Pointer to the physical guest page tracking structure. /** Temporary hack. Replaced by PGM_PAGE_INIT_ZERO once the old code is kicked out. */ /** @name The Page state, PGMPAGE::u2StateX. * This is a per-VM page that's never ever mapped writable. */ * This is a per-VM page allocated from the page pool (or wherever * we get MMIO2 pages from if the type is MMIO2). /** A allocated page that's being monitored for writes. * The shadow page table mappings are read-only. When a write occurs, the * fWrittenTo member is set, the page remapped as read-write and the state * moved back to allocated. */ /** The page is shared, aka. copy-on-write. * This is a page that's shared with other VMs. */ * @returns page state (PGM_PAGE_STATE_*). * @param pPage Pointer to the physical guest page tracking structure. * @param pPage Pointer to the physical guest page tracking structure. * @param _uState The new page state. * Gets the host physical address of the guest page. * @returns host physical address (RTHCPHYS). * @param pPage Pointer to the physical guest page tracking structure. * Sets the host physical address of the guest page. * @param pPage Pointer to the physical guest page tracking structure. * @param _HCPhys The new host physical address. * @returns The Page ID; NIL_GMM_PAGEID if it's a ZERO page. * @param pPage Pointer to the physical guest page tracking structure. #define PGM_PAGE_GET_PAGEID(pPage) ( ((uint32_t)(pPage)->HCPhys >> (48 - 12)) | ((uint32_t)(pPage)->HCPhys & 0xfff) ) * @param pPage Pointer to the physical guest page tracking structure. #define PGM_PAGE_SET_PAGEID(pPage, _idPage) do { (pPage)->HCPhys = (((pPage)->HCPhys) & UINT64_C(0x0000fffffffff000)) \ | (((_idPage) & 0x0ffff000) << (48-12)); } while (0) * @returns The Chunk ID; NIL_GMM_CHUNKID if it's a ZERO page. * @param pPage Pointer to the physical guest page tracking structure. #if GMM_CHUNKID_SHIFT == 12 # define PGM_PAGE_GET_CHUNKID(pPage) ( (uint32_t)((pPage)->HCPhys >> 48) ) #elif GMM_CHUNKID_SHIFT > 12 # define PGM_PAGE_GET_CHUNKID(pPage) ( (uint32_t)((pPage)->HCPhys >> (48 + (GMM_CHUNKID_SHIFT - 12)) ) #elif GMM_CHUNKID_SHIFT < 12 # define PGM_PAGE_GET_CHUNKID(pPage) ( ( (uint32_t)((pPage)->HCPhys >> 48) << (12 - GMM_CHUNKID_SHIFT) ) \ | ( (uint32_t)((pPage)->HCPhys & 0xfff) >> GMM_CHUNKID_SHIFT ) ) # error "GMM_CHUNKID_SHIFT isn't defined or something." * Get the index of the page within the allocaiton chunk. * @returns The page index. * @param pPage Pointer to the physical guest page tracking structure. #if GMM_CHUNKID_SHIFT <= 12 # define PGM_PAGE_GET_PAGE_IN_CHUNK(pPage) ( (uint32_t)((pPage)->HCPhys & GMM_PAGEID_IDX_MASK) ) # define PGM_PAGE_GET_PAGE_IN_CHUNK(pPage) ( (uint32_t)((pPage)->HCPhys & 0xfff) \ | ( (uint32_t)((pPage)->HCPhys >> 48) & (RT_BIT_32(GMM_CHUNKID_SHIFT - 12) - 1) ) ) * @returns The page type. * @param pPage Pointer to the physical guest page tracking structure. * @param pPage Pointer to the physical guest page tracking structure. * @param _enmType The new page type (PGMPAGETYPE). * Checks if the page is 'reserved'. * @param pPage Pointer to the physical guest page tracking structure. * Checks if the page is marked for MMIO. * @param pPage Pointer to the physical guest page tracking structure. * Checks if the page is backed by the ZERO page. * @param pPage Pointer to the physical guest page tracking structure. * Checks if the page is backed by a SHARED page. * @param pPage Pointer to the physical guest page tracking structure. * Marks the paget as written to (for GMM change monitoring). * @param pPage Pointer to the physical guest page tracking structure. * Clears the written-to indicator. * @param pPage Pointer to the physical guest page tracking structure. * Checks if the page was marked as written-to. * @param pPage Pointer to the physical guest page tracking structure. /** @name Physical Access Handler State values (PGMPAGE::u2HandlerPhysStateX). * @remarks The values are assigned in order of priority, so we can calculate * the correct state for a page with different handlers installed. /** No handler installed. */ /** Monitoring is temporarily disabled. */ /** Write access is monitored. */ /** All access is monitored. */ * Gets the physical access handler state of a page. * @returns PGM_PAGE_HNDL_PHYS_STATE_* value. * @param pPage Pointer to the physical guest page tracking structure. * Sets the physical access handler state of a page. * @param pPage Pointer to the physical guest page tracking structure. * @param _uState The new state value. * Checks if the page has any physical access handlers, including temporariliy disabled ones. * @param pPage Pointer to the physical guest page tracking structure. * Checks if the page has any active physical access handlers. * @param pPage Pointer to the physical guest page tracking structure. /** @name Virtual Access Handler State values (PGMPAGE::u2HandlerVirtStateX). * @remarks The values are assigned in order of priority, so we can calculate * the correct state for a page with different handlers installed. /** No handler installed. */ /* 1 is reserved so the lineup is identical with the physical ones. */ /** Write access is monitored. */ /** All access is monitored. */ * Gets the virtual access handler state of a page. * @returns PGM_PAGE_HNDL_VIRT_STATE_* value. * @param pPage Pointer to the physical guest page tracking structure. * Sets the virtual access handler state of a page. * @param pPage Pointer to the physical guest page tracking structure. * @param _uState The new state value. * Checks if the page has any virtual access handlers. * @param pPage Pointer to the physical guest page tracking structure. * Same as PGM_PAGE_HAS_ANY_VIRTUAL_HANDLERS - can't disable pages in * @param pPage Pointer to the physical guest page tracking structure. * Checks if the page has any access handlers, including temporarily disabled ones. * @param pPage Pointer to the physical guest page tracking structure. * Checks if the page has any active access handlers. * @param pPage Pointer to the physical guest page tracking structure. * Checks if the page has any active access handlers catching all accesses. * @param pPage Pointer to the physical guest page tracking structure. * Ram range for GC Phys to HC Phys conversion. * Can be used for HC Virt to GC Phys and HC Virt to HC Phys * conversions too, but we'll let MM handle that for now. * This structure is used by linked lists in both GC and HC. /** Pointer to the next RAM range - for R3. */ /** Pointer to the next RAM range - for R0. */ /** Pointer to the next RAM range - for GC. */ /** Pointer alignment. */ /** Start of the range. Page aligned. */ /** Last address in the range (inclusive). Page aligned (-1). */ /** Size of the range. (Page aligned of course). */ /** HC virtual lookup ranges for chunks. Currently only used with MM_RAM_FLAGS_DYNAMIC_ALLOC ranges. */ /** HC virtual lookup ranges for chunks. Currently only used with MM_RAM_FLAGS_DYNAMIC_ALLOC ranges. */ /** Start of the HC mapping of the range. This is only used for MMIO2. */ /** The range description. */ /** Padding to make aPage aligned on sizeof(PGMPAGE). */ /** Array of physical guest page tracking structures. */ /** Pointer to Ram range for GC Phys to HC Phys conversion. */ /** Return hc ptr corresponding to the ram range and physical offset */ * Per page tracking structure for ROM image. * A ROM image may have a shadow page, in which case we may have * two pages backing it. This structure contains the PGMPAGE for * both while PGMRAMRANGE have a copy of the active one. It is * important that these aren't out of sync in any regard other * than page pool tracking data. /** The page structure for the virgin ROM page. */ /** The page structure for the shadow RAM page. */ /** The current protection setting. */ /** Pad the structure size to a multiple of 8. */ /** Pointer to a ROM page tracking structure. */ * A registered ROM image. * This is needed to keep track of ROM image since they generally * intrude into a PGMRAMRANGE. It also keeps track of additional * info like the two page sets (read-only virgin and read-write shadow), * the current state of each page. * Because access handlers cannot easily be executed in a different * context, the ROM ranges needs to be accessible and in all contexts. /** Pointer to the next range - R3. */ /** Pointer to the next range - R0. */ /** Pointer to the next range - GC. */ /** Address of the range. */ /** Address of the last byte in the range. */ /** Size of the range. */ /** The flags (PGMPHYS_ROM_FLAG_*). */ /**< Alignment padding ensuring that aPages is sizeof(PGMROMPAGE) aligned. */ /** Pointer to the original bits when PGMPHYS_ROM_FLAG_PERMANENT_BINARY was specified. * This is used for strictness checks. */ /** The ROM description. */ /** The per page tracking structures. */ /** Pointer to a ROM range. */ * A registered MMIO2 (= Device RAM) range. * There are a few reason why we need to keep track of these * registrations. One of them is the deregistration & cleanup * stuff, while another is that the PGMRAMRANGE associated with * such a region may have to be removed from the ram range list. * Overlapping with a RAM range has to be 100% or none at all. The * pages in the existing RAM range must not be ROM nor MMIO. A guru * meditation will be raised if a partial overlap or an overlap of * ROM pages is encountered. On an overlap we will free all the * existing RAM pages and put in the ram range pages instead. /** The owner of the range. (a device) */ /** Pointer to the ring-3 mapping of the allocation. */ /** Pointer to the next range - R3. */ /** Whether it's mapped or not. */ /** Whether it's overlapping or not. */ /** The PCI region number. * @remarks This ASSUMES that nobody will ever really need to have multiple * PCI devices with matching MMIO region numbers on a single device. */ /**< Alignment padding for putting the ram range on a PGMPAGE alignment boundrary. */ /** The associated RAM range. */ /** Pointer to a MMIO2 range. */ /** @todo r=bird: fix typename. */ /** HC pointer to physical page */ /** GC Physical address for cache entry */ /** Bitmap of valid cache entries */ /** Pointer to an allocation chunk ring-3 mapping. */ /** Pointer to an allocation chunk ring-3 mapping pointer. */ * Ring-3 tracking structore for an allocation chunk ring-3 mapping. * The primary tree (Core) uses the chunk id as key. * The secondary tree (AgeCore) is used for ageing and uses ageing sequence number as key. /** The key is the chunk id. */ /** The key is the ageing sequence number. */ /** The current age thingy. */ /** The current reference count. */ /** The current permanent reference count. */ /** The mapping address. */ * Allocation chunk ring-3 mapping TLB entry. /** Pointer to the an allocation chunk ring-3 mapping TLB entry. */ /** The number of TLB entries in PGMCHUNKR3MAPTLB. * @remark Must be a power of two value. */ * Allocation chunk ring-3 mapping TLB. * @remarks We use a TLB to speed up lookups by avoiding walking the AVL. * At first glance this might look kinda odd since AVL trees are * supposed to give the most optimial lookup times of all trees * due to their balancing. However, take a tree with 1023 nodes * in it, that's 10 levels, meaning that most searches has to go * down 9 levels before they find what they want. This isn't fast * compared to a TLB hit. There is the factor of cache misses, * and of course the problem with trees and branch prediction. * This is why we use TLBs in front of most of the trees. * @todo Generalize this TLB + AVL stuff, shouldn't be all that * difficult when we switch to inlined AVL trees (from kStuff). * Calculates the index of a guest page in the Ring-3 Chunk TLB. * @returns Chunk TLB index. * @param idChunk The Chunk ID. * Ring-3 guest page mapping TLB entry. * @remarks used in ring-0 as well at the moment. /** Address of the page. */ /** Pointer to the page mapping tracking structure, PGMCHUNKR3MAP. */ /** Pointer to an entry in the HC physical TLB. */ /** The number of entries in the ring-3 guest page mapping TLB. * @remarks The value must be a power of two. */ * Ring-3 guest page mapping TLB. * @remarks used in ring-0 as well at the moment. /** Pointer to the ring-3 guest page mapping TLB. */ * Calculates the index of the TLB entry for the specified guest page. * @returns Physical TLB index. * @param GCPhys The guest physical address. /** @name Context neutrual page mapper TLB. * Hoping to avoid some code and bug duplication parts of the GCxxx->CCPtr * code is writting in a kind of context neutrual way. Time will show whether * this actually makes sense or not... /** @typedef PPGMPAGEMAPTLB * The page mapper TLB pointer type for the current context. */ /** @typedef PPGMPAGEMAPTLB * The page mapper TLB entry pointer type for the current context. */ /** @typedef PPGMPAGEMAPTLB * The page mapper TLB entry pointer pointer type for the current context. */ /** @def PGMPAGEMAPTLB_ENTRIES * The number of TLB entries in the page mapper TLB for the current context. */ /** @def PGM_PAGEMAPTLB_IDX * Calculate the TLB index for a guest physical address. * @returns The TLB index. * @param GCPhys The guest physical address. */ * Pointer to a page mapper unit for current context. */ /** @typedef PPPGMPAGEMAP * Pointer to a page mapper unit pointer for current context. */ // typedef PPGMPAGEGCMAPTLB PPGMPAGEMAPTLB; // typedef PPGMPAGEGCMAPTLBE PPGMPAGEMAPTLBE; // typedef PPGMPAGEGCMAPTLBE *PPPGMPAGEMAPTLBE; // typedef PPGMPAGER0MAPTLB PPGMPAGEMAPTLB; // typedef PPGMPAGER0MAPTLBE PPGMPAGEMAPTLBE; // typedef PPGMPAGER0MAPTLBE *PPPGMPAGEMAPTLBE; //# define PGM_PAGEMAPTLB_ENTRIES PGM_PAGER0MAPTLB_ENTRIES //# define PGM_PAGEMAPTLB_IDX(GCPhys) PGM_PAGER0MAPTLB_IDX(GCPhys) // typedef PPGMCHUNKR0MAP PPGMPAGEMAP; // typedef PPPGMCHUNKR0MAP PPPGMPAGEMAP; /** @name PGM Pool Indexes. * Aka. the unique shadow page identifier. /** NIL page pool IDX. */ /** The first normal index. */ /** Page directory (32-bit root). */ /** The extended PAE page directory (2048 entries, works as root currently). */ /** PAE Page Directory Table 0. */ /** PAE Page Directory Table 1. */ /** PAE Page Directory Table 2. */ /** PAE Page Directory Table 3. */ /** Page Directory Pointer Table (PAE root, not currently used). */ /** Page Map Level-4 (64-bit root). */ /** The first normal index. */ /** The last valid index. (inclusive, 14 bits) */ /** The NIL index for the parent chain. */ * Node in the chain linking a shadowed page to it's parent (user). /** The index to the next item in the chain. NIL_PGMPOOL_USER_INDEX is no next. */ /** The user page index. */ /** Index into the user table. */ /** The NIL index for the phys ext chain. */ * Node in the chain of physical cross reference extents. /** The index to the next item in the chain. NIL_PGMPOOL_PHYSEXT_INDEX is no next. */ /** The user page index. */ * The kind of page that's being shadowed. /** The virtual invalid 0 entry. */ /** The entry is free (=unused). */ /** Shw: 32-bit page table; Gst: no paging */ /** Shw: 32-bit page table; Gst: 32-bit page table. */ /** Shw: 32-bit page table; Gst: 4MB page. */ /** Shw: PAE page table; Gst: no paging */ /** Shw: PAE page table; Gst: 32-bit page table. */ /** Shw: PAE page table; Gst: Half of a 4MB page. */ /** Shw: PAE page table; Gst: PAE page table. */ /** Shw: PAE page table; Gst: 2MB page. */ /** Shw: PAE page directory; Gst: 32-bit page directory. */ /** Shw: PAE page directory; Gst: PAE page directory. */ /** Shw: 64-bit page directory pointer table; Gst: 64-bit page directory pointer table. */ /** Shw: 64-bit page directory table; Gst: 64-bit page directory table. */ /** Shw: Root 32-bit page directory. */ /** Shw: Root PAE page directory */ /** Shw: Root PAE page directory pointer table (legacy, 4 entries). */ /** Shw: Root page map level-4 table. */ /** The last valid entry. */ * The tracking data for a page in the pool. /** AVL node code with the (HC) physical address of this page. */ /** Pointer to the HC mapping of the page. */ /** The guest physical address. */ /** The kind of page we're shadowing. (This is really a PGMPOOLKIND enum.) */ /** The index of this page. */ /** The next entry in the list this page currently resides in. * It's either in the free list or in the GCPhys hash. */ /** Head of the user chain. NIL_PGMPOOL_USER_INDEX if not currently in use. */ /** The number of present entries. */ /** The first entry in the table which is present. */ /** The number of modifications to the monitored page. */ /** The next modified page. NIL_PGMPOOL_IDX if tail. */ /** The previous modified page. NIL_PGMPOOL_IDX if head. */ /** The next page sharing access handler. NIL_PGMPOOL_IDX if tail. */ /** The previous page sharing access handler. NIL_PGMPOOL_IDX if head. */ /** The next page in the age list. */ /** The previous page in the age list. */ #
endif /* PGMPOOL_WITH_CACHE */ /** Used to indicate that the page is zeroed. */ /** Used to indicate that a PT has non-global entries. */ /** Used to indicate that we're monitoring writes to the guest page. */ /** Used to indicate that the page is in the cache (e.g. in the GCPhys hash). * (All pages are in the age list.) */ /** This is used by the R3 access handlers when invoked by an async thread. * It's a hack required because of REMR3NotifyHandlerPhysicalDeregister. */ /** Used to indicate that the guest is mapping the page is also used as a CR3. * In these cases the access handler acts differently and will check * for mapping conflicts like the normal CR3 handler. * @todo When we change the CR3 shadowing to use pool pages, this flag can be * replaced by a list of pages which share access handler. /** The hash table size. */ /** The hash function. */ * The shadow page pool instance data. * It's all one big allocation made at init time, except for the * pages that is. The user nodes follows immediatly after the /** The VM handle - HC Ptr. */ /** The VM handle - GC Ptr. */ /** The max pool size. This includes the special IDs. */ /** The current pool size. */ /** The head of the free page list. */ /** Head of the chain of free user nodes. */ /** The number of user nodes we've allocated. */ /** The number of present page table entries in the entire pool. */ /** Pointer to the array of user nodes - GC pointer. */ /** Pointer to the array of user nodes - HC pointer. */ #
endif /* PGMPOOL_WITH_USER_TRACKING */ /** Head of the chain of free phys ext nodes. */ /** The number of user nodes we've allocated. */ /** Pointer to the array of physical xref extent - GC pointer. */ /** Pointer to the array of physical xref extent nodes - HC pointer. */ #
endif /* PGMPOOL_WITH_GCPHYS_TRACKING */ /** Hash table for GCPhys addresses. */ /** The head of the age list. */ /** The tail of the age list. */ /** Set if the cache is enabled. */ #
endif /* PGMPOOL_WITH_CACHE */ /** Head of the list of modified pages. */ /** The current number of modified pages. */ /** Access handler, GC. */ /** Access handler, R0. */ /** Access handler, R3. */ /** The access handler description (HC ptr). */ #
endif /* PGMPOOL_WITH_MONITORING */ /** The number of pages currently in use. */ /** The high wather mark for cUsedPages. */ /** Profiling pgmPoolAlloc(). */ /** Profiling pgmPoolClearAll(). */ /** Profiling pgmPoolFlushAllInt(). */ /** Profiling pgmPoolFlushPage(). */ /** Profiling pgmPoolFree(). */ /** Profiling time spent zeroing pages. */ /** Profiling of pgmPoolTrackDeref. */ /** Profiling pgmTrackFlushGCPhysPT. */ /** Profiling pgmTrackFlushGCPhysPTs. */ /** Profiling pgmTrackFlushGCPhysPTsSlow. */ /** Number of times we've been out of user records. */ /** Profiling deref activity related tracking GC physical pages. */ /** Number of linear searches for a HCPhys in the ram ranges. */ /** The number of failing pgmPoolTrackPhysExtAlloc calls. */ /** Profiling the GC PT access handler. */ /** Times we've failed interpreting the instruction. */ /** Profiling the pgmPoolFlushPage calls made from the GC PT access handler. */ /** Times we've detected fork(). */ /** Profiling the GC access we've handled (except REP STOSD). */ /** Times we've failed interpreting a patch code instruction. */ /** Times we've failed interpreting a patch code instruction during flushing. */ /** The number of times we've seen rep prefixes we can't handle. */ /** Profiling the REP STOSD cases we've handled. */ /** Profiling the HC PT access handler. */ /** Times we've failed interpreting the instruction. */ /** Profiling the pgmPoolFlushPage calls made from the HC PT access handler. */ /** Times we've detected fork(). */ /** Profiling the HC access we've handled (except REP STOSD). */ /** The number of times we've seen rep prefixes we can't handle. */ /** Profiling the REP STOSD cases we've handled. */ /** The number of times we're called in an async thread an need to flush. */ /** The high wather mark for cModifiedPages. */ /** The number of cache hits. */ /** The number of cache misses. */ /** The number of times we've got a conflict of 'kind' in the cache. */ /** Number of times we've been out of pages. */ /** The number of cacheable allocations. */ /** The number of uncacheable allocations. */ /** The AVL tree for looking up a page by its HC physical address. */ /** Array of pages. (cMaxPages in length) * The Id is the index into thist array. /** @def PGMPOOL_PAGE_2_PTR * Maps a pool page pool into the current context. * @returns VBox status code. * @param pVM The VM handle. * @param pPage The pool page. * @remark In HC this uses PGMGCDynMapHCPage(), so it will consume of the * small page window employeed by that function. Be careful. * @remark There is no need to assert on the result. * Trees are using self relative offsets as pointers. * So, all its data, including the root pointer, must be in the heap for HC and GC * to have the same layout. /** Physical access handlers (AVL range+offsetptr tree). */ /** Virtual access handlers (AVL range + GC ptr tree). */ /** Virtual access handlers (Phys range AVL range + offsetptr tree). */ /** Virtual access handlers for the hypervisor (AVL range + GC ptr tree). */ /** Pointer to PGM trees. */ /** @name Paging mode macros * Data for each paging mode. /** The guest mode type. */ /** The shadow mode type. */ /** @name Function pointers for Shadow paging. /** @name Function pointers for Guest paging. /** @name Function pointers for Both Shadow and Guest paging. * Converts a PGM pointer into a VM pointer. * @returns Pointer to the VM structure the PGM is part of. * @param pPGM Pointer to PGM instance data. /** Offset to the VM structure. */ * This will be redefined at least two more times before we're done, I'm sure. * The current code is only to get on with the coding. * - 2004-06-10: initial version, bird. * - 2004-07-02: 1st time, bird. * - 2004-10-18: 2nd time, bird. * - 2005-07-xx: 3rd time, bird. /** Pointer to the page table entries for the dynamic page mapping area - GCPtr. */ /** Pointer to the page table entries for the dynamic page mapping area - GCPtr. */ /** The host paging mode. (This is what SUPLib reports.) */ /** The shadow paging mode. */ /** The guest paging mode. */ /** The current physical address representing in the guest CR3 register. */ /** Pointer to the 5 page CR3 content mapping. * The first page is always the CR3 (in some form) while the 4 other pages * are used of the PDs in PAE mode. */ /** The physical address of the currently monitored guest CR3 page. * When this value is NIL_RTGCPHYS no page is being monitored. */ /** @name 32-bit Guest Paging. /** The guest's page directory, HC pointer. */ /** The guest's page directory, static GC mapping. */ /** @name PAE Guest Paging. /** The guest's page directory pointer table, static GC mapping. */ /** The guest's page directory pointer table, HC pointer. */ /** The guest's page directories, HC pointers. * These are individual pointers and don't have to be adjecent. * These don't have to be up-to-date - use pgmGstGetPaePD() to access them. */ /** The guest's page directories, static GC mapping. * Unlike the HC array the first entry can be accessed as a 2048 entry PD. * These don't have to be up-to-date - use pgmGstGetPaePD() to access them. */ /** The physical addresses of the guest page directories (PAE) pointed to by apGstPagePDsHC/GC. */ /** The physical addresses of the monitored guest page directories (PAE). */ /** @name AMD64 Guest Paging. /** The guest's page directory pointer table, HC pointer. */ /** @name 32-bit Shadow Paging /** The 32-Bit PD - HC Ptr. */ /** The 32-Bit PD - GC Ptr. */ /** The Physical Address (HC) of the 32-Bit PD. */ /** @name PAE Shadow Paging /** The four PDs for the low 4GB - HC Ptr. * Even though these are 4 pointers, what they point at is a single table. * Thus, it's possible to walk the 2048 entries starting where apHCPaePDs[0] points. */ /** The four PDs for the low 4GB - GC Ptr. * Same kind of mapping as apHCPaePDs. */ /** The Physical Address (HC) of the four PDs for the low 4GB. * These are *NOT* 4 contiguous pages. */ /** The PAE PDP - HC Ptr. */ /** The Physical Address (HC) of the PAE PDPT. */ /** The PAE PDPT - GC Ptr. */ /** @name AMD64 Shadow Paging /** The Page Map Level 4 table - HC Ptr. */ /** The Physical Address (HC) of the Page Map Level 4 table. */ /** @name Function pointers for Shadow paging. /** @name Function pointers for Guest paging. /** @name Function pointers for Both Shadow and Guest paging. /** Pointer to SHW+GST mode data (function pointers). * The index into this table is made up from */ /** Pointer to the list of RAM ranges (Phys GC -> Phys HC conversion) - for R3. * This is sorted by physical address and contains no overlapping ranges. */ /** R0 pointer corresponding to PGM::pRamRangesR3. */ /** GC pointer corresponding to PGM::pRamRangesR3. */ /** The configured RAM size. */ /** Pointer to the list of ROM ranges - for R3. * This is sorted by physical address and contains no overlapping ranges. */ /** R0 pointer corresponding to PGM::pRomRangesR3. */ /** GC pointer corresponding to PGM::pRomRangesR3. */ /** Alignment padding. */ /** Pointer to the list of MMIO2 ranges - for R3. /** PGM offset based trees - HC Ptr. */ /** PGM offset based trees - GC Ptr. */ /** Linked list of GC mappings - for GC. * The list is sorted ascending on address. /** Linked list of GC mappings - for HC. * The list is sorted ascending on address. /** Linked list of GC mappings - for R0. * The list is sorted ascending on address. /** If set no conflict checks are required. (boolean) */ /** If set, then no mappings are put into the shadow page table. (boolean) */ /** Size of fixed mapping */ /** Base address (GC) of fixed mapping */ /** @name Intermediate Context /** Pointer to the intermediate page directory - Normal. */ /** Pointer to the intermedate page tables - Normal. * There are two page tables, one for the identity mapping and one for * the host context mapping (of the core code). */ /** Pointer to the intermedate page tables - PAE. */ /** Pointer to the intermedate page directory - PAE. */ /** Pointer to the intermedate page directory - PAE. */ /** Pointer to the intermedate page-map level 4 - AMD64. */ /** Pointer to the intermedate page directory - AMD64. */ /** The Physical Address (HC) of the intermediate Page Directory - Normal. */ /** The Physical Address (HC) of the intermediate Page Directory Pointer Table - PAE. */ /** The Physical Address (HC) of the intermediate Page Map Level 4 table - AMD64. */ /** Base address of the dynamic page mapping area. * The array is MM_HYPER_DYNAMIC_SIZE bytes big. /** The index of the last entry used in the dynamic page mapping area. */ /** Cache containing the last entries in the dynamic page mapping area. * The cache size is covering half of the mapping area. */ * Our current approach to A20 emulation is to let REM do it and don't bother * anywhere else. The interesting Guests will be operating with it enabled anyway. * But whould need arrise, we'll subject physical addresses to this mask. */ /** A20 gate state - boolean! */ /** What needs syncing (PGM_SYNC_*). * This is used to queue operations for PGMSyncCR3, PGMInvalidatePage, * PGMFlushTLB, and PGMR3Load. */ /** PGM critical section. * This protects the physical & virtual access handlers, ram ranges, * and the page flag updating (some of it anyway). /** Shadow Page Pool - HC Ptr. */ /** Shadow Page Pool - GC Ptr. */ /** We're not in a state which permits writes to guest memory. * (Only used in strict builds.) */ /** Flush the cache on the next access. */ /** @todo r=bird: Fix member names!*/ /** PGMPhysWrite cache */ * Data associated with managing the ring-3 mappings of the allocation chunks. /** The chunk tree, ordered by chunk id. */ /** The chunk mapping TLB. */ /** The number of mapped chunks. */ /** The maximum number of mapped chunks. /** The chunk age tree, ordered by ageing sequence number. */ /** Number of pgmR3PhysChunkFindUnmapCandidate calls left to the next ageing. */ * The page mapping TLB for ring-3 and (for the time being) ring-0. /** The host physical address of the zero page. */ /** The ring-3 mapping of the zero page. */ /** The ring-0 mapping of the zero page. */ /** The GC mapping of the zero page. */ /** The number of handy pages. */ * This array is used in a two way communication between pgmPhysAllocPage * and GMMR0AllocateHandyPages, with PGMR3PhysAllocateHandyPages serving as * The size of this array is important, see pgmPhysEnsureHandyPage for details. * (The current size of 32 pages, means 128 KB of handy memory.) /** @name Release Statistics uint32_t cAllPages;
/**< The total number of pages. (Should be Private + Shared + Zero.) */ /** The number of times the guest has switched mode since last reset or statistics reset. */ /** GC: Which statistic this \#PF should be attributed to. */ /** HC: Which statistic this \#PF should be attributed to. */ /** GC: PGMSyncPT() profiling. */ /** GC: The number of times PGMSyncPT() needed to allocate page tables. */ /** GC: The number of times PGMSyncPT() detected conflicts. */ /** GC: The number of times PGMSyncPT() failed. */ /** GC: PGMGCInvalidatePage() profiling. */ /** GC: The number of times PGMGCInvalidatePage() was called for a 4KB page. */ /** GC: The number of times PGMGCInvalidatePage() was called for a 4MB page. */ /** GC: The number of times PGMGCInvalidatePage() skipped a 4MB page. */ /** GC: The number of times PGMGCInvalidatePage() was called for a not accessed page directory. */ /** GC: The number of times PGMGCInvalidatePage() was called for a not present page directory. */ /** GC: The number of times PGMGCInvalidatePage() was called for a page directory containing mappings (no conflict). */ /** GC: The number of times PGMGCInvalidatePage() was called for an out of sync page directory. */ /** HC: The number of times PGMGCInvalidatePage() was skipped due to not present shw or pending pending SyncCR3. */ /** GC: The number of times user page is out of sync was detected in GC. */ /** GC: The number of times supervisor page is out of sync was detected in GC. */ /** GC: The number of dynamic page mapping cache hits */ /** GC: The number of dynamic page mapping cache misses */ /** GC: The number of times pgmGCGuestPDWriteHandler() was successfully called. */ /** GC: The number of times pgmGCGuestPDWriteHandler() was called and we had to fall back to the recompiler. */ /** GC: The number of times pgmGCGuestPDWriteHandler() was called and a conflict was detected. */ /** GC: Number of out-of-sync handled pages. */ /** GC: Number of traps due to physical access handlers. */ /** GC: Number of traps due to virtual access handlers. */ /** GC: Number of traps due to virtual access handlers found by physical address. */ /** GC: Number of traps due to virtual access handlers found by virtual address (without proper physical flags). */ /** GC: Number of traps due to access outside range of monitored page(s). */ /** GC: Number of traps due to access to invalid physical memory. */ /** GC: The number of times pgmGCGuestROMWriteHandler() was successfully called. */ /** GC: The number of times pgmGCGuestROMWriteHandler() was called and we had to fall back to the recompiler */ /** HC: PGMR3InvalidatePage() profiling. */ /** HC: The number of times PGMR3InvalidatePage() was called for a 4KB page. */ /** HC: The number of times PGMR3InvalidatePage() was called for a 4MB page. */ /** HC: The number of times PGMR3InvalidatePage() skipped a 4MB page. */ /** HC: The number of times PGMR3InvalidatePage() was called for a not accessed page directory. */ /** HC: The number of times PGMR3InvalidatePage() was called for a not present page directory. */ /** HC: The number of times PGMR3InvalidatePage() was called for a page directory containing mappings (no conflict). */ /** HC: The number of times PGMGCInvalidatePage() was called for an out of sync page directory. */ /** HC: The number of times PGMR3InvalidatePage() was skipped due to not present shw or pending pending SyncCR3. */ /** HC: PGMR3SyncPT() profiling. */ /** HC: pgmr3SyncPTResolveConflict() profiling (includes the entire relocation). */ /** HC: Number of times PGMR3CheckMappingConflicts() detected a conflict. */ /** HC: The total number of times pgmHCGuestPDWriteHandler() was called. */ /** HC: The number of times pgmHCGuestPDWriteHandler() detected a conflict */ /** HC: The number of pages marked not present for accessed bit emulation. */ /** HC: The number of pages marked read-only for dirty bit tracking. */ /** HC: The number of pages marked read-only for dirty bit tracking. */ /** HC: The number of traps generated for dirty bit tracking. */ /** HC: The number of pages already dirty or readonly. */ /** GC: The number of pages marked not present for accessed bit emulation. */ /** GC: The number of pages marked read-only for dirty bit tracking. */ /** GC: The number of pages marked read-only for dirty bit tracking. */ /** GC: The number of traps generated for dirty bit tracking. */ /** GC: The number of pages already dirty or readonly. */ /** GC: The number of pages marked dirty because of write accesses. */ /** GC: The number of pages already marked dirty because of write accesses. */ /** GC: The number of real pages faults during dirty bit tracking. */ /** GC: Profiling of the PGMTrackDirtyBit() body */ /** HC: Profiling of the PGMTrackDirtyBit() body */ /** GC: Profiling of the PGMGstModifyPage() body */ /** HC: Profiling of the PGMGstModifyPage() body */ /** GC: The number of time we've marked a PD not present from SyncPage to virtualize the accessed bit. */ /** GC: The number of time we've encountered an out-of-sync PD in SyncPage. */ /** HC: The number of time we've marked a PD not present from SyncPage to virtualize the accessed bit. */ /** HC: The number of time we've encountered an out-of-sync PD in SyncPage. */ /** Profiling of the PGMFlushTLB() body. */ /** The number of times PGMFlushTLB was called with a new CR3, non-global. (switch) */ /** The number of times PGMFlushTLB was called with a new CR3, global. (switch) */ /** The number of times PGMFlushTLB was called with the same CR3, non-global. (flush) */ /** The number of times PGMFlushTLB was called with the same CR3, global. (flush) */ /** GC: Profiling of pgmHandlerVirtualFindByPhysAddr. */ /** HC: Profiling of pgmHandlerVirtualFindByPhysAddr. */ /** HC: The number of times PGMR3HandlerPhysicalReset is called. */ /** The number of first time shadowings. */ /** The number of times switching to cRef2, i.e. the page is being shadowed by two PTs. */ /** The number of times we're tracking using cRef2. */ /** The number of times we're hitting pages which has overflowed cRef2. */ /** The number of times the extent list grows to long. */ /** Profiling of SyncPageWorkerTrackDeref (expensive). */ /** Ring-3/0 page mapper TLB hits. */ /** Ring-3/0 page mapper TLB misses. */ /** Ring-3/0 chunk mapper TLB hits. */ /** Ring-3/0 chunk mapper TLB misses. */ /** Times a shared page has been replaced by a private one. */ /** Times the zero page has been replaced by a private one. */ /** The number of times we've executed GMMR3AllocateHandyPages. */ /** Allocated mbs of guest ram */ /** Nr of pgmr3PhysGrowRange calls. */ /** @name PGM::fSyncFlags Flags /** Updates the virtual access handler state bit in PGMPAGE. */ /** Check monitoring on next CR3 (re)load and invalidate page. */ /** Clear the page pool (a light weight flush). */ * Gets the PGMRAMRANGE structure for a guest page. * @returns Pointer to the RAM range on success. * @returns NULL on a VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS condition. * @param pPGM PGM handle. * @param GCPhys The GC physical address. * Optimize for the first range. * Gets the PGMPAGE structure for a guest page. * @returns Pointer to the page on success. * @returns NULL on a VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS condition. * @param pPGM PGM handle. * @param GCPhys The GC physical address. * Optimize for the first range. * Gets the PGMPAGE structure for a guest page. * Old Phys code: Will make sure the page is present. * @returns VBox status code. * @retval VINF_SUCCESS and a valid *ppPage on success. * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if the address isn't valid. * @param pPGM PGM handle. * @param GCPhys The GC physical address. * @param ppPage Where to store the page poitner on success. * Optimize for the first range. *
ppPage =
NULL;
/* avoid incorrect and very annoying GCC warnings */ * Make sure it's present. *
ppPage =
NULL;
/* avoid incorrect and very annoying GCC warnings */ * Gets the PGMPAGE structure for a guest page. * Old Phys code: Will make sure the page is present. * @returns VBox status code. * @retval VINF_SUCCESS and a valid *ppPage on success. * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if the address isn't valid. * @param pPGM PGM handle. * @param GCPhys The GC physical address. * @param ppPage Where to store the page poitner on success. * @param ppRamHint Where to read and store the ram list hint. * The caller initializes this to NULL before the call. *
ppPage =
NULL;
/* Kill the incorrect and extremely annoying GCC warnings. */ * Make sure it's present. * Gets the PGMPAGE structure for a guest page together with the PGMRAMRANGE. * @returns Pointer to the page on success. * @returns NULL on a VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS condition. * @param pPGM PGM handle. * @param GCPhys The GC physical address. * @param ppRam Where to store the pointer to the PGMRAMRANGE. * Optimize for the first range. * Gets the PGMPAGE structure for a guest page together with the PGMRAMRANGE. * @returns Pointer to the page on success. * @returns NULL on a VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS condition. * @param pPGM PGM handle. * @param GCPhys The GC physical address. * @param ppPage Where to store the pointer to the PGMPAGE structure. * @param ppRam Where to store the pointer to the PGMRAMRANGE structure. * Optimize for the first range. *
ppRam =
NULL;
/* Shut up silly GCC warnings. */ * Make sure it's present. * Convert GC Phys to HC Phys. * @param pPGM PGM handle. * @param GCPhys The GC physical address. * @param pHCPhys Where to store the corresponding HC physical address. * @deprecated Doesn't deal with zero, shared or write monitored pages. * Avoid when writing new code! * Queries the Physical TLB entry for a physical guest page, * attemting to load the TLB entry if necessary. * @returns VBox status code. * @retval VINF_SUCCESS on success * @retval VERR_PGM_INVALID_GC_PHYSICAL_ADDRESS if it's not a valid physical address. * @param pPGM The PGM instance handle. * @param GCPhys The address of the guest page. * @param ppTlbe Where to store the pointer to the TLB entry. * Convert GC Phys to HC Virt. * @param pPGM PGM handle. * @param GCPhys The GC physical address. * @param pHCPtr Where to store the corresponding HC virtual address. * @deprecated This will be eliminated by PGMPhysGCPhys2CCPtr. *
pHCPtr = 0;
/* Shut up silly GCC warnings. */ *
pHCPtr = 0;
/* Shut up silly GCC warnings. */#
endif /* !VBOX_WITH_NEW_PHYS_CODE */ * Convert GC Phys to HC Virt. * @param GCPhys The GC physical address. * @param pHCPtr Where to store the corresponding HC virtual address. * @deprecated This will be eliminated. Don't use it. /* Physical chunk in dynamically allocated range not present? */ * Convert GC Phys to HC Virt and HC Phys. * @param pPGM PGM handle. * @param GCPhys The GC physical address. * @param pHCPtr Where to store the corresponding HC virtual address. * @param pHCPhys Where to store the HC Physical address and its flags. * @deprecated Will go away or be changed. Only user is MapCR3. MapCR3 will have to do ring-3 * and ring-0 locking of the CR3 in a lazy fashion I'm fear... or perhaps not. we'll see. *
pHCPtr = 0;
/* Shut up crappy GCC warnings */ * Clears flags associated with a RAM address. * @returns VBox status code. * @param pPGM PGM handle. * @param GCPhys Guest context physical address. * @param fFlags fFlags to clear. (Bits 0-11.) * Clears flags associated with a RAM address. * @returns VBox status code. * @param pPGM PGM handle. * @param GCPhys Guest context physical address. * @param fFlags fFlags to clear. (Bits 0-11.) * @param ppRamHint Where to read and store the ram list hint. * The caller initializes this to NULL before the call. * Sets (bitwise OR) flags associated with a RAM address. * @returns VBox status code. * @param pPGM PGM handle. * @param GCPhys Guest context physical address. * @param fFlags fFlags to set clear. (Bits 0-11.) * Sets (bitwise OR) flags associated with a RAM address. * @returns VBox status code. * @param pPGM PGM handle. * @param GCPhys Guest context physical address. * @param fFlags fFlags to set clear. (Bits 0-11.) * @param ppRamHint Where to read and store the ram list hint. * The caller initializes this to NULL before the call. * Gets the page directory for the specified address. * @returns Pointer to the page directory in question. * @returns NULL if the page directory is not present or on an invalid page. * @param pPGM Pointer to the PGM instance data. * @param GCPtr The address. /* cache is out-of-sync. */ /* returning NIL_RTGCPHYS is ok if we assume it's just an invalid page of some kind emulated as all 0s. */ * Gets the page directory entry for the specified address. * @returns Pointer to the page directory entry in question. * @returns NULL if the page directory is not present or on an invalid page. * @param pPGM Pointer to the PGM instance data. * @param GCPtr The address. /* The cache is out-of-sync. */ /* returning NIL_RTGCPHYS is ok if we assume it's just an invalid page or something which we'll emulate as all 0s. */ * Gets the page directory entry for the specified address. * @returns The page directory entry in question. * @returns A non-present entry if the page directory is not present or on an invalid page. * @param pPGM Pointer to the PGM instance data. * @param GCPtr The address. /* cache is out-of-sync. */ * Gets the page directory pointer table entry for the specified address * and returns the index into the page directory * @returns Pointer to the page directory in question. * @returns NULL if the page directory is not present or on an invalid page. * @param pPGM Pointer to the PGM instance data. * @param GCPtr The address. * @param piPD Receives the index into the returned page directory /* cache is out-of-sync. */ /* returning NIL_RTGCPHYS is ok if we assume it's just an invalid page of some kind emulated as all 0s. */ * Gets the page directory pointer entry for the specified address. * @returns Pointer to the page directory pointer entry in question. * @returns NULL if the page directory is not present or on an invalid page. * @param pPGM Pointer to the PGM instance data. * @param GCPtr The address. * @param ppPml4e Page Map Level-4 Entry (out) * Gets the page directory entry for the specified address. * @returns The page directory entry in question. * @returns A non-present entry if the page directory is not present or on an invalid page. * @param pPGM Pointer to the PGM instance data. * @param GCPtr The address. * @param ppPml4e Page Map Level-4 Entry (out) * @param pPdpe Page directory pointer table entry (out) * Gets the page directory entry for the specified address. * @returns The page directory entry in question. * @returns A non-present entry if the page directory is not present or on an invalid page. * @param pPGM Pointer to the PGM instance data. * @param GCPtr The address. * Gets the page directory entry for the specified address. * @returns Pointer to the page directory entry in question. * @returns NULL if the page directory is not present or on an invalid page. * @param pPGM Pointer to the PGM instance data. * @param GCPtr The address. * Gets the GUEST page directory pointer for the specified address. * @returns The page directory in question. * @returns NULL if the page directory is not present or on an invalid page. * @param pPGM Pointer to the PGM instance data. * @param GCPtr The address. * @param ppPml4e Page Map Level-4 Entry (out) * @param pPdpe Page directory pointer table entry (out) * @param piPD Receives the index into the returned page directory * Checks if any of the specified page flags are set for the given page. * @returns true if any of the flags are set. * @returns false if all the flags are clear. * @param pPGM PGM handle. * @param GCPhys The GC physical address. * @param fFlags The flags to check for. * Gets the page state for a physical handler. * @returns The physical handler page state. * @param pCur The physical handler in question. * Gets the page state for a virtual handler. * @returns The virtual handler page state. * @param pCur The virtual handler in question. * @remarks This should never be used on a hypervisor access handler. * Clears one physical page of a virtual handler * @param pPGM Pointer to the PGM instance. * @param pCur Virtual handler structure * @param iPage Physical page index * @remark Only used when PGM_SYNC_UPDATE_PAGE_BIT_VIRTUAL is being set, so no * need to care about other handlers in the same page. * Remove the node from the tree (it's supposed to be in the tree if we get here!). (
"pPhys2Virt=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n",
/* We're the head of the alias chain. */ (
"pPhys2Virt=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n",
(
"wanted: pPhys2Virt=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n" " got: pRemove=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n",
/* Insert the next list in the alias chain into the tree. */ (
"pNext=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32}\n",
/* Locate the previous node in the alias chain. */ (
"pPhys2Virt=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32} pPrev=%p\n",
LogFlow((
"pgmHandlerVirtualClearPage: removed %p:{.offNextAlias=%#RX32} from alias chain. prev %p:{.offNextAlias=%#RX32} [%VGp-%VGp]\n",
(
"pPhys2Virt=%p:{.Core.Key=%VGp, .Core.KeyLast=%VGp, .offVirtHandler=%#RX32, .offNextAlias=%#RX32} pPrev=%p\n",
Log2((
"PHYS2VIRT: Removing %VGp-%VGp %#RX32 %s\n",
* Clear the ram flags for this page. * Internal worker for finding a 'in-use' shadow page give by it's physical address. * @returns Pointer to the shadow page structure. * @param HCPhys The HC physical address of the shadow page. * Internal worker for finding a 'in-use' shadow page give by it's physical address. * @returns Pointer to the shadow page structure. * @param idx The pool page index. * Clear references to guest physical memory. * @param pPoolPage The pool page. * @param pPhysPage The physical guest page tracking structure. * Just deal with the simple case here. * Moves the page to the head of the age list. * This is done when the cached page is used in one way or another. * @param pPage The cached page. * Move to the head of the age list. #
endif /* PGMPOOL_WITH_CACHE */ * Tells if mappings are to be put into the shadow page table or not * @returns boolean result /* There are no mappings in VT-x and AMD-V mode. */