VirtualBox

Ignore:
Timestamp:
Mar 20, 2022 2:04:30 AM (3 years ago)
Author:
vboxsync
Message:

VbglR0PhysHeapAlloc: Addressed a couple of issues in vbglPhysHeapChunkAlloc and align allocations according to the pointer size. bugref:10188

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibPhysHeap.cpp

    r93115 r94314  
    296296}
    297297
    298 static VBGLPHYSHEAPBLOCK *vbglPhysHeapChunkAlloc (uint32_t cbSize)
    299 {
    300     RTCCPHYS physAddr;
     298static VBGLPHYSHEAPBLOCK *vbglPhysHeapChunkAlloc(uint32_t cbMinBlock)
     299{
     300    RTCCPHYS           PhysAddr = NIL_RTHCPHYS;
    301301    VBGLPHYSHEAPCHUNK *pChunk;
    302     VBGLPHYSHEAPBLOCK *pBlock;
    303     VBGL_PH_dprintf(("Allocating new chunk of size %d\n", cbSize));
    304 
    305     /* Compute chunk size to allocate */
    306     if (cbSize < VBGL_PH_CHUNKSIZE)
    307     {
    308         /* Includes case of block size 0 during initialization */
    309         cbSize = VBGL_PH_CHUNKSIZE;
    310     }
    311     else
    312     {
    313         /* Round up to next chunk size, which must be power of 2 */
    314         cbSize = (cbSize + (VBGL_PH_CHUNKSIZE - 1)) & ~(VBGL_PH_CHUNKSIZE - 1);
    315     }
    316 
    317     physAddr = 0;
    318     /* This function allocates physical contiguous memory (below 4GB) according to the IPRT docs.
    319      * Address < 4G is required for the port IO.
    320      */
    321     pChunk = (VBGLPHYSHEAPCHUNK *)RTMemContAlloc (&physAddr, cbSize);
    322 
    323     if (!pChunk)
    324     {
    325         LogRel(("vbglPhysHeapChunkAlloc: failed to alloc %u contiguous bytes.\n", cbSize));
    326         return NULL;
    327     }
    328 
    329     AssertRelease(physAddr < _4G && physAddr + cbSize <= _4G);
    330 
    331     pChunk->u32Signature     = VBGL_PH_CHUNKSIGNATURE;
    332     pChunk->cbSize           = cbSize;
    333     pChunk->physAddr         = (uint32_t)physAddr;
    334     pChunk->cAllocatedBlocks = 0;
    335     pChunk->pNext            = g_vbgldata.pChunkHead;
    336     pChunk->pPrev            = NULL;
    337 
    338     /* Initialize the free block, which now occupies entire chunk. */
    339     pBlock = (VBGLPHYSHEAPBLOCK *)((char *)pChunk + sizeof (VBGLPHYSHEAPCHUNK));
    340 
    341     vbglPhysHeapInitBlock (pBlock, pChunk, cbSize - sizeof (VBGLPHYSHEAPCHUNK) - sizeof (VBGLPHYSHEAPBLOCK));
    342 
    343     vbglPhysHeapInsertBlock (NULL, pBlock);
    344 
    345     g_vbgldata.pChunkHead = pChunk;
    346 
    347     VBGL_PH_dprintf(("Allocated chunk %p, block = %p size=%x\n", pChunk, pBlock, cbSize));
    348 
    349     return pBlock;
     302    uint32_t           cbChunk;
     303    VBGL_PH_dprintf(("Allocating new chunk for %#x byte allocation\n", cbMinBlock));
     304    AssertReturn(cbMinBlock < _128M, NULL); /* paranoia */
     305
     306    /* Compute the size of the new chunk, rounding up to next chunk size,
     307       which must be power of 2. */
     308    Assert(RT_IS_POWER_OF_TWO(VBGL_PH_CHUNKSIZE));
     309    cbChunk = cbMinBlock + sizeof(VBGLPHYSHEAPCHUNK) + sizeof(VBGLPHYSHEAPBLOCK);
     310    cbChunk = RT_ALIGN_32(cbChunk, VBGL_PH_CHUNKSIZE);
     311
     312    /* This function allocates physical contiguous memory below 4 GB.  This 4GB
     313       limitation stems from using a 32-bit OUT instruction to pass a block
     314       physical address to the host. */
     315    pChunk = (VBGLPHYSHEAPCHUNK *)RTMemContAlloc(&PhysAddr, cbChunk);
     316    if (pChunk)
     317    {
     318        VBGLPHYSHEAPCHUNK *pOldHeadChunk;
     319        VBGLPHYSHEAPBLOCK *pBlock;
     320        AssertRelease(PhysAddr < _4G && PhysAddr + cbChunk <= _4G);
     321
     322        /* Init the new chunk. */
     323        pChunk->u32Signature     = VBGL_PH_CHUNKSIGNATURE;
     324        pChunk->cbSize           = cbChunk;
     325        pChunk->physAddr         = (uint32_t)PhysAddr;
     326        pChunk->cAllocatedBlocks = 0;
     327        pChunk->pNext            = NULL;
     328        pChunk->pPrev            = NULL;
     329
     330        /* Initialize the free block, which now occupies entire chunk. */
     331        pBlock = (VBGLPHYSHEAPBLOCK *)(pChunk + 1);
     332        vbglPhysHeapInitBlock(pBlock, pChunk, cbChunk - sizeof(VBGLPHYSHEAPCHUNK) - sizeof(VBGLPHYSHEAPBLOCK));
     333        vbglPhysHeapInsertBlock(NULL, pBlock);
     334
     335        /* Add the chunk to the list. */
     336        pOldHeadChunk = g_vbgldata.pChunkHead;
     337        pChunk->pNext = pOldHeadChunk;
     338        if (pOldHeadChunk)
     339            pOldHeadChunk->pPrev = pChunk;
     340        g_vbgldata.pChunkHead    = pChunk;
     341
     342        VBGL_PH_dprintf(("Allocated chunk %p LB %#x, block %p LB %#x\n", pChunk, cbChunk, pBlock, pBlock->cbDataSize));
     343        return pBlock;
     344    }
     345    LogRel(("vbglPhysHeapChunkAlloc: failed to alloc %u (%#x) contiguous bytes.\n", cbChunk, cbChunk));
     346    return NULL;
    350347}
    351348
     
    405402{
    406403    VBGLPHYSHEAPBLOCK *pBlock, *pIter;
    407     int rc = vbglPhysHeapEnter ();
    408 
     404    int rc;
     405
     406    /*
     407     * Align the size to a pointer size to avoid getting misaligned header pointers and whatnot.
     408     */
     409    cbSize = RT_ALIGN_32(cbSize, sizeof(void *));
     410
     411    rc = vbglPhysHeapEnter ();
    409412    if (RT_FAILURE(rc))
    410413        return NULL;
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