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:
parent
7395b3e3e7
commit
2d64b7bbb2
18
hw/pci/pci.c
18
hw/pci/pci.c
@ -416,6 +416,22 @@ const char *pci_root_bus_path(PCIDevice *dev)
|
|||||||
return rootbus->qbus.name;
|
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,
|
static void pci_root_bus_init(PCIBus *bus, DeviceState *parent,
|
||||||
MemoryRegion *address_space_mem,
|
MemoryRegion *address_space_mem,
|
||||||
MemoryRegion *address_space_io,
|
MemoryRegion *address_space_io,
|
||||||
@ -2718,7 +2734,7 @@ AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
|
|||||||
|
|
||||||
iommu_bus = parent_bus;
|
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 iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, devfn);
|
||||||
}
|
}
|
||||||
return &address_space_memory;
|
return &address_space_memory;
|
||||||
|
@ -222,6 +222,7 @@ const VMStateDescription vmstate_pcihost = {
|
|||||||
static Property pci_host_properties_common[] = {
|
static Property pci_host_properties_common[] = {
|
||||||
DEFINE_PROP_BOOL("x-config-reg-migration-enabled", PCIHostState,
|
DEFINE_PROP_BOOL("x-config-reg-migration-enabled", PCIHostState,
|
||||||
mig_enabled, true),
|
mig_enabled, true),
|
||||||
|
DEFINE_PROP_BOOL("bypass-iommu", PCIHostState, bypass_iommu, false),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -480,6 +480,7 @@ void pci_for_each_bus(PCIBus *bus,
|
|||||||
|
|
||||||
PCIBus *pci_device_root_bus(const PCIDevice *d);
|
PCIBus *pci_device_root_bus(const PCIDevice *d);
|
||||||
const char *pci_root_bus_path(PCIDevice *dev);
|
const char *pci_root_bus_path(PCIDevice *dev);
|
||||||
|
bool pci_bus_bypass_iommu(PCIBus *bus);
|
||||||
PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn);
|
PCIDevice *pci_find_device(PCIBus *bus, int bus_num, uint8_t devfn);
|
||||||
int pci_qdev_find_device(const char *id, PCIDevice **pdev);
|
int pci_qdev_find_device(const char *id, PCIDevice **pdev);
|
||||||
void pci_bus_get_w64_range(PCIBus *bus, Range *range);
|
void pci_bus_get_w64_range(PCIBus *bus, Range *range);
|
||||||
|
@ -43,6 +43,7 @@ struct PCIHostState {
|
|||||||
uint32_t config_reg;
|
uint32_t config_reg;
|
||||||
bool mig_enabled;
|
bool mig_enabled;
|
||||||
PCIBus *bus;
|
PCIBus *bus;
|
||||||
|
bool bypass_iommu;
|
||||||
|
|
||||||
QLIST_ENTRY(PCIHostState) next;
|
QLIST_ENTRY(PCIHostState) next;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user