qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH 6/9] s390x/virtio-ccw: Wire up irq routing and i


From: Alexander Graf
Subject: Re: [Qemu-devel] [PATCH 6/9] s390x/virtio-ccw: Wire up irq routing and irqfds.
Date: Wed, 16 Apr 2014 18:29:36 +0200
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:24.0) Gecko/20100101 Thunderbird/24.4.0


On 16.04.14 16:44, Cornelia Huck wrote:
On Wed, 16 Apr 2014 13:29:05 +0200
Alexander Graf <address@hidden> wrote:

On 14.04.14 18:48, Cornelia Huck wrote:
Make use of the new s390 adapter irq routing support to enable real
in-kernel irqfds for virtio-ccw with adapter interrupts.

Note that s390 doesn't provide the common KVM_CAP_IRQCHIP capability, but
rather needs KVM_CAP_S390_IRQCHIP to be enabled. This is to ensure backward
compatibility.

Reviewed-by: Thomas Huth <address@hidden>
Signed-off-by: Cornelia Huck <address@hidden>
---
   hw/s390x/virtio-ccw.c      |  165 
++++++++++++++++++++++++++++++++++++++++----
   hw/s390x/virtio-ccw.h      |    2 +
   include/hw/s390x/adapter.h |   23 ++++++
   include/qemu/typedefs.h    |    1 +
   include/sysemu/kvm.h       |    2 +
   kvm-all.c                  |   38 +++++++++-
   kvm-stub.c                 |    5 ++
   target-s390x/kvm.c         |    5 ++
   8 files changed, 228 insertions(+), 13 deletions(-)
   create mode 100644 include/hw/s390x/adapter.h

diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index 69efa6c..5612ccc 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -21,6 +21,7 @@
   #include "hw/sysbus.h"
   #include "qemu/bitops.h"
   #include "hw/virtio/virtio-bus.h"
+#include "hw/s390x/adapter.h"
#include "ioinst.h"
   #include "css.h"
@@ -48,7 +49,7 @@ static IndAddr *get_indicator(hwaddr ind_addr, int len)
       return indicator;
   }
-static void release_indicator(IndAddr *indicator)
+static void release_indicator(uint32_t adapter_id, IndAddr *indicator)
   {
       assert(indicator->refcnt > 0);
       indicator->refcnt--;
@@ -56,9 +57,31 @@ static void release_indicator(IndAddr *indicator)
           return;
       }
       QTAILQ_REMOVE(&indicator_addresses, indicator, sibling);
+    if (indicator->map) {
+        s390_io_adapter_map(adapter_id, indicator->map, false);
+    }
       g_free(indicator);
   }
+static int map_indicator(uint32_t adapter_id, IndAddr *indicator)
+{
+    int ret;
+
+    if (indicator->map) {
+        return 0; /* already mapped is not an error */
+    }
+    indicator->map = indicator->addr;
+    ret = s390_io_adapter_map(adapter_id, indicator->map, true);
+    if ((ret != 0) && (ret != -ENOSYS)) {
+        goto out_err;
+    }
+    return 0;
+
+out_err:
+    indicator->map = 0;
+    return -EFAULT;
+}
+
   static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size,
                                  VirtioCcwDevice *dev);
@@ -733,7 +756,7 @@ static int virtio_ccw_exit(VirtioCcwDevice *dev)
           g_free(sch);
       }
       if (dev->indicators) {
-        release_indicator(dev->indicators);
+        release_indicator(dev->adapter_id, dev->indicators);
           dev->indicators = NULL;
       }
       return 0;
@@ -1034,15 +1057,15 @@ static void virtio_ccw_reset(DeviceState *d)
       virtio_reset(vdev);
       css_reset_sch(dev->sch);
       if (dev->indicators) {
-        release_indicator(dev->indicators);
+        release_indicator(dev->adapter_id, dev->indicators);
           dev->indicators = NULL;
       }
       if (dev->indicators2) {
-        release_indicator(dev->indicators2);
+        release_indicator(dev->adapter_id, dev->indicators2);
           dev->indicators2 = NULL;
       }
       if (dev->summary_indicator) {
-        release_indicator(dev->summary_indicator);
+        release_indicator(dev->adapter_id, dev->summary_indicator);
           dev->summary_indicator = NULL;
       }
   }
@@ -1078,6 +1101,100 @@ static int virtio_ccw_set_host_notifier(DeviceState *d, 
int n, bool assign)
       return virtio_ccw_set_guest2host_notifier(dev, n, assign, false);
   }
+static int virtio_ccw_get_adapter_info(VirtioCcwDevice *dev,
+                                       AdapterInfo *adapter)
+{
+    int r;
+
+    if (!dev->sch->thinint_active) {
+        return -EINVAL;
+    }
+
+    r = map_indicator(dev->adapter_id, dev->summary_indicator);
+    if (r) {
+        return r;
+    }
+    r = map_indicator(dev->adapter_id, dev->indicators);
+    if (r) {
+        return r;
+    }
+    adapter->summary_addr = dev->summary_indicator->map;
+    adapter->ind_addr = dev->indicators->map;
+    adapter->ind_offset = dev->ind_bit;
+    adapter->summary_offset = 7;
+    adapter->adapter_id = dev->adapter_id;
+
+    return 0;
+}
+
+static int virtio_ccw_setup_irqroutes(VirtioCcwDevice *dev, int nvqs)
+{
+    int i;
+    VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
+    int ret;
+    AdapterInfo adapter;
+
+    ret = virtio_ccw_get_adapter_info(dev, &adapter);
+    if (ret) {
+        return ret;
+    }
+    for (i = 0; i < nvqs; i++) {
+        if (!virtio_queue_get_num(vdev, i)) {
+            break;
+        }
+        ret = kvm_irqchip_add_adapter_route(kvm_state, &adapter);
Why is interrupt routing code in virtio-ccw.c? Shouldn't that live in
the flic?
It needs information about the virtio-ccw device (and the
virtio-device).

Could we somehow manage to get a workflow like this?

  payload = virtoccwdevice->get_adapter_payload();
  flic->add_adapter_route(payload);

So that the virtio-ccw bus only becomes glue between the virtio-ccw device and our flic?


Alex




reply via email to

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