VirtualBox

Changeset 92326 in vbox


Ignore:
Timestamp:
Nov 10, 2021 3:14:52 PM (3 years ago)
Author:
vboxsync
Message:

VMM/GMM,PGM: Optimize zeroing of RAM allocations by not doing it again if the OS already zeroed an allocation. bugref:10093

Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/gmm.h

    r92292 r92326  
    232232     * @input   GMMR0AllocateHandyPages expects the guest physical address
    233233     *          to update the GMMPAGE structure with. Pass GMM_GCPHYS_UNSHAREABLE
    234      *          when appropriate and NIL_RTHCPHYS when the page wasn't used
     234     *          when appropriate and NIL_GMMPAGEDESC_PHYS when the page wasn't used
    235235     *          for any specific guest address.
    236236     *
    237237     *          GMMR0AllocatePage expects the guest physical address to put in
    238238     *          the GMMPAGE structure for the page it allocates for this entry.
    239      *          Pass NIL_RTHCPHYS and GMM_GCPHYS_UNSHAREABLE as above.
     239     *          Pass NIL_GMMPAGEDESC_PHYS and GMM_GCPHYS_UNSHAREABLE as above.
    240240     *
    241241     * @output  The host physical address of the allocated page.
    242      *          NIL_RTHCPHYS on allocation failure.
    243      *
    244      * ASSUMES: sizeof(RTHCPHYS) >= sizeof(RTGCPHYS).
     242     *          NIL_GMMPAGEDESC_PHYS on allocation failure.
     243     *
     244     * ASSUMES: sizeof(RTHCPHYS) >= sizeof(RTGCPHYS) and that physical addresses are
     245     *          limited to 63 or fewer bits (52 by AMD64 arch spec).
    245246     */
    246     RTHCPHYS                    HCPhysGCPhys;
     247    RTHCPHYS                    HCPhysGCPhys : 63;
     248    /** Set if the memory was zeroed. */
     249    RTHCPHYS                    fZeroed : 1;
    247250
    248251    /** The Page ID.
     
    274277/** Pointer to a page allocation. */
    275278typedef GMMPAGEDESC *PGMMPAGEDESC;
     279
     280/** Special NIL value for GMMPAGEDESC::HCPhysGCPhys. */
     281#define NIL_GMMPAGEDESC_PHYS        UINT64_C(0x7fffffffffffffff)
    276282
    277283/** GMMPAGEDESC::HCPhysGCPhys value that indicates that the page is unsharable.
  • trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp

    r92162 r92326  
    889889    uint32_t iHandyPage = --pVM->pgm.s.cHandyPages;
    890890    AssertMsg(iHandyPage < RT_ELEMENTS(pVM->pgm.s.aHandyPages), ("%d\n", iHandyPage));
    891     Assert(pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys != NIL_RTHCPHYS);
     891    Assert(pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys != NIL_GMMPAGEDESC_PHYS);
    892892    Assert(!(pVM->pgm.s.aHandyPages[iHandyPage].HCPhysGCPhys & ~X86_PTE_PAE_PG_MASK));
    893893    Assert(pVM->pgm.s.aHandyPages[iHandyPage].idPage != NIL_GMM_PAGEID);
  • trunk/src/VBox/VMM/VMMR0/GMMR0.cpp

    r92249 r92326  
    260260        uint16_t    u16Reserved0;
    261261        /** Reserved. Checksum or something? */
    262         uint32_t    u30Reserved1 : 30;
     262        uint32_t    u30Reserved1 : 29;
     263        /** Set if the page was zeroed. */
     264        uint32_t    fZeroed : 1;
    263265        /** The page state. */
    264266        uint32_t    u2State : 2;
     
    525527    uint16_t            cRegisteredVMs;
    526528
    527     /** The number of freed chunks ever.  This is used a list generation to
    528      *  avoid restarting the cleanup scanning when the list wasn't modified. */
    529     uint32_t            cFreedChunks;
     529    /** The index of the next mutex to use. */
     530    uint32_t            iNextChunkMtx;
     531    /** Chunk locks for reducing lock contention without having to allocate
     532     * one lock per chunk. */
     533    struct
     534    {
     535        /** The mutex */
     536        RTSEMFASTMUTEX      hMtx;
     537        /** The number of threads currently using this mutex. */
     538        uint32_t volatile   cUsers;
     539    } aChunkMtx[64];
     540
     541    /** The number of freed chunks ever.  This is used as list generation to
     542     * avoid restarting the cleanup scanning when the list wasn't modified. */
     543    uint32_t volatile   cFreedChunks;
    530544    /** The previous allocated Chunk ID.
    531545     * Used as a hint to avoid scanning the whole bitmap. */
     
    535549     * The NIL id (0) is marked allocated. */
    536550    uint32_t            bmChunkId[(GMM_CHUNKID_LAST + 1 + 31) / 32];
    537 
    538     /** The index of the next mutex to use. */
    539     uint32_t            iNextChunkMtx;
    540     /** Chunk locks for reducing lock contention without having to allocate
    541      * one lock per chunk. */
    542     struct
    543     {
    544         /** The mutex */
    545         RTSEMFASTMUTEX      hMtx;
    546         /** The number of threads currently using this mutex. */
    547         uint32_t volatile   cUsers;
    548     } aChunkMtx[64];
    549551} GMM;
    550552/** Pointer to the GMM instance. */
     
    14101412                     */
    14111413                    pChunk->aPages[iPage].u = 0;
    1412                     pChunk->aPages[iPage].Free.iNext = pChunk->iFreeHead;
    14131414                    pChunk->aPages[iPage].Free.u2State = GMM_PAGE_STATE_FREE;
     1415                    pChunk->aPages[iPage].Free.fZeroed = false;
     1416                    pChunk->aPages[iPage].Free.iNext   = pChunk->iFreeHead;
    14141417                    pChunk->iFreeHead = iPage;
    14151418                    pChunk->cPrivate--;
     
    19961999     */
    19972000    int32_t idChunk = ++pGMM->idChunkPrev;
    1998 #if 0 /** @todo enable this code */
    1999     if (    idChunk <= GMM_CHUNKID_LAST
     2001    if (    (uint32_t)idChunk <= GMM_CHUNKID_LAST
    20002002        &&  idChunk > NIL_GMM_CHUNKID
    2001         &&  !ASMAtomicBitTestAndSet(&pVMM->bmChunkId[0], idChunk))
     2003        &&  !ASMAtomicBitTestAndSet(&pGMM->bmChunkId[0], idChunk))
    20022004        return idChunk;
    2003 #endif
    20042005
    20052006    /*
     
    20562057          pPage, iPage, (pChunk->Core.Key << GMM_CHUNKID_SHIFT) | iPage,
    20572058          pPage->Common.u2State, pChunk->iFreeHead, pPage->Free.iNext));
     2059
     2060    bool const fZeroed = pPage->Free.fZeroed;
    20582061
    20592062    /* make the page private. */
     
    20692072
    20702073    /* update the page descriptor. */
    2071     pPageDesc->HCPhysGCPhys = RTR0MemObjGetPagePhysAddr(pChunk->hMemObj, iPage);
    2072     Assert(pPageDesc->HCPhysGCPhys != NIL_RTHCPHYS);
    2073     pPageDesc->idPage = (pChunk->Core.Key << GMM_CHUNKID_SHIFT) | iPage;
    20742074    pPageDesc->idSharedPage = NIL_GMM_PAGEID;
     2075    pPageDesc->idPage       = (pChunk->Core.Key << GMM_CHUNKID_SHIFT) | iPage;
     2076    RTHCPHYS const HCPhys = RTR0MemObjGetPagePhysAddr(pChunk->hMemObj, iPage);
     2077    Assert(HCPhys != NIL_RTHCPHYS); Assert(HCPhys < NIL_GMMPAGEDESC_PHYS);
     2078    pPageDesc->HCPhysGCPhys = HCPhys;
     2079    pPageDesc->fZeroed      = fZeroed;
    20752080}
    20762081
     
    21662171        pChunk->fFlags      = fChunkFlags;
    21672172        pChunk->uidOwner    = pSession ? SUPR0GetSessionUid(pSession) : NIL_RTUID;
     2173
    21682174        for (unsigned iPage = 0; iPage < RT_ELEMENTS(pChunk->aPages) - 1; iPage++)
    21692175        {
    21702176            pChunk->aPages[iPage].Free.u2State = GMM_PAGE_STATE_FREE;
    2171             pChunk->aPages[iPage].Free.iNext = iPage + 1;
     2177            pChunk->aPages[iPage].Free.fZeroed = true;
     2178            pChunk->aPages[iPage].Free.iNext   = iPage + 1;
    21722179        }
    21732180        pChunk->aPages[RT_ELEMENTS(pChunk->aPages) - 1].Free.u2State = GMM_PAGE_STATE_FREE;
     2181        pChunk->aPages[RT_ELEMENTS(pChunk->aPages) - 1].Free.fZeroed = true;
    21742182        pChunk->aPages[RT_ELEMENTS(pChunk->aPages) - 1].Free.iNext   = UINT16_MAX;
    21752183
    21762184        /*
    2177          * Allocate a Chunk ID and insert it into the tree.
    2178          * This has to be done behind the mutex of course.
     2185         * Zero the memory if it wasn't zeroed by the host already.
     2186         * This simplifies keeping secret kernel bits from userland and brings
     2187         * everyone to the same level wrt allocation zeroing.
    21792188         */
    2180         rc = gmmR0MutexAcquire(pGMM);
     2189        rc = VINF_SUCCESS;
     2190        if (!RTR0MemObjWasZeroInitialized(hMemObj))
     2191        {
     2192#ifdef VBOX_WITH_LINEAR_HOST_PHYS_MEM
     2193            for (uint32_t iPage = 0; iPage < (GMM_CHUNK_SIZE >> PAGE_SHIFT); iPage++)
     2194            {
     2195                void *pvPage = NULL;
     2196                rc = SUPR0HCPhysToVirt(RTR0MemObjGetPagePhysAddr(hMemObj, iPage), &pvPage);
     2197                AssertRC(rc);
     2198                if (RT_SUCCESS(rc))
     2199                    RT_BZERO(pvPage, PAGE_SIZE);
     2200                else
     2201                    break;
     2202            }
     2203#else
     2204            RT_BZERO(pbMapping, GMM_CHUNK_SIZE);
     2205#endif
     2206        }
    21812207        if (RT_SUCCESS(rc))
    21822208        {
    2183             if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
     2209            /*
     2210             * Allocate a Chunk ID and insert it into the tree.
     2211             * This has to be done behind the mutex of course.
     2212             */
     2213            rc = gmmR0MutexAcquire(pGMM);
     2214            if (RT_SUCCESS(rc))
    21842215            {
    2185                 pChunk->Core.Key = gmmR0AllocateChunkId(pGMM);
    2186                 if (   pChunk->Core.Key != NIL_GMM_CHUNKID
    2187                     && pChunk->Core.Key <= GMM_CHUNKID_LAST)
     2216                if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
    21882217                {
    2189                     RTSpinlockAcquire(pGMM->hSpinLockTree);
    2190                     if (RTAvlU32Insert(&pGMM->pChunks, &pChunk->Core))
     2218                    pChunk->Core.Key = gmmR0AllocateChunkId(pGMM);
     2219                    if (   pChunk->Core.Key != NIL_GMM_CHUNKID
     2220                        && pChunk->Core.Key <= GMM_CHUNKID_LAST)
    21912221                    {
    2192                         pGMM->cChunks++;
    2193                         RTListAppend(&pGMM->ChunkList, &pChunk->ListNode);
     2222                        RTSpinlockAcquire(pGMM->hSpinLockTree);
     2223                        if (RTAvlU32Insert(&pGMM->pChunks, &pChunk->Core))
     2224                        {
     2225                            pGMM->cChunks++;
     2226                            RTListAppend(&pGMM->ChunkList, &pChunk->ListNode);
     2227                            RTSpinlockRelease(pGMM->hSpinLockTree);
     2228
     2229                            gmmR0LinkChunk(pChunk, pSet);
     2230
     2231                            LogFlow(("gmmR0RegisterChunk: pChunk=%p id=%#x cChunks=%d\n", pChunk, pChunk->Core.Key, pGMM->cChunks));
     2232
     2233                            if (ppChunk)
     2234                                *ppChunk = pChunk;
     2235                            GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
     2236                            return VINF_SUCCESS;
     2237                        }
    21942238                        RTSpinlockRelease(pGMM->hSpinLockTree);
    2195 
    2196                         gmmR0LinkChunk(pChunk, pSet);
    2197 
    2198                         LogFlow(("gmmR0RegisterChunk: pChunk=%p id=%#x cChunks=%d\n", pChunk, pChunk->Core.Key, pGMM->cChunks));
    2199 
    2200                         if (ppChunk)
    2201                             *ppChunk = pChunk;
    2202                         GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
    2203                         return VINF_SUCCESS;
    22042239                    }
    2205                     RTSpinlockRelease(pGMM->hSpinLockTree);
     2240
     2241                    /* bail out */
     2242                    rc = VERR_GMM_CHUNK_INSERT;
    22062243                }
    2207 
    2208                 /* bail out */
    2209                 rc = VERR_GMM_CHUNK_INSERT;
     2244                else
     2245                    rc = VERR_GMM_IS_NOT_SANE;
     2246                gmmR0MutexRelease(pGMM);
    22102247            }
    2211             else
    2212                 rc = VERR_GMM_IS_NOT_SANE;
    2213             gmmR0MutexRelease(pGMM);
    22142248        }
    22152249
     
    25462580 * @param   enmAccount  The account to charge.
    25472581 *
    2548  * @remarks Call takes the giant GMM lock.
     2582 * @remarks Caller owns the giant GMM lock.
    25492583 */
    25502584static int gmmR0AllocatePagesNew(PGMM pGMM, PGVM pGVM, uint32_t cPages, PGMMPAGEDESC paPages, GMMACCOUNT enmAccount)
     
    27262760            paPages[iPage].idPage       = NIL_GMM_PAGEID;
    27272761            paPages[iPage].idSharedPage = NIL_GMM_PAGEID;
    2728             paPages[iPage].HCPhysGCPhys = NIL_RTHCPHYS;
     2762            paPages[iPage].HCPhysGCPhys = NIL_GMMPAGEDESC_PHYS;
     2763            paPages[iPage].fZeroed      = false;
    27292764        }
    27302765
     
    27942829        AssertMsgReturn(    (    paPages[iPage].HCPhysGCPhys <= GMM_GCPHYS_LAST
    27952830                             && !(paPages[iPage].HCPhysGCPhys & PAGE_OFFSET_MASK))
    2796                         ||  paPages[iPage].HCPhysGCPhys == NIL_RTHCPHYS
     2831                        ||  paPages[iPage].HCPhysGCPhys == NIL_GMMPAGEDESC_PHYS
    27972832                        ||  paPages[iPage].HCPhysGCPhys == GMM_GCPHYS_UNSHAREABLE,
    27982833                        ("#%#x: %RHp\n", iPage, paPages[iPage].HCPhysGCPhys),
    27992834                        VERR_INVALID_PARAMETER);
     2835        /* ignore fZeroed here */
    28002836        AssertMsgReturn(    paPages[iPage].idPage <= GMM_PAGEID_LAST
    28012837                        /*||  paPages[iPage].idPage == NIL_GMM_PAGEID*/,
     
    28082844    for (; iPage < cPagesToAlloc; iPage++)
    28092845    {
    2810         AssertMsgReturn(paPages[iPage].HCPhysGCPhys == NIL_RTHCPHYS,   ("#%#x: %RHp\n", iPage, paPages[iPage].HCPhysGCPhys), VERR_INVALID_PARAMETER);
     2846        AssertMsgReturn(paPages[iPage].HCPhysGCPhys == NIL_GMMPAGEDESC_PHYS, ("#%#x: %RHp\n", iPage, paPages[iPage].HCPhysGCPhys), VERR_INVALID_PARAMETER);
     2847        AssertMsgReturn(paPages[iPage].fZeroed      == false,          ("#%#x: %#x\n", iPage, paPages[iPage].fZeroed),       VERR_INVALID_PARAMETER);
    28112848        AssertMsgReturn(paPages[iPage].idPage       == NIL_GMM_PAGEID, ("#%#x: %#x\n", iPage, paPages[iPage].idPage),        VERR_INVALID_PARAMETER);
    28122849        AssertMsgReturn(paPages[iPage].idSharedPage == NIL_GMM_PAGEID, ("#%#x: %#x\n", iPage, paPages[iPage].idSharedPage),  VERR_INVALID_PARAMETER);
     
    28442881
    28452882                                paPages[iPage].idPage       = NIL_GMM_PAGEID;
    2846                                 paPages[iPage].HCPhysGCPhys = NIL_RTHCPHYS;
     2883                                paPages[iPage].HCPhysGCPhys = NIL_GMMPAGEDESC_PHYS;
     2884                                paPages[iPage].fZeroed      = false;
    28472885                            }
    28482886                            else
     
    29142952            if (RT_SUCCESS(rc) && cPagesToAlloc > 0)
    29152953            {
    2916 #if defined(VBOX_STRICT) && 0 /** @todo re-test this later. Appeared to be a PGM init bug. */
     2954#ifdef VBOX_STRICT
    29172955                for (iPage = 0; iPage < cPagesToAlloc; iPage++)
    29182956                {
    2919                     Assert(paPages[iPage].HCPhysGCPhys  == NIL_RTHCPHYS);
     2957                    Assert(paPages[iPage].HCPhysGCPhys  == NIL_GMMPAGEDESC_PHYS);
     2958                    Assert(paPages[iPage].fZeroed       == false);
    29202959                    Assert(paPages[iPage].idPage        == NIL_GMM_PAGEID);
    29212960                    Assert(paPages[iPage].idSharedPage  == NIL_GMM_PAGEID);
     
    29843023    for (unsigned iPage = 0; iPage < cPages; iPage++)
    29853024    {
    2986         AssertMsgReturn(    paPages[iPage].HCPhysGCPhys == NIL_RTHCPHYS
     3025        AssertMsgReturn(    paPages[iPage].HCPhysGCPhys == NIL_GMMPAGEDESC_PHYS
    29873026                        ||  paPages[iPage].HCPhysGCPhys == GMM_GCPHYS_UNSHAREABLE
    29883027                        ||  (    enmAccount == GMMACCOUNT_BASE
     
    29913030                        ("#%#x: %RHp enmAccount=%d\n", iPage, paPages[iPage].HCPhysGCPhys, enmAccount),
    29923031                        VERR_INVALID_PARAMETER);
    2993         AssertMsgReturn(paPages[iPage].idPage == NIL_GMM_PAGEID, ("#%#x: %#x\n", iPage, paPages[iPage].idPage), VERR_INVALID_PARAMETER);
     3032        AssertMsgReturn(paPages[iPage].fZeroed      == false,          ("#%#x: %#x\n", iPage, paPages[iPage].fZeroed), VERR_INVALID_PARAMETER);
     3033        AssertMsgReturn(paPages[iPage].idPage       == NIL_GMM_PAGEID, ("#%#x: %#x\n", iPage, paPages[iPage].idPage), VERR_INVALID_PARAMETER);
    29943034        AssertMsgReturn(paPages[iPage].idSharedPage == NIL_GMM_PAGEID, ("#%#x: %#x\n", iPage, paPages[iPage].idSharedPage), VERR_INVALID_PARAMETER);
    29953035    }
    29963036
     3037    /*
     3038     * Grab the giant mutex and get working.
     3039     */
    29973040    gmmR0MutexAcquire(pGMM);
    29983041    if (GMM_CHECK_SANITY_UPON_ENTERING(pGMM))
     
    30113054        rc = VERR_GMM_IS_NOT_SANE;
    30123055    gmmR0MutexRelease(pGMM);
     3056
    30133057    LogFlow(("GMMR0AllocatePages: returns %Rrc\n", rc));
    30143058    return rc;
     
    30443088 * Allocate a large page to represent guest RAM
    30453089 *
    3046  * The allocated pages are not cleared and will contains random garbage.
     3090 * The allocated pages are zeroed upon return.
    30473091 *
    30483092 * @returns VBox status code:
     
    31373181                gmmR0LinkChunk(pChunk, pSet);
    31383182                gmmR0MutexRelease(pGMM);
     3183
    31393184                LogFlow(("GMMR0AllocateLargePage: returns VINF_SUCCESS\n"));
    31403185                return VINF_SUCCESS;
     
    34203465    pPage->u = 0;
    34213466    pPage->Free.u2State = GMM_PAGE_STATE_FREE;
     3467    pPage->Free.fZeroed = false;
    34223468    Assert(pChunk->iFreeHead < RT_ELEMENTS(pChunk->aPages) || pChunk->iFreeHead == UINT16_MAX);
    34233469    pPage->Free.iNext = pChunk->iFreeHead;
     
    34583504    else
    34593505        gmmR0FreeChunk(pGMM, NULL, pChunk, false);
    3460 
    34613506}
    34623507
  • trunk/src/VBox/VMM/VMMR0/PGMR0.cpp

    r92248 r92326  
    170170            Assert(pGVM->pgm.s.aHandyPages[i].idPage <= GMM_PAGEID_LAST);
    171171            Assert(pGVM->pgm.s.aHandyPages[i].idSharedPage == NIL_GMM_PAGEID);
    172             Assert(pGVM->pgm.s.aHandyPages[i].HCPhysGCPhys != NIL_RTHCPHYS);
     172            Assert(pGVM->pgm.s.aHandyPages[i].HCPhysGCPhys != NIL_GMMPAGEDESC_PHYS);
    173173            Assert(!(pGVM->pgm.s.aHandyPages[i].HCPhysGCPhys & ~X86_PTE_PAE_PG_MASK));
    174174        }
     
    189189            for (i = iFirst; i < RT_ELEMENTS(pGVM->pgm.s.aHandyPages); i++)
    190190            {
    191                 Assert(pGVM->pgm.s.aHandyPages[i].idPage == NIL_GMM_PAGEID);
     191                Assert(pGVM->pgm.s.aHandyPages[i].idPage       == NIL_GMM_PAGEID);
    192192                Assert(pGVM->pgm.s.aHandyPages[i].idSharedPage == NIL_GMM_PAGEID);
    193                 Assert(pGVM->pgm.s.aHandyPages[i].HCPhysGCPhys == NIL_RTHCPHYS);
     193                Assert(pGVM->pgm.s.aHandyPages[i].HCPhysGCPhys == NIL_GMMPAGEDESC_PHYS);
     194                Assert(pGVM->pgm.s.aHandyPages[i].fZeroed      == false);
    194195            }
    195196#endif
     
    216217                    Assert(pGVM->pgm.s.aHandyPages[i].idPage <= GMM_PAGEID_LAST);
    217218                    Assert(pGVM->pgm.s.aHandyPages[i].idSharedPage == NIL_GMM_PAGEID);
    218                     Assert(pGVM->pgm.s.aHandyPages[i].HCPhysGCPhys != NIL_RTHCPHYS);
     219                    Assert(pGVM->pgm.s.aHandyPages[i].HCPhysGCPhys != NIL_GMMPAGEDESC_PHYS);
    219220                    Assert(!(pGVM->pgm.s.aHandyPages[i].HCPhysGCPhys & ~X86_PTE_PAE_PG_MASK));
    220221                }
     
    222223                for (i = cPages + iFirst; i < RT_ELEMENTS(pGVM->pgm.s.aHandyPages); i++)
    223224                {
    224                     Assert(pGVM->pgm.s.aHandyPages[i].idPage == NIL_GMM_PAGEID);
     225                    Assert(pGVM->pgm.s.aHandyPages[i].idPage       == NIL_GMM_PAGEID);
    225226                    Assert(pGVM->pgm.s.aHandyPages[i].idSharedPage == NIL_GMM_PAGEID);
    226                     Assert(pGVM->pgm.s.aHandyPages[i].HCPhysGCPhys == NIL_RTHCPHYS);
     227                    Assert(pGVM->pgm.s.aHandyPages[i].HCPhysGCPhys == NIL_GMMPAGEDESC_PHYS);
     228                    Assert(pGVM->pgm.s.aHandyPages[i].fZeroed      == false);
    227229                }
    228230#endif
     
    311313     * Do the job.
    312314     */
    313     int rc = GMMR0AllocateLargePage(pGVM, idCpu, _2M,
    314                                     &pGVM->pgm.s.aLargeHandyPage[0].idPage,
    315                                     &pGVM->pgm.s.aLargeHandyPage[0].HCPhysGCPhys);
     315    RTHCPHYS HCPhys = NIL_GMMPAGEDESC_PHYS;
     316    int rc = GMMR0AllocateLargePage(pGVM, idCpu, _2M, &pGVM->pgm.s.aLargeHandyPage[0].idPage, &HCPhys);
    316317    if (RT_SUCCESS(rc))
    317318        pGVM->pgm.s.cLargeHandyPages = 1;
     319    pGVM->pgm.s.aLargeHandyPage[0].HCPhysGCPhys = HCPhys;
     320    pGVM->pgm.s.aLargeHandyPage[0].fZeroed      = true;
    318321
    319322    return rc;
  • trunk/src/VBox/VMM/VMMR3/GMM.cpp

    r92248 r92326  
    109109#ifdef LOG_ENABLED
    110110        for (uint32_t iPage = 0; iPage < pReq->cPages; iPage++)
    111             Log3(("GMMR3AllocatePagesPerform: idPage=%#x HCPhys=%RHp\n",
    112                   pReq->aPages[iPage].idPage, pReq->aPages[iPage].HCPhysGCPhys));
     111            Log3(("GMMR3AllocatePagesPerform: idPage=%#x HCPhys=%RHp fZeroed=%d\n",
     112                  pReq->aPages[iPage].idPage, pReq->aPages[iPage].HCPhysGCPhys, pReq->aPages[iPage].fZeroed));
    113113#endif
    114114        return rc;
  • trunk/src/VBox/VMM/VMMR3/PGM.cpp

    r92248 r92326  
    755755    for (unsigned i = 0; i < RT_ELEMENTS(pVM->pgm.s.aHandyPages); i++)
    756756    {
    757         pVM->pgm.s.aHandyPages[i].HCPhysGCPhys  = NIL_RTHCPHYS;
     757        pVM->pgm.s.aHandyPages[i].HCPhysGCPhys  = NIL_GMMPAGEDESC_PHYS;
     758        pVM->pgm.s.aHandyPages[i].fZeroed       = false;
    758759        pVM->pgm.s.aHandyPages[i].idPage        = NIL_GMM_PAGEID;
    759760        pVM->pgm.s.aHandyPages[i].idSharedPage  = NIL_GMM_PAGEID;
     
    762763    for (unsigned i = 0; i < RT_ELEMENTS(pVM->pgm.s.aLargeHandyPage); i++)
    763764    {
    764         pVM->pgm.s.aLargeHandyPage[i].HCPhysGCPhys  = NIL_RTHCPHYS;
     765        pVM->pgm.s.aLargeHandyPage[i].HCPhysGCPhys  = NIL_GMMPAGEDESC_PHYS;
     766        pVM->pgm.s.aLargeHandyPage[i].fZeroed       = false;
    765767        pVM->pgm.s.aLargeHandyPage[i].idPage        = NIL_GMM_PAGEID;
    766768        pVM->pgm.s.aLargeHandyPage[i].idSharedPage  = NIL_GMM_PAGEID;
  • trunk/src/VBox/VMM/VMMR3/PGMPhys.cpp

    r92248 r92326  
    44034403        {
    44044404            pReq->aPages[iPage].HCPhysGCPhys = GCPhys + (iPage << PAGE_SHIFT);
    4405             pReq->aPages[iPage].idPage = NIL_GMM_PAGEID;
     4405            pReq->aPages[iPage].fZeroed      = false;
     4406            pReq->aPages[iPage].idPage       = NIL_GMM_PAGEID;
    44064407            pReq->aPages[iPage].idSharedPage = NIL_GMM_PAGEID;
    44074408        }
     
    58405841        uint32_t idPage = pVM->pgm.s.aLargeHandyPage[0].idPage;
    58415842        RTHCPHYS HCPhys = pVM->pgm.s.aLargeHandyPage[0].HCPhysGCPhys;
    5842 
    5843         void *pv;
    5844 
    5845         /* Map the large page into our address space.
    5846          *
    5847          * Note: assuming that within the 2 MB range:
    5848          * - GCPhys + PAGE_SIZE = HCPhys + PAGE_SIZE (whole point of this exercise)
    5849          * - user space mapping is continuous as well
    5850          * - page id (GCPhys) + 1 = page id (GCPhys + PAGE_SIZE)
     5843        Assert(pVM->pgm.s.aLargeHandyPage[0].fZeroed);
     5844
     5845        /*
     5846         * Enter the pages into PGM.
    58515847         */
    5852         rc = pgmPhysPageMapByPageID(pVM, idPage, HCPhys, &pv);
    5853         AssertLogRelMsg(RT_SUCCESS(rc), ("idPage=%#x HCPhysGCPhys=%RHp rc=%Rrc\n", idPage, HCPhys, rc));
    5854 
    5855         if (RT_SUCCESS(rc))
    5856         {
     5848        STAM_PROFILE_START(&pVM->pgm.s.Stats.StatClearLargePage, b);
     5849        for (unsigned i = 0; i < _2M/PAGE_SIZE; i++)
     5850        {
     5851            PPGMPAGE pPage;
     5852            rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
     5853            AssertRC(rc);
     5854
     5855            Assert(PGM_PAGE_IS_ZERO(pPage));
     5856            STAM_COUNTER_INC(&pVM->pgm.s.Stats.StatRZPageReplaceZero);
     5857            pVM->pgm.s.cZeroPages--;
     5858
    58575859            /*
    5858              * Clear the pages.
     5860             * Do the PGMPAGE modifications.
    58595861             */
    5860             STAM_PROFILE_START(&pVM->pgm.s.Stats.StatClearLargePage, b);
    5861             for (unsigned i = 0; i < _2M/PAGE_SIZE; i++)
    5862             {
    5863                 ASMMemZeroPage(pv);
    5864 
    5865                 PPGMPAGE pPage;
    5866                 rc = pgmPhysGetPageEx(pVM, GCPhys, &pPage);
    5867                 AssertRC(rc);
    5868 
    5869                 Assert(PGM_PAGE_IS_ZERO(pPage));
    5870                 STAM_COUNTER_INC(&pVM->pgm.s.Stats.StatRZPageReplaceZero);
    5871                 pVM->pgm.s.cZeroPages--;
    5872 
    5873                 /*
    5874                  * Do the PGMPAGE modifications.
    5875                  */
    5876                 pVM->pgm.s.cPrivatePages++;
    5877                 PGM_PAGE_SET_HCPHYS(pVM, pPage, HCPhys);
    5878                 PGM_PAGE_SET_PAGEID(pVM, pPage, idPage);
    5879                 PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ALLOCATED);
    5880                 PGM_PAGE_SET_PDE_TYPE(pVM, pPage, PGM_PAGE_PDE_TYPE_PDE);
    5881                 PGM_PAGE_SET_PTE_INDEX(pVM, pPage, 0);
    5882                 PGM_PAGE_SET_TRACKING(pVM, pPage, 0);
    5883 
    5884                 /* Somewhat dirty assumption that page ids are increasing. */
    5885                 idPage++;
    5886 
    5887                 HCPhys += PAGE_SIZE;
    5888                 GCPhys += PAGE_SIZE;
    5889 
    5890                 pv = (void *)((uintptr_t)pv + PAGE_SIZE);
    5891 
    5892                 Log3(("PGMR3PhysAllocateLargePage: idPage=%#x HCPhys=%RGp\n", idPage, HCPhys));
    5893             }
    5894             STAM_PROFILE_STOP(&pVM->pgm.s.Stats.StatClearLargePage, b);
    5895 
    5896             /* Flush all TLBs. */
    5897             PGM_INVL_ALL_VCPU_TLBS(pVM);
    5898             pgmPhysInvalidatePageMapTLB(pVM);
    5899         }
     5862            pVM->pgm.s.cPrivatePages++;
     5863            PGM_PAGE_SET_HCPHYS(pVM, pPage, HCPhys);
     5864            PGM_PAGE_SET_PAGEID(pVM, pPage, idPage);
     5865            PGM_PAGE_SET_STATE(pVM, pPage, PGM_PAGE_STATE_ALLOCATED);
     5866            PGM_PAGE_SET_PDE_TYPE(pVM, pPage, PGM_PAGE_PDE_TYPE_PDE);
     5867            PGM_PAGE_SET_PTE_INDEX(pVM, pPage, 0);
     5868            PGM_PAGE_SET_TRACKING(pVM, pPage, 0);
     5869
     5870            /* Somewhat dirty assumption that page ids are increasing. */
     5871            idPage++;
     5872
     5873            HCPhys += PAGE_SIZE;
     5874            GCPhys += PAGE_SIZE;
     5875            Log3(("PGMR3PhysAllocateLargePage: idPage=%#x HCPhys=%RGp\n", idPage, HCPhys));
     5876        }
     5877        STAM_PROFILE_STOP(&pVM->pgm.s.Stats.StatClearLargePage, b);
     5878
     5879        /* Flush all TLBs. */
     5880        PGM_INVL_ALL_VCPU_TLBS(pVM);
     5881        pgmPhysInvalidatePageMapTLB(pVM);
     5882
    59005883        pVM->pgm.s.cLargeHandyPages = 0;
    59015884    }
     
    60035986        {
    60045987            PGMMPAGEDESC pPage = &pVM->pgm.s.aHandyPages[iClear];
    6005             void *pv;
    6006             rc = pgmPhysPageMapByPageID(pVM, pPage->idPage, pPage->HCPhysGCPhys, &pv);
    6007             AssertLogRelMsgBreak(RT_SUCCESS(rc),
    6008                                  ("%u/%u: idPage=%#x HCPhysGCPhys=%RHp rc=%Rrc\n",
    6009                                   iClear, pVM->pgm.s.cHandyPages, pPage->idPage, pPage->HCPhysGCPhys, rc));
    6010             ASMMemZeroPage(pv);
     5988            if (!pPage->fZeroed)
     5989            {
     5990                void *pv;
     5991                rc = pgmPhysPageMapByPageID(pVM, pPage->idPage, pPage->HCPhysGCPhys, &pv);
     5992                AssertLogRelMsgBreak(RT_SUCCESS(rc),
     5993                                     ("%u/%u: idPage=%#x HCPhysGCPhys=%RHp rc=%Rrc\n",
     5994                                      iClear, pVM->pgm.s.cHandyPages, pPage->idPage, pPage->HCPhysGCPhys, rc));
     5995                ASMMemZeroPage(pv);
     5996                pPage->fZeroed = true;
     5997            }
     5998#ifdef VBOX_STRICT
     5999            else
     6000            {
     6001                void *pv;
     6002                rc = pgmPhysPageMapByPageID(pVM, pPage->idPage, pPage->HCPhysGCPhys, &pv);
     6003                AssertLogRelMsgBreak(RT_SUCCESS(rc),
     6004                                     ("%u/%u: idPage=%#x HCPhysGCPhys=%RHp rc=%Rrc\n",
     6005                                      iClear, pVM->pgm.s.cHandyPages, pPage->idPage, pPage->HCPhysGCPhys, rc));
     6006                Assert(ASMMemIsZeroPage(pv));
     6007            }
     6008#endif
    60116009            iClear++;
    60126010            Log3(("PGMR3PhysAllocateHandyPages: idPage=%#x HCPhys=%RGp\n", pPage->idPage, pPage->HCPhysGCPhys));
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