All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-trivial] [PATCH] RFC kvm irqfd: add directly mapped MSI IRQ support
@ 2013-06-20 14:08 ` Alexey Kardashevskiy
  0 siblings, 0 replies; 72+ messages in thread
From: Alexey Kardashevskiy @ 2013-06-20 14:08 UTC (permalink / raw)
  To: qemu-devel
  Cc: Anthony Liguori, Michael S . Tsirkin, Alexey Kardashevskiy,
	Benjamin Herrenschmidt, Alexander Graf, qemu-trivial,
	Alex Williamson, qemu-ppc, Paolo Bonzini, Paul Mackerras,
	David Gibson

At the moment QEMU creates a route for every MSI IRQ.

Now we are about to add IRQFD support on PPC64-pseries platform.
pSeries already has in-kernel emulated interrupt controller with
8192 IRQs. Also, pSeries PHB already supports MSIMessage to IRQ
mapping as a part of PAPR requirements for MSI/MSIX guests.
Specifically, the pSeries guest does not touch MSIMessage's at
all, instead it uses rtas_ibm_change_msi and rtas_ibm_query_interrupt_source
rtas calls to do the mapping.

Therefore we do not really need more routing than we got already.
The patch introduces the infrastructure to enable direct IRQ mapping.

Signed-off-by: Alexey Kardashevskiy <aik@ozlabs.ru>

---

The patch is raw and ugly indeed, I made it only to demonstrate
the idea and see if it has right to live or not.

For some reason which I do not really understand (limited GSI numbers?)
the existing code always adds routing and I do not see why we would need it.

Thanks!
---
 hw/misc/vfio.c           |   11 +++++++++--
 hw/pci/pci.c             |   13 +++++++++++++
 hw/ppc/spapr_pci.c       |   13 +++++++++++++
 hw/virtio/virtio-pci.c   |   26 ++++++++++++++++++++------
 include/hw/pci/pci.h     |    4 ++++
 include/hw/pci/pci_bus.h |    1 +
 6 files changed, 60 insertions(+), 8 deletions(-)

diff --git a/hw/misc/vfio.c b/hw/misc/vfio.c
index 14aac04..2d9eef7 100644
--- a/hw/misc/vfio.c
+++ b/hw/misc/vfio.c
@@ -639,7 +639,11 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr,
      * Attempt to enable route through KVM irqchip,
      * default to userspace handling if unavailable.
      */
-    vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1;
+
+    vector->virq = msg ? pci_bus_map_msi(vdev->pdev.bus, *msg) : -1;
+    if (vector->virq < 0) {
+        vector->virq = msg ? kvm_irqchip_add_msi_route(kvm_state, *msg) : -1;
+    }
     if (vector->virq < 0 ||
         kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt,
                                        vector->virq) < 0) {
@@ -807,7 +811,10 @@ retry:
          * Attempt to enable route through KVM irqchip,
          * default to userspace handling if unavailable.
          */
-        vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg);
+        vector->virq = pci_bus_map_msi(vdev->pdev.bus, msg);
+        if (vector->virq < 0) {
+            vector->virq = kvm_irqchip_add_msi_route(kvm_state, msg);
+        }
         if (vector->virq < 0 ||
             kvm_irqchip_add_irqfd_notifier(kvm_state, &vector->interrupt,
                                            vector->virq) < 0) {
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index a976e46..a9875e9 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1254,6 +1254,19 @@ void pci_device_set_intx_routing_notifier(PCIDevice *dev,
     dev->intx_routing_notifier = notifier;
 }
 
+void pci_bus_set_map_msi_fn(PCIBus *bus, pci_map_msi_fn map_msi_fn)
+{
+    bus->map_msi = map_msi_fn;
+}
+
+int pci_bus_map_msi(PCIBus *bus, MSIMessage msg)
+{
+    if (bus->map_msi) {
+        return bus->map_msi(bus, msg);
+    }
+    return -1;
+}
+
 /*
  * PCI-to-PCI bridge specification
  * 9.1: Interrupt routing. Table 9-1
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 80408c9..9ef9a29 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -500,6 +500,18 @@ static void spapr_msi_write(void *opaque, hwaddr addr,
     qemu_irq_pulse(xics_get_qirq(spapr->icp, irq));
 }
 
+static int spapr_msi_get_irq(PCIBus *bus, MSIMessage msg)
+{
+    DeviceState *par = bus->qbus.parent;
+    sPAPRPHBState *sphb = (sPAPRPHBState *) par;
+    unsigned long addr = msg.address - sphb->msi_win_addr;
+    int ndev = addr >> 16;
+    int vec = ((addr & 0xFFFF) >> 2) | msg.data;
+    uint32_t irq = sphb->msi_table[ndev].irq + vec;
+
+    return (int)irq;
+}
+
 static const MemoryRegionOps spapr_msi_ops = {
     /* There is no .read as the read result is undefined by PCI spec */
     .read = NULL,
@@ -664,6 +676,7 @@ static int _spapr_phb_init(SysBusDevice *s)
 
         sphb->lsi_table[i].irq = irq;
     }
+    pci_bus_set_map_msi_fn(bus, spapr_msi_get_irq);
 
     return 0;
 }
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index d309416..587f53e 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -472,6 +472,8 @@ static unsigned virtio_pci_get_features(DeviceState *d)
     return proxy->host_features;
 }
 
+extern int spapr_msi_get_irq(PCIBus *bus, MSIMessage *msg);
+
 static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
                                         unsigned int queue_no,
                                         unsigned int vector,
@@ -481,7 +483,10 @@ static int kvm_virtio_pci_vq_vector_use(VirtIOPCIProxy *proxy,
     int ret;
 
     if (irqfd->users == 0) {
-        ret = kvm_irqchip_add_msi_route(kvm_state, msg);
+        ret = pci_bus_map_msi(proxy->pci_dev.bus, msg);
+        if (ret < 0) {
+            ret = kvm_irqchip_add_msi_route(kvm_state, msg);
+        }
         if (ret < 0) {
             return ret;
         }
@@ -609,14 +614,23 @@ static int virtio_pci_vq_vector_unmask(VirtIOPCIProxy *proxy,
     VirtQueue *vq = virtio_get_queue(proxy->vdev, queue_no);
     EventNotifier *n = virtio_queue_get_guest_notifier(vq);
     VirtIOIRQFD *irqfd;
-    int ret = 0;
+    int ret = 0, tmp;
 
     if (proxy->vector_irqfd) {
         irqfd = &proxy->vector_irqfd[vector];
-        if (irqfd->msg.data != msg.data || irqfd->msg.address != msg.address) {
-            ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg);
-            if (ret < 0) {
-                return ret;
+
+        tmp = pci_bus_map_msi(proxy->pci_dev.bus, msg);
+        if (tmp >= 0) {
+            if (irqfd->virq != tmp) {
+                fprintf(stderr, "FIXME: MSI(-X) vector has changed from %X to %x\n",
+                        irqfd->virq, tmp);
+            }
+        } else {
+            if (irqfd->msg.data != msg.data || irqfd->msg.address != msg.address) {
+                ret = kvm_irqchip_update_msi_route(kvm_state, irqfd->virq, msg);
+                if (ret < 0) {
+                    return ret;
+                }
             }
         }
     }
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 8797802..632739a 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -332,6 +332,7 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev);
 typedef void (*pci_set_irq_fn)(void *opaque, int irq_num, int level);
 typedef int (*pci_map_irq_fn)(PCIDevice *pci_dev, int irq_num);
 typedef PCIINTxRoute (*pci_route_irq_fn)(void *opaque, int pin);
+typedef int (*pci_map_msi_fn)(PCIBus *bus, MSIMessage msg);
 
 typedef enum {
     PCI_HOTPLUG_DISABLED,
@@ -375,6 +376,9 @@ bool pci_intx_route_changed(PCIINTxRoute *old, PCIINTxRoute *new);
 void pci_bus_fire_intx_routing_notifier(PCIBus *bus);
 void pci_device_set_intx_routing_notifier(PCIDevice *dev,
                                           PCIINTxRoutingNotifier notifier);
+void pci_bus_set_map_msi_fn(PCIBus *bus, pci_map_msi_fn map_msi_fn);
+int pci_bus_map_msi(PCIBus *bus, MSIMessage msg);
+
 void pci_device_reset(PCIDevice *dev);
 void pci_bus_reset(PCIBus *bus);
 
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 66762f6..81efd2b 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -16,6 +16,7 @@ struct PCIBus {
     pci_set_irq_fn set_irq;
     pci_map_irq_fn map_irq;
     pci_route_irq_fn route_intx_to_irq;
+    pci_map_msi_fn map_msi;
     pci_hotplug_fn hotplug;
     DeviceState *hotplug_qdev;
     void *irq_opaque;
-- 
1.7.10.4



^ permalink raw reply related	[flat|nested] 72+ messages in thread

end of thread, other threads:[~2013-06-24 17:09 UTC | newest]

Thread overview: 72+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-20 14:08 [Qemu-trivial] [PATCH] RFC kvm irqfd: add directly mapped MSI IRQ support Alexey Kardashevskiy
2013-06-20 14:08 ` [Qemu-devel] " Alexey Kardashevskiy
2013-06-20 15:38 ` [Qemu-trivial] " Michael S. Tsirkin
2013-06-20 15:38   ` [Qemu-devel] " Michael S. Tsirkin
2013-06-20 16:37 ` [Qemu-trivial] " Anthony Liguori
2013-06-20 16:37   ` Anthony Liguori
2013-06-20 23:51   ` [Qemu-trivial] " Alexey Kardashevskiy
2013-06-20 23:51     ` Alexey Kardashevskiy
2013-06-23 14:07     ` [Qemu-trivial] " Michael S. Tsirkin
2013-06-23 14:07       ` Michael S. Tsirkin
2013-06-23 15:02       ` [Qemu-trivial] " Anthony Liguori
2013-06-23 15:02         ` Anthony Liguori
2013-06-23 21:39         ` [Qemu-trivial] [Qemu-ppc] " Benjamin Herrenschmidt
2013-06-23 21:39           ` [Qemu-devel] [Qemu-ppc] " Benjamin Herrenschmidt
2013-06-23 21:58           ` [Qemu-trivial] [Qemu-ppc] [Qemu-devel] " Anthony Liguori
2013-06-23 21:58             ` [Qemu-devel] [Qemu-ppc] " Anthony Liguori
2013-06-24  4:46             ` [Qemu-trivial] [Qemu-ppc] [Qemu-devel] " Alex Williamson
2013-06-24  4:46               ` [Qemu-devel] [Qemu-ppc] " Alex Williamson
2013-06-24 12:24               ` [Qemu-trivial] [Qemu-ppc] [Qemu-devel] " Anthony Liguori
2013-06-24 12:24                 ` [Qemu-devel] [Qemu-ppc] " Anthony Liguori
2013-06-24 12:39                 ` [Qemu-trivial] " Gleb Natapov
2013-06-24 12:39                   ` Gleb Natapov
2013-06-23 21:36       ` [Qemu-trivial] [Qemu-devel] " Benjamin Herrenschmidt
2013-06-23 21:36         ` Benjamin Herrenschmidt
2013-06-24 12:10         ` [Qemu-trivial] " Michael S. Tsirkin
2013-06-24 12:10           ` Michael S. Tsirkin
2013-06-20 16:51 ` [Qemu-trivial] " Alex Williamson
2013-06-20 16:51   ` [Qemu-devel] " Alex Williamson
2013-06-21  1:56   ` [Qemu-trivial] " Alexey Kardashevskiy
2013-06-21  1:56     ` [Qemu-devel] " Alexey Kardashevskiy
2013-06-21  2:34     ` [Qemu-trivial] " Alex Williamson
2013-06-21  2:34       ` [Qemu-devel] " Alex Williamson
2013-06-21  2:49       ` [Qemu-trivial] " Alexey Kardashevskiy
2013-06-21  2:49         ` [Qemu-devel] " Alexey Kardashevskiy
2013-06-21  4:46         ` [Qemu-trivial] " Alex Williamson
2013-06-21  4:46           ` [Qemu-devel] " Alex Williamson
2013-06-21  5:12           ` [Qemu-trivial] " Benjamin Herrenschmidt
2013-06-21  5:12             ` [Qemu-devel] " Benjamin Herrenschmidt
2013-06-21  6:03             ` [Qemu-trivial] " Alex Williamson
2013-06-21  6:03               ` [Qemu-devel] " Alex Williamson
2013-06-21  6:12               ` [Qemu-trivial] " Benjamin Herrenschmidt
2013-06-21  6:12                 ` [Qemu-devel] " Benjamin Herrenschmidt
2013-06-21  6:40                 ` [Qemu-trivial] " Alexey Kardashevskiy
2013-06-21  6:40                   ` [Qemu-devel] " Alexey Kardashevskiy
2013-06-23 15:06           ` [Qemu-trivial] " Anthony Liguori
2013-06-23 15:06             ` Anthony Liguori
2013-06-24  4:44             ` [Qemu-trivial] " Alex Williamson
2013-06-24  4:44               ` Alex Williamson
2013-06-24 12:25               ` [Qemu-trivial] " Anthony Liguori
2013-06-24 12:25                 ` Anthony Liguori
2013-06-24  7:13             ` [Qemu-trivial] " Gleb Natapov
2013-06-24  7:13               ` Gleb Natapov
2013-06-24 12:32               ` [Qemu-trivial] " Anthony Liguori
2013-06-24 12:32                 ` Anthony Liguori
2013-06-24 12:37                 ` [Qemu-trivial] " Alexander Graf
2013-06-24 12:37                   ` Alexander Graf
2013-06-24 13:06                 ` [Qemu-trivial] " Gleb Natapov
2013-06-24 13:06                   ` Gleb Natapov
2013-06-24 13:34                   ` [Qemu-trivial] " Anthony Liguori
2013-06-24 13:34                     ` Anthony Liguori
2013-06-24 13:41                     ` [Qemu-trivial] " Michael S. Tsirkin
2013-06-24 13:41                       ` Michael S. Tsirkin
2013-06-24 14:31                       ` [Qemu-trivial] " Anthony Liguori
2013-06-24 14:31                         ` Anthony Liguori
2013-06-24 14:34                         ` [Qemu-trivial] " Alexander Graf
2013-06-24 14:34                           ` Alexander Graf
2013-06-24 15:17                           ` [Qemu-trivial] " Anthony Liguori
2013-06-24 15:17                             ` Anthony Liguori
2013-06-24 16:48                             ` [Qemu-trivial] " Gleb Natapov
2013-06-24 16:48                               ` Gleb Natapov
2013-06-24 16:35                     ` [Qemu-trivial] " Gleb Natapov
2013-06-24 16:35                       ` Gleb Natapov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.