virtio: rng: disallow multiple device registrations, fixes crashes
The code currently only supports one virtio-rng device at a time. Invoking guests with multiple devices causes the guest to blow up. Check if we've already registered and initialised the driver. Also cleanup in case of registration errors or hot-unplug so that a new device can be used. Reported-by: Peter Krempa <pkrempa@redhat.com> Reported-by: <yunzheng@redhat.com> Signed-off-by: Amit Shah <amit.shah@redhat.com> Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Cc: stable@kernel.org
This commit is contained in:
@@ -92,14 +92,22 @@ static int probe_common(struct virtio_device *vdev)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
if (vq) {
|
||||||
|
/* We only support one device for now */
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
/* We expect a single virtqueue. */
|
/* We expect a single virtqueue. */
|
||||||
vq = virtio_find_single_vq(vdev, random_recv_done, "input");
|
vq = virtio_find_single_vq(vdev, random_recv_done, "input");
|
||||||
if (IS_ERR(vq))
|
if (IS_ERR(vq)) {
|
||||||
return PTR_ERR(vq);
|
err = PTR_ERR(vq);
|
||||||
|
vq = NULL;
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
err = hwrng_register(&virtio_hwrng);
|
err = hwrng_register(&virtio_hwrng);
|
||||||
if (err) {
|
if (err) {
|
||||||
vdev->config->del_vqs(vdev);
|
vdev->config->del_vqs(vdev);
|
||||||
|
vq = NULL;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,6 +120,7 @@ static void remove_common(struct virtio_device *vdev)
|
|||||||
busy = false;
|
busy = false;
|
||||||
hwrng_unregister(&virtio_hwrng);
|
hwrng_unregister(&virtio_hwrng);
|
||||||
vdev->config->del_vqs(vdev);
|
vdev->config->del_vqs(vdev);
|
||||||
|
vq = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int virtrng_probe(struct virtio_device *vdev)
|
static int virtrng_probe(struct virtio_device *vdev)
|
||||||
|
Reference in New Issue
Block a user