diff options
Diffstat (limited to 'hw/pci/pci.c')
-rw-r--r-- | hw/pci/pci.c | 13 |
1 files changed, 5 insertions, 8 deletions
diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 4700e95206..eba7ca25ad 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -2383,17 +2383,14 @@ static void pci_device_class_init(ObjectClass *klass, void *data) AddressSpace *pci_device_iommu_address_space(PCIDevice *dev) { PCIBus *bus = PCI_BUS(dev->bus); + PCIBus *iommu_bus = bus; - if (bus->iommu_fn) { - return bus->iommu_fn(bus, bus->iommu_opaque, dev->devfn); + while(iommu_bus && !iommu_bus->iommu_fn && iommu_bus->parent_dev) { + iommu_bus = PCI_BUS(iommu_bus->parent_dev->bus); } - - 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); + if (iommu_bus && iommu_bus->iommu_fn) { + return iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, dev->devfn); } - return &address_space_memory; } |