yeahuh / rpms / qemu-kvm

Forked from rpms/qemu-kvm 2 years ago
Clone

Blame SOURCES/0038-s390x-ccw-make-sure-all-ccw-devices-are-properly-res.patch

26ba25
From 39b8d397fe34ae375e33371ee58894d13667560b Mon Sep 17 00:00:00 2001
26ba25
From: Cornelia Huck <cohuck@redhat.com>
26ba25
Date: Tue, 15 May 2018 07:33:47 +0000
26ba25
Subject: s390x/ccw: make sure all ccw devices are properly reset
26ba25
26ba25
Thomas reported that the subchannel for a  3270 device that ended up
26ba25
in a broken state (status pending even though not enabled) did not
26ba25
get out of that state even after a reboot (which involves a subsytem
26ba25
reset). The reason for this is that the 3270 device did not define
26ba25
a reset handler.
26ba25
26ba25
Let's fix this by introducing a base reset handler (set up for all
26ba25
ccw devices) that resets the subchannel and have virtio-ccw call
26ba25
its virtio-specific reset procedure in addition to that.
26ba25
26ba25
CC: qemu-stable@nongnu.org
26ba25
Reported-by: Thomas Huth <thuth@redhat.com>
26ba25
Suggested-by: Christian Borntraeger <borntraeger@de.ibm.com>
26ba25
Reviewed-by: Thomas Huth <thuth@redhat.com>
26ba25
Tested-by: Thomas Huth <thuth@redhat.com>
26ba25
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
26ba25
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
26ba25
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
26ba25
(cherry picked from commit 838fb84f83c84f00d15b1bede5e080b495644458)
26ba25
---
26ba25
 hw/s390x/ccw-device.c | 8 ++++++++
26ba25
 hw/s390x/virtio-ccw.c | 9 ++++++---
26ba25
 hw/s390x/virtio-ccw.h | 1 +
26ba25
 3 files changed, 15 insertions(+), 3 deletions(-)
26ba25
26ba25
diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c
26ba25
index f9bfa15..7cd73df 100644
26ba25
--- a/hw/s390x/ccw-device.c
26ba25
+++ b/hw/s390x/ccw-device.c
26ba25
@@ -40,6 +40,13 @@ static Property ccw_device_properties[] = {
26ba25
     DEFINE_PROP_END_OF_LIST(),
26ba25
 };
26ba25
 
26ba25
+static void ccw_device_reset(DeviceState *d)
26ba25
+{
26ba25
+    CcwDevice *ccw_dev = CCW_DEVICE(d);
26ba25
+
26ba25
+    css_reset_sch(ccw_dev->sch);
26ba25
+}
26ba25
+
26ba25
 static void ccw_device_class_init(ObjectClass *klass, void *data)
26ba25
 {
26ba25
     DeviceClass *dc = DEVICE_CLASS(klass);
26ba25
@@ -48,6 +55,7 @@ static void ccw_device_class_init(ObjectClass *klass, void *data)
26ba25
     k->realize = ccw_device_realize;
26ba25
     k->refill_ids = ccw_device_refill_ids;
26ba25
     dc->props = ccw_device_properties;
26ba25
+    dc->reset = ccw_device_reset;
26ba25
 }
26ba25
 
26ba25
 const VMStateDescription vmstate_ccw_dev = {
26ba25
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
26ba25
index 2db8cc6..dfedd84 100644
26ba25
--- a/hw/s390x/virtio-ccw.c
26ba25
+++ b/hw/s390x/virtio-ccw.c
26ba25
@@ -1061,10 +1061,12 @@ static void virtio_ccw_reset(DeviceState *d)
26ba25
 {
26ba25
     VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
26ba25
     VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
26ba25
-    CcwDevice *ccw_dev = CCW_DEVICE(d);
26ba25
+    VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
26ba25
 
26ba25
     virtio_ccw_reset_virtio(dev, vdev);
26ba25
-    css_reset_sch(ccw_dev->sch);
26ba25
+    if (vdc->parent_reset) {
26ba25
+        vdc->parent_reset(d);
26ba25
+    }
26ba25
 }
26ba25
 
26ba25
 static void virtio_ccw_vmstate_change(DeviceState *d, bool running)
26ba25
@@ -1721,12 +1723,13 @@ static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
26ba25
 {
26ba25
     DeviceClass *dc = DEVICE_CLASS(klass);
26ba25
     CCWDeviceClass *k = CCW_DEVICE_CLASS(dc);
26ba25
+    VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_CLASS(klass);
26ba25
 
26ba25
     k->unplug = virtio_ccw_busdev_unplug;
26ba25
     dc->realize = virtio_ccw_busdev_realize;
26ba25
     dc->unrealize = virtio_ccw_busdev_unrealize;
26ba25
     dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
26ba25
-    dc->reset = virtio_ccw_reset;
26ba25
+    device_class_set_parent_reset(dc, virtio_ccw_reset, &vdc->parent_reset);
26ba25
 }
26ba25
 
26ba25
 static const TypeInfo virtio_ccw_device_info = {
26ba25
diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
26ba25
index 2fc5130..3453aa1 100644
26ba25
--- a/hw/s390x/virtio-ccw.h
26ba25
+++ b/hw/s390x/virtio-ccw.h
26ba25
@@ -77,6 +77,7 @@ typedef struct VirtIOCCWDeviceClass {
26ba25
     CCWDeviceClass parent_class;
26ba25
     void (*realize)(VirtioCcwDevice *dev, Error **errp);
26ba25
     void (*unrealize)(VirtioCcwDevice *dev, Error **errp);
26ba25
+    void (*parent_reset)(DeviceState *dev);
26ba25
 } VirtIOCCWDeviceClass;
26ba25
 
26ba25
 /* Performance improves when virtqueue kick processing is decoupled from the
26ba25
-- 
26ba25
1.8.3.1
26ba25