mirror of https://gitee.com/openkylin/qemu.git
pci: Introduce helper to retrieve a PCI device's DMA address space
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 <david@gibson.dropbear.id.au> [aik: added inheritance from parent if iommu is not set for the current bus] Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
1ae2757c6c
commit
9eda7d373e
24
hw/pci/pci.c
24
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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue