pci: introduce a bus master container
96a8821d21
("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>
This commit is contained in:
parent
e45da65322
commit
3716d5902d
|
@ -88,8 +88,8 @@ static void pci_init_bus_master(PCIDevice *pci_dev)
|
||||||
OBJECT(pci_dev), "bus master",
|
OBJECT(pci_dev), "bus master",
|
||||||
dma_as->root, 0, memory_region_size(dma_as->root));
|
dma_as->root, 0, memory_region_size(dma_as->root));
|
||||||
memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);
|
memory_region_set_enabled(&pci_dev->bus_master_enable_region, false);
|
||||||
address_space_init(&pci_dev->bus_master_as,
|
memory_region_add_subregion(&pci_dev->bus_master_container_region, 0,
|
||||||
&pci_dev->bus_master_enable_region, pci_dev->name);
|
&pci_dev->bus_master_enable_region);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pcibus_machine_done(Notifier *notifier, void *data)
|
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->devfn = devfn;
|
||||||
pci_dev->requester_id_cache = pci_req_id_cache_get(pci_dev);
|
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) {
|
if (qdev_hotplug) {
|
||||||
pci_init_bus_master(pci_dev);
|
pci_init_bus_master(pci_dev);
|
||||||
}
|
}
|
||||||
|
|
|
@ -284,6 +284,7 @@ struct PCIDevice {
|
||||||
char name[64];
|
char name[64];
|
||||||
PCIIORegion io_regions[PCI_NUM_REGIONS];
|
PCIIORegion io_regions[PCI_NUM_REGIONS];
|
||||||
AddressSpace bus_master_as;
|
AddressSpace bus_master_as;
|
||||||
|
MemoryRegion bus_master_container_region;
|
||||||
MemoryRegion bus_master_enable_region;
|
MemoryRegion bus_master_enable_region;
|
||||||
|
|
||||||
/* do not access the following fields */
|
/* do not access the following fields */
|
||||||
|
|
Loading…
Reference in a new issue