VirtualBox

Ignore:
Timestamp:
Jun 5, 2024 12:59:51 AM (8 months ago)
Author:
vboxsync
Message:

VMM/PGM: Refactored RAM ranges, MMIO2 ranges and ROM ranges and added MMIO ranges (to PGM) so we can safely access RAM ranges at runtime w/o fear of them ever being freed up. It is now only possible to create these during VM creation and loading, and they will live till VM destruction (except for MMIO2 which could be destroyed during loading (PCNet fun)). The lookup handling is by table instead of pointer tree. No more ring-0 pointers in shared data. bugref:10687 bugref:10093

File:
1 edited

Legend:

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

    r100966 r104840  
    8888    AssertCompile(sizeof(pGVM->pgmr0.s) <= sizeof(pGVM->pgmr0.padding));
    8989
     90    /* Set the RAM range memory handles to NIL. */
     91    AssertCompile(RT_ELEMENTS(pGVM->pgmr0.s.acRamRangePages)   == RT_ELEMENTS(pGVM->pgmr0.s.apRamRanges));
     92    AssertCompile(RT_ELEMENTS(pGVM->pgmr0.s.ahRamRangeMemObjs) == RT_ELEMENTS(pGVM->pgmr0.s.apRamRanges));
     93    AssertCompile(RT_ELEMENTS(pGVM->pgmr0.s.ahRamRangeMapObjs) == RT_ELEMENTS(pGVM->pgmr0.s.apRamRanges));
     94    for (uint32_t i = 0; i < RT_ELEMENTS(pGVM->pgmr0.s.ahRamRangeMemObjs); i++)
     95    {
     96        pGVM->pgmr0.s.ahRamRangeMemObjs[i] = NIL_RTR0MEMOBJ;
     97        pGVM->pgmr0.s.ahRamRangeMapObjs[i] = NIL_RTR0MEMOBJ;
     98    }
     99    Assert(pGVM->pgmr0.s.idRamRangeMax == 0); /* the structure is ZERO'ed */
     100
     101    /* Set the MMIO2 range memory handles to NIL. */
     102    AssertCompile(RT_ELEMENTS(pGVM->pgmr0.s.ahMmio2MemObjs) == RT_ELEMENTS(pGVM->pgmr0.s.apMmio2RamRanges));
     103    AssertCompile(RT_ELEMENTS(pGVM->pgmr0.s.ahMmio2MapObjs) == RT_ELEMENTS(pGVM->pgmr0.s.apMmio2RamRanges));
     104    for (uint32_t i = 0; i < RT_ELEMENTS(pGVM->pgmr0.s.ahMmio2MemObjs); i++)
     105    {
     106        pGVM->pgmr0.s.ahMmio2MemObjs[i] = NIL_RTR0MEMOBJ;
     107        pGVM->pgmr0.s.ahMmio2MapObjs[i] = NIL_RTR0MEMOBJ;
     108    }
     109
     110    /* Set the ROM range memory handles to NIL. */
     111    AssertCompile(RT_ELEMENTS(pGVM->pgmr0.s.ahRomRangeMemObjs) == RT_ELEMENTS(pGVM->pgmr0.s.apRomRanges));
     112    AssertCompile(RT_ELEMENTS(pGVM->pgmr0.s.ahRomRangeMapObjs) == RT_ELEMENTS(pGVM->pgmr0.s.apRomRanges));
     113    for (uint32_t i = 0; i < RT_ELEMENTS(pGVM->pgmr0.s.ahRomRangeMemObjs); i++)
     114    {
     115        pGVM->pgmr0.s.ahRomRangeMemObjs[i] = NIL_RTR0MEMOBJ;
     116        pGVM->pgmr0.s.ahRomRangeMapObjs[i] = NIL_RTR0MEMOBJ;
     117    }
     118
     119    /* Set the physical handler related memory handles to NIL. */
    90120    AssertCompile(RT_ELEMENTS(pGVM->pgmr0.s.ahPoolMemObjs) == RT_ELEMENTS(pGVM->pgmr0.s.ahPoolMapObjs));
    91121    for (uint32_t i = 0; i < RT_ELEMENTS(pGVM->pgmr0.s.ahPoolMemObjs); i++)
     
    278308        AssertRC(rc);
    279309        pGVM->pgmr0.s.hPhysHandlerMemObj = NIL_RTR0MEMOBJ;
     310    }
     311
     312    for (uint32_t i = 0; i < RT_ELEMENTS(pGVM->pgmr0.s.ahRomRangeMemObjs); i++)
     313    {
     314        if (pGVM->pgmr0.s.ahRomRangeMapObjs[i] != NIL_RTR0MEMOBJ)
     315        {
     316            int rc = RTR0MemObjFree(pGVM->pgmr0.s.ahRomRangeMapObjs[i], true /*fFreeMappings*/);
     317            AssertRC(rc);
     318            pGVM->pgmr0.s.ahRomRangeMapObjs[i] = NIL_RTR0MEMOBJ;
     319        }
     320
     321        if (pGVM->pgmr0.s.ahRomRangeMemObjs[i] != NIL_RTR0MEMOBJ)
     322        {
     323            int rc = RTR0MemObjFree(pGVM->pgmr0.s.ahRomRangeMemObjs[i], true /*fFreeMappings*/);
     324            AssertRC(rc);
     325            pGVM->pgmr0.s.ahRomRangeMemObjs[i] = NIL_RTR0MEMOBJ;
     326        }
     327    }
     328
     329    for (uint32_t i = 0; i < RT_ELEMENTS(pGVM->pgmr0.s.ahMmio2MemObjs); i++)
     330    {
     331        if (pGVM->pgmr0.s.ahMmio2MapObjs[i] != NIL_RTR0MEMOBJ)
     332        {
     333            int rc = RTR0MemObjFree(pGVM->pgmr0.s.ahMmio2MapObjs[i], true /*fFreeMappings*/);
     334            AssertRC(rc);
     335            pGVM->pgmr0.s.ahMmio2MapObjs[i] = NIL_RTR0MEMOBJ;
     336        }
     337
     338        if (pGVM->pgmr0.s.ahMmio2MemObjs[i] != NIL_RTR0MEMOBJ)
     339        {
     340            int rc = RTR0MemObjFree(pGVM->pgmr0.s.ahMmio2MemObjs[i], true /*fFreeMappings*/);
     341            AssertRC(rc);
     342            pGVM->pgmr0.s.ahMmio2MemObjs[i] = NIL_RTR0MEMOBJ;
     343        }
     344    }
     345
     346    uint32_t const cRangesMax = RT_MIN(pGVM->pgmr0.s.idRamRangeMax, RT_ELEMENTS(pGVM->pgmr0.s.ahRamRangeMemObjs) - 1U) + 1U;
     347    for (uint32_t i = 0; i < cRangesMax; i++)
     348    {
     349        if (pGVM->pgmr0.s.ahRamRangeMapObjs[i] != NIL_RTR0MEMOBJ)
     350        {
     351            int rc = RTR0MemObjFree(pGVM->pgmr0.s.ahRamRangeMapObjs[i], true /*fFreeMappings*/);
     352            AssertRC(rc);
     353            pGVM->pgmr0.s.ahRamRangeMapObjs[i] = NIL_RTR0MEMOBJ;
     354        }
     355
     356        if (pGVM->pgmr0.s.ahRamRangeMemObjs[i] != NIL_RTR0MEMOBJ)
     357        {
     358            int rc = RTR0MemObjFree(pGVM->pgmr0.s.ahRamRangeMemObjs[i], true /*fFreeMappings*/);
     359            AssertRC(rc);
     360            pGVM->pgmr0.s.ahRamRangeMemObjs[i] = NIL_RTR0MEMOBJ;
     361        }
    280362    }
    281363
     
    710792 * @param   hMmio2      Handle to look up.
    711793 */
    712 DECLINLINE(PPGMREGMMIO2RANGE) pgmR0PhysMmio2Find(PGVM pGVM, PPDMDEVINS pDevIns, PGMMMIO2HANDLE hMmio2)
     794DECLINLINE(int32_t) pgmR0PhysMmio2ValidateHandle(PGVM pGVM, PPDMDEVINS pDevIns, PGMMMIO2HANDLE hMmio2)
    713795{
    714796    /*
     
    716798     * ring-3 pointers and this probably will require some kind of refactoring anyway.
    717799     */
    718     if (hMmio2 <= RT_ELEMENTS(pGVM->pgm.s.apMmio2RangesR0) && hMmio2 != 0)
    719     {
    720         PPGMREGMMIO2RANGE pCur = pGVM->pgm.s.apMmio2RangesR0[hMmio2 - 1];
    721         if (pCur && pCur->pDevInsR3 == pDevIns->pDevInsForR3)
    722         {
    723             Assert(pCur->idMmio2 == hMmio2);
    724             return pCur;
    725         }
    726         Assert(!pCur);
    727     }
    728     return NULL;
     800    AssertReturn(hMmio2 <= RT_ELEMENTS(pGVM->pgm.s.aMmio2Ranges) && hMmio2 != 0, VERR_INVALID_HANDLE);
     801    uint32_t const idx = hMmio2 - 1U;
     802    AssertReturn(pGVM->pgm.s.aMmio2Ranges[idx].pDevInsR3 == pDevIns->pDevInsForR3, VERR_NOT_OWNER);
     803    AssertReturn(pGVM->pgm.s.aMmio2Ranges[idx].idMmio2 == hMmio2, VERR_INVALID_HANDLE);
     804    AssertReturn(pGVM->pgmr0.s.ahMmio2MapObjs[idx] != NIL_RTR0MEMOBJ, VERR_INVALID_HANDLE);
     805    AssertReturn(pGVM->pgmr0.s.acMmio2RangePages[idx] != 0, VERR_INVALID_HANDLE);
     806    return idx;
    729807}
    730808
     
    744822                                            size_t offSub, size_t cbSub, void **ppvMapping)
    745823{
     824    *ppvMapping = NULL;
    746825    AssertReturn(!(offSub & HOST_PAGE_OFFSET_MASK), VERR_UNSUPPORTED_ALIGNMENT);
    747826    AssertReturn(!(cbSub  & HOST_PAGE_OFFSET_MASK), VERR_UNSUPPORTED_ALIGNMENT);
    748827
    749828    /*
    750      * Translate hRegion into a range pointer.
    751      */
    752     PPGMREGMMIO2RANGE pFirstRegMmio = pgmR0PhysMmio2Find(pGVM, pDevIns, hMmio2);
    753     AssertReturn(pFirstRegMmio, VERR_NOT_FOUND);
     829     * Validate and translate hMmio2 into an MMIO2 index.
     830     */
     831    uint32_t const   idxFirst = pgmR0PhysMmio2ValidateHandle(pGVM, pDevIns, hMmio2);
     832    AssertReturn((int32_t)idxFirst >= 0, (int32_t)idxFirst);
     833
    754834#ifndef VBOX_WITH_LINEAR_HOST_PHYS_MEM
    755     uint8_t * const pvR0  = (uint8_t *)pFirstRegMmio->pvR0;
     835    uint8_t * const  pbR0     = pGVM->pgmr0.s.apbMmio2Backing[idxFirst];
    756836#else
    757     RTR3PTR const  pvR3   = pFirstRegMmio->pvR3;
     837    RTR0MEMOBJ const hMemObj  = pGVM->pgmr0.s.ahMmio2MemObjs[idxFirst];
    758838#endif
    759     RTGCPHYS const cbReal = pFirstRegMmio->cbReal;
    760     pFirstRegMmio = NULL;
     839    RTGCPHYS const   cbReal   = (RTGCPHYS)pGVM->pgmr0.s.acMmio2RangePages[idxFirst] << GUEST_PAGE_SHIFT;
    761840    ASMCompilerBarrier();
    762841
     
    767846        AssertReturn(cbSub < cbReal && cbSub + offSub <= cbReal, VERR_OUT_OF_RANGE);
    768847
    769     /*
    770      * Do the mapping.
    771      */
    772848#ifndef VBOX_WITH_LINEAR_HOST_PHYS_MEM
    773     AssertPtr(pvR0);
    774     *ppvMapping = pvR0 + offSub;
     849    /*
     850     * Just return the address of the existing ring-0 mapping.
     851     */
     852    AssertPtrReturn(pbR0, VERR_INTERNAL_ERROR_4);
     853    *ppvMapping = &pbR0[offSub];
    775854    return VINF_SUCCESS;
    776855#else
    777     return SUPR0PageMapKernel(pGVM->pSession, pvR3, (uint32_t)offSub, (uint32_t)cbSub, 0 /*fFlags*/, ppvMapping);
     856    /*
     857     * Call IPRT to do the mapping.  Cleanup is done indirectly by telling
     858     * RTR0MemObjFree to include mappings.  It can only be done once, so no
     859     * risk of excessive mapping leaks.
     860     */
     861    RTR0MEMOBJ hMapObj;
     862    int rc = RTR0MemObjMapKernelEx(&hMapObj, hMemObj, (void *)-1, 0, RTMEM_PROT_READ | RTMEM_PROT_WRITE, offSub, cbSub);
     863    if (RT_SUCCESS(rc))
     864        *ppvMapping = RTR0MemObjAddress(hMapObj);
     865    return rc;
    778866#endif
    779867}
     
    10581146
    10591147#ifdef VBOX_WITH_PCI_PASSTHROUGH
     1148# error fixme
    10601149    if (pGVM->pgm.s.fPciPassthrough)
    10611150    {
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