DMA reentrancy problems can occur in BHs: dev_mmio->schedule_bh dev_bh->dma_write->dev_mmio
This patch attempts to address this scenario by marking the device as engaged_in_io, when it calls into PCI and SGList DMA APIs. Signed-off-by: Alexander Bulekov <alx...@bu.edu> --- include/hw/pci/pci.h | 6 +++++- softmmu/dma-helpers.c | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index e7cdf2d5ec..8420984b23 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -808,7 +808,11 @@ static inline MemTxResult pci_dma_rw(PCIDevice *dev, dma_addr_t addr, void *buf, dma_addr_t len, DMADirection dir) { - return dma_memory_rw(pci_get_address_space(dev), addr, buf, len, dir); + MemTxResult result; + dev->qdev.engaged_in_io = true; + result = dma_memory_rw(pci_get_address_space(dev), addr, buf, len, dir); + dev->qdev.engaged_in_io = false; + return result; } /** diff --git a/softmmu/dma-helpers.c b/softmmu/dma-helpers.c index 7d766a5e89..dd27ba4def 100644 --- a/softmmu/dma-helpers.c +++ b/softmmu/dma-helpers.c @@ -303,6 +303,7 @@ static uint64_t dma_buf_rw(uint8_t *ptr, int32_t len, QEMUSGList *sg, resid = sg->size; sg_cur_index = 0; len = MIN(len, resid); + sg->dev->engaged_in_io = true; while (len > 0) { ScatterGatherEntry entry = sg->sg[sg_cur_index++]; int32_t xfer = MIN(len, entry.len); @@ -311,6 +312,7 @@ static uint64_t dma_buf_rw(uint8_t *ptr, int32_t len, QEMUSGList *sg, len -= xfer; resid -= xfer; } + sg->dev->engaged_in_io = true; return resid; } -- 2.33.0