summaryrefslogtreecommitdiffstats
path: root/drivers/char/hw_random/virtio-rng.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-07-19 08:25:54 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2014-07-19 08:25:54 +0200
commit4e106275290bdb015bc16dc48e55d78cc480e7c7 (patch)
tree0fe35ef231b8219883230e6a39a193ea57ac5418 /drivers/char/hw_random/virtio-rng.c
parentMerge tag 'gfs2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/steve... (diff)
parenthwrng: virtio - ensure reads happen after successful probe (diff)
downloadlinux-4e106275290bdb015bc16dc48e55d78cc480e7c7.tar.xz
linux-4e106275290bdb015bc16dc48e55d78cc480e7c7.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu: "This push fixes a boot hang in virt guests when the virtio RNG is enabled" * git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: hwrng: virtio - ensure reads happen after successful probe hwrng: fetch randomness only after device init
Diffstat (limited to 'drivers/char/hw_random/virtio-rng.c')
-rw-r--r--drivers/char/hw_random/virtio-rng.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
index f3e71501de54..e9b15bc18b4d 100644
--- a/drivers/char/hw_random/virtio-rng.c
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -38,6 +38,8 @@ struct virtrng_info {
int index;
};
+static bool probe_done;
+
static void random_recv_done(struct virtqueue *vq)
{
struct virtrng_info *vi = vq->vdev->priv;
@@ -67,6 +69,13 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
int ret;
struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
+ /*
+ * Don't ask host for data till we're setup. This call can
+ * happen during hwrng_register(), after commit d9e7972619.
+ */
+ if (unlikely(!probe_done))
+ return 0;
+
if (!vi->busy) {
vi->busy = true;
init_completion(&vi->have_data);
@@ -137,6 +146,7 @@ static int probe_common(struct virtio_device *vdev)
return err;
}
+ probe_done = true;
return 0;
}