qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC PATCH 2/2] pci: add PCIIOMMUOps and PCIIOMMUIntRemapFu


From: Peter Xu
Subject: [Qemu-devel] [RFC PATCH 2/2] pci: add PCIIOMMUOps and PCIIOMMUIntRemapFunc
Date: Wed, 17 Feb 2016 18:25:42 +0800

This patch extended the current PCI IOMMU functions into operation list,
one new op is added to do interrupt remapping.

Currently it is not working since int_remap is always NULL. It only
provide a interface to extend PCI MSI to support interrupt remapping in
the future.

One helper function pci_setup_iommu_ops() is introduced. We can use this
instead of the origin pci_setup_iommu() one to extend interrupt
remapping on specific platform.

Signed-off-by: Peter Xu <address@hidden>
---
 hw/pci/pci.c             | 21 ++++++++++++++++-----
 include/hw/pci/pci.h     | 10 ++++++++++
 include/hw/pci/pci_bus.h |  2 +-
 3 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 3f58bd4..65046e4 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -2404,21 +2404,32 @@ AddressSpace *pci_device_iommu_address_space(PCIDevice 
*dev)
     PCIBus *bus = PCI_BUS(dev->bus);
     PCIBus *iommu_bus = bus;
 
-    while(iommu_bus && !iommu_bus->iommu_fn && iommu_bus->parent_dev) {
+    while(iommu_bus && !iommu_bus->iommu_ops.as_lookup && \
+          iommu_bus->parent_dev) {
         iommu_bus = PCI_BUS(iommu_bus->parent_dev->bus);
     }
-    if (iommu_bus && iommu_bus->iommu_fn) {
-        return iommu_bus->iommu_fn(bus, iommu_bus->iommu_opaque, dev->devfn);
+    if (iommu_bus && iommu_bus->iommu_ops.as_lookup) {
+        return iommu_bus->iommu_ops.as_lookup(bus, iommu_bus->iommu_opaque,
+                                              dev->devfn);
     }
     return &address_space_memory;
 }
 
-void pci_setup_iommu(PCIBus *bus, PCIIOMMUASLookupFunc fn, void *opaque)
+void pci_setup_iommu_ops(PCIBus *bus, PCIIOMMUOps *ops, void *opaque)
 {
-    bus->iommu_fn = fn;
+    bus->iommu_ops = *ops;
     bus->iommu_opaque = opaque;
 }
 
+void pci_setup_iommu(PCIBus *bus, PCIIOMMUASLookupFunc fn, void *opaque)
+{
+    PCIIOMMUOps ops = {
+        .as_lookup = fn,
+        .int_remap = NULL,
+    };
+    pci_setup_iommu_ops(bus, &ops, 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 846afee..3636151 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -418,10 +418,20 @@ void pci_bus_get_w64_range(PCIBus *bus, Range *range);
 
 void pci_device_deassert_intx(PCIDevice *dev);
 
+/* IOMMU op to find address space for device */
 typedef AddressSpace *(*PCIIOMMUASLookupFunc)(PCIBus *, void *, int);
+/* IOMMU op to do interrupt remapping */
+typedef int (*PCIIOMMUIntRemapFunc)(void *, MSIMessage *origin, MSIMessage 
*out);
+
+struct PCIIOMMUOps {
+    PCIIOMMUASLookupFunc as_lookup;
+    PCIIOMMUIntRemapFunc int_remap;
+};
+typedef struct PCIIOMMUOps PCIIOMMUOps;
 
 AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
 void pci_setup_iommu(PCIBus *bus, PCIIOMMUASLookupFunc fn, void *opaque);
+void pci_setup_iommu_ops(PCIBus *bus, PCIIOMMUOps *ops, void *opaque);
 
 static inline void
 pci_set_byte(uint8_t *config, uint8_t val)
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index a8ab9c2..034a411 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -20,7 +20,7 @@ typedef struct PCIBusClass {
 
 struct PCIBus {
     BusState qbus;
-    PCIIOMMUASLookupFunc iommu_fn;
+    PCIIOMMUOps iommu_ops;
     void *iommu_opaque;
     uint8_t devfn_min;
     pci_set_irq_fn set_irq;
-- 
2.4.3




reply via email to

[Prev in Thread] Current Thread [Next in Thread]