VirtualBox

Changeset 45311 in vbox


Ignore:
Timestamp:
Apr 3, 2013 2:55:30 PM (11 years ago)
Author:
vboxsync
Message:

IOM: Prepared for using read/write locking, still using the old exclusive stuff though. Found and fixed an REM/IOM lock order issue.

Location:
trunk/src/VBox/VMM
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IOMAll.cpp

    r45305 r45311  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2006-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    4949{
    5050#ifdef IOM_WITH_CRIT_SECT_RW
    51     return PDMCritSectRwIsWriteOwner(&pVM->iom.s.CritSect);
     51    return PDMCritSectRwIsInitialized(&pVM->iom.s.CritSect)
     52        && PDMCritSectRwIsWriteOwner(&pVM->iom.s.CritSect);
    5253#else
    5354    return PDMCritSectIsOwner(&pVM->iom.s.CritSect);
     
    230231 *        handle is buggy and doesn't handle all cases. */
    231232    /* Take the IOM lock before performing any device I/O. */
    232     int rc2 = IOM_LOCK(pVM);
     233    int rc2 = IOM_LOCK_SHARED(pVM);
    233234#ifndef IN_RING3
    234235    if (rc2 == VERR_SEM_BUSY)
     
    275276        {
    276277            STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->InRZToR3); });
    277             IOM_UNLOCK(pVM);
     278            IOM_UNLOCK_SHARED(pVM);
    278279            return VINF_IOM_R3_IOPORT_READ;
    279280        }
     
    281282        void           *pvUser    = pRange->pvUser;
    282283        PPDMDEVINS      pDevIns   = pRange->pDevIns;
    283         IOM_UNLOCK(pVM);
     284        IOM_UNLOCK_SHARED(pVM);
    284285
    285286        /*
     
    341342            STAM_COUNTER_INC(&pStats->InRZToR3);
    342343# endif
    343         IOM_UNLOCK(pVM);
     344        IOM_UNLOCK_SHARED(pVM);
    344345        return VINF_IOM_R3_IOPORT_READ;
    345346    }
     
    352353    if (pStats)
    353354        STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(In));
    354     else
    355     {
    356 # ifndef IN_RING3
    357         /* Ring-3 will have to create the statistics record. */
    358         IOM_UNLOCK(pVM);
    359         return VINF_IOM_R3_IOPORT_READ;
    360 # else
    361         pStats = iomR3IOPortStatsCreate(pVM, Port, NULL);
    362         if (pStats)
    363             STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(In));
    364 # endif
    365     }
    366355#endif
    367356
     
    374363        default:
    375364            AssertMsgFailed(("Invalid I/O port size %d. Port=%d\n", cbValue, Port));
    376             IOM_UNLOCK(pVM);
     365            IOM_UNLOCK_SHARED(pVM);
    377366            return VERR_IOM_INVALID_IOPORT_SIZE;
    378367    }
    379368    Log3(("IOMIOPortRead: Port=%RTiop *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", Port, *pu32Value, cbValue));
    380     IOM_UNLOCK(pVM);
     369    IOM_UNLOCK_SHARED(pVM);
    381370    return VINF_SUCCESS;
    382371}
     
    404393{
    405394    /* Take the IOM lock before performing any device I/O. */
    406     int rc2 = IOM_LOCK(pVM);
     395    int rc2 = IOM_LOCK_SHARED(pVM);
    407396#ifndef IN_RING3
    408397    if (rc2 == VERR_SEM_BUSY)
     
    452441        {
    453442            STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->InRZToR3); });
    454             IOM_UNLOCK(pVM);
     443            IOM_UNLOCK_SHARED(pVM);
    455444            return VINF_IOM_R3_IOPORT_READ;
    456445        }
     
    458447        void           *pvUser    = pRange->pvUser;
    459448        PPDMDEVINS      pDevIns   = pRange->pDevIns;
    460         IOM_UNLOCK(pVM);
     449        IOM_UNLOCK_SHARED(pVM);
    461450
    462451        /*
     
    505494            STAM_COUNTER_INC(&pStats->InRZToR3);
    506495# endif
    507         IOM_UNLOCK(pVM);
     496        IOM_UNLOCK_SHARED(pVM);
    508497        return VINF_IOM_R3_IOPORT_READ;
    509498    }
     
    516505    if (pStats)
    517506        STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(In));
    518     else
    519     {
    520 # ifndef IN_RING3
    521         /* Ring-3 will have to create the statistics record. */
    522         IOM_UNLOCK(pVM);
    523         return VINF_IOM_R3_IOPORT_READ;
    524 # else
    525         pStats = iomR3IOPortStatsCreate(pVM, Port, NULL);
    526         if (pStats)
    527             STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(In));
    528 # endif
    529     }
    530507#endif
    531508
    532509    Log3(("IOMIOPortReadStr: Port=%RTiop pGCPtrDst=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=VINF_SUCCESS\n",
    533510          Port, pGCPtrDst, pcTransfers, cTransfers, *pcTransfers, cb));
    534     IOM_UNLOCK(pVM);
     511    IOM_UNLOCK_SHARED(pVM);
    535512    return VINF_SUCCESS;
    536513}
     
    556533{
    557534    /* Take the IOM lock before performing any device I/O. */
    558     int rc2 = IOM_LOCK(pVM);
     535    int rc2 = IOM_LOCK_SHARED(pVM);
    559536#ifndef IN_RING3
    560537    if (rc2 == VERR_SEM_BUSY)
     
    603580        {
    604581            STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->OutRZToR3); });
    605             IOM_UNLOCK(pVM);
     582            IOM_UNLOCK_SHARED(pVM);
    606583            return VINF_IOM_R3_IOPORT_WRITE;
    607584        }
     
    609586        void           *pvUser    = pRange->pvUser;
    610587        PPDMDEVINS      pDevIns   = pRange->pDevIns;
    611         IOM_UNLOCK(pVM);
     588        IOM_UNLOCK_SHARED(pVM);
    612589
    613590        /*
     
    655632            STAM_COUNTER_INC(&pStats->OutRZToR3);
    656633# endif
    657         IOM_UNLOCK(pVM);
     634        IOM_UNLOCK_SHARED(pVM);
    658635        return VINF_IOM_R3_IOPORT_WRITE;
    659636    }
     
    667644    if (pStats)
    668645        STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(Out));
    669     else
    670     {
    671 # ifndef IN_RING3
    672         /* R3 will have to create the statistics record. */
    673         IOM_UNLOCK(pVM);
    674         return VINF_IOM_R3_IOPORT_WRITE;
    675 # else
    676         pStats = iomR3IOPortStatsCreate(pVM, Port, NULL);
    677         if (pStats)
    678             STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(Out));
    679 # endif
    680     }
    681646#endif
    682647    Log3(("IOMIOPortWrite: Port=%RTiop u32=%08RX32 cb=%d nop\n", Port, u32Value, cbValue));
    683     IOM_UNLOCK(pVM);
     648    IOM_UNLOCK_SHARED(pVM);
    684649    return VINF_SUCCESS;
    685650}
     
    707672{
    708673    /* Take the IOM lock before performing any device I/O. */
    709     int rc2 = IOM_LOCK(pVM);
     674    int rc2 = IOM_LOCK_SHARED(pVM);
    710675#ifndef IN_RING3
    711676    if (rc2 == VERR_SEM_BUSY)
     
    755720        {
    756721            STAM_STATS({ if (pStats) STAM_COUNTER_INC(&pStats->OutRZToR3); });
    757             IOM_UNLOCK(pVM);
     722            IOM_UNLOCK_SHARED(pVM);
    758723            return VINF_IOM_R3_IOPORT_WRITE;
    759724        }
     
    761726        void           *pvUser    = pRange->pvUser;
    762727        PPDMDEVINS      pDevIns   = pRange->pDevIns;
    763         IOM_UNLOCK(pVM);
     728        IOM_UNLOCK_SHARED(pVM);
    764729
    765730        /*
     
    808773            STAM_COUNTER_INC(&pStats->OutRZToR3);
    809774# endif
    810         IOM_UNLOCK(pVM);
     775        IOM_UNLOCK_SHARED(pVM);
    811776        return VINF_IOM_R3_IOPORT_WRITE;
    812777    }
     
    819784    if (pStats)
    820785        STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(Out));
    821     else
    822     {
    823 # ifndef IN_RING3
    824         /* Ring-3 will have to create the statistics record. */
    825         IOM_UNLOCK(pVM);
    826         return VINF_IOM_R3_IOPORT_WRITE;
    827 # else
    828         pStats = iomR3IOPortStatsCreate(pVM, Port, NULL);
    829         if (pStats)
    830             STAM_COUNTER_INC(&pStats->CTX_SUFF_Z(Out));
    831 # endif
    832     }
    833786#endif
    834787
    835788    Log3(("IOMIOPortWriteStr: Port=%RTiop pGCPtrSrc=%p pcTransfer=%p:{%#x->%#x} cb=%d rc=VINF_SUCCESS\n",
    836789          Port, pGCPtrSrc, pcTransfers, cTransfers, *pcTransfers, cb));
    837     IOM_UNLOCK(pVM);
     790    IOM_UNLOCK_SHARED(pVM);
    838791    return VINF_SUCCESS;
    839792}
  • trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp

    r45305 r45311  
    55
    66/*
    7  * Copyright (C) 2006-2012 Oracle Corporation
     7 * Copyright (C) 2006-2013 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    277277{
    278278#ifdef VBOX_WITH_STATISTICS
     279    int rcSem = IOM_LOCK_SHARED(pVM);
     280    if (rcSem == VERR_SEM_BUSY)
     281        return VINF_IOM_R3_MMIO_WRITE;
    279282    PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhysFault, pRange);
    280     Assert(pStats);
    281 #endif
    282 
     283    if (!pStats)
     284# ifdef IN_RING3
     285        return VERR_NO_MEMORY;
     286# else
     287        return VINF_IOM_R3_MMIO_WRITE;
     288# endif
    283289    STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfWrite), a);
     290#endif
     291
    284292    VBOXSTRICTRC rc;
    285293    if (RT_LIKELY(pRange->CTX_SUFF(pfnWriteCallback)))
     
    295303    else
    296304        rc = VINF_SUCCESS;
     305
    297306    STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a);
    298307    STAM_COUNTER_INC(&pStats->Accesses);
     
    484493{
    485494#ifdef VBOX_WITH_STATISTICS
     495    int rcSem = IOM_LOCK_SHARED(pVM);
     496    if (rcSem == VERR_SEM_BUSY)
     497        return VINF_IOM_R3_MMIO_READ;
    486498    PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhys, pRange);
    487     Assert(pStats);
     499    if (!pStats)
     500# ifdef IN_RING3
     501        return VERR_NO_MEMORY;
     502# else
     503        return VINF_IOM_R3_MMIO_READ;
     504# endif
    488505    STAM_PROFILE_START(&pStats->CTX_SUFF_Z(ProfRead), a);
    489506#endif
     
    512529        }
    513530    }
     531
    514532    STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfRead), a);
    515533    STAM_COUNTER_INC(&pStats->Accesses);
     
    977995    {
    978996#ifndef IN_RC
    979         if (    CPUMIsGuestIn64BitCode(VMMGetCpu(pVM))
     997        if (    CPUMIsGuestIn64BitCode(pVCpu)
    980998            &&  pRegFrame->rcx >= _4G)
    981999            return VINF_EM_RAW_EMULATE_INSTR;
     
    14891507static int iomMMIOHandler(PVM pVM, PVMCPU pVCpu, uint32_t uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault, void *pvUser)
    14901508{
    1491     int rc = IOM_LOCK(pVM);
     1509    int rc = IOM_LOCK_SHARED(pVM);
    14921510#ifndef IN_RING3
    14931511    if (rc == VERR_SEM_BUSY)
     
    15021520    Assert(pRange);
    15031521    Assert(pRange == iomMmioGetRange(pVM, pVCpu, GCPhysFault));
    1504 
    1505 #ifdef VBOX_WITH_STATISTICS
    1506     /*
    1507      * Locate the statistics, if > PAGE_SIZE we'll use the first byte for everything.
     1522    iomMmioRetainRange(pRange);
     1523#ifndef VBOX_WITH_STATISTICS
     1524    IOM_UNLOCK_SHARED(pVM);
     1525
     1526#else
     1527    /*
     1528     * Locate the statistics.
    15081529     */
    15091530    PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhysFault, pRange);
    15101531    if (!pStats)
    15111532    {
     1533        iomMmioReleaseRange(pVM, pRange);
    15121534# ifdef IN_RING3
    1513         IOM_UNLOCK(pVM);
    15141535        return VERR_NO_MEMORY;
    15151536# else
    15161537        STAM_PROFILE_STOP(&pVM->iom.s.StatRZMMIOHandler, a);
    15171538        STAM_COUNTER_INC(&pVM->iom.s.StatRZMMIOFailures);
    1518         IOM_UNLOCK(pVM);
    15191539        return VINF_IOM_R3_MMIO_READ_WRITE;
    15201540# endif
     
    15451565        STAM_PROFILE_STOP(&pVM->iom.s.StatRZMMIOHandler, a);
    15461566        STAM_COUNTER_INC(&pVM->iom.s.StatRZMMIOFailures);
    1547         IOM_UNLOCK(pVM);
     1567        iomMmioReleaseRange(pVM, pRange);
    15481568        return VINF_IOM_R3_MMIO_READ_WRITE;
    15491569    }
     
    15531573     * Retain the range and do locking.
    15541574     */
    1555     iomMmioRetainRange(pRange);
    15561575    PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
    1557     IOM_UNLOCK(pVM);
    15581576    rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_R3_MMIO_READ_WRITE);
    15591577    if (rc != VINF_SUCCESS)
     
    15711589    if (RT_FAILURE(rc))
    15721590    {
     1591        PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    15731592        iomMmioReleaseRange(pVM, pRange);
    1574         PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    15751593        return rc;
    15761594    }
     
    17051723
    17061724    STAM_PROFILE_STOP(&pVM->iom.s.StatRZMMIOHandler, a);
     1725    PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    17071726    iomMmioReleaseRange(pVM, pRange);
    1708     PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    17091727    return rc;
    17101728}
     
    17411759VMMDECL(VBOXSTRICTRC) IOMMMIOPhysHandler(PVM pVM, PVMCPU pVCpu, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault)
    17421760{
    1743     int rc2 = IOM_LOCK(pVM); NOREF(rc2);
     1761    int rc2 = IOM_LOCK_SHARED(pVM); NOREF(rc2);
    17441762#ifndef IN_RING3
    17451763    if (rc2 == VERR_SEM_BUSY)
     
    17481766    VBOXSTRICTRC rcStrict = iomMMIOHandler(pVM, pVCpu, (uint32_t)uErrorCode, pCtxCore, GCPhysFault,
    17491767                                           iomMmioGetRange(pVM, pVCpu, GCPhysFault));
    1750     IOM_UNLOCK(pVM);
     1768    IOM_UNLOCK_SHARED(pVM);
    17511769    return VBOXSTRICTRC_VAL(rcStrict);
    17521770}
     
    17811799     * Validate the range.
    17821800     */
    1783     int rc = IOM_LOCK(pVM);
     1801    int rc = IOM_LOCK_SHARED(pVM);
    17841802    AssertRC(rc);
    17851803    Assert(pRange == iomMmioGetRange(pVM, pVCpu, GCPhysFault));
     
    17901808    iomMmioRetainRange(pRange);
    17911809    PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
    1792     IOM_UNLOCK(pVM);
     1810    IOM_UNLOCK_SHARED(pVM);
    17931811    rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_R3_MMIO_READ_WRITE);
    17941812    if (rc != VINF_SUCCESS)
     
    18281846{
    18291847    /* Take the IOM lock before performing any MMIO. */
    1830     VBOXSTRICTRC rc = IOM_LOCK(pVM);
     1848    VBOXSTRICTRC rc = IOM_LOCK_SHARED(pVM);
    18311849#ifndef IN_RING3
    18321850    if (rc == VERR_SEM_BUSY)
     
    18451863    {
    18461864        AssertMsgFailed(("Handlers and page tables are out of sync or something! GCPhys=%RGp cbValue=%d\n", GCPhys, cbValue));
    1847         IOM_UNLOCK(pVM);
     1865        IOM_UNLOCK_SHARED(pVM);
    18481866        return VERR_IOM_MMIO_RANGE_NOT_FOUND;
    18491867    }
    1850 #ifdef VBOX_WITH_STATISTICS
     1868    iomMmioRetainRange(pRange);
     1869#ifndef VBOX_WITH_STATISTICS
     1870    IOM_UNLOCK_SHARED(pVM);
     1871
     1872#else  /* VBOX_WITH_STATISTICS */
    18511873    PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhys, pRange);
    18521874    if (!pStats)
    18531875    {
    1854         IOM_UNLOCK(pVM);
     1876        iomMmioReleaseRange(pVM, pRange);
    18551877# ifdef IN_RING3
    18561878        return VERR_NO_MEMORY;
     
    18671889         * Perform locking.
    18681890         */
    1869         iomMmioRetainRange(pRange);
    18701891        PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
    1871         IOM_UNLOCK(pVM);
    18721892        rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_R3_MMIO_WRITE);
    18731893        if (rc != VINF_SUCCESS)
     
    18931913            case VINF_SUCCESS:
    18941914                Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", GCPhys, *pu32Value, cbValue));
     1915                PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    18951916                iomMmioReleaseRange(pVM, pRange);
    1896                 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    18971917                return rc;
    18981918#ifndef IN_RING3
     
    19031923            default:
    19041924                Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc)));
     1925                PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    19051926                iomMmioReleaseRange(pVM, pRange);
    1906                 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    19071927                return rc;
    19081928
     
    19101930                iomMMIODoRead00s(pu32Value, cbValue);
    19111931                Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc)));
     1932                PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    19121933                iomMmioReleaseRange(pVM, pRange);
    1913                 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    19141934                return VINF_SUCCESS;
    19151935
     
    19171937                iomMMIODoReadFFs(pu32Value, cbValue);
    19181938                Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, *pu32Value, cbValue, VBOXSTRICTRC_VAL(rc)));
     1939                PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    19191940                iomMmioReleaseRange(pVM, pRange);
    1920                 PDMCritSectLeave(pDevIns->CTX_SUFF(pCritSectRo));
    19211941                return VINF_SUCCESS;
    19221942        }
     
    19271947    {
    19281948        STAM_COUNTER_INC(&pStats->CTX_MID_Z(Read,ToR3));
    1929         IOM_UNLOCK(pVM);
     1949        iomMmioReleaseRange(pVM, pRange);
    19301950        return VINF_IOM_R3_MMIO_READ;
    19311951    }
     
    19391959    iomMMIODoReadFFs(pu32Value, cbValue);
    19401960    Log4(("IOMMMIORead: GCPhys=%RGp *pu32=%08RX32 cb=%d rc=VINF_SUCCESS\n", GCPhys, *pu32Value, cbValue));
    1941     IOM_UNLOCK(pVM);
     1961    iomMmioReleaseRange(pVM, pRange);
    19421962    return VINF_SUCCESS;
    19431963}
     
    19581978{
    19591979    /* Take the IOM lock before performing any MMIO. */
    1960     VBOXSTRICTRC rc = IOM_LOCK(pVM);
     1980    VBOXSTRICTRC rc = IOM_LOCK_SHARED(pVM);
    19611981#ifndef IN_RING3
    19621982    if (rc == VERR_SEM_BUSY)
     
    19751995    {
    19761996        AssertMsgFailed(("Handlers and page tables are out of sync or something! GCPhys=%RGp cbValue=%d\n", GCPhys, cbValue));
    1977         IOM_UNLOCK(pVM);
     1997        IOM_UNLOCK_SHARED(pVM);
    19781998        return VERR_IOM_MMIO_RANGE_NOT_FOUND;
    19791999    }
    1980 #ifdef VBOX_WITH_STATISTICS
     2000    iomMmioRetainRange(pRange);
     2001#ifndef VBOX_WITH_STATISTICS
     2002    IOM_UNLOCK_SHARED(pVM);
     2003
     2004#else  /* VBOX_WITH_STATISTICS */
    19812005    PIOMMMIOSTATS pStats = iomMmioGetStats(pVM, pVCpu, GCPhys, pRange);
    19822006    if (!pStats)
    19832007    {
    1984         IOM_UNLOCK(pVM);
     2008        iomMmioReleaseRange(pVM, pRange);
    19852009# ifdef IN_RING3
    19862010        return VERR_NO_MEMORY;
     
    19972021         * Perform locking.
    19982022         */
    1999         iomMmioRetainRange(pRange);
    20002023        PPDMDEVINS pDevIns = pRange->CTX_SUFF(pDevIns);
    2001         IOM_UNLOCK(pVM);
    20022024        rc = PDMCritSectEnter(pDevIns->CTX_SUFF(pCritSectRo), VINF_IOM_R3_MMIO_READ);
    20032025        if (rc != VINF_SUCCESS)
     
    20332055    {
    20342056        STAM_COUNTER_INC(&pStats->CTX_MID_Z(Write,ToR3));
    2035         IOM_UNLOCK(pVM);
     2057        iomMmioReleaseRange(pVM, pRange);
    20362058        return VINF_IOM_R3_MMIO_WRITE;
    20372059    }
     
    20442066    STAM_PROFILE_STOP(&pStats->CTX_SUFF_Z(ProfWrite), a);
    20452067    Log4(("IOMMMIOWrite: GCPhys=%RGp u32=%08RX32 cb=%d rc=%Rrc\n", GCPhys, u32Value, cbValue, VINF_SUCCESS));
    2046     IOM_UNLOCK(pVM);
     2068    iomMmioReleaseRange(pVM, pRange);
    20472069    return VINF_SUCCESS;
    20482070}
     
    24092431        return VINF_SUCCESS;    /* ignore */
    24102432
    2411     int rc = IOM_LOCK(pVM);
     2433    int rc = IOM_LOCK_SHARED(pVM);
    24122434    if (RT_FAILURE(rc))
    24132435        return VINF_SUCCESS; /* better luck the next time around */
     
    24312453    rc = PGMHandlerPhysicalPageAlias(pVM, pRange->GCPhys, GCPhys, GCPhysRemapped);
    24322454
    2433     IOM_UNLOCK(pVM);
     2455    IOM_UNLOCK_SHARED(pVM);
    24342456    AssertRCReturn(rc, rc);
    24352457
  • trunk/src/VBox/VMM/VMMR3/IOM.cpp

    r45305 r45311  
    245245     * (1) The irrelvant access not holding the lock is in assertion code.
    246246     */
    247     IOM_LOCK(pVM);
     247    IOM_LOCK_EXCL(pVM);
    248248    VMCPUID iCpu = pVM->cCpus;
    249249    while (iCpu-- > 0)
     
    272272    }
    273273
    274     IOM_UNLOCK(pVM);
     274    IOM_UNLOCK_EXCL(pVM);
    275275}
    276276
     
    415415 * @param   pszDesc     Description.
    416416 */
    417 PIOMIOPORTSTATS iomR3IOPortStatsCreate(PVM pVM, RTIOPORT Port, const char *pszDesc)
    418 {
    419     Assert(IOM_IS_EXCL_LOCK_OWNER(pVM));
     417static PIOMIOPORTSTATS iomR3IOPortStatsCreate(PVM pVM, RTIOPORT Port, const char *pszDesc)
     418{
     419    IOM_LOCK_EXCL(pVM);
    420420
    421421    /* check if it already exists. */
    422422    PIOMIOPORTSTATS pPort = (PIOMIOPORTSTATS)RTAvloIOPortGet(&pVM->iom.s.pTreesR3->IOPortStatTree, Port);
    423423    if (pPort)
     424    {
     425        IOM_UNLOCK_EXCL(pVM);
    424426        return pPort;
     427    }
    425428
    426429    /* allocate stats node. */
     
    433436        if (RTAvloIOPortInsert(&pVM->iom.s.pTreesR3->IOPortStatTree, &pPort->Core))
    434437        {
     438            IOM_UNLOCK_EXCL(pVM);
     439
    435440            /* put a name on common ports. */
    436441            if (!pszDesc)
     
    453458            return pPort;
    454459        }
     460
    455461        AssertMsgFailed(("what! Port=%d\n", Port));
    456462        MMHyperFree(pVM, pPort);
    457463    }
     464    IOM_UNLOCK_EXCL(pVM);
    458465    return NULL;
    459466}
     
    471478PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc)
    472479{
    473     Assert(IOM_IS_EXCL_LOCK_OWNER(pVM));
    474 #ifdef DEBUG_sandervl
    475     AssertGCPhys32(GCPhys);
    476 #endif
     480    IOM_LOCK_EXCL(pVM);
    477481
    478482    /* check if it already exists. */
    479483    PIOMMMIOSTATS pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pVM->iom.s.pTreesR3->MmioStatTree, GCPhys);
    480484    if (pStats)
     485    {
     486        IOM_UNLOCK_EXCL(pVM);
    481487        return pStats;
     488    }
    482489
    483490    /* allocate stats node. */
     
    490497        if (RTAvloGCPhysInsert(&pVM->iom.s.pTreesR3->MmioStatTree, &pStats->Core))
    491498        {
     499            IOM_UNLOCK_EXCL(pVM);
     500
    492501            rc = STAMR3RegisterF(pVM, &pStats->Accesses,    STAMTYPE_COUNTER, STAMVISIBILITY_USED, STAMUNIT_OCCURENCES,     pszDesc, "/IOM/MMIO/%RGp",              GCPhys); AssertRC(rc);
    493502            rc = STAMR3RegisterF(pVM, &pStats->ProfReadR3,  STAMTYPE_PROFILE, STAMVISIBILITY_USED, STAMUNIT_TICKS_PER_CALL, pszDesc, "/IOM/MMIO/%RGp/Read-R3",      GCPhys); AssertRC(rc);
     
    503512        MMHyperFree(pVM, pStats);
    504513    }
     514    IOM_UNLOCK_EXCL(pVM);
    505515    return NULL;
    506516}
     
    584594         * Try Insert it.
    585595         */
    586         IOM_LOCK(pVM);
     596        IOM_LOCK_EXCL(pVM);
    587597        if (RTAvlroIOPortInsert(&pVM->iom.s.pTreesR3->IOPortTreeR3, &pRange->Core))
    588598        {
     
    591601                iomR3IOPortStatsCreate(pVM, PortStart + iPort, pszDesc);
    592602#endif
    593             IOM_UNLOCK(pVM);
     603            IOM_UNLOCK_EXCL(pVM);
    594604            return VINF_SUCCESS;
    595605        }
    596         IOM_UNLOCK(pVM);
     606        IOM_UNLOCK_EXCL(pVM);
    597607
    598608        /* conflict. */
     
    650660    }
    651661
    652     IOM_LOCK(pVM);
     662    IOM_LOCK_EXCL(pVM);
    653663
    654664    /*
     
    662672        {
    663673            AssertMsgFailed(("No R3! Port=#x %#x-%#x! (%s)\n", Port, PortStart, (unsigned)PortStart + cPorts - 1, pszDesc));
    664             IOM_UNLOCK(pVM);
     674            IOM_UNLOCK_EXCL(pVM);
    665675            return VERR_IOM_NO_R3_IOPORT_RANGE;
    666676        }
     
    673683        {
    674684            AssertMsgFailed(("Not owner! Port=%#x %#x-%#x! (%s)\n", Port, PortStart, (unsigned)PortStart + cPorts - 1, pszDesc));
    675             IOM_UNLOCK(pVM);
     685            IOM_UNLOCK_EXCL(pVM);
    676686            return VERR_IOM_NOT_IOPORT_RANGE_OWNER;
    677687        }
     
    707717        if (RTAvlroIOPortInsert(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortTreeRC, &pRange->Core))
    708718        {
    709             IOM_UNLOCK(pVM);
     719            IOM_UNLOCK_EXCL(pVM);
    710720            return VINF_SUCCESS;
    711721        }
     
    716726        rc = VERR_IOM_IOPORT_RANGE_CONFLICT;
    717727    }
    718     IOM_UNLOCK(pVM);
     728    IOM_UNLOCK_EXCL(pVM);
    719729    return rc;
    720730}
     
    765775    }
    766776
    767     IOM_LOCK(pVM);
     777    IOM_LOCK_EXCL(pVM);
     778
    768779    /*
    769780     * Validate that there are ring-3 ranges for the ports.
     
    776787        {
    777788            AssertMsgFailed(("No R3! Port=#x %#x-%#x! (%s)\n", Port, PortStart, (unsigned)PortStart + cPorts - 1, pszDesc));
    778             IOM_UNLOCK(pVM);
     789            IOM_UNLOCK_EXCL(pVM);
    779790            return VERR_IOM_NO_R3_IOPORT_RANGE;
    780791        }
     
    787798        {
    788799            AssertMsgFailed(("Not owner! Port=%#x %#x-%#x! (%s)\n", Port, PortStart, (unsigned)PortStart + cPorts - 1, pszDesc));
    789             IOM_UNLOCK(pVM);
     800            IOM_UNLOCK_EXCL(pVM);
    790801            return VERR_IOM_NOT_IOPORT_RANGE_OWNER;
    791802        }
     
    821832        if (RTAvlroIOPortInsert(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortTreeR0, &pRange->Core))
    822833        {
    823             IOM_UNLOCK(pVM);
     834            IOM_UNLOCK_EXCL(pVM);
    824835            return VINF_SUCCESS;
    825836        }
     
    830841        rc = VERR_IOM_IOPORT_RANGE_CONFLICT;
    831842    }
    832     IOM_UNLOCK(pVM);
     843    IOM_UNLOCK_EXCL(pVM);
    833844    return rc;
    834845}
     
    868879    }
    869880
    870     IOM_LOCK(pVM);
     881    IOM_LOCK_EXCL(pVM);
    871882
    872883    /* Flush the IO port lookup cache */
     
    889900                AssertMsgFailed(("Removal of ports in range %#x-%#x rejected because not owner of %#x-%#x (%s)\n",
    890901                                 PortStart, PortLast, pRange->Core.Key, pRange->Core.KeyLast, pRange->pszDesc));
    891                 IOM_UNLOCK(pVM);
     902                IOM_UNLOCK_EXCL(pVM);
    892903                return VERR_IOM_NOT_IOPORT_RANGE_OWNER;
    893904            }
     
    953964                if (RT_FAILURE(rc2))
    954965                {
    955                     IOM_UNLOCK(pVM);
     966                    IOM_UNLOCK_EXCL(pVM);
    956967                    return rc2;
    957968                }
     
    10361047                if (RT_FAILURE(rc2))
    10371048                {
    1038                     IOM_UNLOCK(pVM);
     1049                    IOM_UNLOCK_EXCL(pVM);
    10391050                    return rc2;
    10401051                }
     
    11181129                if (RT_FAILURE(rc2))
    11191130                {
    1120                     IOM_UNLOCK(pVM);
     1131                    IOM_UNLOCK_EXCL(pVM);
    11211132                    return rc2;
    11221133                }
     
    11471158
    11481159    /* done */
    1149     IOM_UNLOCK(pVM);
     1160    IOM_UNLOCK_EXCL(pVM);
    11501161    return rc;
    11511162}
     
    14131424         * Try register it with PGM and then insert it into the tree.
    14141425         */
    1415         IOM_LOCK(pVM);
    1416         iomR3FlushCache(pVM);
    14171426        rc = PGMR3PhysMMIORegister(pVM, GCPhysStart, cbRange,
    14181427                                   IOMR3MMIOHandler, pRange,
     
    14211430        if (RT_SUCCESS(rc))
    14221431        {
     1432            IOM_LOCK_EXCL(pVM);
    14231433            if (RTAvlroGCPhysInsert(&pVM->iom.s.pTreesR3->MMIOTree, &pRange->Core))
    14241434            {
    1425                 IOM_UNLOCK(pVM);
     1435                iomR3FlushCache(pVM);
     1436                IOM_UNLOCK_EXCL(pVM);
    14261437                return VINF_SUCCESS;
    14271438            }
    14281439
    14291440            /* bail out */
    1430             IOM_UNLOCK(pVM);
     1441            IOM_UNLOCK_EXCL(pVM);
    14311442            DBGFR3Info(pVM->pUVM, "mmio", NULL, NULL);
    14321443            AssertMsgFailed(("This cannot happen!\n"));
    14331444            rc = VERR_IOM_IOPORT_IPE_3;
    14341445        }
    1435         else
    1436             IOM_UNLOCK(pVM);
    14371446
    14381447        MMHyperFree(pVM, pRange);
     
    14841493     * Find the MMIO range and check that the input matches.
    14851494     */
    1486     IOM_LOCK(pVM);
     1495    IOM_LOCK_EXCL(pVM);
    14871496    PIOMMMIORANGE pRange = iomMmioGetRange(pVM, pVCpu, GCPhysStart);
    1488     AssertReturnStmt(pRange, IOM_UNLOCK(pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND);
    1489     AssertReturnStmt(pRange->pDevInsR3 == pDevIns, IOM_UNLOCK(pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER);
    1490     AssertReturnStmt(pRange->GCPhys == GCPhysStart, IOM_UNLOCK(pVM), VERR_IOM_INVALID_MMIO_RANGE);
    1491     AssertReturnStmt(pRange->cb == cbRange, IOM_UNLOCK(pVM), VERR_IOM_INVALID_MMIO_RANGE);
     1497    AssertReturnStmt(pRange, IOM_UNLOCK_EXCL(pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND);
     1498    AssertReturnStmt(pRange->pDevInsR3 == pDevIns, IOM_UNLOCK_EXCL(pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER);
     1499    AssertReturnStmt(pRange->GCPhys == GCPhysStart, IOM_UNLOCK_EXCL(pVM), VERR_IOM_INVALID_MMIO_RANGE);
     1500    AssertReturnStmt(pRange->cb == cbRange, IOM_UNLOCK_EXCL(pVM), VERR_IOM_INVALID_MMIO_RANGE);
    14921501
    14931502    pRange->pvUserRC          = pvUser;
     
    14961505    pRange->pfnFillCallbackRC = pfnFillCallback;
    14971506    pRange->pDevInsRC         = MMHyperCCToRC(pVM, pDevIns);
    1498     IOM_UNLOCK(pVM);
     1507    IOM_UNLOCK_EXCL(pVM);
    14991508
    15001509    return VINF_SUCCESS;
     
    15431552     * Find the MMIO range and check that the input matches.
    15441553     */
    1545     IOM_LOCK(pVM);
     1554    IOM_LOCK_EXCL(pVM);
    15461555    PIOMMMIORANGE pRange = iomMmioGetRange(pVM, pVCpu, GCPhysStart);
    1547     AssertReturnStmt(pRange, IOM_UNLOCK(pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND);
    1548     AssertReturnStmt(pRange->pDevInsR3 == pDevIns, IOM_UNLOCK(pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER);
    1549     AssertReturnStmt(pRange->GCPhys == GCPhysStart, IOM_UNLOCK(pVM), VERR_IOM_INVALID_MMIO_RANGE);
    1550     AssertReturnStmt(pRange->cb == cbRange, IOM_UNLOCK(pVM), VERR_IOM_INVALID_MMIO_RANGE);
     1556    AssertReturnStmt(pRange, IOM_UNLOCK_EXCL(pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND);
     1557    AssertReturnStmt(pRange->pDevInsR3 == pDevIns, IOM_UNLOCK_EXCL(pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER);
     1558    AssertReturnStmt(pRange->GCPhys == GCPhysStart, IOM_UNLOCK_EXCL(pVM), VERR_IOM_INVALID_MMIO_RANGE);
     1559    AssertReturnStmt(pRange->cb == cbRange, IOM_UNLOCK_EXCL(pVM), VERR_IOM_INVALID_MMIO_RANGE);
    15511560
    15521561    pRange->pvUserR0          = pvUser;
     
    15551564    pRange->pfnFillCallbackR0 = pfnFillCallback;
    15561565    pRange->pDevInsR0         = MMHyperCCToR0(pVM, pDevIns);
    1557     IOM_UNLOCK(pVM);
     1566    IOM_UNLOCK_EXCL(pVM);
    15581567
    15591568    return VINF_SUCCESS;
     
    15911600    PVMCPU pVCpu = VMMGetCpu(pVM); Assert(pVCpu);
    15921601
    1593     IOM_LOCK(pVM);
     1602    IOM_LOCK_EXCL(pVM);
    15941603
    15951604    /*
     
    16021611        if (!pRange)
    16031612        {
    1604             IOM_UNLOCK(pVM);
     1613            IOM_UNLOCK_EXCL(pVM);
    16051614            return VERR_IOM_MMIO_RANGE_NOT_FOUND;
    16061615        }
    16071616        AssertMsgReturnStmt(pRange->pDevInsR3 == pDevIns,
    16081617                            ("Not owner! GCPhys=%RGp %RGp LB%#x %s\n", GCPhys, GCPhysStart, cbRange, pRange->pszDesc),
    1609                             IOM_UNLOCK(pVM),
     1618                            IOM_UNLOCK_EXCL(pVM),
    16101619                            VERR_IOM_NOT_MMIO_RANGE_OWNER);
    16111620        AssertMsgReturnStmt(pRange->Core.KeyLast <= GCPhysLast,
    16121621                            ("Incomplete R3 range! GCPhys=%RGp %RGp LB%#x %s\n", GCPhys, GCPhysStart, cbRange, pRange->pszDesc),
    1613                             IOM_UNLOCK(pVM),
     1622                            IOM_UNLOCK_EXCL(pVM),
    16141623                            VERR_IOM_INCOMPLETE_MMIO_RANGE);
    16151624
     
    16301639        Assert(pRange);
    16311640        Assert(pRange->Core.Key == GCPhys && pRange->Core.KeyLast <= GCPhysLast);
    1632         IOM_UNLOCK(pVM); /** @todo r=bird: Why are we leaving the lock here? We don't leave it when registering the range above... */
     1641        IOM_UNLOCK_EXCL(pVM); /* Lock order fun. */
    16331642
    16341643        /* remove it from PGM */
     
    16361645        AssertRC(rc);
    16371646
    1638         IOM_LOCK(pVM);
     1647        IOM_LOCK_EXCL(pVM);
    16391648
    16401649        /* advance and free. */
     
    16481657    }
    16491658
    1650     IOM_UNLOCK(pVM);
     1659    IOM_UNLOCK_EXCL(pVM);
    16511660    return VINF_SUCCESS;
    16521661}
  • trunk/src/VBox/VMM/include/IOMInline.h

    r45305 r45311  
    167167 * @returns NULL if not found (R0/GC), or out of memory (R3).
    168168 *
    169  * @param   pVM     Pointer to the VM.
    170  * @param   pVCpu   Pointer to the virtual CPU structure of the caller.
    171  * @param   GCPhys  Physical address to lookup.
    172  * @param   pRange  The MMIO range.
     169 * @param   pVM         Pointer to the VM.
     170 * @param   pVCpu       Pointer to the virtual CPU structure of the caller.
     171 * @param   GCPhys      Physical address to lookup.
     172 * @param   pRange      The MMIO range.
     173 *
     174 * @remarks The caller holds the IOM critical section with shared access prior
     175 *          to calling this method.  Upon return, the lock has been released!
     176 *          This is ugly, but it's a necessary evil since we cannot upgrade read
     177 *          locks to write locks and the whole purpose here is calling
     178 *          iomR3MMIOStatsCreate.
    173179 */
    174180DECLINLINE(PIOMMMIOSTATS) iomMmioGetStats(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, PIOMMMIORANGE pRange)
    175181{
    176     IOM_LOCK_SHARED_EX(pVM, VINF_SUCCESS);
     182    Assert(IOM_IS_SHARED_LOCK_OWNER(pVM));
    177183
    178184    /* For large ranges, we'll put everything on the first byte. */
     
    187193# ifdef IN_RING3
    188194        if (!pStats)
    189             pStats = iomR3MMIOStatsCreate(pVM, GCPhys, pRange->pszDesc);
     195        {
     196            IOM_UNLOCK_SHARED(pVM);
     197            return iomR3MMIOStatsCreate(pVM, GCPhys, pRange->pszDesc);
     198        }
    190199# endif
    191200    }
  • trunk/src/VBox/VMM/include/IOMInternal.h

    r45305 r45311  
    423423void                iomMmioFreeRange(PVM pVM, PIOMMMIORANGE pRange);
    424424#ifdef IN_RING3
    425 PIOMIOPORTSTATS     iomR3IOPortStatsCreate(PVM pVM, RTIOPORT Port, const char *pszDesc);
    426425PIOMMMIOSTATS       iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc);
    427426#endif /* IN_RING3 */
     
    436435/* IOM locking helpers. */
    437436#ifdef IOM_WITH_CRIT_SECT_RW
    438 # define IOM_LOCK(a_pVM)                        PDMCritSectRwEnterExcl(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)
    439 # define IOM_UNLOCK(a_pVM)                      do { PDMCritSectRwLeaveExcl(&(a_pVM)->iom.s.CritSect); } while (0)
    440 # if 1 /* for the time being (the lookup caches needs to be in VMCPU) */
     437# define IOM_LOCK_EXCL(a_pVM)                   PDMCritSectRwEnterExcl(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)
     438# define IOM_UNLOCK_EXCL(a_pVM)                 do { PDMCritSectRwLeaveExcl(&(a_pVM)->iom.s.CritSect); } while (0)
     439# if 0 /* for the time being (the lookup caches needs to be in VMCPU) */
    441440# define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy)    PDMCritSectRwEnterExcl(&(a_pVM)->iom.s.CritSect, (a_rcBusy))
    442441# define IOM_UNLOCK_SHARED(a_pVM)               do { PDMCritSectRwLeaveExcl(&(a_pVM)->iom.s.CritSect); } while (0)
     
    449448# define IOM_IS_EXCL_LOCK_OWNER(a_pVM)          PDMCritSectRwIsWriteOwner(&(a_pVM)->iom.s.CritSect)
    450449#else
    451 # define IOM_LOCK(a_pVM)                        PDMCritSectEnter(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)
    452 # define IOM_UNLOCK(a_pVM)                      do { PDMCritSectLeave(&(a_pVM)->iom.s.CritSect); } while (0)
     450# define IOM_LOCK_EXCL(a_pVM)                   PDMCritSectEnter(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)
     451# define IOM_UNLOCK_EXCL(a_pVM)                 do { PDMCritSectLeave(&(a_pVM)->iom.s.CritSect); } while (0)
    453452# define IOM_LOCK_SHARED_EX(a_pVM, a_rcBusy)    PDMCritSectEnter(&(a_pVM)->iom.s.CritSect, (a_rcBusy))
    454453# define IOM_UNLOCK_SHARED(a_pVM)               do { PDMCritSectLeave(&(a_pVM)->iom.s.CritSect); } while (0)
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