VirtualBox

Changeset 20722 in vbox


Ignore:
Timestamp:
Jun 19, 2009 12:34:21 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
48835
Message:

More IOM locking and checks.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/IOM.cpp

    r20700 r20722  
    15351535     * Find the MMIO range and check that the input matches.
    15361536     */
     1537    iomLock(pVM);
    15371538    PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhysStart);
    1538     AssertReturn(pRange, VERR_IOM_MMIO_RANGE_NOT_FOUND);
    1539     AssertReturn(pRange->pDevInsR3 == pDevIns, VERR_IOM_NOT_MMIO_RANGE_OWNER);
    1540     AssertReturn(pRange->GCPhys == GCPhysStart, VERR_IOM_INVALID_MMIO_RANGE);
    1541     AssertReturn(pRange->cb == cbRange, VERR_IOM_INVALID_MMIO_RANGE);
     1539    AssertReturnStmt(pRange, iomUnlock(pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND);
     1540    AssertReturnStmt(pRange->pDevInsR3 == pDevIns, iomUnlock(pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER);
     1541    AssertReturnStmt(pRange->GCPhys == GCPhysStart, iomUnlock(pVM), VERR_IOM_INVALID_MMIO_RANGE);
     1542    AssertReturnStmt(pRange->cb == cbRange, iomUnlock(pVM), VERR_IOM_INVALID_MMIO_RANGE);
    15421543
    15431544    pRange->pvUserRC          = pvUser;
     
    15461547    pRange->pfnFillCallbackRC = pfnFillCallback;
    15471548    pRange->pDevInsRC         = MMHyperCCToRC(pVM, pDevIns);
     1549    iomUnlock(pVM);
    15481550
    15491551    return VINF_SUCCESS;
     
    15891591     * Find the MMIO range and check that the input matches.
    15901592     */
     1593    iomLock(pVM);
    15911594    PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhysStart);
    1592     AssertReturn(pRange, VERR_IOM_MMIO_RANGE_NOT_FOUND);
    1593     AssertReturn(pRange->pDevInsR3 == pDevIns, VERR_IOM_NOT_MMIO_RANGE_OWNER);
    1594     AssertReturn(pRange->GCPhys == GCPhysStart, VERR_IOM_INVALID_MMIO_RANGE);
    1595     AssertReturn(pRange->cb == cbRange, VERR_IOM_INVALID_MMIO_RANGE);
     1595    AssertReturnStmt(pRange, iomUnlock(pVM), VERR_IOM_MMIO_RANGE_NOT_FOUND);
     1596    AssertReturnStmt(pRange->pDevInsR3 == pDevIns, iomUnlock(pVM), VERR_IOM_NOT_MMIO_RANGE_OWNER);
     1597    AssertReturnStmt(pRange->GCPhys == GCPhysStart, iomUnlock(pVM), VERR_IOM_INVALID_MMIO_RANGE);
     1598    AssertReturnStmt(pRange->cb == cbRange, iomUnlock(pVM), VERR_IOM_INVALID_MMIO_RANGE);
    15961599
    15971600    pRange->pvUserR0          = pvUser;
     
    16001603    pRange->pfnFillCallbackR0 = pfnFillCallback;
    16011604    pRange->pDevInsR0         = MMHyperCCToR0(pVM, pDevIns);
     1605    iomUnlock(pVM);
    16021606
    16031607    return VINF_SUCCESS;
  • trunk/src/VBox/VMM/IOMInternal.h

    r20700 r20722  
    473473DECLINLINE(CTX_SUFF(PIOMIOPORTRANGE)) iomIOPortGetRange(PIOM pIOM, RTIOPORT Port)
    474474{
     475#ifdef IN_RING3
     476    if (PDMCritSectIsInitialized(&pIOM->EmtLock))
     477#endif
     478        Assert(IOMIsLockOwner(IOM2VM(pIOM)));
    475479    CTX_SUFF(PIOMIOPORTRANGE) pRange = (CTX_SUFF(PIOMIOPORTRANGE))RTAvlroIOPortRangeGet(&pIOM->CTX_SUFF(pTrees)->CTX_SUFF(IOPortTree), Port);
    476480    return pRange;
     
    489493DECLINLINE(PIOMIOPORTRANGER3) iomIOPortGetRangeR3(PIOM pIOM, RTIOPORT Port)
    490494{
     495#ifdef IN_RING3
     496    if (PDMCritSectIsInitialized(&pIOM->EmtLock))
     497#endif
     498        Assert(IOMIsLockOwner(IOM2VM(pIOM)));
    491499    PIOMIOPORTRANGER3 pRange = (PIOMIOPORTRANGER3)RTAvlroIOPortRangeGet(&pIOM->CTX_SUFF(pTrees)->IOPortTreeR3, Port);
    492500    return pRange;
     
    505513DECLINLINE(PIOMMMIORANGE) iomMMIOGetRange(PIOM pIOM, RTGCPHYS GCPhys)
    506514{
     515#ifdef IN_RING3
     516    if (PDMCritSectIsInitialized(&pIOM->EmtLock))
     517#endif
     518        Assert(IOMIsLockOwner(IOM2VM(pIOM)));
    507519    PIOMMMIORANGE pRange = pIOM->CTX_SUFF(pMMIORangeLast);
    508520    if (    !pRange
     
    511523    return pRange;
    512524}
     525
     526#ifdef VBOX_STRICT
     527/**
     528 * Gets the MMIO range for the specified physical address in the current context.
     529 *
     530 * @returns Pointer to MMIO range.
     531 * @returns NULL if address not in a MMIO range.
     532 *
     533 * @param   pIOM    IOM instance data.
     534 * @param   GCPhys  Physical address to lookup.
     535 */
     536DECLINLINE(PIOMMMIORANGE) iomMMIOGetRangeUnsafe(PIOM pIOM, RTGCPHYS GCPhys)
     537{
     538    PIOMMMIORANGE pRange = pIOM->CTX_SUFF(pMMIORangeLast);
     539    if (    !pRange
     540        ||  GCPhys - pRange->GCPhys >= pRange->cb)
     541        pIOM->CTX_SUFF(pMMIORangeLast) = pRange = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pIOM->CTX_SUFF(pTrees)->MMIOTree, GCPhys);
     542    return pRange;
     543}
     544#endif
    513545
    514546
  • trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp

    r20569 r20722  
    12731273VMMDECL(int) IOMMMIOPhysHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pCtxCore, RTGCPHYS GCPhysFault)
    12741274{
    1275     return iomMMIOHandler(pVM, uErrorCode, pCtxCore, GCPhysFault, iomMMIOGetRange(&pVM->iom.s, GCPhysFault));
     1275    int rc;
     1276    rc = iomLock(pVM);
     1277#ifndef IN_RING3
     1278    if (rc == VERR_SEM_BUSY)
     1279        return (uErrorCode & X86_TRAP_PF_RW) ? VINF_IOM_HC_MMIO_WRITE : VINF_IOM_HC_MMIO_READ;
     1280#endif
     1281    rc = iomMMIOHandler(pVM, uErrorCode, pCtxCore, GCPhysFault, iomMMIOGetRange(&pVM->iom.s, GCPhysFault));
     1282    iomUnlock(pVM);
     1283    return rc;
    12761284}
    12771285
     
    18651873VMMDECL(int) IOMMMIOMapMMIO2Page(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapped, uint64_t fPageFlags)
    18661874{
     1875    /* Currently only called from the VGA device during MMIO. */
     1876    Assert(IOMIsLockOwner(pVM));
    18671877    Log(("IOMMMIOMapMMIO2Page %RGp -> %RGp flags=%RX64\n", GCPhys, GCPhysRemapped, fPageFlags));
    18681878
     
    18821892    PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhys);
    18831893    AssertMsgReturn(pRange,
    1884                     ("Handlers and page tables are out of sync or something! GCPhys=%RGp\n", GCPhys),
    1885                     VERR_IOM_MMIO_RANGE_NOT_FOUND);
     1894            ("Handlers and page tables are out of sync or something! GCPhys=%RGp\n", GCPhys), VERR_IOM_MMIO_RANGE_NOT_FOUND);
     1895
    18861896    Assert((pRange->GCPhys       & PAGE_OFFSET_MASK) == 0);
    18871897    Assert((pRange->Core.KeyLast & PAGE_OFFSET_MASK) == PAGE_OFFSET_MASK);
     
    19301940VMMDECL(int) IOMMMIOMapMMIOHCPage(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint64_t fPageFlags)
    19311941{
     1942    /* Currently only called from VT-x code during a page fault. */
    19321943    Log(("IOMMMIOMapMMIOHCPage %RGp -> %RGp flags=%RX64\n", GCPhys, HCPhys, fPageFlags));
    19331944
     
    19401951     * Lookup the context range node the page belongs to.
    19411952     */
    1942     PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhys);
     1953#ifdef VBOX_STRICT
     1954    /* Can't lock IOM here due to potential deadlocks in the VGA device; not safe to access. */
     1955    PIOMMMIORANGE pRange = iomMMIOGetRangeUnsafe(&pVM->iom.s, GCPhys);
    19431956    AssertMsgReturn(pRange,
    1944                     ("Handlers and page tables are out of sync or something! GCPhys=%RGp\n", GCPhys),
    1945                     VERR_IOM_MMIO_RANGE_NOT_FOUND);
     1957            ("Handlers and page tables are out of sync or something! GCPhys=%RGp\n", GCPhys), VERR_IOM_MMIO_RANGE_NOT_FOUND);
    19461958    Assert((pRange->GCPhys       & PAGE_OFFSET_MASK) == 0);
    19471959    Assert((pRange->Core.KeyLast & PAGE_OFFSET_MASK) == PAGE_OFFSET_MASK);
     1960#endif
    19481961
    19491962    /*
     
    19531966    HCPhys &= ~(RTHCPHYS)PAGE_OFFSET_MASK;
    19541967
    1955     int rc = PGMHandlerPhysicalPageAliasHC(pVM, pRange->GCPhys, GCPhys, HCPhys);
     1968    int rc = PGMHandlerPhysicalPageAliasHC(pVM, GCPhys, GCPhys, HCPhys);
    19561969    AssertRCReturn(rc, rc);
    19571970
     
    19902003     * Lookup the context range node the page belongs to.
    19912004     */
    1992     PIOMMMIORANGE pRange = iomMMIOGetRange(&pVM->iom.s, GCPhys);
     2005#ifdef VBOX_STRICT
     2006    /* Can't lock IOM here due to potential deadlocks in the VGA device; not safe to access. */
     2007    PIOMMMIORANGE pRange = iomMMIOGetRangeUnsafe(&pVM->iom.s, GCPhys);
    19932008    AssertMsgReturn(pRange,
    1994                     ("Handlers and page tables are out of sync or something! GCPhys=%RGp\n", GCPhys),
    1995                     VERR_IOM_MMIO_RANGE_NOT_FOUND);
     2009            ("Handlers and page tables are out of sync or something! GCPhys=%RGp\n", GCPhys), VERR_IOM_MMIO_RANGE_NOT_FOUND);
     2010    Assert((pRange->GCPhys       & PAGE_OFFSET_MASK) == 0);
     2011    Assert((pRange->Core.KeyLast & PAGE_OFFSET_MASK) == PAGE_OFFSET_MASK);
     2012#endif
    19962013
    19972014    /*
     
    20012018     * a page pool flush pending (unlikely).
    20022019     */
    2003     int rc = PGMHandlerPhysicalReset(pVM, pRange->GCPhys);
     2020    int rc = PGMHandlerPhysicalReset(pVM, GCPhys);
    20042021    AssertRC(rc);
    20052022
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette