VirtualBox

Ignore:
Timestamp:
Jun 14, 2011 6:13:48 PM (13 years ago)
Author:
vboxsync
Message:

IOM,PDMCritSect: Extended PDMCritSectEnter to handle rcBusy=VINF_SUCCESS as a request to call ring-3 to acquire a busy lock. Implemented device level locking in the MMIO code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/include/IOMInline.h

    r37426 r37452  
    6565 * @param   GCPhys  Physical address to lookup.
    6666 */
    67 DECLINLINE(PIOMMMIORANGE) iomMMIOGetRange(PVM pVM, RTGCPHYS GCPhys)
     67DECLINLINE(PIOMMMIORANGE) iomMmioGetRange(PVM pVM, RTGCPHYS GCPhys)
    6868{
    69     Assert(PDMCritSectIsOwner(&pVM->iom.s.EmtLock) || !PDMCritSectIsInitialized(&pVM->iom.s.EmtLock));
     69    Assert(PDMCritSectIsOwner(&pVM->iom.s.EmtLock));
    7070    PIOMMMIORANGE pRange = pVM->iom.s.CTX_SUFF(pMMIORangeLast);
    7171    if (    !pRange
    7272        ||  GCPhys - pRange->GCPhys >= pRange->cb)
    73         pVM->iom.s.CTX_SUFF(pMMIORangeLast) = pRange 
     73        pVM->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
    7474            = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOTree, GCPhys);
    7575    return pRange;
     76}
     77
     78/**
     79 * Retain a MMIO range.
     80 *
     81 * @param   pRange  The range to release.
     82 */
     83DECLINLINE(void) iomMmioRetainRange(PIOMMMIORANGE pRange)
     84{
     85    uint32_t cRefs = ASMAtomicIncU32(&pRange->cRefs);
     86    Assert(cRefs > 1);
     87    Assert(cRefs < _1M);
     88}
     89
     90
     91/**
     92 * Gets the referenced MMIO range for the specified physical address in the
     93 * current context.
     94 *
     95 * @returns Pointer to MMIO range.
     96 * @returns NULL if address not in a MMIO range.
     97 *
     98 * @param   pVM     The VM handle.
     99 * @param   GCPhys  Physical address to lookup.
     100 */
     101DECLINLINE(PIOMMMIORANGE) iomMmioGetRangeWithRef(PVM pVM, RTGCPHYS GCPhys)
     102{
     103    int rc = PDMCritSectEnter(&pVM->iom.s.EmtLock, VINF_SUCCESS);
     104    AssertRCReturn(rc, NULL);
     105
     106    PIOMMMIORANGE pRange = pVM->iom.s.CTX_SUFF(pMMIORangeLast);
     107    if (   !pRange
     108        || GCPhys - pRange->GCPhys >= pRange->cb)
     109        pVM->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
     110            = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOTree, GCPhys);
     111    if (pRange)
     112        iomMmioRetainRange(pRange);
     113
     114    PDMCritSectLeave(&pVM->iom.s.EmtLock);
     115    return pRange;
     116}
     117
     118
     119/**
     120 * Releases a MMIO range.
     121 *
     122 * @param   pVM     The VM handle.
     123 * @param   pRange  The range to release.
     124 */
     125DECLINLINE(void) iomMmioReleaseRange(PVM pVM, PIOMMMIORANGE pRange)
     126{
     127    uint32_t cRefs = ASMAtomicDecU32(&pRange->cRefs);
     128    if (!cRefs)
     129        iomMmioFreeRange(pVM, pRange);
    76130}
    77131
     
    92146    if (    !pRange
    93147        ||  GCPhys - pRange->GCPhys >= pRange->cb)
    94         pVM->iom.s.CTX_SUFF(pMMIORangeLast) = pRange 
     148        pVM->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
    95149            = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOTree, GCPhys);
    96150    return pRange;
     
    113167 * @param   pRange      The MMIO range.
    114168 */
    115 DECLINLINE(PIOMMMIOSTATS) iomMMIOGetStats(PVM pVM, RTGCPHYS GCPhys, PIOMMMIORANGE pRange)
     169DECLINLINE(PIOMMMIOSTATS) iomMmioGetStats(PVM pVM, RTGCPHYS GCPhys, PIOMMMIORANGE pRange)
    116170{
    117     Assert(PDMCritSectIsOwner(&pVM->iom.s.EmtLock));
     171    PDMCritSectEnter(&pVM->iom.s.EmtLock, VINF_SUCCESS);
    118172
    119173    /* For large ranges, we'll put everything on the first byte. */
     
    125179        ||  pStats->Core.Key != GCPhys)
    126180    {
    127         pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOStatTree, GCPhys);
     181        pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pVM->iom.s.CTX_SUFF(pTrees)->MmioStatTree, GCPhys);
    128182# ifdef IN_RING3
    129183        if (!pStats)
     
    131185# endif
    132186    }
     187
     188    PDMCritSectLeave(&pVM->iom.s.EmtLock);
    133189    return pStats;
    134190}
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