hw/pci/pci_host: Allow PCI host to bypass iommu

Add a new bypass_iommu property for PCI host and use it to check
whether devices attached to the PCI root bus will bypass iommu.
In pci_device_iommu_address_space(), check the property and
avoid getting iommu address space for devices bypass iommu.

Signed-off-by: Xingang Wang <wangxingang5@huawei.com>
Reviewed-by: Eric Auger <eric.auger@redhat.com>
Message-Id: <1625748919-52456-2-git-send-email-wangxingang5@huawei.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
Xingang Wang 2021-07-08 12:55:11 +00:00 committed by Michael S. Tsirkin
parent 7395b3e3e7
commit 2d64b7bbb2
4 changed files with 20 additions and 1 deletions

View file

@ -416,6 +416,22 @@ const char *pci_root_bus_path(PCIDevice *dev)
return rootbus->qbus.name;
}
bool pci_bus_bypass_iommu(PCIBus *bus)
{
PCIBus *rootbus = bus;
PCIHostState *host_bridge;
if (!pci_bus_is_root(bus)) {
rootbus = pci_device_root_bus(bus->parent_dev);
}
host_bridge = PCI_HOST_BRIDGE(rootbus->qbus.parent);
assert(host_bridge->bus == rootbus);
return host_bridge->bypass_iommu;
}
static void pci_root_bus_init(PCIBus *bus, DeviceState *parent,
MemoryRegion *address_space_mem,
MemoryRegion *address_space_io,
@ -2718,7 +2734,7 @@ AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
iommu_bus = parent_bus;
}
if (iommu_bus && iommu_bus->iommu_fn) {
if (!pci_bus_bypass_iommu(bus) && iommu_bus && iommu_bus->iommu_fn) {
return iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, devfn);
}
return &address_space_memory;