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 13:29:05 +0200
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:24.0) Gecko/20100101 Thunderbird/24.4.0


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?


Alex




reply via email to

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