aboutsummaryrefslogtreecommitdiff
path: root/drivers/virtio/virtio_rng.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/virtio/virtio_rng.c')
-rw-r--r--drivers/virtio/virtio_rng.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/drivers/virtio/virtio_rng.c b/drivers/virtio/virtio_rng.c
index b85545c..786359a 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);