diff mbox series

[v3,02/15] hw/pci: Add a pci_setup_iommu_info() helper

Message ID 20230530175937.24202-3-joao.m.martins@oracle.com
State New
Headers show
Series vfio: VFIO migration support with vIOMMU | expand

Commit Message

Joao Martins May 30, 2023, 5:59 p.m. UTC
Provide a second PCI iommu bus initialization function which returns
PCIAddressSpace rather than an AddressSpace. The function is meant to
superseed pci_setup_iommu().

Under the hood in pci_device_iommu_info() if the new function pointer is
set in the device bus, use that instead and return the new object.

This is preparation for vIOMMU MR to be stored in PCIAddressSpace, thus
made available regardless of guest behaviour.

Signed-off-by: Joao Martins <joao.m.martins@oracle.com>
---
 hw/pci/pci.c             | 14 ++++++++++++--
 include/hw/pci/pci.h     |  2 ++
 include/hw/pci/pci_bus.h |  1 +
 3 files changed, 15 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index ecf8a543aa77..ac10333b5097 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2681,8 +2681,12 @@  PCIAddressSpace pci_device_iommu_info(PCIDevice *dev)
     }
 
     as = &address_space_memory;
-    if (!pci_bus_bypass_iommu(bus) && iommu_bus && iommu_bus->iommu_fn) {
-        as = iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, devfn);
+    if (!pci_bus_bypass_iommu(bus) && iommu_bus) {
+        if (iommu_bus->iommu_fn) {
+            as = iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, devfn);
+        } else if (iommu_bus->iommu_as_fn) {
+            return iommu_bus->iommu_as_fn(bus, iommu_bus->iommu_opaque, devfn);
+        }
     }
     return as_to_pci_as(as);
 }
@@ -2693,6 +2697,12 @@  void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque)
     bus->iommu_opaque = opaque;
 }
 
+void pci_setup_iommu_info(PCIBus *bus, PCIIOMMUASFunc fn, void *opaque)
+{
+    bus->iommu_as_fn = fn;
+    bus->iommu_opaque = opaque;
+}
+
 static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque)
 {
     Range *range = opaque;
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 9ffaf47fe2ab..d2c87d87a24e 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -368,6 +368,7 @@  typedef struct PCIAddressSpace {
 } PCIAddressSpace;
 
 typedef AddressSpace *(*PCIIOMMUFunc)(PCIBus *, void *, int);
+typedef PCIAddressSpace (*PCIIOMMUASFunc)(PCIBus *, void *, int);
 static inline PCIAddressSpace as_to_pci_as(AddressSpace *as)
 {
     PCIAddressSpace ret = { .as = as };
@@ -386,6 +387,7 @@  static inline AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
 }
 
 void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque);
+void pci_setup_iommu_info(PCIBus *bus, PCIIOMMUASFunc fn, void *opaque);
 
 pcibus_t pci_bar_address(PCIDevice *d,
                          int reg, uint8_t type, pcibus_t size);
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 56531759578f..a2795b23a3b0 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -34,6 +34,7 @@  struct PCIBus {
     BusState qbus;
     enum PCIBusFlags flags;
     PCIIOMMUFunc iommu_fn;
+    PCIIOMMUASFunc iommu_as_fn;
     void *iommu_opaque;
     uint8_t devfn_min;
     uint32_t slot_reserved_mask;