VirtualBox

Changeset 92202 in vbox


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

VMM/GMMR0: Tie down chunks to UID and don't cross such. bugref:10093

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMR0/GMMR0.cpp

    r91540 r92202  
    429429    /** The number of mappings.  (Chunk mtx.) */
    430430    uint16_t            cMappingsX;
    431     /** The mapping lock this chunk is using using.  UINT16_MAX if nobody is
    432      *  mapping or freeing anything.  (Giant mtx.) */
     431    /** The mapping lock this chunk is using using.  UINT8_MAX if nobody is mapping
     432     * or freeing anything.  (Giant mtx.) */
    433433    uint8_t volatile    iChunkMtx;
    434434    /** GMM_CHUNK_FLAGS_XXX. (Giant mtx.) */
     
    451451    /** The number of shared pages.  (Giant mtx.) */
    452452    uint16_t            cShared;
     453    /** The UID this chunk is associated with. */
     454    RTUID               uidOwner;
     455    uint32_t            u32Padding;
    453456    /** The pages.  (Giant mtx.) */
    454457    GMMPAGE             aPages[GMM_CHUNK_SIZE >> PAGE_SHIFT];
     
    22192222 * @param   hGVM        The affinity of the chunk. NIL_GVM_HANDLE for no
    22202223 *                      affinity.
     2224 * @param   pSession    Same as @a hGVM.
    22212225 * @param   fChunkFlags The chunk flags, GMM_CHUNK_FLAGS_XXX.
    22222226 * @param   ppChunk     Chunk address (out).  Optional.
     
    22262230 *          the success path.   On failure, no locks will be held.
    22272231 */
    2228 static int gmmR0RegisterChunk(PGMM pGMM, PGMMCHUNKFREESET pSet, RTR0MEMOBJ hMemObj, uint16_t hGVM, uint16_t fChunkFlags,
    2229                               PGMMCHUNK *ppChunk)
     2232static int gmmR0RegisterChunk(PGMM pGMM, PGMMCHUNKFREESET pSet, RTR0MEMOBJ hMemObj, uint16_t hGVM, PSUPDRVSESSION pSession,
     2233                              uint16_t fChunkFlags, PGMMCHUNK *ppChunk)
    22302234{
    22312235    Assert(pGMM->hMtxOwner != RTThreadNativeSelf());
     
    22782282        pChunk->iChunkMtx   = UINT8_MAX;
    22792283        pChunk->fFlags      = fChunkFlags;
     2284        pChunk->uidOwner    = pSession ? SUPR0GetSessionUid(pSession) : NIL_RTUID;
    22802285        for (unsigned iPage = 0; iPage < RT_ELEMENTS(pChunk->aPages) - 1; iPage++)
    22812286        {
     
    23722377         *        do as much work as possible without holding the giant lock. */
    23732378        PGMMCHUNK pChunk;
    2374         rc = gmmR0RegisterChunk(pGMM, pSet, hMemObj, pGVM->hSelf, 0 /*fChunkFlags*/, &pChunk);
     2379        rc = gmmR0RegisterChunk(pGMM, pSet, hMemObj, pGVM->hSelf, pGVM->pSession, 0 /*fChunkFlags*/, &pChunk);
    23752380        if (RT_SUCCESS(rc))
    23762381        {
     
    23962401 * @param   pSet        The set to pick from.
    23972402 * @param   pGVM        Pointer to the global VM structure.
     2403 * @param   uidSelf     The UID of the caller.
    23982404 * @param   iPage       The current page descriptor table index.
    23992405 * @param   cPages      The total number of pages to allocate.
    24002406 * @param   paPages     The page descriptor table (input + ouput).
    24012407 */
    2402 static uint32_t gmmR0AllocatePagesIndiscriminately(PGMMCHUNKFREESET pSet, PGVM pGVM,
     2408static uint32_t gmmR0AllocatePagesIndiscriminately(PGMMCHUNKFREESET pSet, PGVM pGVM, RTUID uidSelf,
    24032409                                                   uint32_t iPage, uint32_t cPages, PGMMPAGEDESC paPages)
    24042410{
     
    24102416        {
    24112417            PGMMCHUNK pNext = pChunk->pFreeNext;
    2412 
    2413             iPage = gmmR0AllocatePagesFromChunk(pChunk, pGVM->hSelf, iPage, cPages, paPages);
    2414             if (iPage >= cPages)
    2415                 return iPage;
     2418            if (   pChunk->uidOwner == uidSelf
     2419                || (   pChunk->cMappingsX == 0
     2420                    && pChunk->cFree == (GMM_CHUNK_SIZE >> PAGE_SHIFT)))
     2421            {
     2422                iPage = gmmR0AllocatePagesFromChunk(pChunk, pGVM->hSelf, iPage, cPages, paPages);
     2423                if (iPage >= cPages)
     2424                    return iPage;
     2425            }
    24162426
    24172427            pChunk = pNext;
     
    24282438 * @param   pSet        The set to pick from.
    24292439 * @param   pGVM        Pointer to the global VM structure.
     2440 * @param   uidSelf     The UID of the caller.
    24302441 * @param   iPage       The current page descriptor table index.
    24312442 * @param   cPages      The total number of pages to allocate.
    24322443 * @param   paPages     The page descriptor table (input + ouput).
    24332444 */
    2434 static uint32_t gmmR0AllocatePagesFromEmptyChunksOnSameNode(PGMMCHUNKFREESET pSet, PGVM pGVM,
     2445static uint32_t gmmR0AllocatePagesFromEmptyChunksOnSameNode(PGMMCHUNKFREESET pSet, PGVM pGVM, RTUID uidSelf,
    24352446                                                            uint32_t iPage, uint32_t cPages, PGMMPAGEDESC paPages)
    24362447{
     
    24432454            PGMMCHUNK pNext = pChunk->pFreeNext;
    24442455
    2445             if (pChunk->idNumaNode == idNumaNode)
     2456            if (   pChunk->idNumaNode == idNumaNode
     2457                && (   pChunk->uidOwner == uidSelf
     2458                    || pChunk->cMappingsX == 0))
    24462459            {
    2447                 pChunk->hGVM = pGVM->hSelf;
     2460                pChunk->hGVM     = pGVM->hSelf;
     2461                pChunk->uidOwner = uidSelf;
    24482462                iPage = gmmR0AllocatePagesFromChunk(pChunk, pGVM->hSelf, iPage, cPages, paPages);
    24492463                if (iPage >= cPages)
     
    24672481 * @param   pSet        The set to pick from.
    24682482 * @param   pGVM        Pointer to the global VM structure.
     2483 * @param   uidSelf     The UID of the caller.
    24692484 * @param   iPage       The current page descriptor table index.
    24702485 * @param   cPages      The total number of pages to allocate.
    24712486 * @param   paPages     The page descriptor table (input + ouput).
    24722487 */
    2473 static uint32_t gmmR0AllocatePagesFromSameNode(PGMMCHUNKFREESET pSet, PGVM pGVM,
     2488static uint32_t gmmR0AllocatePagesFromSameNode(PGMMCHUNKFREESET pSet, PGVM pGVM, RTUID const uidSelf,
    24742489                                               uint32_t iPage, uint32_t cPages, PGMMPAGEDESC paPages)
    24752490{
     
    24842499            PGMMCHUNK pNext = pChunk->pFreeNext;
    24852500
    2486             if (pChunk->idNumaNode == idNumaNode)
     2501            if (   pChunk->idNumaNode == idNumaNode
     2502                && pChunk->uidOwner   == uidSelf)
    24872503            {
    24882504                iPage = gmmR0AllocatePagesFromChunk(pChunk, pGVM->hSelf, iPage, cPages, paPages);
     
    27652781    else
    27662782    {
     2783        RTUID const uidSelf = SUPR0GetSessionUid(pGVM->pSession);
     2784
    27672785        /* Pick the most optimal pages first. */
    27682786        iPage = gmmR0AllocatePagesAssociatedWithVM(pGMM, pGVM, &pGMM->PrivateX, iPage, cPages, paPages);
     
    27742792            if (gmmR0ShouldAllocatePagesInOtherChunksBecauseOfLimits(pGVM))
    27752793            {
    2776                 iPage = gmmR0AllocatePagesFromSameNode(&pGMM->PrivateX, pGVM, iPage, cPages, paPages);
     2794                iPage = gmmR0AllocatePagesFromSameNode(&pGMM->PrivateX, pGVM, uidSelf, iPage, cPages, paPages);
    27772795                fTriedOnSameAlready = true;
    27782796            }
     
    27802798            /* Allocate memory from empty chunks. */
    27812799            if (iPage < cPages)
    2782                 iPage = gmmR0AllocatePagesFromEmptyChunksOnSameNode(&pGMM->PrivateX, pGVM, iPage, cPages, paPages);
     2800                iPage = gmmR0AllocatePagesFromEmptyChunksOnSameNode(&pGMM->PrivateX, pGVM, uidSelf, iPage, cPages, paPages);
    27832801
    27842802            /* Grab empty shared chunks. */
    27852803            if (iPage < cPages)
    2786                 iPage = gmmR0AllocatePagesFromEmptyChunksOnSameNode(&pGMM->Shared, pGVM, iPage, cPages, paPages);
     2804                iPage = gmmR0AllocatePagesFromEmptyChunksOnSameNode(&pGMM->Shared, pGVM, uidSelf, iPage, cPages, paPages);
    27872805
    27882806            /* If there is a lof of free pages spread around, try not waste
     
    27912809                && gmmR0ShouldAllocatePagesInOtherChunksBecauseOfLotsFree(pGMM))
    27922810            {
    2793                 iPage = gmmR0AllocatePagesFromSameNode(&pGMM->PrivateX, pGVM, iPage, cPages, paPages);
     2811                iPage = gmmR0AllocatePagesFromSameNode(&pGMM->PrivateX, pGVM, uidSelf, iPage, cPages, paPages);
    27942812                if (iPage < cPages)
    2795                     iPage = gmmR0AllocatePagesIndiscriminately(&pGMM->PrivateX, pGVM, iPage, cPages, paPages);
     2813                    iPage = gmmR0AllocatePagesIndiscriminately(&pGMM->PrivateX, pGVM, uidSelf, iPage, cPages, paPages);
    27962814            }
    27972815
     
    28052823                while (iPage < cPages && RT_SUCCESS(rc));
    28062824
     2825#if 0 /* We cannot mix chunks with different UIDs. */
    28072826                /* If the host is out of memory, take whatever we can get. */
    28082827                if (   (rc == VERR_NO_MEMORY || rc == VERR_NO_PHYS_MEMORY)
     
    28152834                    rc = VINF_SUCCESS;
    28162835                }
     2836#endif
    28172837            }
    28182838        }
     
    32453265            PGMMCHUNKFREESET pSet = pGMM->fBoundMemoryMode ? &pGVM->gmm.s.Private : &pGMM->PrivateX;
    32463266            PGMMCHUNK pChunk;
    3247             rc = gmmR0RegisterChunk(pGMM, pSet, hMemObj, pGVM->hSelf, GMM_CHUNK_FLAGS_LARGE_PAGE, &pChunk);
     3267            rc = gmmR0RegisterChunk(pGMM, pSet, hMemObj, pGVM->hSelf, pGVM->pSession, GMM_CHUNK_FLAGS_LARGE_PAGE, &pChunk);
    32483268            if (RT_SUCCESS(rc))
    32493269            {
     
    45204540    if (RT_SUCCESS(rc))
    45214541    {
    4522         rc = gmmR0RegisterChunk(pGMM, &pGVM->gmm.s.Private, hMemObj, pGVM->hSelf, GMM_CHUNK_FLAGS_SEEDED, NULL);
     4542        rc = gmmR0RegisterChunk(pGMM, &pGVM->gmm.s.Private, hMemObj, pGVM->hSelf, pGVM->pSession, GMM_CHUNK_FLAGS_SEEDED, NULL);
    45234543        if (RT_SUCCESS(rc))
    45244544            gmmR0MutexRelease(pGMM);
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