diff options
-rw-r--r-- | dma-helpers.c | 178 | ||||
-rw-r--r-- | exec.c | 3 | ||||
-rw-r--r-- | hw/pci/pci.c | 3 | ||||
-rw-r--r-- | hw/ppc/spapr_iommu.c | 2 | ||||
-rw-r--r-- | include/sysemu/dma.h | 79 |
5 files changed, 26 insertions, 239 deletions
diff --git a/dma-helpers.c b/dma-helpers.c index 2e298b6..c53705a 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -14,32 +14,26 @@ /* #define DEBUG_IOMMU */ -static void do_dma_memory_set(AddressSpace *as, - dma_addr_t addr, uint8_t c, dma_addr_t len) +int dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, dma_addr_t len) { + AddressSpace *as = dma->as; + + dma_barrier(dma, DMA_DIRECTION_FROM_DEVICE); + #define FILLBUF_SIZE 512 uint8_t fillbuf[FILLBUF_SIZE]; int l; + bool error = false; memset(fillbuf, c, FILLBUF_SIZE); while (len > 0) { l = len < FILLBUF_SIZE ? len : FILLBUF_SIZE; - address_space_rw(as, addr, fillbuf, l, true); + error |= address_space_rw(as, addr, fillbuf, l, true); len -= l; addr += l; } -} -int dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, dma_addr_t len) -{ - dma_barrier(dma, DMA_DIRECTION_FROM_DEVICE); - - if (dma_has_iommu(dma)) { - return iommu_dma_memory_set(dma, addr, c, len); - } - do_dma_memory_set(dma->as, addr, c, len); - - return 0; + return error; } void qemu_sglist_init(QEMUSGList *qsg, int alloc_hint, DMAContext *dma) @@ -278,162 +272,10 @@ void dma_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, bdrv_acct_start(bs, cookie, sg->size, type); } -bool iommu_dma_memory_valid(DMAContext *dma, dma_addr_t addr, dma_addr_t len, - DMADirection dir) +void dma_context_init(DMAContext *dma, AddressSpace *as) { - hwaddr paddr, plen; - #ifdef DEBUG_IOMMU - fprintf(stderr, "dma_memory_check context=%p addr=0x" DMA_ADDR_FMT - " len=0x" DMA_ADDR_FMT " dir=%d\n", dma, addr, len, dir); -#endif - - while (len) { - if (dma->translate(dma, addr, &paddr, &plen, dir) != 0) { - return false; - } - - /* The translation might be valid for larger regions. */ - if (plen > len) { - plen = len; - } - - if (!address_space_access_valid(dma->as, paddr, len, - dir == DMA_DIRECTION_FROM_DEVICE)) { - return false; - } - - len -= plen; - addr += plen; - } - - return true; -} - -int iommu_dma_memory_rw(DMAContext *dma, dma_addr_t addr, - void *buf, dma_addr_t len, DMADirection dir) -{ - hwaddr paddr, plen; - int err; - -#ifdef DEBUG_IOMMU - fprintf(stderr, "dma_memory_rw context=%p addr=0x" DMA_ADDR_FMT " len=0x" - DMA_ADDR_FMT " dir=%d\n", dma, addr, len, dir); -#endif - - while (len) { - err = dma->translate(dma, addr, &paddr, &plen, dir); - if (err) { - /* - * In case of failure on reads from the guest, we clean the - * destination buffer so that a device that doesn't test - * for errors will not expose qemu internal memory. - */ - memset(buf, 0, len); - return -1; - } - - /* The translation might be valid for larger regions. */ - if (plen > len) { - plen = len; - } - - address_space_rw(dma->as, paddr, buf, plen, dir == DMA_DIRECTION_FROM_DEVICE); - - len -= plen; - addr += plen; - buf += plen; - } - - return 0; -} - -int iommu_dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, - dma_addr_t len) -{ - hwaddr paddr, plen; - int err; - -#ifdef DEBUG_IOMMU - fprintf(stderr, "dma_memory_set context=%p addr=0x" DMA_ADDR_FMT - " len=0x" DMA_ADDR_FMT "\n", dma, addr, len); -#endif - - while (len) { - err = dma->translate(dma, addr, &paddr, &plen, - DMA_DIRECTION_FROM_DEVICE); - if (err) { - return err; - } - - /* The translation might be valid for larger regions. */ - if (plen > len) { - plen = len; - } - - do_dma_memory_set(dma->as, paddr, c, plen); - - len -= plen; - addr += plen; - } - - return 0; -} - -void dma_context_init(DMAContext *dma, AddressSpace *as, DMATranslateFunc translate, - DMAMapFunc map, DMAUnmapFunc unmap) -{ -#ifdef DEBUG_IOMMU - fprintf(stderr, "dma_context_init(%p, %p, %p, %p)\n", - dma, translate, map, unmap); + fprintf(stderr, "dma_context_init(%p -> %p)\n", dma, as); #endif dma->as = as; - dma->translate = translate; - dma->map = map; - dma->unmap = unmap; -} - -void *iommu_dma_memory_map(DMAContext *dma, dma_addr_t addr, dma_addr_t *len, - DMADirection dir) -{ - int err; - hwaddr paddr, plen; - void *buf; - - if (dma->map) { - return dma->map(dma, addr, len, dir); - } - - plen = *len; - err = dma->translate(dma, addr, &paddr, &plen, dir); - if (err) { - return NULL; - } - - /* - * If this is true, the virtual region is contiguous, - * but the translated physical region isn't. We just - * clamp *len, much like address_space_map() does. - */ - if (plen < *len) { - *len = plen; - } - - buf = address_space_map(dma->as, paddr, &plen, dir == DMA_DIRECTION_FROM_DEVICE); - *len = plen; - - return buf; -} - -void iommu_dma_memory_unmap(DMAContext *dma, void *buffer, dma_addr_t len, - DMADirection dir, dma_addr_t access_len) -{ - if (dma->unmap) { - dma->unmap(dma, buffer, len, dir, access_len); - return; - } - - address_space_unmap(dma->as, buffer, len, dir == DMA_DIRECTION_FROM_DEVICE, - access_len); - } @@ -1840,8 +1840,7 @@ static void memory_map_init(void) memory_listener_register(&io_memory_listener, &address_space_io); memory_listener_register(&tcg_memory_listener, &address_space_memory); - dma_context_init(&dma_context_memory, &address_space_memory, - NULL, NULL, NULL); + dma_context_init(&dma_context_memory, &address_space_memory); } MemoryRegion *get_system_memory(void) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index a3eb19e..3bcd07d 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -814,8 +814,9 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, memory_region_set_enabled(&pci_dev->bus_master_enable_region, false); address_space_init(&pci_dev->bus_master_as, &pci_dev->bus_master_enable_region); pci_dev->dma = g_new(DMAContext, 1); - dma_context_init(pci_dev->dma, &pci_dev->bus_master_as, NULL, NULL, NULL); + dma_context_init(pci_dev->dma, &pci_dev->bus_master_as); } + pci_dev->devfn = devfn; pstrcpy(pci_dev->name, sizeof(pci_dev->name), name); pci_dev->irq_state = 0; diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index 6e33929..4667e11 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -158,7 +158,7 @@ sPAPRTCETable *spapr_tce_new_table(uint32_t liobn, size_t window_size) memory_region_init_iommu(&tcet->iommu, &spapr_iommu_ops, "iommu-spapr", UINT64_MAX); address_space_init(&tcet->as, &tcet->iommu); - dma_context_init(&tcet->dma, &tcet->as, NULL, NULL, NULL); + dma_context_init(&tcet->dma, &tcet->as); QLIST_INSERT_HEAD(&spapr_tce_tables, tcet, list); diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h index 02e0dcd..3317dcf 100644 --- a/include/sysemu/dma.h +++ b/include/sysemu/dma.h @@ -46,26 +46,8 @@ typedef uint64_t dma_addr_t; #define DMA_ADDR_BITS 64 #define DMA_ADDR_FMT "%" PRIx64 -typedef int DMATranslateFunc(DMAContext *dma, - dma_addr_t addr, - hwaddr *paddr, - hwaddr *len, - DMADirection dir); -typedef void* DMAMapFunc(DMAContext *dma, - dma_addr_t addr, - dma_addr_t *len, - DMADirection dir); -typedef void DMAUnmapFunc(DMAContext *dma, - void *buffer, - dma_addr_t len, - DMADirection dir, - dma_addr_t access_len); - struct DMAContext { AddressSpace *as; - DMATranslateFunc *translate; - DMAMapFunc *map; - DMAUnmapFunc *unmap; }; /* A global DMA context corresponding to the address_space_memory @@ -98,41 +80,22 @@ static inline void dma_barrier(DMAContext *dma, DMADirection dir) } } -static inline bool dma_has_iommu(DMAContext *dma) -{ - return dma && dma->translate; -} - /* Checks that the given range of addresses is valid for DMA. This is * useful for certain cases, but usually you should just use * dma_memory_{read,write}() and check for errors */ -bool iommu_dma_memory_valid(DMAContext *dma, dma_addr_t addr, dma_addr_t len, - DMADirection dir); static inline bool dma_memory_valid(DMAContext *dma, dma_addr_t addr, dma_addr_t len, DMADirection dir) { - if (!dma_has_iommu(dma)) { - return address_space_access_valid(dma->as, addr, len, - dir == DMA_DIRECTION_FROM_DEVICE); - } else { - return iommu_dma_memory_valid(dma, addr, len, dir); - } + return address_space_access_valid(dma->as, addr, len, + dir == DMA_DIRECTION_FROM_DEVICE); } -int iommu_dma_memory_rw(DMAContext *dma, dma_addr_t addr, - void *buf, dma_addr_t len, DMADirection dir); static inline int dma_memory_rw_relaxed(DMAContext *dma, dma_addr_t addr, void *buf, dma_addr_t len, DMADirection dir) { - if (!dma_has_iommu(dma)) { - /* Fast-path for no IOMMU */ - address_space_rw(dma->as, addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE); - return 0; - } else { - return iommu_dma_memory_rw(dma, addr, buf, len, dir); - } + return address_space_rw(dma->as, addr, buf, len, dir == DMA_DIRECTION_FROM_DEVICE); } static inline int dma_memory_read_relaxed(DMAContext *dma, dma_addr_t addr, @@ -170,43 +133,26 @@ static inline int dma_memory_write(DMAContext *dma, dma_addr_t addr, DMA_DIRECTION_FROM_DEVICE); } -int iommu_dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, - dma_addr_t len); - int dma_memory_set(DMAContext *dma, dma_addr_t addr, uint8_t c, dma_addr_t len); -void *iommu_dma_memory_map(DMAContext *dma, - dma_addr_t addr, dma_addr_t *len, - DMADirection dir); static inline void *dma_memory_map(DMAContext *dma, dma_addr_t addr, dma_addr_t *len, DMADirection dir) { - if (!dma_has_iommu(dma)) { - hwaddr xlen = *len; - void *p; - - p = address_space_map(dma->as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE); - *len = xlen; - return p; - } else { - return iommu_dma_memory_map(dma, addr, len, dir); - } + hwaddr xlen = *len; + void *p; + + p = address_space_map(dma->as, addr, &xlen, dir == DMA_DIRECTION_FROM_DEVICE); + *len = xlen; + return p; } -void iommu_dma_memory_unmap(DMAContext *dma, - void *buffer, dma_addr_t len, - DMADirection dir, dma_addr_t access_len); static inline void dma_memory_unmap(DMAContext *dma, void *buffer, dma_addr_t len, DMADirection dir, dma_addr_t access_len) { - if (!dma_has_iommu(dma)) { - address_space_unmap(dma->as, buffer, (hwaddr)len, - dir == DMA_DIRECTION_FROM_DEVICE, access_len); - } else { - iommu_dma_memory_unmap(dma, buffer, len, dir, access_len); - } + address_space_unmap(dma->as, buffer, (hwaddr)len, + dir == DMA_DIRECTION_FROM_DEVICE, access_len); } #define DEFINE_LDST_DMA(_lname, _sname, _bits, _end) \ @@ -247,8 +193,7 @@ DEFINE_LDST_DMA(q, q, 64, be); #undef DEFINE_LDST_DMA -void dma_context_init(DMAContext *dma, AddressSpace *as, DMATranslateFunc translate, - DMAMapFunc map, DMAUnmapFunc unmap); +void dma_context_init(DMAContext *dma, AddressSpace *as); struct ScatterGatherEntry { dma_addr_t base; |