diff options
Diffstat (limited to 'drivers/virtio/virtio_rng.c')
-rw-r--r-- | drivers/virtio/virtio_rng.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/virtio/virtio_rng.c b/drivers/virtio/virtio_rng.c index b85545c2ee5..786359a6e36 100644 --- a/drivers/virtio/virtio_rng.c +++ b/drivers/virtio/virtio_rng.c @@ -20,7 +20,7 @@ struct virtio_rng_priv { static int virtio_rng_read(struct udevice *dev, void *data, size_t len) { int ret; - unsigned int rsize; + unsigned int rsize = 1; unsigned char buf[BUFFER_SIZE] __aligned(4); unsigned char *ptr = data; struct virtio_sg sg; @@ -29,7 +29,12 @@ static int virtio_rng_read(struct udevice *dev, void *data, size_t len) while (len) { sg.addr = buf; - sg.length = min(len, sizeof(buf)); + /* + * Work around implementations which always return 8 bytes + * less than requested, down to 0 bytes, which would + * cause an endless loop otherwise. + */ + sg.length = min(rsize ? len : len + 8, sizeof(buf)); sgs[0] = &sg; ret = virtqueue_add(priv->rng_vq, sgs, 0, 1); |