This patch adds pci_device_get_iommu_attr() to get vIOMMU attributes. e.g. if nesting IOMMU wanted. Cc: Kevin Tian <kevin.tian@xxxxxxxxx> Cc: Jacob Pan <jacob.jun.pan@xxxxxxxxxxxxxxx> Cc: Peter Xu <peterx@xxxxxxxxxx> Cc: Eric Auger <eric.auger@xxxxxxxxxx> Cc: Yi Sun <yi.y.sun@xxxxxxxxxxxxxxx> Cc: David Gibson <david@xxxxxxxxxxxxxxxxxxxxx> Cc: Michael S. Tsirkin <mst@xxxxxxxxxx> Signed-off-by: Liu Yi L <yi.l.liu@xxxxxxxxx> --- hw/pci/pci.c | 35 ++++++++++++++++++++++++++++++----- include/hw/pci/pci.h | 7 +++++++ 2 files changed, 37 insertions(+), 5 deletions(-) diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 61f115d742..19365e2799 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -2665,7 +2665,8 @@ static void pci_device_class_base_init(ObjectClass *klass, void *data) } } -AddressSpace *pci_device_iommu_address_space(PCIDevice *dev) +static void pci_device_get_iommu_bus_devfn(PCIDevice *dev, + PCIBus **pbus, uint8_t *pdevfn) { PCIBus *bus = pci_get_bus(dev); PCIBus *iommu_bus = bus; @@ -2716,14 +2717,38 @@ AddressSpace *pci_device_iommu_address_space(PCIDevice *dev) iommu_bus = parent_bus; } - if (iommu_bus && iommu_bus->iommu_ops && - iommu_bus->iommu_ops->get_address_space) { - return iommu_bus->iommu_ops->get_address_space(bus, - iommu_bus->iommu_opaque, devfn); + *pbus = iommu_bus; + *pdevfn = devfn; +} + +AddressSpace *pci_device_iommu_address_space(PCIDevice *dev) +{ + PCIBus *bus; + uint8_t devfn; + + pci_device_get_iommu_bus_devfn(dev, &bus, &devfn); + if (bus && bus->iommu_ops && + bus->iommu_ops->get_address_space) { + return bus->iommu_ops->get_address_space(bus, + bus->iommu_opaque, devfn); } return &address_space_memory; } +int pci_device_get_iommu_attr(PCIDevice *dev, IOMMUAttr attr, void *data) +{ + PCIBus *bus; + uint8_t devfn; + + pci_device_get_iommu_bus_devfn(dev, &bus, &devfn); + if (bus && bus->iommu_ops && + bus->iommu_ops->get_iommu_attr) { + return bus->iommu_ops->get_iommu_attr(bus, bus->iommu_opaque, + devfn, attr, data); + } + return -ENOENT; +} + void pci_setup_iommu(PCIBus *bus, const PCIIOMMUOps *ops, void *opaque) { bus->iommu_ops = ops; diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h index d6b962f646..b99e05c81e 100644 --- a/include/hw/pci/pci.h +++ b/include/hw/pci/pci.h @@ -485,13 +485,20 @@ void pci_bus_get_w64_range(PCIBus *bus, Range *range); void pci_device_deassert_intx(PCIDevice *dev); +typedef enum IOMMUAttr { + IOMMU_WANT_NESTING, +} IOMMUAttr; + typedef struct PCIIOMMUOps PCIIOMMUOps; struct PCIIOMMUOps { AddressSpace * (*get_address_space)(PCIBus *bus, void *opaque, int32_t devfn); + int (*get_iommu_attr)(PCIBus *bus, void *opaque, int32_t devfn, + IOMMUAttr attr, void *data); }; AddressSpace *pci_device_iommu_address_space(PCIDevice *dev); +int pci_device_get_iommu_attr(PCIDevice *dev, IOMMUAttr attr, void *data); void pci_setup_iommu(PCIBus *bus, const PCIIOMMUOps *iommu_ops, void *opaque); static inline void -- 2.25.1