One fix for virtio-ccw, fixing a problem introduced with

"virtio_ccw: fix vcdev pointer handling issues" and noticed just
 after it went into git.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIcBAABAgAGBQJTGD7oAAoJEN7Pa5PG8C+vlA8QAJ1tJ7o4wfqklh/NV0D24FQM
 eC2TPvUigSS4AbFAwfYqNHkuK+k80CuUHhX4hqErJ7vsWSI+pkrk7fzLs+H+zrHf
 eE+hILdKoVAPgAB03+tPVn2o+sVfTKTaFIbiRDcR2afJdLAtAJ8B8hrmZSLJWP/w
 iLhYdZhab9J62XQkieearhV0KZwQYMBkG0KM33TGFdrQw4Crsar32QgH/DFuD7bJ
 4K2sppvt+pHCiIjk5baHkTt8Ngvslk2af73OgQCb2wTrk5SrMN03yFhm88SErtgl
 bTb2ybVnl1FpzFG3zZIYS8QhVTS8mj8W/3ie6mJ2G4JtUJFgHISLwKGPegLRYgdi
 e99ahKfKBleR60pAgplWU+7beTzRe92QhX5VGu20qNafuRQMaWIxqqctybT2v8ga
 NW6pXzYVorxTLipDnwgHrcEA2IhBtwTl2wCX6SXkoAZms1EkNkvzL4PMbkjZETVQ
 ++TMgGN5GA6Ak/yVSJfOO13qe465BHvff6PbYcmN/vTX5wy6AlnDu5fsRoUwl7OS
 vKR9JhQJXG3eJ/13Kex7To3qoceDNJjslmJnDyM8eKKfYCOawwEZPJ54jB9odset
 IHFMPQvkJZzled6ByqqR2yxcGW4DPdYac9mVxKO1Z3eGP7/QWkhwqza5qJfT2+MA
 zfdATG/Ym7uTFBIbR9XS
 =qLB9
 -----END PGP SIGNATURE-----

Merge tag 'kvm-s390-20140306' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into kvm-next

One fix for virtio-ccw, fixing a problem introduced with
"virtio_ccw: fix vcdev pointer handling issues" and noticed just
after it went into git.
This commit is contained in:
Paolo Bonzini 2014-03-06 12:50:54 +01:00
commit b010926dc8

View File

@ -61,6 +61,7 @@ struct virtio_ccw_device {
unsigned long indicators2; unsigned long indicators2;
struct vq_config_block *config_block; struct vq_config_block *config_block;
bool is_thinint; bool is_thinint;
bool going_away;
void *airq_info; void *airq_info;
}; };
@ -995,30 +996,39 @@ static struct virtio_ccw_device *virtio_grab_drvdata(struct ccw_device *cdev)
spin_lock_irqsave(get_ccwdev_lock(cdev), flags); spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
vcdev = dev_get_drvdata(&cdev->dev); vcdev = dev_get_drvdata(&cdev->dev);
if (!vcdev) { if (!vcdev || vcdev->going_away) {
spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
return NULL; return NULL;
} }
dev_set_drvdata(&cdev->dev, NULL); vcdev->going_away = true;
spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
return vcdev; return vcdev;
} }
static void virtio_ccw_remove(struct ccw_device *cdev) static void virtio_ccw_remove(struct ccw_device *cdev)
{ {
unsigned long flags;
struct virtio_ccw_device *vcdev = virtio_grab_drvdata(cdev); struct virtio_ccw_device *vcdev = virtio_grab_drvdata(cdev);
if (vcdev && cdev->online) if (vcdev && cdev->online)
unregister_virtio_device(&vcdev->vdev); unregister_virtio_device(&vcdev->vdev);
spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
dev_set_drvdata(&cdev->dev, NULL);
spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
cdev->handler = NULL; cdev->handler = NULL;
} }
static int virtio_ccw_offline(struct ccw_device *cdev) static int virtio_ccw_offline(struct ccw_device *cdev)
{ {
unsigned long flags;
struct virtio_ccw_device *vcdev = virtio_grab_drvdata(cdev); struct virtio_ccw_device *vcdev = virtio_grab_drvdata(cdev);
if (vcdev) if (vcdev) {
unregister_virtio_device(&vcdev->vdev); unregister_virtio_device(&vcdev->vdev);
spin_lock_irqsave(get_ccwdev_lock(cdev), flags);
dev_set_drvdata(&cdev->dev, NULL);
spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags);
}
return 0; return 0;
} }