VirtualBox

Changeset 87127 in vbox for trunk/src/VBox/Devices/PC


Ignore:
Timestamp:
Dec 25, 2020 1:10:15 PM (4 years ago)
Author:
vboxsync
Message:

DMA,PDM: Pass the pDevIns of the caller to PDMDMAREG::pfnRegister. DMA controller now locks all registered DMA devices before doing callbacks, as it is in the best position to deal with the lock order inversion issue. bugref:9888

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevDMA.cpp

    r84913 r87127  
    103103/* State information for a single DMA channel. */
    104104typedef struct {
     105    PPDMDEVINS                          pDevInsHandler; /**< The device instance the channel is associated with. */
    105106    RTR3PTR                             pvUser;         /* User specific context. */
    106107    R3PTRTYPE(PFNDMATRANSFERHANDLER)    pfnXferHandler; /* Transfer handler for channel. */
     
    591592
    592593    Log3(("DMA address %screment, mode %d\n", IS_MODE_DEC(ch->u8Mode) ? "de" : "in", ch->u8Mode >> 6));
     594    AssertReturnVoid(ch->pfnXferHandler);
    593595
    594596    /* Addresses and counts are shifted for 16-bit channels. */
     
    597599     * transferring more than it should if auto-init is not in use.
    598600     */
    599     end_cnt = ch->pfnXferHandler(pThis->pDevIns, ch->pvUser, (ctlidx * 4) + chidx,
     601    end_cnt = ch->pfnXferHandler(ch->pDevInsHandler, ch->pvUser, (ctlidx * 4) + chidx,
    600602                                 start_cnt, (ch->u16BaseCount + 1) << dc->is16bit);
    601603    ch->u16CurCount = end_cnt >> dc->is16bit;
     
    624626    DMAControl  *dc;
    625627    int          chidx, mask;
     628
    626629    STAM_PROFILE_START(&pThis->StatRun, a);
     630
     631    /* We must first lock all the devices then the DMAC or we end up with a
     632       lock order validation when the callback helpers (PDMDMACREG) are being
     633       invoked from I/O port and MMIO callbacks in channel devices.  While this
     634       may sound a little brutish, it's actually in line with the bus locking
     635       the original DMAC did back in the days. Besides, we've only got the FDC
     636       and SB16 as potential customers here at present, so hardly a problem. */
     637    for (unsigned idxCtl = 0; idxCtl < RT_ELEMENTS(pThis->DMAC); idxCtl++)
     638        for (unsigned idxCh = 0; idxCh < RT_ELEMENTS(pThis->DMAC[idxCtl].ChState); idxCh++)
     639            if (pThis->DMAC[idxCtl].ChState[idxCh].pDevInsHandler)
     640                PDMDevHlpCritSectEnter(pDevIns, pThis->DMAC[idxCtl].ChState[idxCh].pDevInsHandler->pCritSectRoR3, VERR_IGNORED);
    627641    PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VERR_IGNORED);
    628642
     
    644658    }
    645659
     660    /* Unlock everything (order is mostly irrelevant). */
     661    for (unsigned idxCtl = 0; idxCtl < RT_ELEMENTS(pThis->DMAC); idxCtl++)
     662        for (unsigned idxCh = 0; idxCh < RT_ELEMENTS(pThis->DMAC[idxCtl].ChState); idxCh++)
     663            if (pThis->DMAC[idxCtl].ChState[idxCh].pDevInsHandler)
     664                PDMDevHlpCritSectLeave(pDevIns, pThis->DMAC[idxCtl].ChState[idxCh].pDevInsHandler->pCritSectRoR3);
    646665    PDMDevHlpCritSectLeave(pDevIns, pDevIns->pCritSectRoR3);
     666
    647667    STAM_PROFILE_STOP(&pThis->StatRun, a);
    648668    return 0;
     
    652672 * @interface_method_impl{PDMDMAREG,pfnRegister}
    653673 */
    654 static DECLCALLBACK(void) dmaR3Register(PPDMDEVINS pDevIns, unsigned uChannel,
     674static DECLCALLBACK(void) dmaR3Register(PPDMDEVINS pDevIns, unsigned uChannel, PPDMDEVINS pDevInsHandler,
    655675                                        PFNDMATRANSFERHANDLER pfnTransferHandler, void *pvUser)
    656676{
     
    661681
    662682    PDMDevHlpCritSectEnter(pDevIns, pDevIns->pCritSectRoR3, VERR_IGNORED);
     683    ch->pDevInsHandler = pDevInsHandler;
    663684    ch->pfnXferHandler = pfnTransferHandler;
    664685    ch->pvUser = pvUser;
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