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

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