* [PATCH 1/2] virtio-rng: fix boot with virtio-rng device
@ 2014-05-15 13:21 Sasha Levin
2014-05-15 13:21 ` [PATCH 2/2] virtio-rng: fixes for device registration/unregistration Sasha Levin
2014-05-16 2:09 ` [PATCH 1/2] virtio-rng: fix boot with virtio-rng device Rusty Russell
0 siblings, 2 replies; 3+ messages in thread
From: Sasha Levin @ 2014-05-15 13:21 UTC (permalink / raw)
To: rusty; +Cc: mpm, herbert, linux-kernel, akong, Sasha Levin
Commit "virtio-rng: support multiple virtio-rng devices" has broken
boot with a virtio-rng device because the 'init' callback of the
virtio-rng device was left unitialized to garbage, and got called
by the hwrng infrastructure, killing the guest on boot.
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
Also, do we really need multiple virtio-rng devices? I know it's
nice to have, but if there isn't a solid use-case behind it we're
just adding bugs to working code without any benefit.
drivers/char/hw_random/virtio-rng.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index 12e242b..5b25daa 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -95,7 +95,7 @@ static int probe_common(struct virtio_device *vdev)
int err, i;
struct virtrng_info *vi = NULL;
- vi = kmalloc(sizeof(struct virtrng_info), GFP_KERNEL);
+ vi = kzalloc(sizeof(struct virtrng_info), GFP_KERNEL);
vi->hwrng.name = kmalloc(40, GFP_KERNEL);
init_completion(&vi->have_data);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] virtio-rng: fixes for device registration/unregistration
2014-05-15 13:21 [PATCH 1/2] virtio-rng: fix boot with virtio-rng device Sasha Levin
@ 2014-05-15 13:21 ` Sasha Levin
2014-05-16 2:09 ` [PATCH 1/2] virtio-rng: fix boot with virtio-rng device Rusty Russell
1 sibling, 0 replies; 3+ messages in thread
From: Sasha Levin @ 2014-05-15 13:21 UTC (permalink / raw)
To: rusty; +Cc: mpm, herbert, linux-kernel, akong, Sasha Levin
There are several fixes in this patch (mostly because it's hard
splitting them up):
- Revert the name field in struct hwrng back to 'const'. Also, don't
do an extra kmalloc for the name - just wasteful.
- Deal with allocation failures properly.
- Use IDA to allocate device number instead of brute forcing one.
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
---
drivers/char/hw_random/virtio-rng.c | 41 ++++++++++++++++++++---------------
include/linux/hw_random.h | 2 +-
2 files changed, 24 insertions(+), 19 deletions(-)
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index 5b25daa..f3e7150 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -25,6 +25,7 @@
#include <linux/virtio_rng.h>
#include <linux/module.h>
+static DEFINE_IDA(rng_index_ida);
struct virtrng_info {
struct virtio_device *vdev;
@@ -33,6 +34,8 @@ struct virtrng_info {
unsigned int data_avail;
struct completion have_data;
bool busy;
+ char name[25];
+ int index;
};
static void random_recv_done(struct virtqueue *vq)
@@ -92,41 +95,45 @@ static void virtio_cleanup(struct hwrng *rng)
static int probe_common(struct virtio_device *vdev)
{
- int err, i;
+ int err, index;
struct virtrng_info *vi = NULL;
vi = kzalloc(sizeof(struct virtrng_info), GFP_KERNEL);
- vi->hwrng.name = kmalloc(40, GFP_KERNEL);
+ if (!vi)
+ return -ENOMEM;
+
+ vi->index = index = ida_simple_get(&rng_index_ida, 0, 0, GFP_KERNEL);
+ if (index < 0) {
+ kfree(vi);
+ return index;
+ }
+ sprintf(vi->name, "virtio_rng.%d", index);
init_completion(&vi->have_data);
- vi->hwrng.read = virtio_read;
- vi->hwrng.cleanup = virtio_cleanup;
- vi->hwrng.priv = (unsigned long)vi;
+ vi->hwrng = (struct hwrng) {
+ .read = virtio_read,
+ .cleanup = virtio_cleanup,
+ .priv = (unsigned long)vi,
+ .name = vi->name,
+ };
vdev->priv = vi;
/* We expect a single virtqueue. */
vi->vq = virtio_find_single_vq(vdev, random_recv_done, "input");
if (IS_ERR(vi->vq)) {
err = PTR_ERR(vi->vq);
- kfree(vi->hwrng.name);
vi->vq = NULL;
kfree(vi);
- vi = NULL;
+ ida_simple_remove(&rng_index_ida, index);
return err;
}
- i = 0;
- do {
- sprintf(vi->hwrng.name, "virtio_rng.%d", i++);
- err = hwrng_register(&vi->hwrng);
- } while (err == -EEXIST);
-
+ err = hwrng_register(&vi->hwrng);
if (err) {
vdev->config->del_vqs(vdev);
- kfree(vi->hwrng.name);
vi->vq = NULL;
kfree(vi);
- vi = NULL;
+ ida_simple_remove(&rng_index_ida, index);
return err;
}
@@ -140,10 +147,8 @@ static void remove_common(struct virtio_device *vdev)
vi->busy = false;
hwrng_unregister(&vi->hwrng);
vdev->config->del_vqs(vdev);
- kfree(vi->hwrng.name);
- vi->vq = NULL;
+ ida_simple_remove(&rng_index_ida, vi->index);
kfree(vi);
- vi = NULL;
}
static int virtrng_probe(struct virtio_device *vdev)
diff --git a/include/linux/hw_random.h b/include/linux/hw_random.h
index 02d9c87..b4b0eef 100644
--- a/include/linux/hw_random.h
+++ b/include/linux/hw_random.h
@@ -31,7 +31,7 @@
* @priv: Private data, for use by the RNG driver.
*/
struct hwrng {
- char *name;
+ const char *name;
int (*init)(struct hwrng *rng);
void (*cleanup)(struct hwrng *rng);
int (*data_present)(struct hwrng *rng, int wait);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH 1/2] virtio-rng: fix boot with virtio-rng device
2014-05-15 13:21 [PATCH 1/2] virtio-rng: fix boot with virtio-rng device Sasha Levin
2014-05-15 13:21 ` [PATCH 2/2] virtio-rng: fixes for device registration/unregistration Sasha Levin
@ 2014-05-16 2:09 ` Rusty Russell
1 sibling, 0 replies; 3+ messages in thread
From: Rusty Russell @ 2014-05-16 2:09 UTC (permalink / raw)
To: Sasha Levin; +Cc: mpm, herbert, linux-kernel, akong, Sasha Levin
Sasha Levin <sasha.levin@oracle.com> writes:
> Commit "virtio-rng: support multiple virtio-rng devices" has broken
> boot with a virtio-rng device because the 'init' callback of the
> virtio-rng device was left unitialized to garbage, and got called
> by the hwrng infrastructure, killing the guest on boot.
>
> Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
> ---
>
> Also, do we really need multiple virtio-rng devices? I know it's
> nice to have, but if there isn't a solid use-case behind it we're
> just adding bugs to working code without any benefit.
Hmm, thanks for this. It's my fault, I should have gone through this
with a fine-tooth comb once I saw the const change in hwrng.
As Amos pointed out in the commit message, qemu support multiple entropy
sources. It's a line ball: since you've done the work, I'll apply it
(if you'd just submitted a bug report I'd probably revert the commit).
AFAICT Amos owes you a beer :)
Cheers,
Rusty.
PS: Added Fixes: line.
> drivers/char/hw_random/virtio-rng.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
> index 12e242b..5b25daa 100644
> --- a/drivers/char/hw_random/virtio-rng.c
> +++ b/drivers/char/hw_random/virtio-rng.c
> @@ -95,7 +95,7 @@ static int probe_common(struct virtio_device *vdev)
> int err, i;
> struct virtrng_info *vi = NULL;
>
> - vi = kmalloc(sizeof(struct virtrng_info), GFP_KERNEL);
> + vi = kzalloc(sizeof(struct virtrng_info), GFP_KERNEL);
> vi->hwrng.name = kmalloc(40, GFP_KERNEL);
> init_completion(&vi->have_data);
>
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2014-05-18 23:36 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-05-15 13:21 [PATCH 1/2] virtio-rng: fix boot with virtio-rng device Sasha Levin
2014-05-15 13:21 ` [PATCH 2/2] virtio-rng: fixes for device registration/unregistration Sasha Levin
2014-05-16 2:09 ` [PATCH 1/2] virtio-rng: fix boot with virtio-rng device Rusty Russell
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.