Re: [PATCH 2/2] vfio-ccw: support async command subregion

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

 



On 22/11/2018 17:54, Cornelia Huck wrote:
A vfio-ccw device may provide an async command subregion for
issuing halt/clear subchannel requests. If it is present, use
it for sending halt/clear request to the device; if not, fall
back to emulation (as done today).

Signed-off-by: Cornelia Huck <cohuck@xxxxxxxxxx>
---
  hw/s390x/css.c              |  27 +++++++--
  hw/vfio/ccw.c               | 109 +++++++++++++++++++++++++++++++++++-
  include/hw/s390x/s390-ccw.h |   3 +
  3 files changed, 133 insertions(+), 6 deletions(-)

diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index 04ec5cc970..0897c041c5 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -22,6 +22,7 @@
  #include "trace.h"
  #include "hw/s390x/s390_flic.h"
  #include "hw/s390x/s390-virtio-ccw.h"
+#include "hw/s390x/s390-ccw.h"
typedef struct CrwContainer {
      CRW crw;
@@ -1194,6 +1195,26 @@ static void sch_handle_start_func_virtual(SubchDev *sch)
} +static void sch_handle_halt_func_passthrough(SubchDev *sch)
+{
+    int ret;
+
+    ret = vfio_ccw_handle_halt(sch);
+    if (ret == -ENOSYS) {
+        sch_handle_halt_func(sch);
+    }
+}
+
+static void sch_handle_clear_func_passthrough(SubchDev *sch)
+{
+    int ret;
+
+    ret = vfio_ccw_handle_clear(sch);
+    if (ret == -ENOSYS) {
+        sch_handle_clear_func(sch);
+    }
+}
+
  static IOInstEnding sch_handle_start_func_passthrough(SubchDev *sch)
  {
@@ -1237,11 +1258,9 @@ IOInstEnding do_subchannel_work_passthrough(SubchDev *sch)
      SCSW *s = &sch->curr_status.scsw;
if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {
-        /* TODO: Clear handling */
-        sch_handle_clear_func(sch);
+        sch_handle_clear_func_passthrough(sch);
      } else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {
-        /* TODO: Halt handling */
-        sch_handle_halt_func(sch);
+        sch_handle_halt_func_passthrough(sch);
      } else if (s->ctrl & SCSW_FCTL_START_FUNC) {
          return sch_handle_start_func_passthrough(sch);
      }
diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c
index 9246729a75..dd0fecf168 100644
--- a/hw/vfio/ccw.c
+++ b/hw/vfio/ccw.c
@@ -2,9 +2,12 @@
   * vfio based subchannel assignment support
   *
   * Copyright 2017 IBM Corp.
+ * Copyright 2018 Red Hat, Inc.
+ *
   * Author(s): Dong Jia Shi <bjsdjshi@xxxxxxxxxxxxxxxxxx>
   *            Xiao Feng Ren <renxiaof@xxxxxxxxxxxxxxxxxx>
   *            Pierre Morel <pmorel@xxxxxxxxxxxxxxxxxx>
+ *            Cornelia Huck <cohuck@xxxxxxxxxx>
   *
   * This work is licensed under the terms of the GNU GPL, version 2 or (at
   * your option) any later version. See the COPYING file in the top-level
@@ -32,6 +35,9 @@ typedef struct VFIOCCWDevice {
      uint64_t io_region_size;
      uint64_t io_region_offset;
      struct ccw_io_region *io_region;
+    uint64_t async_cmd_region_size;
+    uint64_t async_cmd_region_offset;
+    struct ccw_cmd_region *async_cmd_region;
      EventNotifier io_notifier;
      bool force_orb_pfch;
      bool warned_orb_pfch;
@@ -114,6 +120,87 @@ again:
      }
  }
+int vfio_ccw_handle_clear(SubchDev *sch)
+{
+    S390CCWDevice *cdev = sch->driver_data;
+    VFIOCCWDevice *vcdev = DO_UPCAST(VFIOCCWDevice, cdev, cdev);
+    struct ccw_cmd_region *region = vcdev->async_cmd_region;
+    int ret;
+
+    if (!vcdev->async_cmd_region) {
+        /* Async command region not available, fall back to emulation */
+        return -ENOSYS;
+    }
+
+    memset(region, 0, sizeof(*region));
+    region->command = VFIO_CCW_ASYNC_CMD_CSCH;
+
+again:
+    ret = pwrite(vcdev->vdev.fd, region,
+                 vcdev->async_cmd_region_size, vcdev->async_cmd_region_offset);
+    if (ret != vcdev->async_cmd_region_size) {
+        if (errno == EAGAIN) {


Where do the EAGAIN come from?


+            goto again;
+        }
+        error_report("vfio-ccw: wirte I/O region failed with errno=%d", errno);
+        ret = -errno;
+    } else {
+        ret = region->ret_code;
+    }
+    switch (ret) {
+    case 0:
+    case -ENODEV:
+    case -EACCES:

should never happen?

+        return 0;
+    case -EFAULT:
+    default:
+        sch_gen_unit_exception(sch);
+        css_inject_io_interrupt(sch);
+        return 0;
+    }
+}
+

otherwise LGTM

--
Pierre Morel
Linux/KVM/QEMU in Böblingen - Germany




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux