]>
Commit | Line | Data |
---|---|---|
858d99c4 GKH |
1 | From e84e7a56a3aa2963db506299e29a5f3f09377f9b Mon Sep 17 00:00:00 2001 |
2 | From: Amit Shah <amit.shah@redhat.com> | |
3 | Date: Fri, 8 Mar 2013 11:30:18 +1100 | |
4 | Subject: virtio: rng: disallow multiple device registrations, fixes crashes | |
5 | ||
6 | From: Amit Shah <amit.shah@redhat.com> | |
7 | ||
8 | commit e84e7a56a3aa2963db506299e29a5f3f09377f9b upstream. | |
9 | ||
10 | The code currently only supports one virtio-rng device at a time. | |
11 | Invoking guests with multiple devices causes the guest to blow up. | |
12 | ||
13 | Check if we've already registered and initialised the driver. Also | |
14 | cleanup in case of registration errors or hot-unplug so that a new | |
15 | device can be used. | |
16 | ||
17 | Reported-by: Peter Krempa <pkrempa@redhat.com> | |
18 | Reported-by: <yunzheng@redhat.com> | |
19 | Signed-off-by: Amit Shah <amit.shah@redhat.com> | |
20 | Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> | |
21 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
22 | ||
23 | --- | |
24 | drivers/char/hw_random/virtio-rng.c | 13 +++++++++++-- | |
25 | 1 file changed, 11 insertions(+), 2 deletions(-) | |
26 | ||
27 | --- a/drivers/char/hw_random/virtio-rng.c | |
28 | +++ b/drivers/char/hw_random/virtio-rng.c | |
29 | @@ -92,14 +92,22 @@ static int probe_common(struct virtio_de | |
30 | { | |
31 | int err; | |
32 | ||
33 | + if (vq) { | |
34 | + /* We only support one device for now */ | |
35 | + return -EBUSY; | |
36 | + } | |
37 | /* We expect a single virtqueue. */ | |
38 | vq = virtio_find_single_vq(vdev, random_recv_done, "input"); | |
39 | - if (IS_ERR(vq)) | |
40 | - return PTR_ERR(vq); | |
41 | + if (IS_ERR(vq)) { | |
42 | + err = PTR_ERR(vq); | |
43 | + vq = NULL; | |
44 | + return err; | |
45 | + } | |
46 | ||
47 | err = hwrng_register(&virtio_hwrng); | |
48 | if (err) { | |
49 | vdev->config->del_vqs(vdev); | |
50 | + vq = NULL; | |
51 | return err; | |
52 | } | |
53 | ||
54 | @@ -112,6 +120,7 @@ static void remove_common(struct virtio_ | |
55 | busy = false; | |
56 | hwrng_unregister(&virtio_hwrng); | |
57 | vdev->config->del_vqs(vdev); | |
58 | + vq = NULL; | |
59 | } | |
60 | ||
61 | static int virtrng_probe(struct virtio_device *vdev) |