s390x/ccw: make sure all ccw devices are properly reset

Thomas reported that the subchannel for a  3270 device that ended up
in a broken state (status pending even though not enabled) did not
get out of that state even after a reboot (which involves a subsytem
reset). The reason for this is that the 3270 device did not define
a reset handler.

Let's fix this by introducing a base reset handler (set up for all
ccw devices) that resets the subchannel and have virtio-ccw call
its virtio-specific reset procedure in addition to that.

CC: qemu-stable@nongnu.org
Reported-by: Thomas Huth <thuth@redhat.com>
Suggested-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Thomas Huth <thuth@redhat.com>
Tested-by: Thomas Huth <thuth@redhat.com>
Acked-by: Christian Borntraeger <borntraeger@de.ibm.com>
Reviewed-by: Halil Pasic <pasic@linux.ibm.com>
Signed-off-by: Cornelia Huck <cohuck@redhat.com>
(cherry picked from commit 838fb84f83)
Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
stable-2.11
Cornelia Huck 2018-05-07 15:27:57 +02:00 committed by Michael Roth
parent b2ca602627
commit b68ef5920a
3 changed files with 15 additions and 3 deletions

View File

@ -40,6 +40,13 @@ static Property ccw_device_properties[] = {
DEFINE_PROP_END_OF_LIST(),
};
static void ccw_device_reset(DeviceState *d)
{
CcwDevice *ccw_dev = CCW_DEVICE(d);
css_reset_sch(ccw_dev->sch);
}
static void ccw_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@ -48,6 +55,7 @@ static void ccw_device_class_init(ObjectClass *klass, void *data)
k->realize = ccw_device_realize;
k->refill_ids = ccw_device_refill_ids;
dc->props = ccw_device_properties;
dc->reset = ccw_device_reset;
}
const VMStateDescription vmstate_ccw_dev = {

View File

@ -1057,10 +1057,12 @@ static void virtio_ccw_reset(DeviceState *d)
{
VirtioCcwDevice *dev = VIRTIO_CCW_DEVICE(d);
VirtIODevice *vdev = virtio_bus_get_device(&dev->bus);
CcwDevice *ccw_dev = CCW_DEVICE(d);
VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_GET_CLASS(dev);
virtio_ccw_reset_virtio(dev, vdev);
css_reset_sch(ccw_dev->sch);
if (vdc->parent_reset) {
vdc->parent_reset(d);
}
}
static void virtio_ccw_vmstate_change(DeviceState *d, bool running)
@ -1714,12 +1716,13 @@ static void virtio_ccw_device_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
CCWDeviceClass *k = CCW_DEVICE_CLASS(dc);
VirtIOCCWDeviceClass *vdc = VIRTIO_CCW_DEVICE_CLASS(klass);
k->unplug = virtio_ccw_busdev_unplug;
dc->realize = virtio_ccw_busdev_realize;
dc->unrealize = virtio_ccw_busdev_unrealize;
dc->bus_type = TYPE_VIRTUAL_CSS_BUS;
dc->reset = virtio_ccw_reset;
device_class_set_parent_reset(dc, virtio_ccw_reset, &vdc->parent_reset);
}
static const TypeInfo virtio_ccw_device_info = {

View File

@ -77,6 +77,7 @@ typedef struct VirtIOCCWDeviceClass {
CCWDeviceClass parent_class;
void (*realize)(VirtioCcwDevice *dev, Error **errp);
void (*unrealize)(VirtioCcwDevice *dev, Error **errp);
void (*parent_reset)(DeviceState *dev);
} VirtIOCCWDeviceClass;
/* Performance improves when virtqueue kick processing is decoupled from the