VirtualBox

Changeset 100360 in vbox


Ignore:
Timestamp:
Jul 4, 2023 7:09:24 AM (17 months ago)
Author:
vboxsync
Message:

Additions/VBoxGuest/VBoxGuestR0LibPhysHeap: Make use of the RTR0MemObjContAlloc() API and support allocating memory above 4GiB, bugref:10457

Location:
trunk/src/VBox/Additions/common/VBoxGuest/lib
Files:
4 edited

Legend:

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

    r100267 r100360  
    117117                    g_vbgldata.pMmioReq      = PortInfo.u.Out.pMmioReq;
    118118
    119                     rc = VbglR0PhysHeapInit(g_vbgldata.pMmioReq == NULL /*fAlloc32BitAddr*/);
     119                    /*
     120                     * Initialize the physical heap, only allocate memory below 4GiB if the new
     121                     * MMIO interface isn't available and we are using a 32-bit OUT instruction to pass a block
     122                     * physical address to the host.
     123                     */
     124                    rc = VbglR0PhysHeapInit(g_vbgldata.pMmioReq == NULL ? _4G - 1 : NIL_RTHCPHYS /*HCPhysMax*/);
    120125                    if (RT_SUCCESS(rc))
    121126                    {
     
    208213        g_vbgldata.pMmioReq      = pMmioReq;
    209214
    210         rc = VbglR0PhysHeapInit(pMmioReq == NULL /*fAlloc32BitAddr*/);
     215        /*
     216         * Initialize the physical heap, only allocate memory below 4GiB if the new
     217         * MMIO interface isn't available and we are using a 32-bit OUT instruction to pass a block
     218         * physical address to the host.
     219         */
     220        rc = VbglR0PhysHeapInit(g_vbgldata.pMmioReq == NULL ? _4G - 1 : NIL_RTHCPHYS /*HCPhysMax*/);
    211221        if (RT_SUCCESS(rc))
    212222        {
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibInternal.h

    r100267 r100360  
    152152    /** Head of the chunk list. */
    153153    VBGLPHYSHEAPCHUNK      *pChunkHead;
    154     /** Flag whether all allocations should be below 4GiB to fit into
    155      * a 32-bit address. */
    156     bool                   fAlloc32BitAddr;
     154    /** Maximum physical address allowed for allocations, inclusive. */
     155    RTHCPHYS                HCPhysMax;
    157156    /** @} */
    158157
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/VBoxGuestR0LibPhysHeap.cpp

    r100267 r100360  
    157157 * linker cannot eliminiate functions within objects.  Only drawback is that
    158158 * RTR0MemObjAllocCont requires another heap allocation for the handle.
    159  */
    160 #if defined(DOXYGEN_RUNNING) || (!defined(IN_TESTCASE) && 0)
    161 # define VBGL_PH_USE_MEMOBJ
    162 #endif
     159 *
     160 * Update: Just enable it everywhere so we can more easily use memory above 4G.
     161 */
     162#define VBGL_PH_USE_MEMOBJ
    163163
    164164
     
    233233    /** The allocation handle. */
    234234    RTR0MEMOBJ          hMemObj;
    235 #elif ARCH_BITS == 64
     235#endif
     236#if ARCH_BITS == 64
    236237    /** Pad the size up to 64 bytes. */
    237238# ifdef VBGL_PH_USE_MEMOBJ
     
    532533    cbChunk = RT_ALIGN_32(cbChunk, VBGL_PH_CHUNKSIZE);
    533534
    534     if (g_vbgldata.fAlloc32BitAddr)
    535     {
    536         /*
    537          * This function allocates physical contiguous memory below 4 GB.  This 4GB
    538          * limitation stems from using a 32-bit OUT instruction to pass a block
    539          * physical address to the host.
    540          */
    541535#ifdef VBGL_PH_USE_MEMOBJ
    542         rc = RTR0MemObjAllocCont(&hMemObj, cbChunk, false /*fExecutable*/);
    543         pChunk = (VBGLPHYSHEAPCHUNK *)(RT_SUCCESS(rc) ? RTR0MemObjAddress(hMemObj) : NULL);
     536    rc = RTR0MemObjAllocCont(&hMemObj, cbChunk, g_vbgldata.HCPhysMax, false /*fExecutable*/);
     537    pChunk = (VBGLPHYSHEAPCHUNK *)(RT_SUCCESS(rc) ? RTR0MemObjAddress(hMemObj) : NULL);
     538    PhysAddr = RT_SUCCESS(rc) ? (RTCCPHYS)RTR0MemObjGetPagePhysAddr(hMemObj, 0 /*iPage*/) : NIL_RTCCPHYS;
    544539#else
    545         pChunk = (VBGLPHYSHEAPCHUNK *)RTMemContAlloc(&PhysAddr, cbChunk);
    546 #endif
    547     }
    548     else
    549     {
    550         /** @todo Provide appropriate memory API. */
    551 #ifdef VBGL_PH_USE_MEMOBJ
    552         rc = RTR0MemObjAllocCont(&hMemObj, cbChunk, false /*fExecutable*/);
    553         pChunk = (VBGLPHYSHEAPCHUNK *)(RT_SUCCESS(rc) ? RTR0MemObjAddress(hMemObj) : NULL);
    554 #else
    555         pChunk = (VBGLPHYSHEAPCHUNK *)RTMemContAlloc(&PhysAddr, cbChunk);
    556 #endif
    557     }
     540    pChunk = (VBGLPHYSHEAPCHUNK *)RTMemContAlloc(&PhysAddr, cbChunk);
     541#endif
    558542    if (!pChunk)
    559543    {
     
    567551                cbChunk = RT_ALIGN_32(cbChunk, PAGE_SIZE);
    568552#ifdef VBGL_PH_USE_MEMOBJ
    569                 rc = RTR0MemObjAllocCont(&hMemObj, cbChunk, false /*fExecutable*/);
     553                rc = RTR0MemObjAllocCont(&hMemObj, cbChunk, g_vbgldata.HCPhysMax, false /*fExecutable*/);
    570554                pChunk = (VBGLPHYSHEAPCHUNK *)(RT_SUCCESS(rc) ? RTR0MemObjAddress(hMemObj) : NULL);
     555                PhysAddr = RT_SUCCESS(rc) ? (RTCCPHYS)RTR0MemObjGetPagePhysAddr(hMemObj, 0 /*iPage*/) : NIL_RTCCPHYS;
    571556#else
    572557                pChunk = (VBGLPHYSHEAPCHUNK *)RTMemContAlloc(&PhysAddr, cbChunk);
     
    578563        VBGLPHYSHEAPCHUNK     *pOldHeadChunk;
    579564        VBGLPHYSHEAPFREEBLOCK *pBlock;
    580         AssertRelease(   !g_vbgldata.fAlloc32BitAddr
     565        AssertRelease(   g_vbgldata.HCPhysMax == NIL_RTHCPHYS
    581566                      || (PhysAddr < _4G && PhysAddr + cbChunk <= _4G));
    582567
     
    11831168#endif /* IN_TESTCASE */
    11841169
    1185 DECLR0VBGL(int) VbglR0PhysHeapInit(bool fAlloc32BitAddr)
    1186 {
    1187     g_vbgldata.fAlloc32BitAddr = fAlloc32BitAddr;
    1188     g_vbgldata.hMtxHeap        = NIL_RTSEMFASTMUTEX;
     1170DECLR0VBGL(int) VbglR0PhysHeapInit(RTHCPHYS HCPhysMax)
     1171{
     1172    g_vbgldata.HCPhysMax = HCPhysMax;
     1173    g_vbgldata.hMtxHeap  = NIL_RTSEMFASTMUTEX;
    11891174
    11901175    /* Allocate the first chunk of the heap. */
  • trunk/src/VBox/Additions/common/VBoxGuest/lib/testcase/tstVbglR0PhysHeap-1.cpp

    r100270 r100360  
    5353#define IN_TESTCASE
    5454#define IN_RING0 /* pretend we're in ring-0 so we get access to the functions */
     55#include <iprt/memobj.h>
    5556#include "../VBoxGuestR0LibInternal.h"
    5657
     
    6667
    6768
     69typedef struct TSTMEMOBJ
     70{
     71    size_t cb;
     72} TSTMEMOBJ;
     73typedef TSTMEMOBJ *PTSTMEMOBJ;
     74
     75
    6876/*********************************************************************************************************************************
    6977*   Global Variables                                                                                                             *
     
    7583
    7684/** Drop-in replacement for RTMemContAlloc   */
    77 static void *tstMemContAlloc(PRTCCPHYS pPhys, size_t cb)
    78 {
     85static int tstMemObjContAllocTag(PRTR0MEMOBJ pMemObj, size_t cb, RTHCPHYS PhysHighest, bool fExecutable, const char *pszTag)
     86{
     87    RT_NOREF(pszTag, PhysHighest, fExecutable);
     88
    7989    RTTESTI_CHECK(cb > 0);
    8090
     
    8292    if (g_cChunks < TST_MAX_CHUNKS)
    8393    {
    84         void *pvRet = RTMemAlloc(cb);
    85         if (pvRet)
    86         {
     94        PTSTMEMOBJ pMem = (PTSTMEMOBJ)RTMemAlloc(sizeof(TSTMEMOBJ) + cb);
     95        if (pMem)
     96        {
     97            pMem->cb = cb;
     98
    8799            g_cChunks++;
    88100            g_cbChunks += cb;
    89             *pPhys = (uint32_t)(uintptr_t)pvRet ^ (UINT32_C(0xf0f0f0f0) & ~(uint32_t)PAGE_OFFSET_MASK);
    90 
    91             /* Avoid problematic values that won't happen in real life:  */
    92             if (!*pPhys)
    93                 *pPhys = 4U << PAGE_SHIFT;
    94             if (UINT32_MAX - *pPhys < cb)
    95                 *pPhys -= RT_ALIGN_32(cb, PAGE_SIZE);
    96 
    97             return pvRet;
    98         }
    99     }
    100 
    101     *pPhys = NIL_RTCCPHYS;
    102     return NULL;
    103 }
    104 
    105 
    106 /** Drop-in replacement for RTMemContFree   */
    107 static void tstMemContFree(void *pv, size_t cb)
    108 {
    109     RTTESTI_CHECK(RT_VALID_PTR(pv));
    110     RTTESTI_CHECK(cb > 0);
     101            *pMemObj = (RTR0MEMOBJ)pMem;
     102            return VINF_SUCCESS;
     103        }
     104    }
     105
     106    return VERR_NO_MEMORY;
     107}
     108
     109
     110/** Drop-in replacement for RTR0MemObjAddress   */
     111static void *tstMemObjAddress(RTR0MEMOBJ hMemObj)
     112{
     113    return (void *)((PTSTMEMOBJ)hMemObj + 1);
     114}
     115
     116
     117/** Drop-in replacement for RTR0MemObjGetPagePhysAddr   */
     118static RTHCPHYS tstMemObjGetPagePhysAddr(RTR0MEMOBJ hMemObj, uint32_t iPage)
     119{
     120    RTTESTI_CHECK(iPage == 0);
     121
     122    PTSTMEMOBJ pMemObj = (PTSTMEMOBJ)hMemObj;
     123    uintptr_t PtrMem = (uintptr_t)(pMemObj + 1);
     124    RTHCPHYS Phys = (uint32_t)(uintptr_t)PtrMem ^ (UINT32_C(0xf0f0f0f0) & ~(uint32_t)PAGE_OFFSET_MASK);
     125
     126    /* Avoid problematic values that won't happen in real life:  */
     127    if (!Phys)
     128        Phys = 4U << PAGE_SHIFT;
     129    if (UINT32_MAX - Phys < pMemObj->cb)
     130        Phys -= RT_ALIGN_32(pMemObj->cb, PAGE_SIZE);
     131
     132    return Phys;
     133}
     134
     135
     136/** Drop-in replacement for RTR0MemObjFree   */
     137static void tstMemObjFree(RTR0MEMOBJ hMemObj, bool fFreeMappings)
     138{
     139    RT_NOREF(fFreeMappings);
     140
     141    PTSTMEMOBJ pMemObj = (PTSTMEMOBJ)hMemObj;
     142    RTTESTI_CHECK(RT_VALID_PTR(pMemObj));
     143    RTTESTI_CHECK(pMemObj->cb > 0);
    111144    RTTESTI_CHECK(g_cChunks > 0);
    112     RTMemFree(pv);
    113145    g_cChunks--;
    114     g_cbChunks -= cb;
    115 }
    116 
    117 
    118 #define RTMemContAlloc  tstMemContAlloc
    119 #define RTMemContFree   tstMemContFree
     146    g_cbChunks -= pMemObj->cb;
     147    RTMemFree(pMemObj);
     148}
     149
     150
     151#define RTR0MemObjAllocContTag      tstMemObjContAllocTag
     152#define RTR0MemObjAddress           tstMemObjAddress
     153#define RTR0MemObjGetPagePhysAddr   tstMemObjGetPagePhysAddr
     154#define RTR0MemObjFree              tstMemObjFree
    120155#include "../VBoxGuestR0LibPhysHeap.cpp"
    121156
     
    178213     */
    179214    RTTestSub(hTest, "Basics");
    180     RTTESTI_CHECK_RC(rc = VbglR0PhysHeapInit(true /*fAlloc32BitAddr*/), VINF_SUCCESS);
     215    RTTESTI_CHECK_RC(rc = VbglR0PhysHeapInit(NIL_RTHCPHYS), VINF_SUCCESS);
    181216    if (RT_FAILURE(rc))
    182217        return RTTestSummaryAndDestroy(hTest);
     
    288323     */
    289324    RTTestSub(hTest, "Random Test");
    290     RTTESTI_CHECK_RC(rc = VbglR0PhysHeapInit(true /*fAlloc32BitAddr*/), VINF_SUCCESS);
     325    RTTESTI_CHECK_RC(rc = VbglR0PhysHeapInit(NIL_RTHCPHYS), VINF_SUCCESS);
    291326    if (RT_FAILURE(rc))
    292327        return RTTestSummaryAndDestroy(hTest);
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