When a CIO_GONE notification is received the device_lost flag is set in the virtio_device. This flag should be tested by a backend in order to be able to prevent triggering final I/O to a device that is not reachable any more. The notification is ignored in case remove or set_offline is already running. The virtio_device pointer might point to freed memory in that case. Signed-off-by: Heinz Graalfs <graalfs@xxxxxxxxxxxxxxxxxx> Acked-by: Cornelia Huck <cornelia.huck@xxxxxxxxxx> --- drivers/s390/kvm/virtio_ccw.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/s390/kvm/virtio_ccw.c b/drivers/s390/kvm/virtio_ccw.c index b939a7f..a468b9c 100644 --- a/drivers/s390/kvm/virtio_ccw.c +++ b/drivers/s390/kvm/virtio_ccw.c @@ -27,6 +27,7 @@ #include <linux/module.h> #include <linux/io.h> #include <linux/kvm_para.h> +#include <linux/notifier.h> #include <asm/setup.h> #include <asm/irq.h> #include <asm/cio.h> @@ -1085,8 +1086,26 @@ out_free: static int virtio_ccw_cio_notify(struct ccw_device *cdev, int event) { - /* TODO: Check whether we need special handling here. */ - return 0; + int rc; + struct virtio_ccw_device *vcdev = dev_get_drvdata(&cdev->dev); + + /* + * Make sure vcdev is set + * i.e. set_offline/remove callback not already running + */ + if (!vcdev) + return NOTIFY_DONE; + + switch (event) { + case CIO_GONE: + atomic_inc(&vcdev->vdev.device_lost); + rc = NOTIFY_DONE; + break; + default: + rc = NOTIFY_DONE; + break; + } + return rc; } static struct ccw_device_id virtio_ids[] = { -- 1.8.3.1 _______________________________________________ Virtualization mailing list Virtualization@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linuxfoundation.org/mailman/listinfo/virtualization