From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:55037) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V7oJh-0000nI-TD for qemu-devel@nongnu.org; Fri, 09 Aug 2013 11:09:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V7oJa-00064C-Mr for qemu-devel@nongnu.org; Fri, 09 Aug 2013 11:09:25 -0400 Received: from mail-pd0-f171.google.com ([209.85.192.171]:60193) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V7oJa-00063x-GK for qemu-devel@nongnu.org; Fri, 09 Aug 2013 11:09:18 -0400 Received: by mail-pd0-f171.google.com with SMTP id g10so660181pdj.30 for ; Fri, 09 Aug 2013 08:09:17 -0700 (PDT) From: Alexey Kardashevskiy Date: Sat, 10 Aug 2013 01:09:08 +1000 Message-Id: <1376060948-28790-1-git-send-email-aik@ozlabs.ru> Subject: [Qemu-devel] [PATCH v3] pci: Introduce helper to retrieve a PCI device's DMA address space List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Anthony Liguori , "Michael S . Tsirkin" , Alexey Kardashevskiy , Alex Williamson , Paolo Bonzini , David Gibson A PCI device's DMA address space (possibly an IOMMU) is returned by a method on the PCIBus. At the moment that only has one caller, so the method is simply open coded. We'll need another caller for VFIO, so this patch introduces a helper/wrapper function. If IOMMU is not set, the pci_device_iommu_address_space() function returns the parent's IOMMU skipping the "bus master" address space as otherwise proper emulation would require more effort for no benefit. Signed-off-by: David Gibson [aik: added inheritance from parent if iommu is not set for the current bus] Signed-off-by: Alexey Kardashevskiy --- Changes: v3: * added comment about ignoring bus master address space v2: * added inheritance, needed for a pci-bridge on spapr-ppc64 * pci_iommu_as renamed to pci_device_iommu_address_space --- hw/pci/pci.c | 24 ++++++++++++++++++------ include/hw/pci/pci.h | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 4c004f5..dbfa395 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -812,12 +812,7 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus, } pci_dev->bus = bus; - if (bus->iommu_fn) { - dma_as = bus->iommu_fn(bus, bus->iommu_opaque, devfn); - } else { - /* FIXME: inherit memory region from bus creator */ - dma_as = &address_space_memory; - } + dma_as = pci_device_iommu_address_space(pci_dev); memory_region_init_alias(&pci_dev->bus_master_enable_region, OBJECT(pci_dev), "bus master", @@ -2239,6 +2234,23 @@ static void pci_device_class_init(ObjectClass *klass, void *data) k->props = pci_props; } +AddressSpace *pci_device_iommu_address_space(PCIDevice *dev) +{ + PCIBus *bus = PCI_BUS(dev->bus); + + if (bus->iommu_fn) { + return bus->iommu_fn(bus, bus->iommu_opaque, dev->devfn); + } + + if (bus->parent_dev) { + /** We are ignoring the bus master DMA bit of the bridge + * as it would complicate things such as VFIO for no good reason */ + return pci_device_iommu_address_space(bus->parent_dev); + } + + return &address_space_memory; +} + void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque) { bus->iommu_fn = fn; diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index ccec2ba..2374aa9 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -405,6 +405,7 @@ void pci_device_deassert_intx(PCIDevice *dev); typedef AddressSpace *(*PCIIOMMUFunc)(PCIBus *, void *, int); +AddressSpace *pci_device_iommu_address_space(PCIDevice *dev); void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque); static inline void -- 1.8.3.2