VirtualBox

Changeset 15344 in vbox


Ignore:
Timestamp:
Dec 12, 2008 12:13:56 AM (16 years ago)
Author:
vboxsync
Message:

#3202: Optimizations of the dynamic page mapping code (ring-0). Do lots of the stuff inline, using the set as a 2st level cache and not releasing it for each inner VT-x iteration.

Location:
trunk
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/pgm.h

    r15284 r15344  
    448448VMMDECL(void)       PGMDynMapStartAutoSet(PVMCPU pVCpu);
    449449VMMDECL(void)       PGMDynMapReleaseAutoSet(PVMCPU pVCpu);
     450VMMDECL(void)       PGMDynMapFlushAutoSet(PVMCPU pVCpu);
    450451VMMDECL(void)       PGMDynMapMigrateAutoSet(PVMCPU pVCpu);
    451452
  • trunk/include/VBox/vm.h

    r15236 r15344  
    130130        struct PGMCPU       s;
    131131#endif
    132         char                padding[192];        /* multiple of 64 */
     132        char                padding[1024];       /* multiple of 64 */
    133133    } pgm;
    134134
  • trunk/src/VBox/VMM/PGM.cpp

    r15196 r15344  
    11361136     */
    11371137    pVM->pgm.s.offVM = RT_OFFSETOF(VM, pgm.s);
     1138    pVM->pgm.s.offVCpu = RT_OFFSETOF(VMCPU, pgm.s);
    11381139    pVM->pgm.s.enmShadowMode    = PGMMODE_INVALID;
    11391140    pVM->pgm.s.enmGuestMode     = PGMMODE_INVALID;
     
    15971598
    15981599    /* R0 only: */
    1599     STAM_REG(pVM, &pPGM->StatR0DynMapHCPage,                STAMTYPE_PROFILE, "/PGM/R0/DynMapPage/HCPage",          STAMUNIT_OCCURENCES,     "Calls to PGMDynMapHCPage (ring-0).");
    1600     STAM_REG(pVM, &pPGM->StatR0DynMapHCPageSetOptimize,     STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/HCPageSetOptimize", STAMUNIT_OCCURENCES,   "Calls to pgmDynMapOptimizeAutoSet.");
    1601     STAM_REG(pVM, &pPGM->StatR0DynMapHCPageSetSearchHits,   STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/HCPageSetSearchHits", STAMUNIT_OCCURENCES, "Set search hits.");
    1602     STAM_REG(pVM, &pPGM->StatR0DynMapHCPageSetSearchMisses, STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/HCPageSetSearchMisses", STAMUNIT_OCCURENCES, "Set search misses.");
    16031600    STAM_REG(pVM, &pPGM->StatR0DynMapMigrateInvlPg,         STAMTYPE_COUNTER, "/PGM/R0/DynMapMigrateInvlPg",        STAMUNIT_OCCURENCES,     "invlpg count in PGMDynMapMigrateAutoSet.");
     1601    STAM_REG(pVM, &pPGM->StatR0DynMapGCPageInl,             STAMTYPE_PROFILE, "/PGM/R0/DynMapPageGCPageInl",        STAMUNIT_TICKS_PER_CALL, "Calls to pgmR0DynMapGCPageInlined.");
     1602    STAM_REG(pVM, &pPGM->StatR0DynMapGCPageInlHits,         STAMTYPE_COUNTER, "/PGM/R0/DynMapPageGCPageInl/Hits",   STAMUNIT_OCCURENCES,     "Hash table lookup hits.");
     1603    STAM_REG(pVM, &pPGM->StatR0DynMapGCPageInlMisses,       STAMTYPE_COUNTER, "/PGM/R0/DynMapPageGCPageInl/Misses", STAMUNIT_OCCURENCES,     "Misses that falls back to code common with PGMDynMapHCPage.");
     1604    STAM_REG(pVM, &pPGM->StatR0DynMapGCPageInlRamHits,      STAMTYPE_COUNTER, "/PGM/R0/DynMapPageGCPageInl/RamHits",   STAMUNIT_OCCURENCES,  "1st ram range hits.");
     1605    STAM_REG(pVM, &pPGM->StatR0DynMapGCPageInlRamMisses,    STAMTYPE_COUNTER, "/PGM/R0/DynMapPageGCPageInl/RamMisses", STAMUNIT_OCCURENCES,  "1st ram range misses, takes slow path.");
     1606    STAM_REG(pVM, &pPGM->StatR0DynMapHCPageInl,             STAMTYPE_PROFILE, "/PGM/R0/DynMapPageHCPageInl",        STAMUNIT_TICKS_PER_CALL, "Calls to pgmR0DynMapHCPageInlined.");
     1607    STAM_REG(pVM, &pPGM->StatR0DynMapHCPageInlHits,         STAMTYPE_COUNTER, "/PGM/R0/DynMapPageHCPageInl/Hits",   STAMUNIT_OCCURENCES,     "Hash table lookup hits.");
     1608    STAM_REG(pVM, &pPGM->StatR0DynMapHCPageInlMisses,       STAMTYPE_COUNTER, "/PGM/R0/DynMapPageHCPageInl/Misses", STAMUNIT_OCCURENCES,     "Misses that falls back to code common with PGMDynMapHCPage.");
    16041609    STAM_REG(pVM, &pPGM->StatR0DynMapPage,                  STAMTYPE_COUNTER, "/PGM/R0/DynMapPage",                 STAMUNIT_OCCURENCES,     "Calls to pgmR0DynMapPage");
    1605     STAM_REG(pVM, &pPGM->StatR0DynMapPageHit0,              STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Hit0",            STAMUNIT_OCCURENCES,     "Hit at iPage+0");
    1606     STAM_REG(pVM, &pPGM->StatR0DynMapPageHit1,              STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Hit1",            STAMUNIT_OCCURENCES,     "Hit at iPage+1");
    1607     STAM_REG(pVM, &pPGM->StatR0DynMapPageHit2,              STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Hit2",            STAMUNIT_OCCURENCES,     "Hit at iPage+2");
     1610    STAM_REG(pVM, &pPGM->StatR0DynMapSetOptimize,           STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SetOptimize",     STAMUNIT_OCCURENCES,     "Calls to pgmDynMapOptimizeAutoSet.");
     1611    STAM_REG(pVM, &pPGM->StatR0DynMapSetSearchHits,         STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SetSearchHits",   STAMUNIT_OCCURENCES,     "Set search hits.");
     1612    STAM_REG(pVM, &pPGM->StatR0DynMapSetSearchMisses,       STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/SetSearchMisses", STAMUNIT_OCCURENCES,     "Set search misses.");
     1613    STAM_REG(pVM, &pPGM->StatR0DynMapHCPage,                STAMTYPE_PROFILE, "/PGM/R0/DynMapPage/HCPage",          STAMUNIT_TICKS_PER_CALL, "Calls to PGMDynMapHCPage (ring-0).");
     1614    STAM_REG(pVM, &pPGM->StatR0DynMapPageHits0,             STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Hits0",           STAMUNIT_OCCURENCES,     "Hits at iPage+0");
     1615    STAM_REG(pVM, &pPGM->StatR0DynMapPageHits1,             STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Hits1",           STAMUNIT_OCCURENCES,     "Hits at iPage+1");
     1616    STAM_REG(pVM, &pPGM->StatR0DynMapPageHits2,             STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Hits2",           STAMUNIT_OCCURENCES,     "Hits at iPage+2");
    16081617    STAM_REG(pVM, &pPGM->StatR0DynMapPageInvlPg,            STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/InvlPg",          STAMUNIT_OCCURENCES,     "invlpg count in pgmR0DynMapPageSlow.");
    16091618    STAM_REG(pVM, &pPGM->StatR0DynMapPageSlow,              STAMTYPE_COUNTER, "/PGM/R0/DynMapPage/Slow",            STAMUNIT_OCCURENCES,     "Calls to pgmR0DynMapPageSlow - subtract this from pgmR0DynMapPage to get 1st level hits.");
  • trunk/src/VBox/VMM/PGMInternal.h

    r15196 r15344  
    226226 * @remark  There is no need to assert on the result.
    227227 */
    228 #if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
     228#ifdef IN_RC
    229229# define PGM_HCPHYS_2_PTR(pVM, HCPhys, ppv) \
    230230     PGMDynMapHCPage(pVM, HCPhys, (void **)(ppv))
     231#elif defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
     232# define PGM_HCPHYS_2_PTR(pVM, HCPhys, ppv) \
     233     pgmR0DynMapHCPageInlined(&(pVM)->pgm.s, HCPhys, (void **)(ppv))
    231234#else
    232235# define PGM_HCPHYS_2_PTR(pVM, HCPhys, ppv) \
    233236     MMPagePhys2PageEx(pVM, HCPhys, (void **)(ppv))
     237#endif
     238
     239/** @def PGM_HCPHYS_2_PTR_BY_PGM
     240 * Maps a HC physical page pool address to a virtual address.
     241 *
     242 * @returns VBox status code.
     243 * @param   pPGM    The PGM instance data.
     244 * @param   HCPhys  The HC physical address to map to a virtual one.
     245 * @param   ppv     Where to store the virtual address. No need to cast this.
     246 *
     247 * @remark  In GC this uses PGMGCDynMapHCPage(), so it will consume of the
     248 *          small page window employeed by that function. Be careful.
     249 * @remark  There is no need to assert on the result.
     250 */
     251#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
     252# define PGM_HCPHYS_2_PTR_BY_PGM(pPGM, HCPhys, ppv) \
     253     pgmR0DynMapHCPageInlined(pPGM, HCPhys, (void **)(ppv))
     254#else
     255# define PGM_HCPHYS_2_PTR_BY_PGM(pPGM, HCPhys, ppv) \
     256     PGM_HCPHYS_2_PTR(PGM2VM(pPGM), HCPhys, (void **)(ppv))
    234257#endif
    235258
     
    246269 * @remark  There is no need to assert on the result.
    247270 */
    248 #if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
     271#ifdef IN_RC
    249272# define PGM_GCPHYS_2_PTR(pVM, GCPhys, ppv) \
    250273     PGMDynMapGCPage(pVM, GCPhys, (void **)(ppv))
     274#elif defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
     275# define PGM_GCPHYS_2_PTR(pVM, GCPhys, ppv) \
     276     pgmR0DynMapGCPageInlined(&(pVM)->pgm.s, GCPhys, (void **)(ppv))
    251277#else
    252278# define PGM_GCPHYS_2_PTR(pVM, GCPhys, ppv) \
    253279     PGMPhysGCPhys2R3Ptr(pVM, GCPhys, 1 /* one page only */, (PRTR3PTR)(ppv)) /** @todo this isn't asserting, use PGMRamGCPhys2HCPtr! */
     280#endif
     281
     282/** @def PGM_GCPHYS_2_PTR_BY_PGM
     283 * Maps a GC physical page address to a virtual address.
     284 *
     285 * @returns VBox status code.
     286 * @param   pPGM    Pointer to the PGM instance data.
     287 * @param   GCPhys  The GC physical address to map to a virtual one.
     288 * @param   ppv     Where to store the virtual address. No need to cast this.
     289 *
     290 * @remark  In GC this uses PGMGCDynMapGCPage(), so it will consume of the
     291 *          small page window employeed by that function. Be careful.
     292 * @remark  There is no need to assert on the result.
     293 */
     294#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
     295# define PGM_GCPHYS_2_PTR_BY_PGM(pPGM, GCPhys, ppv) \
     296     pgmR0DynMapGCPageInlined(pPGM, GCPhys, (void **)(ppv))
     297#else
     298# define PGM_GCPHYS_2_PTR_BY_PGM(pPGM, GCPhys, ppv) \
     299     PGM_GCPHYS_2_PTR(PGM2VM(pPGM), GCPhys, ppv)
    254300#endif
    255301
     
    12531299     * The max is UINT16_MAX - 1. */
    12541300    uint16_t                    cRefs;
     1301    /** Pointer to the page. */
     1302    RTR0PTR                     pvPage;
     1303    /** The physical address for this entry. */
     1304    RTHCPHYS                    HCPhys;
    12551305} PGMMAPSETENTRY;
    12561306/** Pointer to a mapping cache usage set entry. */
     
    12711321    /** The entries. */
    12721322    PGMMAPSETENTRY              aEntries[32];
     1323    /** HCPhys -> iEntry fast lookup table.
     1324     * Use PGMMAPSET_HASH for hashing.
     1325     * The entries may or may not be valid, check against cEntries. */
     1326    uint8_t                     aiHashTable[64];
    12731327} PGMMAPSET;
    12741328/** Pointer to the mapping cache set. */
     
    12761330
    12771331/** PGMMAPSET::cEntries value for a closed set. */
    1278 #define PGMMAPSET_CLOSED        UINT32_C(0xdeadc0fe)
     1332#define PGMMAPSET_CLOSED            UINT32_C(0xdeadc0fe)
     1333
     1334/** Hash function for aiHashTable. */
     1335#define PGMMAPSET_HASH(HCPhys)      (((HCPhys) >> PAGE_SHIFT) & 63)
    12791336
    12801337
     
    20422099    /** Offset to the VM structure. */
    20432100    RTINT                           offVM;
     2101    /** Offset of the PGMCPU structure relative to VMCPU. */
     2102    int32_t                         offVCpu;
     2103    /** Alignment padding. */
     2104    int32_t                         i32Alignment;
    20442105
    20452106    /*
     
    25612622
    25622623    /* R0 only: */
     2624    STAMCOUNTER StatR0DynMapMigrateInvlPg;          /**< R0: invlpg in PGMDynMapMigrateAutoSet. */
     2625    STAMPROFILE StatR0DynMapGCPageInl;              /**< R0: Calls to pgmR0DynMapGCPageInlined. */
     2626    STAMCOUNTER StatR0DynMapGCPageInlHits;          /**< R0: Hash table lookup hits. */
     2627    STAMCOUNTER StatR0DynMapGCPageInlMisses;        /**< R0: Misses that falls back to code common with PGMDynMapHCPage. */
     2628    STAMCOUNTER StatR0DynMapGCPageInlRamHits;       /**< R0: 1st ram range hits. */
     2629    STAMCOUNTER StatR0DynMapGCPageInlRamMisses;     /**< R0: 1st ram range misses, takes slow path. */
     2630    STAMPROFILE StatR0DynMapHCPageInl;              /**< R0: Calls to pgmR0DynMapHCPageInlined. */
     2631    STAMCOUNTER StatR0DynMapHCPageInlHits;          /**< R0: Hash table lookup hits. */
     2632    STAMCOUNTER StatR0DynMapHCPageInlMisses;        /**< R0: Misses that falls back to code common with PGMDynMapHCPage. */
    25632633    STAMPROFILE StatR0DynMapHCPage;                 /**< R0: Calls to PGMDynMapHCPage. */
    2564     STAMCOUNTER StatR0DynMapHCPageSetOptimize;      /**< R0: Calls to pgmDynMapOptimizeAutoSet. */
    2565     STAMCOUNTER StatR0DynMapHCPageSetSearchHits;    /**< R0: Set search hits. */
    2566     STAMCOUNTER StatR0DynMapHCPageSetSearchMisses;  /**< R0: Set search misses. */
    2567     STAMCOUNTER StatR0DynMapMigrateInvlPg;          /**< R0: invlpg in PGMDynMapMigrateAutoSet. */
     2634    STAMCOUNTER StatR0DynMapSetOptimize;            /**< R0: Calls to pgmDynMapOptimizeAutoSet. */
     2635    STAMCOUNTER StatR0DynMapSetSearchHits;          /**< R0: Set search hits. */
     2636    STAMCOUNTER StatR0DynMapSetSearchMisses;        /**< R0: Set search misses. */
    25682637    STAMCOUNTER StatR0DynMapPage;                   /**< R0: Calls to pgmR0DynMapPage. */
    2569     STAMCOUNTER StatR0DynMapPageHit0;               /**< R0: Hit at iPage+0. */
    2570     STAMCOUNTER StatR0DynMapPageHit1;               /**< R0: Hit at iPage+1. */
    2571     STAMCOUNTER StatR0DynMapPageHit2;               /**< R0: Hit at iPage+2. */
     2638    STAMCOUNTER StatR0DynMapPageHits0;              /**< R0: Hits at iPage+0. */
     2639    STAMCOUNTER StatR0DynMapPageHits1;              /**< R0: Hits at iPage+1. */
     2640    STAMCOUNTER StatR0DynMapPageHits2;              /**< R0: Hits at iPage+2. */
    25722641    STAMCOUNTER StatR0DynMapPageInvlPg;             /**< R0: invlpg. */
    25732642    STAMCOUNTER StatR0DynMapPageSlow;               /**< R0: Calls to pgmR0DynMapPageSlow. */
     
    28132882int             pgmR3PhysRamReset(PVM pVM);
    28142883int             pgmR3PhysRomReset(PVM pVM);
    2815 #ifndef VBOX_WITH_NEW_PHYS_CODE
     2884# ifndef VBOX_WITH_NEW_PHYS_CODE
    28162885int             pgmr3PhysGrowRange(PVM pVM, RTGCPHYS GCPhys);
    2817 #endif
     2886# endif
    28182887
    28192888int             pgmR3PoolInit(PVM pVM);
     
    28222891
    28232892#endif /* IN_RING3 */
     2893#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
     2894int             pgmR0DynMapHCPageCommon(PVM pVM, PPGMMAPSET pSet, RTHCPHYS HCPhys, void **ppv);
     2895#endif
    28242896#if defined(IN_RC) || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
    28252897void           *pgmPoolMapPage(PVM pVM, PPGMPOOLPAGE pPage);
     
    31573229}
    31583230
     3231#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
     3232
     3233/**
     3234 * Inlined version of the ring-0 version of PGMDynMapHCPage that
     3235 * optimizes access to pages already in the set.
     3236 *
     3237 * @returns See pgmR0DynMapHCPageCommon.
     3238 * @param   pPGM        Pointer to the PVM instance data.
     3239 * @param   HCPhys      The physical address of the page.
     3240 * @param   ppv         Where to store the mapping address.
     3241 */
     3242DECLINLINE(int) pgmR0DynMapHCPageInlined(PPGM pPGM, RTHCPHYS HCPhys, void **ppv)
     3243{
     3244    STAM_PROFILE_START(&pPGM->StatR0DynMapHCPageInl, a);
     3245    PPGMMAPSET  pSet    = &((PPGMCPU)((uint8_t *)VMMGetCpu(PGM2VM(pPGM)) + pPGM->offVCpu))->AutoSet; /* very pretty ;-) */
     3246    Assert(!(HCPhys & PAGE_OFFSET_MASK));
     3247    Assert(pSet->cEntries <= RT_ELEMENTS(pSet->aEntries));
     3248    int         rc;
     3249
     3250    unsigned    iHash   = PGMMAPSET_HASH(HCPhys);
     3251    unsigned    iEntry  = pSet->aiHashTable[iHash];
     3252    if (    iEntry < pSet->cEntries
     3253        &&  pSet->aEntries[iEntry].HCPhys == HCPhys)
     3254    {
     3255        *ppv = pSet->aEntries[iEntry].pvPage;
     3256        STAM_COUNTER_INC(&pPGM->StatR0DynMapHCPageInlHits);
     3257        rc = VINF_SUCCESS;
     3258    }
     3259    else
     3260    {
     3261        STAM_COUNTER_INC(&pPGM->StatR0DynMapHCPageInlMisses);
     3262        rc = pgmR0DynMapHCPageCommon(PGM2VM(pPGM), pSet, HCPhys, ppv);
     3263    }
     3264
     3265    STAM_PROFILE_STOP(&pPGM->StatR0DynMapHCPageInl, a);
     3266    return rc;
     3267}
     3268
     3269
     3270/**
     3271 * Inlined version of the ring-0 version of PGMDynMapGCPage that optimizes
     3272 * access to pages already in the set.
     3273 *
     3274 * @returns See pgmR0DynMapHCPageCommon.
     3275 * @param   pPGM        Pointer to the PVM instance data.
     3276 * @param   HCPhys      The physical address of the page.
     3277 * @param   ppv         Where to store the mapping address.
     3278 */
     3279DECLINLINE(int) pgmR0DynMapGCPageInlined(PPGM pPGM, RTGCPHYS GCPhys, void **ppv)
     3280{
     3281    STAM_PROFILE_START(&pPGM->StatR0DynMapGCPageInl, a);
     3282    Assert(!(GCPhys & PAGE_OFFSET_MASK));
     3283
     3284    /*
     3285     * Get the ram range.
     3286     */
     3287    PPGMRAMRANGE    pRam = pPGM->CTX_SUFF(pRamRanges);
     3288    RTGCPHYS        off = GCPhys - pRam->GCPhys;
     3289    if (RT_UNLIKELY(off >= pRam->cb
     3290        /** @todo   || page state stuff */))
     3291    {
     3292        /* This case is not counted into StatR0DynMapGCPageInl. */
     3293        STAM_COUNTER_INC(&pPGM->StatR0DynMapGCPageInlRamMisses);
     3294        return PGMDynMapGCPage(PGM2VM(pPGM), GCPhys, ppv);
     3295    }
     3296
     3297    RTHCPHYS HCPhys = PGM_PAGE_GET_HCPHYS(&pRam->aPages[off >> PAGE_SHIFT]);
     3298    STAM_COUNTER_INC(&pPGM->StatR0DynMapGCPageInlRamHits);
     3299
     3300    /*
     3301     * pgmR0DynMapHCPageInlined with out stats.
     3302     */
     3303    PPGMMAPSET  pSet    = &((PPGMCPU)((uint8_t *)VMMGetCpu(PGM2VM(pPGM)) + pPGM->offVCpu))->AutoSet; /* very pretty ;-) */
     3304    Assert(!(HCPhys & PAGE_OFFSET_MASK));
     3305    Assert(pSet->cEntries <= RT_ELEMENTS(pSet->aEntries));
     3306    int         rc;
     3307
     3308    unsigned    iHash   = PGMMAPSET_HASH(HCPhys);
     3309    unsigned    iEntry  = pSet->aiHashTable[iHash];
     3310    if (    iEntry < pSet->cEntries
     3311        &&  pSet->aEntries[iEntry].HCPhys == HCPhys)
     3312    {
     3313        *ppv = pSet->aEntries[iEntry].pvPage;
     3314        STAM_COUNTER_INC(&pPGM->StatR0DynMapGCPageInlHits);
     3315        rc = VINF_SUCCESS;
     3316    }
     3317    else
     3318    {
     3319        STAM_COUNTER_INC(&pPGM->StatR0DynMapGCPageInlMisses);
     3320        rc = pgmR0DynMapHCPageCommon(PGM2VM(pPGM), pSet, HCPhys, ppv);
     3321    }
     3322
     3323    STAM_PROFILE_STOP(&pPGM->StatR0DynMapGCPageInl, a);
     3324    return rc;
     3325}
     3326
     3327#endif /* VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0 */
    31593328
    31603329#ifndef IN_RC
     
    33933562#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    33943563    PCX86PD pGuestPD = 0;
    3395     int rc = PGMDynMapGCPage(PGM2VM(pPGM), pPGM->GCPhysCR3, (void **)&pGuestPD);
     3564    int rc = pgmR0DynMapGCPageInlined(pPGM, pPGM->GCPhysCR3, (void **)&pGuestPD);
    33963565    if (RT_FAILURE(rc))
    33973566    {
     
    34173586#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    34183587    PX86PD pGuestPD = 0;
    3419     int rc = PGMDynMapGCPage(PGM2VM(pPGM), pPGM->GCPhysCR3, (void **)&pGuestPD);
     3588    int rc = pgmR0DynMapGCPageInlined(pPGM, pPGM->GCPhysCR3, (void **)&pGuestPD);
    34203589    AssertRCReturn(rc, 0);
    34213590    return &pGuestPD->a[GCPtr >> X86_PD_SHIFT];
     
    34363605#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    34373606    PX86PD pGuestPD = 0;
    3438     int rc = PGMDynMapGCPage(PGM2VM(pPGM), pPGM->GCPhysCR3, (void **)&pGuestPD);
     3607    int rc = pgmR0DynMapGCPageInlined(pPGM, pPGM->GCPhysCR3, (void **)&pGuestPD);
    34393608    AssertRCReturn(rc, 0);
    34403609    return pGuestPD;
     
    34563625#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    34573626    PX86PDPT pGuestPDPT = 0;
    3458     int rc = PGMDynMapGCPage(PGM2VM(pPGM), pPGM->GCPhysCR3, (void **)&pGuestPDPT);
     3627    int rc = pgmR0DynMapGCPageInlined(pPGM, pPGM->GCPhysCR3, (void **)&pGuestPDPT);
    34593628    AssertRCReturn(rc, 0);
    34603629    return pGuestPDPT;
     
    34793648#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    34803649    PX86PDPT pGuestPDPT = 0;
    3481     int rc = PGMDynMapGCPage(PGM2VM(pPGM), pPGM->GCPhysCR3, (void **)&pGuestPDPT);
     3650    int rc = pgmR0DynMapGCPageInlined(pPGM, pPGM->GCPhysCR3, (void **)&pGuestPDPT);
    34823651    AssertRCReturn(rc, 0);
    34833652    return &pGuestPDPT->a[(GCPtr >> X86_PDPT_SHIFT) & X86_PDPT_MASK_PAE];
     
    35163685        /* cache is out-of-sync. */
    35173686        PX86PDPAE pPD;
    3518         int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pGuestPDPT->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
     3687        int rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pGuestPDPT->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
    35193688        if (RT_SUCCESS(rc))
    35203689            return pPD;
     
    35553724        /* The cache is out-of-sync. */
    35563725        PX86PDPAE pPD;
    3557         int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pGuestPDPT->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
     3726        int rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pGuestPDPT->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
    35583727        if (RT_SUCCESS(rc))
    35593728            return &pPD->a[iPD];
     
    35953764            /* cache is out-of-sync. */
    35963765            PX86PDPAE pPD;
    3597             int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pGuestPDPT->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
     3766            int rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pGuestPDPT->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
    35983767            if (RT_SUCCESS(rc))
    35993768                return pPD->a[iPD];
     
    36433812        /* cache is out-of-sync. */
    36443813        PX86PDPAE pPD;
    3645         int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pGuestPDPT->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
     3814        int rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pGuestPDPT->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
    36463815        if (RT_SUCCESS(rc))
    36473816        {
     
    36673836#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    36683837    PX86PML4 pGuestPml4;
    3669     int rc = PGMDynMapGCPage(PGM2VM(pPGM), pPGM->GCPhysCR3, (void **)&pGuestPml4);
     3838    int rc = pgmR0DynMapGCPageInlined(pPGM, pPGM->GCPhysCR3, (void **)&pGuestPml4);
    36703839    AssertRCReturn(rc, NULL);
    36713840    return pGuestPml4;
     
    36883857#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    36893858    PX86PML4 pGuestPml4;
    3690     int rc = PGMDynMapGCPage(PGM2VM(pPGM), pPGM->GCPhysCR3, (void **)&pGuestPml4);
     3859    int rc = pgmR0DynMapGCPageInlined(pPGM, pPGM->GCPhysCR3, (void **)&pGuestPml4);
    36913860    AssertRCReturn(rc, NULL);
    36923861    return &pGuestPml4->a[iPml4];
     
    37093878#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    37103879    PX86PML4 pGuestPml4;
    3711     int rc = PGMDynMapGCPage(PGM2VM(pPGM), pPGM->GCPhysCR3, (void **)&pGuestPml4);
     3880    int rc = pgmR0DynMapGCPageInlined(pPGM, pPGM->GCPhysCR3, (void **)&pGuestPml4);
    37123881    if (RT_FAILURE(rc))
    37133882    {
     
    37403909    {
    37413910        PX86PDPT pPdpt;
    3742         int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPml4e->u & X86_PML4E_PG_MASK, &pPdpt);
     3911        int rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pPml4e->u & X86_PML4E_PG_MASK, &pPdpt);
    37433912        AssertRCReturn(rc, NULL);
    37443913
     
    37693938    {
    37703939        PCX86PDPT   pPdptTemp;
    3771         int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPml4e->u & X86_PML4E_PG_MASK, &pPdptTemp);
     3940        int rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pPml4e->u & X86_PML4E_PG_MASK, &pPdptTemp);
    37723941        AssertRCReturn(rc, ZeroPde);
    37733942
     
    37773946        {
    37783947            PCX86PDPAE pPD;
    3779             rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPdptTemp->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
     3948            rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pPdptTemp->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
    37803949            AssertRCReturn(rc, ZeroPde);
    37813950
     
    38053974    {
    38063975        PCX86PDPT   pPdptTemp;
    3807         int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pGuestPml4->a[iPml4].u & X86_PML4E_PG_MASK, &pPdptTemp);
     3976        int rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pGuestPml4->a[iPml4].u & X86_PML4E_PG_MASK, &pPdptTemp);
    38083977        AssertRCReturn(rc, ZeroPde);
    38093978
     
    38123981        {
    38133982            PCX86PDPAE pPD;
    3814             rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPdptTemp->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
     3983            rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pPdptTemp->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
    38153984            AssertRCReturn(rc, ZeroPde);
    38163985
     
    38384007    {
    38394008        PCX86PDPT   pPdptTemp;
    3840         int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pGuestPml4->a[iPml4].u & X86_PML4E_PG_MASK, &pPdptTemp);
     4009        int rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pGuestPml4->a[iPml4].u & X86_PML4E_PG_MASK, &pPdptTemp);
    38414010        AssertRCReturn(rc, NULL);
    38424011
     
    38454014        {
    38464015            PX86PDPAE pPD;
    3847             rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPdptTemp->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
     4016            rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pPdptTemp->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
    38484017            AssertRCReturn(rc, NULL);
    38494018
     
    38754044    {
    38764045        PCX86PDPT   pPdptTemp;
    3877         int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPml4e->u & X86_PML4E_PG_MASK, &pPdptTemp);
     4046        int rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pPml4e->u & X86_PML4E_PG_MASK, &pPdptTemp);
    38784047        AssertRCReturn(rc, NULL);
    38794048
     
    38834052        {
    38844053            PX86PDPAE pPD;
    3885             rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPdptTemp->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
     4054            rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pPdptTemp->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
    38864055            AssertRCReturn(rc, NULL);
    38874056
     
    39104079    PX86PD          pShwPd;
    39114080    Assert(pPGM->HCPhysShw32BitPD != 0 && pPGM->HCPhysShw32BitPD != NIL_RTHCPHYS);
    3912     int rc = PGM_HCPHYS_2_PTR(PGM2VM(pPGM), pPGM->HCPhysShw32BitPD, &pShwPd);
     4081    int rc = PGM_HCPHYS_2_PTR_BY_PGM(pPGM, pPGM->HCPhysShw32BitPD, &pShwPd);
    39134082    AssertRCReturn(rc, NULL);
    39144083    return pShwPd;
     
    39734142    PX86PDPT pShwPdpt;
    39744143    Assert(pPGM->HCPhysShwPaePdpt != 0 && pPGM->HCPhysShwPaePdpt != NIL_RTHCPHYS);
    3975     int rc = PGM_HCPHYS_2_PTR(PGM2VM(pPGM), pPGM->HCPhysShwPaePdpt, &pShwPdpt);
     4144    int rc = PGM_HCPHYS_2_PTR_BY_PGM(pPGM, pPGM->HCPhysShwPaePdpt, &pShwPdpt);
    39764145    AssertRCReturn(rc, 0);
    39774146    return pShwPdpt;
     
    40054174# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    40064175    PX86PDPAE       pPD;
    4007     int rc = PGM_HCPHYS_2_PTR(PGM2VM(pPGM), pPGM->aHCPhysPaePDs[iPdpt], &pPD);
     4176    int rc = PGM_HCPHYS_2_PTR_BY_PGM(pPGM, pPGM->aHCPhysPaePDs[iPdpt], &pPD);
    40084177    AssertRCReturn(rc, 0);
    40094178    return pPD;
     
    40704239    PX86PML4 pShwPml4;
    40714240    Assert(pPGM->HCPhysShwPaePml4 != 0 && pPGM->HCPhysShwPaePml4 != NIL_RTHCPHYS);
    4072     int rc = PGM_HCPHYS_2_PTR(PGM2VM(pPGM), pPGM->HCPhysShwPaePml4, &pShwPml4);
     4241    int rc = PGM_HCPHYS_2_PTR_BY_PGM(pPGM, pPGM->HCPhysShwPaePml4, &pShwPml4);
    40734242    AssertRCReturn(rc, 0);
    40744243    return pShwPml4;
     
    41364305    {
    41374306        PCX86PDPT   pPdptTemp;
    4138         int rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pGuestPml4->a[iPml4].u & X86_PML4E_PG_MASK, &pPdptTemp);
     4307        int rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pGuestPml4->a[iPml4].u & X86_PML4E_PG_MASK, &pPdptTemp);
    41394308        AssertRCReturn(rc, NULL);
    41404309
     
    41434312        {
    41444313            PX86PDPAE pPD;
    4145             rc = PGM_GCPHYS_2_PTR(PGM2VM(pPGM), pPdptTemp->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
     4314            rc = PGM_GCPHYS_2_PTR_BY_PGM(pPGM, pPdptTemp->a[iPdPt].u & X86_PDPE_PG_MASK, &pPD);
    41464315            AssertRCReturn(rc, NULL);
    41474316
  • trunk/src/VBox/VMM/VMMAll/PGMAll.cpp

    r15226 r15344  
    18501850    RTHCPHYS HCPhys = PGM_PAGE_GET_HCPHYS(&pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT]);
    18511851    //Log(("PGMDynMapGCPage: GCPhys=%RGp HCPhys=%RHp\n", GCPhys, HCPhys));
     1852#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
     1853    return pgmR0DynMapHCPageInlined(&pVM->pgm.s, HCPhys, ppv);
     1854#else
    18521855    return PGMDynMapHCPage(pVM, HCPhys, ppv);
     1856#endif
    18531857}
    18541858
     
    18871891     */
    18881892    RTHCPHYS HCPhys = PGM_PAGE_GET_HCPHYS(&pRam->aPages[(GCPhys - pRam->GCPhys) >> PAGE_SHIFT]);
     1893#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
     1894    int rc = pgmR0DynMapHCPageInlined(&pVM->pgm.s, HCPhys, ppv);
     1895#else
    18891896    int rc = PGMDynMapHCPage(pVM, HCPhys, ppv);
     1897#endif
    18901898    if (RT_SUCCESS(rc))
    18911899        *ppv = (void *)((uintptr_t)*ppv | (GCPhys & PAGE_OFFSET_MASK));
  • trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp

    r15284 r15344  
    500500    RTHCPHYS HCPhys = PGM_PAGE_GET_HCPHYS(pPage);
    501501    Assert(HCPhys != pVM->pgm.s.HCPhysZeroPg);
     502# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
     503    return pgmR0DynMapHCPageInlined(&pVM->pgm.s, HCPhys, ppv);
     504# else
    502505    return PGMDynMapHCPage(pVM, HCPhys, ppv);
     506# endif
    503507
    504508#else /* IN_RING3 || IN_RING0 */
  • trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp

    r14809 r15344  
    102102        Assert(pPage->idx < pVM->pgm.s.CTX_SUFF(pPool)->cCurPages);
    103103        void *pv;
     104# ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
     105        int rc = pgmR0DynMapHCPageInlined(&pVM->pgm.s, pPage->Core.Key, &pv);
     106# else
    104107        int rc = PGMDynMapHCPage(pVM, pPage->Core.Key, &pv);
     108# endif
    105109        AssertReleaseRC(rc);
    106110        return pv;
     
    159163    }
    160164    void *pv;
    161     int rc = PGMDynMapHCPage(pVM, HCPhys, &pv);
     165    int rc = pgmR0DynMapHCPageInlined(&pVM->pgm.s, HCPhys, &pv);
    162166    AssertReleaseRC(rc);
    163167    return pv;
  • trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp

    r15307 r15344  
    20402040#endif
    20412041#ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    2042     PGMDynMapReleaseAutoSet(pVCpu);
     2042    PGMDynMapFlushAutoSet(pVCpu);
    20432043#endif
    20442044
     
    21952195    STAM_PROFILE_ADV_STOP(&pVCpu->hwaccm.s.StatExit1, v);
    21962196    STAM_STATS({ STAM_PROFILE_ADV_START(&pVCpu->hwaccm.s.StatExit2, y); fStatExit2Started = true; });
    2197 
    2198 #ifdef VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0
    2199     PGMDynMapStartAutoSet(pVCpu);
    2200 #endif
    22012197
    22022198    /* Some cases don't need a complete resync of the guest CPU state; handle them here. */
  • trunk/src/VBox/VMM/VMMR0/PGMR0DynMap.cpp

    r15257 r15344  
    361361        while (j-- > 0)
    362362        {
    363             pSet->aEntries[j].iPage = UINT16_MAX;
    364             pSet->aEntries[j].cRefs = 0;
     363            pSet->aEntries[j].iPage  = UINT16_MAX;
     364            pSet->aEntries[j].cRefs  = 0;
     365            pSet->aEntries[j].pvPage = NULL;
     366            pSet->aEntries[j].HCPhys = NIL_RTHCPHYS;
    365367        }
    366368        pSet->cEntries = PGMMAPSET_CLOSED;
     369        memset(&pSet->aiHashTable[0], 0xff, sizeof(pSet->aiHashTable));
    367370    }
    368371
     
    456459                        AssertLogRelMsgFailed(("cRefs=%d iPage=%#x cPages=%u\n", cRefs, iPage, pThis->cPages));
    457460
    458                     pSet->aEntries[j].iPage = UINT16_MAX;
    459                     pSet->aEntries[j].cRefs = 0;
     461                    pSet->aEntries[j].iPage  = UINT16_MAX;
     462                    pSet->aEntries[j].cRefs  = 0;
     463                    pSet->aEntries[j].pvPage = NULL;
     464                    pSet->aEntries[j].HCPhys = NIL_RTHCPHYS;
    460465                }
    461466                pSet->cEntries = PGMMAPSET_CLOSED;
     
    12891294    PPGMR0DYNMAPENTRY   paPages = pThis->paPages;
    12901295    if (RT_LIKELY(paPages[iPage].HCPhys == HCPhys))
    1291         STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageHit0);
     1296        STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageHits0);
    12921297    else
    12931298    {
     
    12961301        {
    12971302            iPage = iPage2;
    1298             STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageHit1);
     1303            STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageHits1);
    12991304        }
    13001305        else
     
    13041309            {
    13051310                iPage = iPage2;
    1306                 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageHit2);
     1311                STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapPageHits2);
    13071312            }
    13081313            else
     
    14961501
    14971502/**
     1503 * Worker that performs the actual flushing of the set.
     1504 *
     1505 * @param   pSet        The set to flush.
     1506 * @param   cEntries    The number of entries.
     1507 */
     1508DECLINLINE(void) pgmDynMapFlushAutoSetWorker(PPGMMAPSET pSet, uint32_t cEntries)
     1509{
     1510    /*
     1511     * Release any pages it's referencing.
     1512     */
     1513    if (    cEntries != 0
     1514        &&  RT_LIKELY(cEntries <= RT_ELEMENTS(pSet->aEntries)))
     1515    {
     1516        PPGMR0DYNMAP    pThis = g_pPGMR0DynMap;
     1517        RTSPINLOCKTMP   Tmp = RTSPINLOCKTMP_INITIALIZER;
     1518        RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
     1519
     1520        uint32_t i = cEntries;
     1521        while (i-- > 0)
     1522        {
     1523            uint32_t iPage = pSet->aEntries[i].iPage;
     1524            Assert(iPage < pThis->cPages);
     1525            int32_t  cRefs = pSet->aEntries[i].cRefs;
     1526            Assert(cRefs > 0);
     1527            pgmR0DynMapReleasePageLocked(pThis, iPage, cRefs);
     1528
     1529            pSet->aEntries[i].iPage = UINT16_MAX;
     1530            pSet->aEntries[i].cRefs = 0;
     1531        }
     1532
     1533        Assert(pThis->cLoad <= pThis->cPages - pThis->cGuardPages);
     1534        RTSpinlockRelease(pThis->hSpinlock, &Tmp);
     1535    }
     1536}
     1537
     1538
     1539/**
    14981540 * Releases the dynamic memory mappings made by PGMDynMapHCPage and associates
    14991541 * since the PGMDynMapStartAutoSet call.
    15001542 *
    1501  * If the set is already closed, nothing will be done.
    1502  *
    15031543 * @param   pVCpu       The shared data for the current virtual CPU.
    15041544 */
     
    15081548
    15091549    /*
    1510      * Is the set open?
    1511      *
    1512      * We might be closed before VM execution and not reopened again before
    1513      * we leave for ring-3 or something.
    1514      */
    1515     uint32_t    i = pSet->cEntries;
    1516     if (i != PGMMAPSET_CLOSED)
    1517     {
    1518         /*
    1519          * Close the set
    1520          */
    1521         AssertMsg(i <= RT_ELEMENTS(pSet->aEntries), ("%#x (%u)\n", i, i));
    1522         pSet->cEntries = PGMMAPSET_CLOSED;
    1523 
    1524         /*
    1525          * Release any pages it's referencing.
    1526          */
    1527         if (i != 0 && RT_LIKELY(i <= RT_ELEMENTS(pSet->aEntries)))
    1528         {
    1529             PPGMR0DYNMAP    pThis = g_pPGMR0DynMap;
    1530             RTSPINLOCKTMP   Tmp = RTSPINLOCKTMP_INITIALIZER;
    1531             RTSpinlockAcquire(pThis->hSpinlock, &Tmp);
    1532 
    1533             while (i-- > 0)
    1534             {
    1535                 uint32_t iPage = pSet->aEntries[i].iPage;
    1536                 Assert(iPage < pThis->cPages);
    1537                 int32_t  cRefs = pSet->aEntries[i].cRefs;
    1538                 Assert(cRefs > 0);
    1539                 pgmR0DynMapReleasePageLocked(pThis, iPage, cRefs);
    1540 
    1541                 pSet->aEntries[i].iPage = UINT16_MAX;
    1542                 pSet->aEntries[i].cRefs = 0;
    1543             }
    1544 
    1545             Assert(pThis->cLoad <= pThis->cPages - pThis->cGuardPages);
    1546             RTSpinlockRelease(pThis->hSpinlock, &Tmp);
    1547         }
    1548     }
    1549 }
     1550     * Close and flush the set.
     1551     */
     1552    uint32_t    cEntries = pSet->cEntries;
     1553    AssertReturnVoid(cEntries != PGMMAPSET_CLOSED);
     1554    AssertMsg(cEntries <= RT_ELEMENTS(pSet->aEntries), ("%#x (%u)\n", cEntries, cEntries));
     1555    pSet->cEntries = PGMMAPSET_CLOSED;
     1556
     1557    pgmDynMapFlushAutoSetWorker(pSet, cEntries);
     1558}
     1559
     1560
     1561/**
     1562 * Flushes the set if it's above a certain threshold.
     1563 *
     1564 * @param   pVCpu       The shared data for the current virtual CPU.
     1565 */
     1566VMMDECL(void) PGMDynMapFlushAutoSet(PVMCPU pVCpu)
     1567{
     1568    PPGMMAPSET  pSet = &pVCpu->pgm.s.AutoSet;
     1569
     1570    /*
     1571     * Only flush it if it's 50% full.
     1572     */
     1573    uint32_t cEntries = pSet->cEntries;
     1574    AssertReturnVoid(cEntries != PGMMAPSET_CLOSED);
     1575    if (cEntries >= RT_ELEMENTS(pSet->aEntries) / 2)
     1576    {
     1577        AssertMsg(cEntries <= RT_ELEMENTS(pSet->aEntries), ("%#x (%u)\n", cEntries, cEntries));
     1578        pSet->cEntries = 0;
     1579
     1580        pgmDynMapFlushAutoSetWorker(pSet, cEntries);
     1581    }
     1582}
     1583
    15501584
    15511585
     
    16381672
    16391673
    1640 /* documented elsewhere - a bit of a mess.
    1641    This is a VERY hot path. */
    1642 VMMDECL(int) PGMDynMapHCPage(PVM pVM, RTHCPHYS HCPhys, void **ppv)
    1643 {
    1644     /*
    1645      * Validate state.
    1646      */
    1647     STAM_PROFILE_START(&pVM->pgm.s.StatR0DynMapHCPage, a);
    1648     AssertPtr(ppv);
    1649     *ppv = NULL;
    1650     AssertMsgReturn(pVM->pgm.s.pvR0DynMapUsed == g_pPGMR0DynMap,
    1651                     ("%p != %p\n", pVM->pgm.s.pvR0DynMapUsed, g_pPGMR0DynMap),
    1652                     VERR_ACCESS_DENIED);
    1653     AssertMsg(!(HCPhys & PAGE_OFFSET_MASK), ("HCPhys=%RHp\n", HCPhys));
    1654     PVMCPU          pVCpu   = VMMGetCpu(pVM);
    1655     PPGMMAPSET      pSet    = &pVCpu->pgm.s.AutoSet;
    1656     AssertPtrReturn(pVCpu, VERR_INTERNAL_ERROR);
    1657     AssertMsgReturn(pSet->cEntries <= RT_ELEMENTS(pSet->aEntries),
    1658                     ("%#x (%u)\n", pSet->cEntries, pSet->cEntries), VERR_WRONG_ORDER);
    1659 
     1674/**
     1675 * Common worker code for PGMDynMapHCPhys, pgmR0DynMapHCPageInlined and
     1676 * pgmR0DynMapGCPageInlined.
     1677 *
     1678 * @returns VBox status code.
     1679 * @param   pVM         The shared VM structure (for statistics).
     1680 * @param   pSet        The set.
     1681 * @param   HCPhys      The physical address of the page.
     1682 * @param   ppv         Where to store the address of the mapping on success.
     1683 */
     1684int pgmR0DynMapHCPageCommon(PVM pVM, PPGMMAPSET pSet, RTHCPHYS HCPhys, void **ppv)
     1685{
    16601686    /*
    16611687     * Map it.
    16621688     */
    1663     uint32_t const  iPage = pgmR0DynMapPage(g_pPGMR0DynMap, HCPhys, pVM, ppv);
     1689    void *pvPage;
     1690    uint32_t const  iPage = pgmR0DynMapPage(g_pPGMR0DynMap, HCPhys, pVM, &pvPage);
    16641691    if (RT_UNLIKELY(iPage == UINT32_MAX))
    16651692    {
    1666         STAM_PROFILE_STOP(&pVM->pgm.s.StatR0DynMapHCPage, a);
    16671693        static uint32_t s_cBitched = 0;
    16681694        if (++s_cBitched < 10)
    16691695            LogRel(("PGMDynMapHCPage: cLoad=%u/%u cPages=%u cGuardPages=%u\n",
    16701696                    g_pPGMR0DynMap->cLoad, g_pPGMR0DynMap->cMaxLoad, g_pPGMR0DynMap->cPages, g_pPGMR0DynMap->cGuardPages));
     1697        *ppv = NULL;
    16711698        return VERR_PGM_DYNMAP_FAILED;
    16721699    }
     
    16841711    if (i-- < 5)
    16851712    {
    1686         pSet->aEntries[pSet->cEntries].cRefs = 1;
    1687         pSet->aEntries[pSet->cEntries].iPage = iPage;
    1688         pSet->cEntries++;
     1713        unsigned iEntry = pSet->cEntries++;
     1714        pSet->aEntries[iEntry].cRefs  = 1;
     1715        pSet->aEntries[iEntry].iPage  = iPage;
     1716        pSet->aEntries[iEntry].pvPage = pvPage;
     1717        pSet->aEntries[iEntry].HCPhys = HCPhys;
     1718        pSet->aiHashTable[PGMMAPSET_HASH(HCPhys)] = iEntry;
    16891719    }
    16901720    /* Any of the last 5 pages? */
     
    17071737    else if (RT_LIKELY(i <= (int32_t)RT_ELEMENTS(pSet->aEntries) / 4 * 3))
    17081738    {
    1709         pSet->aEntries[pSet->cEntries].cRefs = 1;
    1710         pSet->aEntries[pSet->cEntries].iPage = iPage;
    1711         pSet->cEntries++;
     1739        unsigned iEntry = pSet->cEntries++;
     1740        pSet->aEntries[iEntry].cRefs  = 1;
     1741        pSet->aEntries[iEntry].iPage  = iPage;
     1742        pSet->aEntries[iEntry].pvPage = pvPage;
     1743        pSet->aEntries[iEntry].HCPhys = HCPhys;
     1744        pSet->aiHashTable[PGMMAPSET_HASH(HCPhys)] = iEntry;
    17121745    }
    17131746    else
     
    17211754            {
    17221755                pSet->aEntries[i].cRefs++;
    1723                 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapHCPageSetSearchHits);
     1756                STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapSetSearchHits);
    17241757                break;
    17251758            }
    17261759        if (i < 0)
    17271760        {
    1728             STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapHCPageSetSearchMisses);
     1761            STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapSetSearchMisses);
    17291762            if (RT_UNLIKELY(pSet->cEntries >= RT_ELEMENTS(pSet->aEntries)))
    17301763            {
    1731                 STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapHCPageSetOptimize);
     1764                STAM_COUNTER_INC(&pVM->pgm.s.StatR0DynMapSetOptimize);
    17321765                pgmDynMapOptimizeAutoSet(pSet);
    17331766            }
    17341767            if (RT_LIKELY(pSet->cEntries < RT_ELEMENTS(pSet->aEntries)))
    17351768            {
    1736                 pSet->aEntries[pSet->cEntries].cRefs = 1;
    1737                 pSet->aEntries[pSet->cEntries].iPage = iPage;
    1738                 pSet->cEntries++;
     1769                unsigned iEntry = pSet->cEntries++;
     1770                pSet->aEntries[iEntry].cRefs  = 1;
     1771                pSet->aEntries[iEntry].iPage  = iPage;
     1772                pSet->aEntries[iEntry].pvPage = pvPage;
     1773                pSet->aEntries[iEntry].HCPhys = HCPhys;
     1774                pSet->aiHashTable[PGMMAPSET_HASH(HCPhys)] = iEntry;
    17391775            }
    17401776            else
     
    17431779                pgmR0DynMapReleasePage(g_pPGMR0DynMap, iPage, 1);
    17441780
    1745                 STAM_PROFILE_STOP(&pVM->pgm.s.StatR0DynMapHCPage, a);
    17461781                static uint32_t s_cBitched = 0;
    17471782                if (++s_cBitched < 10)
     
    17531788    }
    17541789
     1790    *ppv = pvPage;
     1791    return VINF_SUCCESS;
     1792}
     1793
     1794
     1795/* documented elsewhere - a bit of a mess.
     1796   This is a VERY hot path. */
     1797VMMDECL(int) PGMDynMapHCPage(PVM pVM, RTHCPHYS HCPhys, void **ppv)
     1798{
     1799    /*
     1800     * Validate state.
     1801     */
     1802    STAM_PROFILE_START(&pVM->pgm.s.StatR0DynMapHCPage, a);
     1803    AssertPtr(ppv);
     1804    AssertMsgReturn(pVM->pgm.s.pvR0DynMapUsed == g_pPGMR0DynMap,
     1805                    ("%p != %p\n", pVM->pgm.s.pvR0DynMapUsed, g_pPGMR0DynMap),
     1806                    VERR_ACCESS_DENIED);
     1807    AssertMsg(!(HCPhys & PAGE_OFFSET_MASK), ("HCPhys=%RHp\n", HCPhys));
     1808    PVMCPU          pVCpu   = VMMGetCpu(pVM);
     1809    PPGMMAPSET      pSet    = &pVCpu->pgm.s.AutoSet;
     1810    AssertPtrReturn(pVCpu, VERR_INTERNAL_ERROR);
     1811    AssertMsgReturn(pSet->cEntries <= RT_ELEMENTS(pSet->aEntries),
     1812                    ("%#x (%u)\n", pSet->cEntries, pSet->cEntries), VERR_WRONG_ORDER);
     1813
     1814    /*
     1815     * Call common code.
     1816     */
     1817    int rc = pgmR0DynMapHCPageCommon(pVM, pSet, HCPhys, ppv);
     1818
    17551819    STAM_PROFILE_STOP(&pVM->pgm.s.StatR0DynMapHCPage, a);
    1756     return VINF_SUCCESS;
     1820    return rc;
    17571821}
    17581822
     
    19792043    ASMIntDisable();
    19802044    PGMDynMapMigrateAutoSet(&pVM->aCpus[0]);
     2045    PGMDynMapFlushAutoSet(&pVM->aCpus[0]);
    19812046    PGMDynMapReleaseAutoSet(&pVM->aCpus[0]);
    19822047    ASMIntEnable();
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