aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wang <jasowang@redhat.com>2017-03-13 11:29:58 +0800
committerMichael S. Tsirkin <mst@redhat.com>2017-03-15 19:37:19 +0200
commit3716d5902d743e9a395b7d82f48df4fa56ed1ad3 (patch)
tree429fdbf003372857ba522d7034b0745a4d9d1e7e
parente45da653223869849877ee8f4b86f511f891d4f8 (diff)
pci: introduce a bus master container
96a8821d2141 ("virtio: unbreak virtio-pci with IOMMU after caching ring translations") tries to make IOMMU works with virtio memory region cache, but it requires IOMMU to be created before any virtio devices. This is sub optimal, fixing this by introduce a bus master container to make sure address space can be initialized during device registering, and then we can safely set alias and make bus_master_enable_region as its subregion during bus master initialization. Cc: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Jason Wang <jasowang@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r--hw/pci/pci.c9
-rw-r--r--include/hw/pci/pci.h1
2 files changed, 8 insertions, 2 deletions
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 273f1e4602..ad46390ec5 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -88,8 +88,8 @@ static void pci_init_bus_master(PCIDevice *pci_dev)
OBJECT(pci_dev), "bus master",
dma_as->root, 0, memory_region_size(dma_as->root));
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->name);
+ memory_region_add_subregion(&pci_dev->bus_master_container_region, 0,
+ &pci_dev->bus_master_enable_region);
}
static void pcibus_machine_done(Notifier *notifier, void *data)
@@ -995,6 +995,11 @@ static PCIDevice *do_pci_register_device(PCIDevice *pci_dev, PCIBus *bus,
pci_dev->devfn = devfn;
pci_dev->requester_id_cache = pci_req_id_cache_get(pci_dev);
+ memory_region_init(&pci_dev->bus_master_container_region, OBJECT(pci_dev),
+ "bus master container", UINT64_MAX);
+ address_space_init(&pci_dev->bus_master_as,
+ &pci_dev->bus_master_container_region, pci_dev->name);
+
if (qdev_hotplug) {
pci_init_bus_master(pci_dev);
}
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 9349acbfb2..713ede00bf 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -284,6 +284,7 @@ struct PCIDevice {
char name[64];
PCIIORegion io_regions[PCI_NUM_REGIONS];
AddressSpace bus_master_as;
+ MemoryRegion bus_master_container_region;
MemoryRegion bus_master_enable_region;
/* do not access the following fields */