[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