VirtualBox

Changeset 18984 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Apr 17, 2009 9:00:22 AM (16 years ago)
Author:
vboxsync
Message:

Autoset does belong in PGMCPU

Location:
trunk/src/VBox/VMM
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/PGM.cpp

    r18974 r18984  
    16291629    PGM_REG_COUNTER(&pPGM->StatRCInvlPgSyncMonCR3,            "/PGM/RC/InvlPgSyncMonitorCR3",       "Number of times PGMInvalidatePage() ran into PGM_SYNC_MONITOR_CR3.");
    16301630
    1631     /* R0 only: */
    1632     PGM_REG_COUNTER(&pPGM->StatR0DynMapMigrateInvlPg,         "/PGM/R0/DynMapMigrateInvlPg",        "invlpg count in PGMDynMapMigrateAutoSet.");
    1633     PGM_REG_PROFILE(&pPGM->StatR0DynMapGCPageInl,             "/PGM/R0/DynMapPageGCPageInl",        "Calls to pgmR0DynMapGCPageInlined.");
    1634     PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlHits,         "/PGM/R0/DynMapPageGCPageInl/Hits",   "Hash table lookup hits.");
    1635     PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlMisses,       "/PGM/R0/DynMapPageGCPageInl/Misses", "Misses that falls back to code common with PGMDynMapHCPage.");
    1636     PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlRamHits,      "/PGM/R0/DynMapPageGCPageInl/RamHits",   "1st ram range hits.");
    1637     PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlRamMisses,    "/PGM/R0/DynMapPageGCPageInl/RamMisses", "1st ram range misses, takes slow path.");
    1638     PGM_REG_PROFILE(&pPGM->StatR0DynMapHCPageInl,             "/PGM/R0/DynMapPageHCPageInl",        "Calls to pgmR0DynMapHCPageInlined.");
    1639     PGM_REG_COUNTER(&pPGM->StatR0DynMapHCPageInlHits,         "/PGM/R0/DynMapPageHCPageInl/Hits",   "Hash table lookup hits.");
    1640     PGM_REG_COUNTER(&pPGM->StatR0DynMapHCPageInlMisses,       "/PGM/R0/DynMapPageHCPageInl/Misses", "Misses that falls back to code common with PGMDynMapHCPage.");
    1641     PGM_REG_COUNTER(&pPGM->StatR0DynMapPage,                  "/PGM/R0/DynMapPage",                 "Calls to pgmR0DynMapPage");
    1642     PGM_REG_COUNTER(&pPGM->StatR0DynMapSetOptimize,           "/PGM/R0/DynMapPage/SetOptimize",     "Calls to pgmDynMapOptimizeAutoSet.");
    1643     PGM_REG_COUNTER(&pPGM->StatR0DynMapSetSearchFlushes,      "/PGM/R0/DynMapPage/SetSearchFlushes","Set search restorting to subset flushes.");
    1644     PGM_REG_COUNTER(&pPGM->StatR0DynMapSetSearchHits,         "/PGM/R0/DynMapPage/SetSearchHits",   "Set search hits.");
    1645     PGM_REG_COUNTER(&pPGM->StatR0DynMapSetSearchMisses,       "/PGM/R0/DynMapPage/SetSearchMisses", "Set search misses.");
    1646     PGM_REG_PROFILE(&pPGM->StatR0DynMapHCPage,                "/PGM/R0/DynMapPage/HCPage",          "Calls to PGMDynMapHCPage (ring-0).");
    1647     PGM_REG_COUNTER(&pPGM->StatR0DynMapPageHits0,             "/PGM/R0/DynMapPage/Hits0",           "Hits at iPage+0");
    1648     PGM_REG_COUNTER(&pPGM->StatR0DynMapPageHits1,             "/PGM/R0/DynMapPage/Hits1",           "Hits at iPage+1");
    1649     PGM_REG_COUNTER(&pPGM->StatR0DynMapPageHits2,             "/PGM/R0/DynMapPage/Hits2",           "Hits at iPage+2");
    1650     PGM_REG_COUNTER(&pPGM->StatR0DynMapPageInvlPg,            "/PGM/R0/DynMapPage/InvlPg",          "invlpg count in pgmR0DynMapPageSlow.");
    1651     PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlow,              "/PGM/R0/DynMapPage/Slow",            "Calls to pgmR0DynMapPageSlow - subtract this from pgmR0DynMapPage to get 1st level hits.");
    1652     PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlowLoopHits,      "/PGM/R0/DynMapPage/SlowLoopHits" ,   "Hits in the loop path.");
    1653     PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlowLoopMisses,    "/PGM/R0/DynMapPage/SlowLoopMisses",  "Misses in the loop path. NonLoopMisses = Slow - SlowLoopHit - SlowLoopMisses");
    1654     //PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlowLostHits,      "/PGM/R0/DynMapPage/SlowLostHits",    "Lost hits.");
    1655     PGM_REG_COUNTER(&pPGM->StatR0DynMapSubsets,               "/PGM/R0/Subsets",                    "Times PGMDynMapPushAutoSubset was called.");
    1656     PGM_REG_COUNTER(&pPGM->StatR0DynMapPopFlushes,            "/PGM/R0/SubsetPopFlushes",           "Times PGMDynMapPopAutoSubset flushes the subset.");
    1657     PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[0],           "/PGM/R0/SetSize000..09",              "00-09% filled");
    1658     PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[1],           "/PGM/R0/SetSize010..19",              "10-19% filled");
    1659     PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[2],           "/PGM/R0/SetSize020..29",              "20-29% filled");
    1660     PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[3],           "/PGM/R0/SetSize030..39",              "30-39% filled");
    1661     PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[4],           "/PGM/R0/SetSize040..49",              "40-49% filled");
    1662     PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[5],           "/PGM/R0/SetSize050..59",              "50-59% filled");
    1663     PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[6],           "/PGM/R0/SetSize060..69",              "60-69% filled");
    1664     PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[7],           "/PGM/R0/SetSize070..79",              "70-79% filled");
    1665     PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[8],           "/PGM/R0/SetSize080..89",              "80-89% filled");
    1666     PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[9],           "/PGM/R0/SetSize090..99",              "90-99% filled");
    1667     PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[10],          "/PGM/R0/SetSize100",                 "100% filled");
    1668 
    16691631# ifdef PGMPOOL_WITH_GCPHYS_TRACKING
    16701632    PGM_REG_COUNTER(&pPGM->StatTrackVirgin,                   "/PGM/Track/Virgin",                  "The number of first time shadowings");
     
    17081670            STAMR3RegisterF(pVM, &pPGM->StatSyncPagePD[i], STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,
    17091671                            "The number of SyncPage per PD n.", "/PGM/CPU%d/PDSyncPage/%04X", i, j);
     1672
     1673        /* R0 only: */
     1674        PGM_REG_COUNTER(&pPGM->StatR0DynMapMigrateInvlPg,         "/PGM/CPU%d/R0/DynMapMigrateInvlPg",        "invlpg count in PGMDynMapMigrateAutoSet.");
     1675        PGM_REG_PROFILE(&pPGM->StatR0DynMapGCPageInl,             "/PGM/CPU%d/R0/DynMapPageGCPageInl",        "Calls to pgmR0DynMapGCPageInlined.");
     1676        PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlHits,         "/PGM/CPU%d/R0/DynMapPageGCPageInl/Hits",   "Hash table lookup hits.");
     1677        PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlMisses,       "/PGM/CPU%d/R0/DynMapPageGCPageInl/Misses", "Misses that falls back to code common with PGMDynMapHCPage.");
     1678        PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlRamHits,      "/PGM/CPU%d/R0/DynMapPageGCPageInl/RamHits",   "1st ram range hits.");
     1679        PGM_REG_COUNTER(&pPGM->StatR0DynMapGCPageInlRamMisses,    "/PGM/CPU%d/R0/DynMapPageGCPageInl/RamMisses", "1st ram range misses, takes slow path.");
     1680        PGM_REG_PROFILE(&pPGM->StatR0DynMapHCPageInl,             "/PGM/CPU%d/R0/DynMapPageHCPageInl",        "Calls to pgmR0DynMapHCPageInlined.");
     1681        PGM_REG_COUNTER(&pPGM->StatR0DynMapHCPageInlHits,         "/PGM/CPU%d/R0/DynMapPageHCPageInl/Hits",   "Hash table lookup hits.");
     1682        PGM_REG_COUNTER(&pPGM->StatR0DynMapHCPageInlMisses,       "/PGM/CPU%d/R0/DynMapPageHCPageInl/Misses", "Misses that falls back to code common with PGMDynMapHCPage.");
     1683        PGM_REG_COUNTER(&pPGM->StatR0DynMapPage,                  "/PGM/CPU%d/R0/DynMapPage",                 "Calls to pgmR0DynMapPage");
     1684        PGM_REG_COUNTER(&pPGM->StatR0DynMapSetOptimize,           "/PGM/CPU%d/R0/DynMapPage/SetOptimize",     "Calls to pgmDynMapOptimizeAutoSet.");
     1685        PGM_REG_COUNTER(&pPGM->StatR0DynMapSetSearchFlushes,      "/PGM/CPU%d/R0/DynMapPage/SetSearchFlushes","Set search restorting to subset flushes.");
     1686        PGM_REG_COUNTER(&pPGM->StatR0DynMapSetSearchHits,         "/PGM/CPU%d/R0/DynMapPage/SetSearchHits",   "Set search hits.");
     1687        PGM_REG_COUNTER(&pPGM->StatR0DynMapSetSearchMisses,       "/PGM/CPU%d/R0/DynMapPage/SetSearchMisses", "Set search misses.");
     1688        PGM_REG_PROFILE(&pPGM->StatR0DynMapHCPage,                "/PGM/CPU%d/R0/DynMapPage/HCPage",          "Calls to PGMDynMapHCPage (ring-0).");
     1689        PGM_REG_COUNTER(&pPGM->StatR0DynMapPageHits0,             "/PGM/CPU%d/R0/DynMapPage/Hits0",           "Hits at iPage+0");
     1690        PGM_REG_COUNTER(&pPGM->StatR0DynMapPageHits1,             "/PGM/CPU%d/R0/DynMapPage/Hits1",           "Hits at iPage+1");
     1691        PGM_REG_COUNTER(&pPGM->StatR0DynMapPageHits2,             "/PGM/CPU%d/R0/DynMapPage/Hits2",           "Hits at iPage+2");
     1692        PGM_REG_COUNTER(&pPGM->StatR0DynMapPageInvlPg,            "/PGM/CPU%d/R0/DynMapPage/InvlPg",          "invlpg count in pgmR0DynMapPageSlow.");
     1693        PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlow,              "/PGM/CPU%d/R0/DynMapPage/Slow",            "Calls to pgmR0DynMapPageSlow - subtract this from pgmR0DynMapPage to get 1st level hits.");
     1694        PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlowLoopHits,      "/PGM/CPU%d/R0/DynMapPage/SlowLoopHits" ,   "Hits in the loop path.");
     1695        PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlowLoopMisses,    "/PGM/CPU%d/R0/DynMapPage/SlowLoopMisses",  "Misses in the loop path. NonLoopMisses = Slow - SlowLoopHit - SlowLoopMisses");
     1696        //PGM_REG_COUNTER(&pPGM->StatR0DynMapPageSlowLostHits,      "/PGM/CPU%d/R0/DynMapPage/SlowLostHits",    "Lost hits.");
     1697        PGM_REG_COUNTER(&pPGM->StatR0DynMapSubsets,               "/PGM/CPU%d/R0/Subsets",                    "Times PGMDynMapPushAutoSubset was called.");
     1698        PGM_REG_COUNTER(&pPGM->StatR0DynMapPopFlushes,            "/PGM/CPU%d/R0/SubsetPopFlushes",           "Times PGMDynMapPopAutoSubset flushes the subset.");
     1699        PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[0],           "/PGM/CPU%d/R0/SetSize000..09",              "00-09% filled");
     1700        PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[1],           "/PGM/CPU%d/R0/SetSize010..19",              "10-19% filled");
     1701        PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[2],           "/PGM/CPU%d/R0/SetSize020..29",              "20-29% filled");
     1702        PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[3],           "/PGM/CPU%d/R0/SetSize030..39",              "30-39% filled");
     1703        PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[4],           "/PGM/CPU%d/R0/SetSize040..49",              "40-49% filled");
     1704        PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[5],           "/PGM/CPU%d/R0/SetSize050..59",              "50-59% filled");
     1705        PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[6],           "/PGM/CPU%d/R0/SetSize060..69",              "60-69% filled");
     1706        PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[7],           "/PGM/CPU%d/R0/SetSize070..79",              "70-79% filled");
     1707        PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[8],           "/PGM/CPU%d/R0/SetSize080..89",              "80-89% filled");
     1708        PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[9],           "/PGM/CPU%d/R0/SetSize090..99",              "90-99% filled");
     1709        PGM_REG_COUNTER(&pPGM->aStatR0DynMapSetSize[10],          "/PGM/CPU%d/R0/SetSize100",                 "100% filled");
    17101710
    17111711        /* RZ only: */
  • trunk/src/VBox/VMM/PGMInternal.h

    r18980 r18984  
    21972197    SUPPAGINGMODE                   enmHostMode;
    21982198
    2199 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    2200     /** Automatically tracked physical memory mapping set.
    2201      * Ring-0 and strict raw-mode builds. */
    2202     PGMMAPSET                       AutoSet;
    2203 #endif
    2204 
    22052199    /** 4 MB page mask; 32 or 36 bits depending on PSE-36 (identical for all VCPUs) */
    22062200    RTGCPHYS                        GCPhys4MBPSEMask;
     
    24572451    STAMCOUNTER StatRCInvlPgConflict;               /**< RC: Number of times PGMInvalidatePage() detected a mapping conflict. */
    24582452    STAMCOUNTER StatRCInvlPgSyncMonCR3;             /**< RC: Number of times PGMInvalidatePage() ran into PGM_SYNC_MONITOR_CR3. */
     2453
     2454# ifdef PGMPOOL_WITH_GCPHYS_TRACKING
     2455    STAMCOUNTER StatTrackVirgin;                    /**< The number of first time shadowings. */
     2456    STAMCOUNTER StatTrackAliased;                   /**< The number of times switching to cRef2, i.e. the page is being shadowed by two PTs. */
     2457    STAMCOUNTER StatTrackAliasedMany;               /**< The number of times we're tracking using cRef2. */
     2458    STAMCOUNTER StatTrackAliasedLots;               /**< The number of times we're hitting pages which has overflowed cRef2. */
     2459    STAMCOUNTER StatTrackOverflows;                 /**< The number of times the extent list grows to long. */
     2460    STAMPROFILE StatTrackDeref;                     /**< Profiling of SyncPageWorkerTrackDeref (expensive). */
     2461# endif
     2462#endif
     2463} PGM;
     2464/** Pointer to the PGM instance data. */
     2465typedef PGM *PPGM;
     2466
     2467
     2468/**
     2469 * Converts a PGMCPU pointer into a VM pointer.
     2470 * @returns Pointer to the VM structure the PGM is part of.
     2471 * @param   pPGM   Pointer to PGMCPU instance data.
     2472 */
     2473#define PGMCPU2VM(pPGM)  ( (PVM)((char*)pPGM - pPGM->offVM) )
     2474
     2475/**
     2476 * Converts a PGMCPU pointer into a PGM pointer.
     2477 * @returns Pointer to the VM structure the PGM is part of.
     2478 * @param   pPGM   Pointer to PGMCPU instance data.
     2479 */
     2480#define PGMCPU2PGM(pPGMCpu)  ( (PPGM)((char*)pPGMCpu - pPGMCpu->offPGM) )
     2481
     2482/**
     2483 * PGMCPU Data (part of VMCPU).
     2484 */
     2485typedef struct PGMCPU
     2486{
     2487    /** Offset to the VM structure. */
     2488    RTINT                           offVM;
     2489    /** Offset to the VMCPU structure. */
     2490    RTINT                           offVCpu;
     2491    /** Offset of the PGM structure relative to VMCPU. */
     2492    RTINT                           offPGM;
     2493    RTINT                           uPadding0;      /**< structure size alignment. */
     2494
     2495#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
     2496    /** Automatically tracked physical memory mapping set.
     2497     * Ring-0 and strict raw-mode builds. */
     2498    PGMMAPSET                       AutoSet;
     2499#endif
     2500
     2501    /** A20 gate mask.
     2502     * Our current approach to A20 emulation is to let REM do it and don't bother
     2503     * anywhere else. The interesting Guests will be operating with it enabled anyway.
     2504     * But whould need arrise, we'll subject physical addresses to this mask. */
     2505    RTGCPHYS                        GCPhysA20Mask;
     2506    /** A20 gate state - boolean! */
     2507    bool                            fA20Enabled;
     2508
     2509    /** What needs syncing (PGM_SYNC_*).
     2510     * This is used to queue operations for PGMSyncCR3, PGMInvalidatePage,
     2511     * PGMFlushTLB, and PGMR3Load. */
     2512    RTUINT                          fSyncFlags;
     2513
     2514    /** The shadow paging mode. */
     2515    PGMMODE                         enmShadowMode;
     2516    /** The guest paging mode. */
     2517    PGMMODE                         enmGuestMode;
     2518
     2519    /** The current physical address representing in the guest CR3 register. */
     2520    RTGCPHYS                        GCPhysCR3;
     2521
     2522    /** @name 32-bit Guest Paging.
     2523     * @{ */
     2524    /** The guest's page directory, R3 pointer. */
     2525    R3PTRTYPE(PX86PD)               pGst32BitPdR3;
     2526#ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
     2527    /** The guest's page directory, R0 pointer. */
     2528    R0PTRTYPE(PX86PD)               pGst32BitPdR0;
     2529#endif
     2530    /** The guest's page directory, static RC mapping. */
     2531    RCPTRTYPE(PX86PD)               pGst32BitPdRC;
     2532    /** @} */
     2533
     2534    /** @name PAE Guest Paging.
     2535     * @{ */
     2536    /** The guest's page directory pointer table, static RC mapping. */
     2537    RCPTRTYPE(PX86PDPT)             pGstPaePdptRC;
     2538    /** The guest's page directory pointer table, R3 pointer. */
     2539    R3PTRTYPE(PX86PDPT)             pGstPaePdptR3;
     2540#ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
     2541    /** The guest's page directory pointer table, R0 pointer. */
     2542    R0PTRTYPE(PX86PDPT)             pGstPaePdptR0;
     2543#endif
     2544
     2545    /** The guest's page directories, R3 pointers.
     2546     * These are individual pointers and don't have to be adjecent.
     2547     * These don't have to be up-to-date - use pgmGstGetPaePD() to access them. */
     2548    R3PTRTYPE(PX86PDPAE)            apGstPaePDsR3[4];
     2549    /** The guest's page directories, R0 pointers.
     2550     * Same restrictions as apGstPaePDsR3. */
     2551#ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
     2552    R0PTRTYPE(PX86PDPAE)            apGstPaePDsR0[4];
     2553#endif
     2554    /** The guest's page directories, static GC mapping.
     2555     * Unlike the R3/R0 array the first entry can be accessed as a 2048 entry PD.
     2556     * These don't have to be up-to-date - use pgmGstGetPaePD() to access them. */
     2557    RCPTRTYPE(PX86PDPAE)            apGstPaePDsRC[4];
     2558    /** The physical addresses of the guest page directories (PAE) pointed to by apGstPagePDsHC/GC. */
     2559    RTGCPHYS                        aGCPhysGstPaePDs[4];
     2560    /** The physical addresses of the monitored guest page directories (PAE). */
     2561    RTGCPHYS                        aGCPhysGstPaePDsMonitored[4];
     2562    /** @} */
     2563
     2564    /** @name AMD64 Guest Paging.
     2565     * @{ */
     2566    /** The guest's page directory pointer table, R3 pointer. */
     2567    R3PTRTYPE(PX86PML4)             pGstAmd64Pml4R3;
     2568#ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
     2569    /** The guest's page directory pointer table, R0 pointer. */
     2570    R0PTRTYPE(PX86PML4)             pGstAmd64Pml4R0;
     2571#endif
     2572    /** @} */
     2573
     2574    /** Pointer to the page of the current active CR3 - R3 Ptr. */
     2575    R3PTRTYPE(PPGMPOOLPAGE)         pShwPageCR3R3;
     2576    /** Pointer to the page of the current active CR3 - R0 Ptr. */
     2577    R0PTRTYPE(PPGMPOOLPAGE)         pShwPageCR3R0;
     2578    /** Pointer to the page of the current active CR3 - RC Ptr. */
     2579    RCPTRTYPE(PPGMPOOLPAGE)         pShwPageCR3RC;
     2580    /* The shadow page pool index of the user table as specified during allocation; useful for freeing root pages */
     2581    uint32_t                        iShwUser;
     2582    /* The index into the user table (shadowed) as specified during allocation; useful for freeing root pages. */
     2583    uint32_t                        iShwUserTable;
     2584# if HC_ARCH_BITS == 64
     2585    RTRCPTR                         alignment6; /**< structure size alignment. */
     2586# endif
     2587    /** @} */
     2588
     2589    /** @name Function pointers for Shadow paging.
     2590     * @{
     2591     */
     2592    DECLR3CALLBACKMEMBER(int,       pfnR3ShwRelocate,(PVM pVM, PVMCPU pVCpu, RTGCPTR offDelta));
     2593    DECLR3CALLBACKMEMBER(int,       pfnR3ShwExit,(PVM pVM, PVMCPU pVCpu));
     2594    DECLR3CALLBACKMEMBER(int,       pfnR3ShwGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
     2595    DECLR3CALLBACKMEMBER(int,       pfnR3ShwModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
     2596
     2597    DECLRCCALLBACKMEMBER(int,       pfnRCShwGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
     2598    DECLRCCALLBACKMEMBER(int,       pfnRCShwModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
     2599
     2600    DECLR0CALLBACKMEMBER(int,       pfnR0ShwGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
     2601    DECLR0CALLBACKMEMBER(int,       pfnR0ShwModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
     2602
     2603    /** @} */
     2604
     2605    /** @name Function pointers for Guest paging.
     2606     * @{
     2607     */
     2608    DECLR3CALLBACKMEMBER(int,       pfnR3GstRelocate,(PVM pVM, PVMCPU pVCpu, RTGCPTR offDelta));
     2609    DECLR3CALLBACKMEMBER(int,       pfnR3GstExit,(PVM pVM, PVMCPU pVCpu));
     2610    DECLR3CALLBACKMEMBER(int,       pfnR3GstGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
     2611    DECLR3CALLBACKMEMBER(int,       pfnR3GstModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
     2612    DECLR3CALLBACKMEMBER(int,       pfnR3GstGetPDE,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPde));
     2613    DECLRCCALLBACKMEMBER(int,       pfnRCGstGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
     2614    DECLRCCALLBACKMEMBER(int,       pfnRCGstModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
     2615    DECLRCCALLBACKMEMBER(int,       pfnRCGstGetPDE,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPde));
     2616#if HC_ARCH_BITS == 64
     2617    RTRCPTR                         alignment3; /**< structure size alignment. */
     2618#endif
     2619
     2620    DECLR0CALLBACKMEMBER(int,       pfnR0GstGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
     2621    DECLR0CALLBACKMEMBER(int,       pfnR0GstModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
     2622    DECLR0CALLBACKMEMBER(int,       pfnR0GstGetPDE,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPde));
     2623    /** @} */
     2624
     2625    /** @name Function pointers for Both Shadow and Guest paging.
     2626     * @{
     2627     */
     2628    DECLR3CALLBACKMEMBER(int,       pfnR3BthRelocate,(PVM pVM, PVMCPU pVCpu, RTGCPTR offDelta));
     2629    /*                           no pfnR3BthTrap0eHandler */
     2630    DECLR3CALLBACKMEMBER(int,       pfnR3BthInvalidatePage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));
     2631    DECLR3CALLBACKMEMBER(int,       pfnR3BthSyncCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
     2632    DECLR3CALLBACKMEMBER(int,       pfnR3BthSyncPage,(PVM pVM, PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));
     2633    DECLR3CALLBACKMEMBER(int,       pfnR3BthPrefetchPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));
     2634    DECLR3CALLBACKMEMBER(int,       pfnR3BthVerifyAccessSyncPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));
     2635    DECLR3CALLBACKMEMBER(unsigned,  pfnR3BthAssertCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));
     2636    DECLR3CALLBACKMEMBER(int,       pfnR3BthMapCR3,(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysCR3));
     2637    DECLR3CALLBACKMEMBER(int,       pfnR3BthUnmapCR3,(PVM pVM, PVMCPU pVCpu));
     2638
     2639    DECLR0CALLBACKMEMBER(int,       pfnR0BthTrap0eHandler,(PVM pVM, PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
     2640    DECLR0CALLBACKMEMBER(int,       pfnR0BthInvalidatePage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));
     2641    DECLR0CALLBACKMEMBER(int,       pfnR0BthSyncCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
     2642    DECLR0CALLBACKMEMBER(int,       pfnR0BthSyncPage,(PVM pVM, PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));
     2643    DECLR0CALLBACKMEMBER(int,       pfnR0BthPrefetchPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));
     2644    DECLR0CALLBACKMEMBER(int,       pfnR0BthVerifyAccessSyncPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));
     2645    DECLR0CALLBACKMEMBER(unsigned,  pfnR0BthAssertCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));
     2646    DECLR0CALLBACKMEMBER(int,       pfnR0BthMapCR3,(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysCR3));
     2647    DECLR0CALLBACKMEMBER(int,       pfnR0BthUnmapCR3,(PVM pVM, PVMCPU pVCpu));
     2648
     2649    DECLRCCALLBACKMEMBER(int,       pfnRCBthTrap0eHandler,(PVM pVM, PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
     2650    DECLRCCALLBACKMEMBER(int,       pfnRCBthInvalidatePage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));
     2651    DECLRCCALLBACKMEMBER(int,       pfnRCBthSyncCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
     2652    DECLRCCALLBACKMEMBER(int,       pfnRCBthSyncPage,(PVM pVM, PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));
     2653    DECLRCCALLBACKMEMBER(int,       pfnRCBthPrefetchPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));
     2654    DECLRCCALLBACKMEMBER(int,       pfnRCBthVerifyAccessSyncPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));
     2655    DECLRCCALLBACKMEMBER(unsigned,  pfnRCBthAssertCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));
     2656    DECLRCCALLBACKMEMBER(int,       pfnRCBthMapCR3,(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysCR3));
     2657    DECLRCCALLBACKMEMBER(int,       pfnRCBthUnmapCR3,(PVM pVM, PVMCPU pVCpu));
     2658#if HC_ARCH_BITS == 64
     2659    RTRCPTR                         alignment2; /**< structure size alignment. */
     2660#endif
     2661    /** @} */
     2662
     2663    /** @name Release Statistics
     2664     * @{ */
     2665    /** The number of times the guest has switched mode since last reset or statistics reset. */
     2666    STAMCOUNTER                     cGuestModeChanges;
     2667    /** @} */
     2668
     2669#ifdef VBOX_WITH_STATISTICS /** @todo move this chunk to the heap.  */
     2670    /** @name Statistics
     2671     * @{ */
     2672    /** RC: Which statistic this \#PF should be attributed to. */
     2673    RCPTRTYPE(PSTAMPROFILE)         pStatTrap0eAttributionRC;
     2674    RTRCPTR                         padding0;
     2675    /** R0: Which statistic this \#PF should be attributed to. */
     2676    R0PTRTYPE(PSTAMPROFILE)         pStatTrap0eAttributionR0;
     2677    RTR0PTR                         padding1;
     2678
     2679    /* Common */
     2680    STAMCOUNTER StatSyncPtPD[X86_PG_ENTRIES];       /**< SyncPT - PD distribution. */
     2681    STAMCOUNTER StatSyncPagePD[X86_PG_ENTRIES];     /**< SyncPage - PD distribution. */
    24592682
    24602683    /* R0 only: */
     
    24852708    STAMCOUNTER StatR0DynMapPopFlushes;             /**< R0: Times PGMDynMapPopAutoSubset flushes the subset. */
    24862709    STAMCOUNTER aStatR0DynMapSetSize[11];           /**< R0: Set size distribution. */
    2487 
    2488 # ifdef PGMPOOL_WITH_GCPHYS_TRACKING
    2489     STAMCOUNTER StatTrackVirgin;                    /**< The number of first time shadowings. */
    2490     STAMCOUNTER StatTrackAliased;                   /**< The number of times switching to cRef2, i.e. the page is being shadowed by two PTs. */
    2491     STAMCOUNTER StatTrackAliasedMany;               /**< The number of times we're tracking using cRef2. */
    2492     STAMCOUNTER StatTrackAliasedLots;               /**< The number of times we're hitting pages which has overflowed cRef2. */
    2493     STAMCOUNTER StatTrackOverflows;                 /**< The number of times the extent list grows to long. */
    2494     STAMPROFILE StatTrackDeref;                     /**< Profiling of SyncPageWorkerTrackDeref (expensive). */
    2495 # endif
    2496 #endif
    2497 } PGM;
    2498 /** Pointer to the PGM instance data. */
    2499 typedef PGM *PPGM;
    2500 
    2501 
    2502 /**
    2503  * Converts a PGMCPU pointer into a VM pointer.
    2504  * @returns Pointer to the VM structure the PGM is part of.
    2505  * @param   pPGM   Pointer to PGMCPU instance data.
    2506  */
    2507 #define PGMCPU2VM(pPGM)  ( (PVM)((char*)pPGM - pPGM->offVM) )
    2508 
    2509 /**
    2510  * Converts a PGMCPU pointer into a PGM pointer.
    2511  * @returns Pointer to the VM structure the PGM is part of.
    2512  * @param   pPGM   Pointer to PGMCPU instance data.
    2513  */
    2514 #define PGMCPU2PGM(pPGMCpu)  ( (PPGM)((char*)pPGMCpu - pPGMCpu->offPGM) )
    2515 
    2516 /**
    2517  * PGMCPU Data (part of VMCPU).
    2518  */
    2519 typedef struct PGMCPU
    2520 {
    2521     /** Offset to the VM structure. */
    2522     RTINT                           offVM;
    2523     /** Offset to the VMCPU structure. */
    2524     RTINT                           offVCpu;
    2525     /** Offset of the PGM structure relative to VMCPU. */
    2526     RTINT                           offPGM;
    2527     RTINT                           uPadding0;      /**< structure size alignment. */
    2528 
    2529     /** A20 gate mask.
    2530      * Our current approach to A20 emulation is to let REM do it and don't bother
    2531      * anywhere else. The interesting Guests will be operating with it enabled anyway.
    2532      * But whould need arrise, we'll subject physical addresses to this mask. */
    2533     RTGCPHYS                        GCPhysA20Mask;
    2534     /** A20 gate state - boolean! */
    2535     bool                            fA20Enabled;
    2536 
    2537     /** What needs syncing (PGM_SYNC_*).
    2538      * This is used to queue operations for PGMSyncCR3, PGMInvalidatePage,
    2539      * PGMFlushTLB, and PGMR3Load. */
    2540     RTUINT                          fSyncFlags;
    2541 
    2542     /** The shadow paging mode. */
    2543     PGMMODE                         enmShadowMode;
    2544     /** The guest paging mode. */
    2545     PGMMODE                         enmGuestMode;
    2546 
    2547     /** The current physical address representing in the guest CR3 register. */
    2548     RTGCPHYS                        GCPhysCR3;
    2549 
    2550     /** @name 32-bit Guest Paging.
    2551      * @{ */
    2552     /** The guest's page directory, R3 pointer. */
    2553     R3PTRTYPE(PX86PD)               pGst32BitPdR3;
    2554 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
    2555     /** The guest's page directory, R0 pointer. */
    2556     R0PTRTYPE(PX86PD)               pGst32BitPdR0;
    2557 #endif
    2558     /** The guest's page directory, static RC mapping. */
    2559     RCPTRTYPE(PX86PD)               pGst32BitPdRC;
    2560     /** @} */
    2561 
    2562     /** @name PAE Guest Paging.
    2563      * @{ */
    2564     /** The guest's page directory pointer table, static RC mapping. */
    2565     RCPTRTYPE(PX86PDPT)             pGstPaePdptRC;
    2566     /** The guest's page directory pointer table, R3 pointer. */
    2567     R3PTRTYPE(PX86PDPT)             pGstPaePdptR3;
    2568 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
    2569     /** The guest's page directory pointer table, R0 pointer. */
    2570     R0PTRTYPE(PX86PDPT)             pGstPaePdptR0;
    2571 #endif
    2572 
    2573     /** The guest's page directories, R3 pointers.
    2574      * These are individual pointers and don't have to be adjecent.
    2575      * These don't have to be up-to-date - use pgmGstGetPaePD() to access them. */
    2576     R3PTRTYPE(PX86PDPAE)            apGstPaePDsR3[4];
    2577     /** The guest's page directories, R0 pointers.
    2578      * Same restrictions as apGstPaePDsR3. */
    2579 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
    2580     R0PTRTYPE(PX86PDPAE)            apGstPaePDsR0[4];
    2581 #endif
    2582     /** The guest's page directories, static GC mapping.
    2583      * Unlike the R3/R0 array the first entry can be accessed as a 2048 entry PD.
    2584      * These don't have to be up-to-date - use pgmGstGetPaePD() to access them. */
    2585     RCPTRTYPE(PX86PDPAE)            apGstPaePDsRC[4];
    2586     /** The physical addresses of the guest page directories (PAE) pointed to by apGstPagePDsHC/GC. */
    2587     RTGCPHYS                        aGCPhysGstPaePDs[4];
    2588     /** The physical addresses of the monitored guest page directories (PAE). */
    2589     RTGCPHYS                        aGCPhysGstPaePDsMonitored[4];
    2590     /** @} */
    2591 
    2592     /** @name AMD64 Guest Paging.
    2593      * @{ */
    2594     /** The guest's page directory pointer table, R3 pointer. */
    2595     R3PTRTYPE(PX86PML4)             pGstAmd64Pml4R3;
    2596 #ifndef VBOX_WITH_2X_4GB_ADDR_SPACE
    2597     /** The guest's page directory pointer table, R0 pointer. */
    2598     R0PTRTYPE(PX86PML4)             pGstAmd64Pml4R0;
    2599 #endif
    2600     /** @} */
    2601 
    2602     /** Pointer to the page of the current active CR3 - R3 Ptr. */
    2603     R3PTRTYPE(PPGMPOOLPAGE)         pShwPageCR3R3;
    2604     /** Pointer to the page of the current active CR3 - R0 Ptr. */
    2605     R0PTRTYPE(PPGMPOOLPAGE)         pShwPageCR3R0;
    2606     /** Pointer to the page of the current active CR3 - RC Ptr. */
    2607     RCPTRTYPE(PPGMPOOLPAGE)         pShwPageCR3RC;
    2608     /* The shadow page pool index of the user table as specified during allocation; useful for freeing root pages */
    2609     uint32_t                        iShwUser;
    2610     /* The index into the user table (shadowed) as specified during allocation; useful for freeing root pages. */
    2611     uint32_t                        iShwUserTable;
    2612 # if HC_ARCH_BITS == 64
    2613     RTRCPTR                         alignment6; /**< structure size alignment. */
    2614 # endif
    2615     /** @} */
    2616 
    2617     /** @name Function pointers for Shadow paging.
    2618      * @{
    2619      */
    2620     DECLR3CALLBACKMEMBER(int,       pfnR3ShwRelocate,(PVM pVM, PVMCPU pVCpu, RTGCPTR offDelta));
    2621     DECLR3CALLBACKMEMBER(int,       pfnR3ShwExit,(PVM pVM, PVMCPU pVCpu));
    2622     DECLR3CALLBACKMEMBER(int,       pfnR3ShwGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
    2623     DECLR3CALLBACKMEMBER(int,       pfnR3ShwModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
    2624 
    2625     DECLRCCALLBACKMEMBER(int,       pfnRCShwGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
    2626     DECLRCCALLBACKMEMBER(int,       pfnRCShwModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
    2627 
    2628     DECLR0CALLBACKMEMBER(int,       pfnR0ShwGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTHCPHYS pHCPhys));
    2629     DECLR0CALLBACKMEMBER(int,       pfnR0ShwModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
    2630 
    2631     /** @} */
    2632 
    2633     /** @name Function pointers for Guest paging.
    2634      * @{
    2635      */
    2636     DECLR3CALLBACKMEMBER(int,       pfnR3GstRelocate,(PVM pVM, PVMCPU pVCpu, RTGCPTR offDelta));
    2637     DECLR3CALLBACKMEMBER(int,       pfnR3GstExit,(PVM pVM, PVMCPU pVCpu));
    2638     DECLR3CALLBACKMEMBER(int,       pfnR3GstGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
    2639     DECLR3CALLBACKMEMBER(int,       pfnR3GstModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
    2640     DECLR3CALLBACKMEMBER(int,       pfnR3GstGetPDE,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPde));
    2641     DECLRCCALLBACKMEMBER(int,       pfnRCGstGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
    2642     DECLRCCALLBACKMEMBER(int,       pfnRCGstModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
    2643     DECLRCCALLBACKMEMBER(int,       pfnRCGstGetPDE,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPde));
    2644 #if HC_ARCH_BITS == 64
    2645     RTRCPTR                         alignment3; /**< structure size alignment. */
    2646 #endif
    2647 
    2648     DECLR0CALLBACKMEMBER(int,       pfnR0GstGetPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, uint64_t *pfFlags, PRTGCPHYS pGCPhys));
    2649     DECLR0CALLBACKMEMBER(int,       pfnR0GstModifyPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, size_t cbPages, uint64_t fFlags, uint64_t fMask));
    2650     DECLR0CALLBACKMEMBER(int,       pfnR0GstGetPDE,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtr, PX86PDEPAE pPde));
    2651     /** @} */
    2652 
    2653     /** @name Function pointers for Both Shadow and Guest paging.
    2654      * @{
    2655      */
    2656     DECLR3CALLBACKMEMBER(int,       pfnR3BthRelocate,(PVM pVM, PVMCPU pVCpu, RTGCPTR offDelta));
    2657     /*                           no pfnR3BthTrap0eHandler */
    2658     DECLR3CALLBACKMEMBER(int,       pfnR3BthInvalidatePage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));
    2659     DECLR3CALLBACKMEMBER(int,       pfnR3BthSyncCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
    2660     DECLR3CALLBACKMEMBER(int,       pfnR3BthSyncPage,(PVM pVM, PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));
    2661     DECLR3CALLBACKMEMBER(int,       pfnR3BthPrefetchPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));
    2662     DECLR3CALLBACKMEMBER(int,       pfnR3BthVerifyAccessSyncPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));
    2663     DECLR3CALLBACKMEMBER(unsigned,  pfnR3BthAssertCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));
    2664     DECLR3CALLBACKMEMBER(int,       pfnR3BthMapCR3,(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysCR3));
    2665     DECLR3CALLBACKMEMBER(int,       pfnR3BthUnmapCR3,(PVM pVM, PVMCPU pVCpu));
    2666 
    2667     DECLR0CALLBACKMEMBER(int,       pfnR0BthTrap0eHandler,(PVM pVM, PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
    2668     DECLR0CALLBACKMEMBER(int,       pfnR0BthInvalidatePage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));
    2669     DECLR0CALLBACKMEMBER(int,       pfnR0BthSyncCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
    2670     DECLR0CALLBACKMEMBER(int,       pfnR0BthSyncPage,(PVM pVM, PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));
    2671     DECLR0CALLBACKMEMBER(int,       pfnR0BthPrefetchPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));
    2672     DECLR0CALLBACKMEMBER(int,       pfnR0BthVerifyAccessSyncPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));
    2673     DECLR0CALLBACKMEMBER(unsigned,  pfnR0BthAssertCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));
    2674     DECLR0CALLBACKMEMBER(int,       pfnR0BthMapCR3,(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysCR3));
    2675     DECLR0CALLBACKMEMBER(int,       pfnR0BthUnmapCR3,(PVM pVM, PVMCPU pVCpu));
    2676 
    2677     DECLRCCALLBACKMEMBER(int,       pfnRCBthTrap0eHandler,(PVM pVM, PVMCPU pVCpu, RTGCUINT uErr, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault));
    2678     DECLRCCALLBACKMEMBER(int,       pfnRCBthInvalidatePage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));
    2679     DECLRCCALLBACKMEMBER(int,       pfnRCBthSyncCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr0, uint64_t cr3, uint64_t cr4, bool fGlobal));
    2680     DECLRCCALLBACKMEMBER(int,       pfnRCBthSyncPage,(PVM pVM, PVMCPU pVCpu, X86PDE PdeSrc, RTGCPTR GCPtrPage, unsigned cPages, unsigned uError));
    2681     DECLRCCALLBACKMEMBER(int,       pfnRCBthPrefetchPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage));
    2682     DECLRCCALLBACKMEMBER(int,       pfnRCBthVerifyAccessSyncPage,(PVM pVM, PVMCPU pVCpu, RTGCPTR GCPtrPage, unsigned fFlags, unsigned uError));
    2683     DECLRCCALLBACKMEMBER(unsigned,  pfnRCBthAssertCR3,(PVM pVM, PVMCPU pVCpu, uint64_t cr3, uint64_t cr4, RTGCPTR GCPtr, RTGCPTR cb));
    2684     DECLRCCALLBACKMEMBER(int,       pfnRCBthMapCR3,(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhysCR3));
    2685     DECLRCCALLBACKMEMBER(int,       pfnRCBthUnmapCR3,(PVM pVM, PVMCPU pVCpu));
    2686 #if HC_ARCH_BITS == 64
    2687     RTRCPTR                         alignment2; /**< structure size alignment. */
    2688 #endif
    2689     /** @} */
    2690 
    2691     /** @name Release Statistics
    2692      * @{ */
    2693     /** The number of times the guest has switched mode since last reset or statistics reset. */
    2694     STAMCOUNTER                     cGuestModeChanges;
    2695     /** @} */
    2696 
    2697 #ifdef VBOX_WITH_STATISTICS /** @todo move this chunk to the heap.  */
    2698     /** @name Statistics
    2699      * @{ */
    2700     /** RC: Which statistic this \#PF should be attributed to. */
    2701     RCPTRTYPE(PSTAMPROFILE)         pStatTrap0eAttributionRC;
    2702     RTRCPTR                         padding0;
    2703     /** R0: Which statistic this \#PF should be attributed to. */
    2704     R0PTRTYPE(PSTAMPROFILE)         pStatTrap0eAttributionR0;
    2705     RTR0PTR                         padding1;
    2706 
    2707     /* Common */
    2708     STAMCOUNTER StatSyncPtPD[X86_PG_ENTRIES];       /**< SyncPT - PD distribution. */
    2709     STAMCOUNTER StatSyncPagePD[X86_PG_ENTRIES];     /**< SyncPage - PD distribution. */
    27102710
    27112711    /* RZ only: */
     
    32193219DECLINLINE(int) pgmR0DynMapHCPageInlined(PPGM pPGM, RTHCPHYS HCPhys, void **ppv)
    32203220{
    3221     PVM         pVM  = PGM2VM(pPGM);
    3222     PPGMMAPSET  pSet = &pPGM->AutoSet;
    3223 
    3224     STAM_PROFILE_START(&pPGM->StatR0DynMapHCPageInl, a);
     3221    PVM         pVM     = PGM2VM(pPGM);
     3222    PPGMCPU     pPGMCPU = (PPGMCPU)((uint8_t *)VMMGetCpu(pVM) + pPGM->offVCpuPGM); /* very pretty ;-) */
     3223    PPGMMAPSET  pSet    = &pPGMCPU->AutoSet;
     3224
     3225    STAM_PROFILE_START(&pPGMCPU->StatR0DynMapHCPageInl, a);
    32253226    Assert(!(HCPhys & PAGE_OFFSET_MASK));
    32263227    Assert(pSet->cEntries <= RT_ELEMENTS(pSet->aEntries));
     
    32323233    {
    32333234        *ppv = pSet->aEntries[iEntry].pvPage;
    3234         STAM_COUNTER_INC(&pPGM->StatR0DynMapHCPageInlHits);
     3235        STAM_COUNTER_INC(&pPGMCPU->StatR0DynMapHCPageInlHits);
    32353236    }
    32363237    else
    32373238    {
    3238         STAM_COUNTER_INC(&pPGM->StatR0DynMapHCPageInlMisses);
     3239        STAM_COUNTER_INC(&pPGMCPU->StatR0DynMapHCPageInlMisses);
    32393240        pgmR0DynMapHCPageCommon(pVM, pSet, HCPhys, ppv);
    32403241    }
    32413242
    3242     STAM_PROFILE_STOP(&pPGM->StatR0DynMapHCPageInl, a);
     3243    STAM_PROFILE_STOP(&pPGMCPU->StatR0DynMapHCPageInl, a);
    32433244    return VINF_SUCCESS;
    32443245}
     
    32563257DECLINLINE(int) pgmR0DynMapGCPageInlined(PPGM pPGM, RTGCPHYS GCPhys, void **ppv)
    32573258{
    3258     PVM         pVM  = PGM2VM(pPGM);
    3259     PPGMMAPSET  pSet = &pPGM->AutoSet;
    3260 
    3261     STAM_PROFILE_START(&pPGM->StatR0DynMapGCPageInl, a);
     3259    PVM     pVM     = PGM2VM(pPGM);
     3260    PPGMCPU pPGMCPU = (PPGMCPU)((uint8_t *)VMMGetCpu(pVM) + pPGM->offVCpuPGM); /* very pretty ;-) */
     3261
     3262    STAM_PROFILE_START(&pPGMCPU->StatR0DynMapGCPageInl, a);
    32623263    Assert(!(GCPhys & PAGE_OFFSET_MASK));
    32633264
     
    32713272    {
    32723273        /* This case is not counted into StatR0DynMapGCPageInl. */
    3273         STAM_COUNTER_INC(&pPGM->StatR0DynMapGCPageInlRamMisses);
     3274        STAM_COUNTER_INC(&pPGMCPU->StatR0DynMapGCPageInlRamMisses);
    32743275        return PGMDynMapGCPage(pVM, GCPhys, ppv);
    32753276    }
    32763277
    32773278    RTHCPHYS HCPhys = PGM_PAGE_GET_HCPHYS(&pRam->aPages[off >> PAGE_SHIFT]);
    3278     STAM_COUNTER_INC(&pPGM->StatR0DynMapGCPageInlRamHits);
     3279    STAM_COUNTER_INC(&pPGMCPU->StatR0DynMapGCPageInlRamHits);
    32793280
    32803281    /*
    32813282     * pgmR0DynMapHCPageInlined with out stats.
    32823283     */
     3284    PPGMMAPSET pSet = &pPGMCPU->AutoSet;
    32833285    Assert(!(HCPhys & PAGE_OFFSET_MASK));
    32843286    Assert(pSet->cEntries <= RT_ELEMENTS(pSet->aEntries));
     
    32903292    {
    32913293        *ppv = pSet->aEntries[iEntry].pvPage;
    3292         STAM_COUNTER_INC(&pPGM->StatR0DynMapGCPageInlHits);
     3294        STAM_COUNTER_INC(&pPGMCPU->StatR0DynMapGCPageInlHits);
    32933295    }
    32943296    else
    32953297    {
    3296         STAM_COUNTER_INC(&pPGM->StatR0DynMapGCPageInlMisses);
     3298        STAM_COUNTER_INC(&pPGMCPU->StatR0DynMapGCPageInlMisses);
    32973299        pgmR0DynMapHCPageCommon(pVM, pSet, HCPhys, ppv);
    32983300    }
    32993301
    3300     STAM_PROFILE_STOP(&pPGM->StatR0DynMapGCPageInl, a);
     3302    STAM_PROFILE_STOP(&pPGMCPU->StatR0DynMapGCPageInl, a);
    33013303    return VINF_SUCCESS;
    33023304}
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r18982 r18984  
    978978    {
    979979#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    980         uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVM);
     980        uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu);
    981981        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, (RTGCPTR)pu32, NULL);
    982         PGMDynMapPopAutoSubset(pVM, iPrevSubset);
     982        PGMDynMapPopAutoSubset(pVCpu, iPrevSubset);
    983983#else
    984984        pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, (RTGCPTR)pu32, NULL);
     
    10341034     */
    10351035#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    1036     uint32_t    iPrevSubset = PGMDynMapPushAutoSubset(pVM);
     1036    uint32_t    iPrevSubset = PGMDynMapPushAutoSubset(pVCpu);
    10371037    pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, pvFault, pCpu);
    1038     PGMDynMapPopAutoSubset(pVM, iPrevSubset);
     1038    PGMDynMapPopAutoSubset(pVCpu, iPrevSubset);
    10391039#else
    10401040    pgmPoolMonitorChainChanging(pVCpu, pPool, pPage, GCPhysFault, pvFault, pCpu);
     
    26682668               pgmPoolTrackFlushGCPhysPTs will/may kill the pool otherwise. */
    26692669            PVMCPU pVCpu = VMMGetCpu(pVM);
    2670             uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVM);
     2670            uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu);
    26712671# endif
    26722672
     
    26832683
    26842684# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    2685             PGMDynMapPopAutoSubset(pVM, iPrevSubset);
     2685            PGMDynMapPopAutoSubset(pVCpu, iPrevSubset);
    26862686# endif
    26872687        }
     
    26962696        /* Start a subset here because pgmPoolTrackFlushGCPhysPTsSlow kill the pool otherwise. */
    26972697        PVMCPU pVCpu = VMMGetCpu(pVM);
    2698         uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVM);
     2698        uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu);
    26992699# endif
    27002700        rc = pgmPoolTrackFlushGCPhysPTsSlow(pVM, pPhysPage);
     
    27042704
    27052705# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    2706     PGMDynMapPopAutoSubset(pVM, iPrevSubset);
     2706    PGMDynMapPopAutoSubset(pVCpu, iPrevSubset);
    27072707# endif
    27082708
     
    40014001int pgmPoolFlushPage(PPGMPOOL pPool, PPGMPOOLPAGE pPage)
    40024002{
    4003     int rc  = VINF_SUCCESS;
    4004     PVM pVM = pPool->CTX_SUFF(pVM);
    4005 
     4003    int rc = VINF_SUCCESS;
    40064004    STAM_PROFILE_START(&pPool->StatFlushPage, f);
    40074005    LogFlow(("pgmPoolFlushPage: pPage=%p:{.Key=%RHp, .idx=%d, .enmKind=%s, .GCPhys=%RGp}\n",
     
    40214019     * Quietly reject any attempts at flushing the currently active shadow CR3 mapping
    40224020     */
    4023     if (pgmPoolIsPageLocked(&pVM->pgm.s, pPage))
     4021    if (pgmPoolIsPageLocked(&pPool->CTX_SUFF(pVM)->pgm.s, pPage))
    40244022    {
    40254023        AssertMsg(   pPage->enmKind == PGMPOOLKIND_64BIT_PML4
     
    40324030                  || pPage->enmKind == PGMPOOLKIND_PAE_PD2_FOR_32BIT_PD
    40334031                  || pPage->enmKind == PGMPOOLKIND_PAE_PD3_FOR_32BIT_PD,
    4034                   ("Can't free the shadow CR3! (%RHp vs %RHp kind=%d\n", PGMGetHyperCR3(VMMGetCpu(pVM)), pPage->Core.Key, pPage->enmKind));
     4032                  ("Can't free the shadow CR3! (%RHp vs %RHp kind=%d\n", PGMGetHyperCR3(VMMGetCpu(pPool->CTX_SUFF(pVM))), pPage->Core.Key, pPage->enmKind));
    40354033        Log(("pgmPoolFlushPage: current active shadow CR3, rejected. enmKind=%s idx=%d\n", pgmPoolPoolKindToStr(pPage->enmKind), pPage->idx));
    40364034        return VINF_SUCCESS;
     
    40394037#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    40404038    /* Start a subset so we won't run out of mapping space. */
    4041     uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVM);
     4039    PVMCPU pVCpu = VMMGetCpu(pPool->CTX_SUFF(pVM));
     4040    uint32_t iPrevSubset = PGMDynMapPushAutoSubset(pVCpu);
    40424041#endif
    40434042
     
    40664065#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    40674066    /* Heavy stuff done. */
    4068     PGMDynMapPopAutoSubset(pVM, iPrevSubset);
     4067    PGMDynMapPopAutoSubset(pVCpu, iPrevSubset);
    40694068#endif
    40704069
  • trunk/src/VBox/VMM/VMMR0/HWACCMR0.cpp

    r18977 r18984  
    986986
    987987#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
    988         PGMDynMapMigrateAutoSet(pVM);
     988        PGMDynMapMigrateAutoSet(pVCpu);
    989989#endif
    990990    }
     
    10641064
    10651065#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
    1066     PGMDynMapStartAutoSet(pVM);
     1066    PGMDynMapStartAutoSet(pVCpu);
    10671067#endif
    10681068
     
    10721072
    10731073#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
    1074     PGMDynMapReleaseAutoSet(pVM);
     1074    PGMDynMapReleaseAutoSet(pVCpu);
    10751075#endif
    10761076    return rc;
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r18976 r18984  
    21362136#endif
    21372137#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    2138     PGMDynMapFlushAutoSet(pVM);
     2138    PGMDynMapFlushAutoSet(pVCpu);
    21392139#endif
    21402140
  • trunk/src/VBox/VMM/VMMR0/PGMR0DynMap.cpp

    r18983 r18984  
    355355     * Initialize the auto sets.
    356356     */
    357     PPGMMAPSET pSet = &pVM->pgm.s.AutoSet;
    358     uint32_t j = RT_ELEMENTS(pSet->aEntries);
    359     while (j-- > 0)
    360     {
    361         pSet->aEntries[j].iPage  = UINT16_MAX;
    362         pSet->aEntries[j].cRefs  = 0;
    363         pSet->aEntries[j].pvPage = NULL;
    364         pSet->aEntries[j].HCPhys = NIL_RTHCPHYS;
    365     }
    366     pSet->cEntries = PGMMAPSET_CLOSED;
    367     pSet->iSubset = UINT32_MAX;
    368     pSet->iCpu = -1;
    369     memset(&pSet->aiHashTable[0], 0xff, sizeof(pSet->aiHashTable));
     357    VMCPUID idCpu = pVM->cCPUs;
     358    AssertReturn(idCpu > 0 && idCpu <= VMCPU_MAX_CPU_COUNT, VERR_INTERNAL_ERROR);
     359    while (idCpu-- > 0)
     360    {
     361        PPGMMAPSET pSet = &pVM->aCpus[idCpu].pgm.s.AutoSet;
     362        uint32_t j = RT_ELEMENTS(pSet->aEntries);
     363        while (j-- > 0)
     364        {
     365            pSet->aEntries[j].iPage  = UINT16_MAX;
     366            pSet->aEntries[j].cRefs  = 0;
     367            pSet->aEntries[j].pvPage = NULL;
     368            pSet->aEntries[j].HCPhys = NIL_RTHCPHYS;
     369        }
     370        pSet->cEntries = PGMMAPSET_CLOSED;
     371        pSet->iSubset = UINT32_MAX;
     372        pSet->iCpu = -1;
     373        memset(&pSet->aiHashTable[0], 0xff, sizeof(pSet->aiHashTable));
     374    }
    370375
    371376    /*
     
    438443         * Clean up and check the auto sets.
    439444         */
    440         PPGMMAPSET pSet = &pVM->pgm.s.AutoSet;
    441         uint32_t j = pSet->cEntries;
    442         if (j <= RT_ELEMENTS(pSet->aEntries))
    443         {
    444             /*
    445                 * The set is open, close it.
    446                 */
     445        VMCPUID idCpu = pVM->cCPUs;
     446        while (idCpu-- > 0)
     447        {
     448            PPGMMAPSET pSet = &pVM->aCpus[idCpu].pgm.s.AutoSet;
     449            uint32_t j = pSet->cEntries;
     450            if (j <= RT_ELEMENTS(pSet->aEntries))
     451            {
     452                /*
     453                 * The set is open, close it.
     454                 */
     455                while (j-- > 0)
     456                {
     457                    int32_t  cRefs = pSet->aEntries[j].cRefs;
     458                    uint32_t iPage = pSet->aEntries[j].iPage;
     459                    LogRel(("PGMR0DynMapTermVM: %d dangling refs to %#x\n", cRefs, iPage));
     460                    if (iPage < pThis->cPages && cRefs > 0)
     461                        pgmR0DynMapReleasePage(pThis, iPage, cRefs);
     462                    else
     463                        AssertLogRelMsgFailed(("cRefs=%d iPage=%#x cPages=%u\n", cRefs, iPage, pThis->cPages));
     464
     465                    pSet->aEntries[j].iPage  = UINT16_MAX;
     466                    pSet->aEntries[j].cRefs  = 0;
     467                    pSet->aEntries[j].pvPage = NULL;
     468                    pSet->aEntries[j].HCPhys = NIL_RTHCPHYS;
     469                }
     470                pSet->cEntries = PGMMAPSET_CLOSED;
     471                pSet->iSubset = UINT32_MAX;
     472                pSet->iCpu = -1;
     473            }
     474            else
     475                AssertMsg(j == PGMMAPSET_CLOSED, ("cEntries=%#x\n", j));
     476
     477            j = RT_ELEMENTS(pSet->aEntries);
    447478            while (j-- > 0)
    448479            {
    449                 int32_t  cRefs = pSet->aEntries[j].cRefs;
    450                 uint32_t iPage = pSet->aEntries[j].iPage;
    451                 LogRel(("PGMR0DynMapTermVM: %d dangling refs to %#x\n", cRefs, iPage));
    452                 if (iPage < pThis->cPages && cRefs > 0)
    453                     pgmR0DynMapReleasePage(pThis, iPage, cRefs);
    454                 else
    455                     AssertLogRelMsgFailed(("cRefs=%d iPage=%#x cPages=%u\n", cRefs, iPage, pThis->cPages));
    456 
    457                 pSet->aEntries[j].iPage  = UINT16_MAX;
    458                 pSet->aEntries[j].cRefs  = 0;
    459                 pSet->aEntries[j].pvPage = NULL;
    460                 pSet->aEntries[j].HCPhys = NIL_RTHCPHYS;
    461             }
    462             pSet->cEntries = PGMMAPSET_CLOSED;
    463             pSet->iSubset = UINT32_MAX;
    464             pSet->iCpu = -1;
    465         }
    466         else
    467             AssertMsg(j == PGMMAPSET_CLOSED, ("cEntries=%#x\n", j));
    468 
    469         j = RT_ELEMENTS(pSet->aEntries);
    470         while (j-- > 0)
    471         {
    472             Assert(pSet->aEntries[j].iPage == UINT16_MAX);
    473             Assert(!pSet->aEntries[j].cRefs);
     480                Assert(pSet->aEntries[j].iPage == UINT16_MAX);
     481                Assert(!pSet->aEntries[j].cRefs);
     482            }
    474483        }
    475484
     
    11761185static uint32_t pgmR0DynMapPageSlow(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, uint32_t iPage, PVM pVM)
    11771186{
    1178     STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageSlow);
     1187#ifdef VBOX_WITH_STATISTICS
     1188    PVMCPU pVCpu = VMMGetCpu(pVM);
     1189#endif
     1190    STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageSlow);
    11791191
    11801192    /*
     
    12041216            if (paPages[iFreePage].HCPhys == HCPhys)
    12051217            {
    1206                 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageSlowLoopHits);
     1218                STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageSlowLoopHits);
    12071219                return iFreePage;
    12081220            }
     
    12151227                return UINT32_MAX;
    12161228        }
    1217         STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageSlowLoopMisses);
     1229        STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageSlowLoopMisses);
    12181230#ifdef VBOX_WITH_STATISTICS
    12191231        fLooped = true;
     
    12271239        for (uint32_t iPage2 = (iPage + 3) % cPages; iPage2 != iPage; iPage2 = (iPage2 + 1) % cPages)
    12281240            if (paPages[iPage2].HCPhys == HCPhys)
    1229                 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageSlowLostHits);
     1241                STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageSlowLostHits);
    12301242#endif
    12311243
     
    12751287DECLINLINE(uint32_t) pgmR0DynMapPage(PPGMR0DYNMAP pThis, RTHCPHYS HCPhys, int32_t iRealCpu, PVM pVM, void **ppvPage)
    12761288{
     1289#ifdef VBOX_WITH_STATISTICS
     1290    PVMCPU pVCpu = VMMGetCpu(pVM);
     1291#endif
    12771292    RTSPINLOCKTMP   Tmp       = RTSPINLOCKTMP_INITIALIZER;
    12781293    RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
    12791294    AssertMsg(!(HCPhys & PAGE_OFFSET_MASK), ("HCPhys=%RHp\n", HCPhys));
    1280     STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPage);
     1295    STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPage);
    12811296
    12821297    /*
     
    12921307    PPGMR0DYNMAPENTRY   paPages = pThis->paPages;
    12931308    if (RT_LIKELY(paPages[iPage].HCPhys == HCPhys))
    1294         STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageHits0);
     1309        STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageHits0);
    12951310    else
    12961311    {
     
    12991314        {
    13001315            iPage = iPage2;
    1301             STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageHits1);
     1316            STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageHits1);
    13021317        }
    13031318        else
     
    13071322            {
    13081323                iPage = iPage2;
    1309                 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageHits2);
     1324                STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageHits2);
    13101325            }
    13111326            else
     
    13561371    if (RT_UNLIKELY(fInvalidateIt))
    13571372    {
    1358         STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageInvlPg);
     1373        STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapPageInvlPg);
    13591374        ASMInvalidatePage(pvPage);
    13601375    }
     
    14901505 * API is called.
    14911506 *
    1492  * @param   pVM         Pointer to the shared VM structure.
    1493  */
    1494 VMMDECL(void) PGMDynMapStartAutoSet(PVM pVM)
    1495 {
    1496     Assert(pVM->pgm.s.AutoSet.cEntries == PGMMAPSET_CLOSED);
    1497     Assert(pVM->pgm.s.AutoSet.iSubset == UINT32_MAX);
    1498     pVM->pgm.s.AutoSet.cEntries = 0;
    1499     pVM->pgm.s.AutoSet.iCpu = RTMpCpuIdToSetIndex(RTMpCpuId());
     1507 * @param   pVCpu       The shared data for the current virtual CPU.
     1508 */
     1509VMMDECL(void) PGMDynMapStartAutoSet(PVMCPU pVCpu)
     1510{
     1511    Assert(pVCpu->pgm.s.AutoSet.cEntries == PGMMAPSET_CLOSED);
     1512    Assert(pVCpu->pgm.s.AutoSet.iSubset == UINT32_MAX);
     1513    pVCpu->pgm.s.AutoSet.cEntries = 0;
     1514    pVCpu->pgm.s.AutoSet.iCpu = RTMpCpuIdToSetIndex(RTMpCpuId());
    15001515}
    15011516
     
    15421557 * since the PGMDynMapStartAutoSet call.
    15431558 *
    1544  * @param   pVM         Pointer to the shared VM structure.
    1545  */
    1546 VMMDECL(void) PGMDynMapReleaseAutoSet(PVM pVM)
    1547 {
    1548     PPGMMAPSET  pSet = &pVM->pgm.s.AutoSet;
     1559 * @param   pVCpu       The shared data for the current virtual CPU.
     1560 */
     1561VMMDECL(void) PGMDynMapReleaseAutoSet(PVMCPU pVCpu)
     1562{
     1563    PPGMMAPSET  pSet = &pVCpu->pgm.s.AutoSet;
    15491564
    15501565    /*
     
    15571572    pSet->iCpu = -1;
    15581573
    1559     STAM_COUNTER_INC(&pVM->pgm.s.aStatR0DynMapSetSize[(cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]);
     1574    STAM_COUNTER_INC(&pVCpu->pgm.s.aStatR0DynMapSetSize[(cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]);
    15601575    AssertMsg(cEntries < PGMMAPSET_MAX_FILL, ("%u\n", cEntries));
    15611576    if (cEntries > RT_ELEMENTS(pSet->aEntries) * 50 / 100)
     
    15691584 * Flushes the set if it's above a certain threshold.
    15701585 *
    1571  * @param   pVM         Pointer to the shared VM structure.
    1572  */
    1573 VMMDECL(void) PGMDynMapFlushAutoSet(PVM pVM)
    1574 {
    1575     PPGMMAPSET  pSet = &pVM->pgm.s.AutoSet;
     1586 * @param   pVCpu       The shared data for the current virtual CPU.
     1587 */
     1588VMMDECL(void) PGMDynMapFlushAutoSet(PVMCPU pVCpu)
     1589{
     1590    PPGMMAPSET  pSet = &pVCpu->pgm.s.AutoSet;
    15761591    AssertMsg(pSet->iCpu == RTMpCpuIdToSetIndex(RTMpCpuId()), ("%d %d(%d) efl=%#x\n", pSet->iCpu, RTMpCpuIdToSetIndex(RTMpCpuId()), RTMpCpuId(), ASMGetFlags()));
    15771592
     
    15811596    uint32_t cEntries = pSet->cEntries;
    15821597    AssertReturnVoid(cEntries != PGMMAPSET_CLOSED);
    1583     STAM_COUNTER_INC(&pVM->pgm.s.aStatR0DynMapSetSize[(cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]);
     1598    STAM_COUNTER_INC(&pVCpu->pgm.s.aStatR0DynMapSetSize[(cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]);
    15841599    if (cEntries >= RT_ELEMENTS(pSet->aEntries) * 45 / 100)
    15851600    {
     
    16051620 * the entries will have been flagged as invalidated.
    16061621 *
    1607  * @param   pVM         Pointer to the shared VM structure.
     1622 * @param   pVCpu       The shared data for the current virtual CPU.
    16081623 * @thread  EMT
    16091624 */
    1610 VMMDECL(void) PGMDynMapMigrateAutoSet(PVM pVM)
    1611 {
    1612     PPGMMAPSET      pSet     = &pVM->pgm.s.AutoSet;
     1625VMMDECL(void) PGMDynMapMigrateAutoSet(PVMCPU pVCpu)
     1626{
     1627    PPGMMAPSET      pSet     = &pVCpu->pgm.s.AutoSet;
    16131628    int32_t         iRealCpu = RTMpCpuIdToSetIndex(RTMpCpuId());
    16141629    if (pSet->iCpu != iRealCpu)
     
    16351650
    16361651                        ASMInvalidatePage(pThis->paPages[iPage].pvPage);
    1637                         STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapMigrateInvlPg);
     1652                        STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapMigrateInvlPg);
    16381653
    16391654                        RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
     
    17031718 * @returns The index of the previous subset. Pass this to
    17041719 *        PGMDynMapPopAutoSubset when poping it.
    1705  * @param   pVM             Pointer to the shared VM structure.
    1706  */
    1707 VMMDECL(uint32_t) PGMDynMapPushAutoSubset(PVM pVM)
    1708 {
    1709     PPGMMAPSET      pSet = &pVM->pgm.s.AutoSet;
     1720 * @param   pVCpu           Pointer to the virtual cpu data.
     1721 */
     1722VMMDECL(uint32_t) PGMDynMapPushAutoSubset(PVMCPU pVCpu)
     1723{
     1724    PPGMMAPSET      pSet = &pVCpu->pgm.s.AutoSet;
    17101725    AssertReturn(pSet->cEntries != PGMMAPSET_CLOSED, UINT32_MAX);
    17111726    uint32_t        iPrevSubset = pSet->iSubset;
    17121727Assert(iPrevSubset == UINT32_MAX);
    17131728    pSet->iSubset = pSet->cEntries;
    1714     STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapSubsets);
     1729    STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapSubsets);
    17151730    return iPrevSubset;
    17161731}
     
    17201735 * Pops a subset created by a previous call to PGMDynMapPushAutoSubset.
    17211736 *
    1722  * @param   pVM             Pointer to the shared VM structure.
     1737 * @param   pVCpu           Pointer to the virtual cpu data.
    17231738 * @param   iPrevSubset     What PGMDynMapPushAutoSubset returned.
    17241739 */
    1725 VMMDECL(void) PGMDynMapPopAutoSubset(PVM pVM, uint32_t iPrevSubset)
    1726 {
    1727     PPGMMAPSET      pSet = &pVM->pgm.s.AutoSet;
     1740VMMDECL(void) PGMDynMapPopAutoSubset(PVMCPU pVCpu, uint32_t iPrevSubset)
     1741{
     1742    PPGMMAPSET      pSet = &pVCpu->pgm.s.AutoSet;
    17281743    uint32_t        cEntries = pSet->cEntries;
    17291744    AssertReturnVoid(cEntries != PGMMAPSET_CLOSED);
    17301745    AssertReturnVoid(pSet->iSubset <= iPrevSubset || iPrevSubset == UINT32_MAX);
    1731     Assert(iPrevSubset == UINT32_MAX);
    1732     STAM_COUNTER_INC(&pVM->pgm.s.aStatR0DynMapSetSize[(cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]);
     1746Assert(iPrevSubset == UINT32_MAX);
     1747    STAM_COUNTER_INC(&pVCpu->pgm.s.aStatR0DynMapSetSize[(cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]);
    17331748    if (    cEntries >= RT_ELEMENTS(pSet->aEntries) * 40 / 100
    17341749        &&  cEntries != pSet->iSubset)
     
    18011816int pgmR0DynMapHCPageCommon(PVM pVM, PPGMMAPSET pSet, RTHCPHYS HCPhys, void **ppv)
    18021817{
     1818#ifdef VBOX_WITH_STATISTICS
     1819    PVMCPU pVCpu = VMMGetCpu(pVM);
     1820#endif
    18031821    AssertMsg(pSet->iCpu == RTMpCpuIdToSetIndex(RTMpCpuId()), ("%d %d(%d) efl=%#x\n", pSet->iCpu, RTMpCpuIdToSetIndex(RTMpCpuId()), RTMpCpuId(), ASMGetFlags()));
    18041822
     
    18731891            {
    18741892                pSet->aEntries[i].cRefs++;
    1875                 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapSetSearchHits);
     1893                STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapSetSearchHits);
    18761894                break;
    18771895            }
    18781896        if (i < 0)
    18791897        {
    1880             STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapSetSearchMisses);
     1898            STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapSetSearchMisses);
    18811899            if (pSet->iSubset < pSet->cEntries)
    18821900            {
    1883                 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapSetSearchFlushes);
    1884                 STAM_COUNTER_INC(&pVM->pgm.s.aStatR0DynMapSetSize[(pSet->cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]);
     1901                STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapSetSearchFlushes);
     1902                STAM_COUNTER_INC(&pVCpu->pgm.s.aStatR0DynMapSetSize[(pSet->cEntries * 10 / RT_ELEMENTS(pSet->aEntries)) % 11]);
    18851903                AssertMsg(pSet->cEntries < PGMMAPSET_MAX_FILL, ("%u\n", pSet->cEntries));
    18861904                pgmDynMapFlushSubset(pSet);
     
    18891907            if (RT_UNLIKELY(pSet->cEntries >= RT_ELEMENTS(pSet->aEntries)))
    18901908            {
    1891                 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapSetOptimize);
     1909                STAM_COUNTER_INC(&pVCpu->pgm.s.StatR0DynMapSetOptimize);
    18921910                pgmDynMapOptimizeAutoSet(pSet);
    18931911            }
     
    19251943VMMDECL(int) PGMDynMapHCPage(PVM pVM, RTHCPHYS HCPhys, void **ppv)
    19261944{
     1945#ifdef VBOX_WITH_STATISTICS
     1946    PVMCPU pVCpu = VMMGetCpu(pVM);
     1947#endif
    19271948    /*
    19281949     * Validate state.
    19291950     */
    1930     STAM_PROFILE_START(&pVM->pgm.s.StatR0DynMapHCPage, a);
     1951    STAM_PROFILE_START(&pVCpu->pgm.s.StatR0DynMapHCPage, a);
    19311952    AssertPtr(ppv);
    19321953    AssertMsg(pVM->pgm.s.pvR0DynMapUsed == g_pPGMR0DynMap,
    19331954              ("%p != %p\n", pVM->pgm.s.pvR0DynMapUsed, g_pPGMR0DynMap));
    19341955    AssertMsg(!(HCPhys & PAGE_OFFSET_MASK), ("HCPhys=%RHp\n", HCPhys));
    1935     PPGMMAPSET      pSet    = &pVM->pgm.s.AutoSet;
     1956    PVMCPU          pVCpu   = VMMGetCpu(pVM);
     1957    AssertPtr(pVCpu);
     1958    PPGMMAPSET      pSet    = &pVCpu->pgm.s.AutoSet;
    19361959    AssertMsg(pSet->cEntries <= RT_ELEMENTS(pSet->aEntries),
    19371960              ("%#x (%u)\n", pSet->cEntries, pSet->cEntries));
     
    19421965    int rc = pgmR0DynMapHCPageCommon(pVM, pSet, HCPhys, ppv);
    19431966
    1944     STAM_PROFILE_STOP(&pVM->pgm.s.StatR0DynMapHCPage, a);
     1967    STAM_PROFILE_STOP(&pVCpu->pgm.s.StatR0DynMapHCPage, a);
    19451968    return rc;
    19461969}
     
    19832006    LogRel(("pgmR0DynMapTest: ****** START ******\n"));
    19842007    PPGMR0DYNMAP    pThis = g_pPGMR0DynMap;
    1985     PPGMMAPSET      pSet  = &pVM->pgm.s.AutoSet;
     2008    PPGMMAPSET      pSet  = &pVM->aCpus[0].pgm.s.AutoSet;
    19862009    uint32_t        i;
    19872010
     
    20042027    LogRel(("Test #1\n"));
    20052028    ASMIntDisable();
    2006     PGMDynMapStartAutoSet(pVM);
     2029    PGMDynMapStartAutoSet(&pVM->aCpus[0]);
    20072030
    20082031    uint64_t cr3 = ASMGetCR3() & ~(uint64_t)PAGE_OFFSET_MASK;
     
    20252048        LogRel(("Test #2\n"));
    20262049        ASMIntDisable();
    2027         PGMDynMapMigrateAutoSet(pVM);
     2050        PGMDynMapMigrateAutoSet(&pVM->aCpus[0]);
    20282051        for (i = 0 ; i < UINT16_MAX*2 - 1 && RT_SUCCESS(rc) && pv2 == pv; i++)
    20292052        {
     
    20632086            LogRel(("Test #3\n"));
    20642087            ASMIntDisable();
    2065             PGMDynMapMigrateAutoSet(pVM);
     2088            PGMDynMapMigrateAutoSet(&pVM->aCpus[0]);
    20662089            pv2 = NULL;
    20672090            for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) - 5 && RT_SUCCESS(rc) && pv2 != pv; i++)
     
    20912114                LogRel(("Test #4\n"));
    20922115                ASMIntDisable();
    2093                 PGMDynMapMigrateAutoSet(pVM);
     2116                PGMDynMapMigrateAutoSet(&pVM->aCpus[0]);
    20942117                for (i = 0 ; i < RT_ELEMENTS(pSet->aEntries) + 2; i++)
    20952118                {
     
    21062129                    LogRel(("Test #5\n"));
    21072130                    ASMIntDisable();
    2108                     PGMDynMapMigrateAutoSet(pVM);
    2109                     PGMDynMapReleaseAutoSet(pVM);
    2110                     PGMDynMapStartAutoSet(pVM);
     2131                    PGMDynMapMigrateAutoSet(&pVM->aCpus[0]);
     2132                    PGMDynMapReleaseAutoSet(&pVM->aCpus[0]);
     2133                    PGMDynMapStartAutoSet(&pVM->aCpus[0]);
    21112134                    ASMIntEnable();
    21122135
     
    21362159        LogRel(("Test #5\n"));
    21372160        ASMIntDisable();
    2138         PGMDynMapMigrateAutoSet(pVM);
     2161        PGMDynMapMigrateAutoSet(&pVM->aCpus[0]);
    21392162        RTHCPHYS  HCPhysPT = RTR0MemObjGetPagePhysAddr(pThis->pSegHead->ahMemObjPTs[0], 0);
    21402163        rc  = PGMDynMapHCPage(pVM, HCPhysPT, &pv);
     
    21732196    LogRel(("Cleanup.\n"));
    21742197    ASMIntDisable();
    2175     PGMDynMapMigrateAutoSet(pVM);
    2176     PGMDynMapFlushAutoSet(pVM);
    2177     PGMDynMapReleaseAutoSet(pVM);
     2198    PGMDynMapMigrateAutoSet(&pVM->aCpus[0]);
     2199    PGMDynMapFlushAutoSet(&pVM->aCpus[0]);
     2200    PGMDynMapReleaseAutoSet(&pVM->aCpus[0]);
    21782201    ASMIntEnable();
    21792202
  • trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp

    r18974 r18984  
    411411    GEN_CHECK_OFF(PGMCPU, offVCpu);
    412412    GEN_CHECK_OFF(PGMCPU, offPGM);
    413 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    414     GEN_CHECK_OFF(PGM, AutoSet);
     413#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE
     414    GEN_CHECK_OFF(PGMCPU, AutoSet);
    415415#endif
    416416    GEN_CHECK_OFF(PGMCPU, GCPhysA20Mask);
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette