]>
Commit | Line | Data |
---|---|---|
9a904337 SL |
1 | From 0630163ea843d0f3fa8a45668b82c2789005cb53 Mon Sep 17 00:00:00 2001 |
2 | From: David Tolnay <dtolnay@gmail.com> | |
3 | Date: Mon, 7 Jan 2019 14:36:11 -0800 | |
4 | Subject: hwrng: virtio - Avoid repeated init of completion | |
5 | ||
6 | [ Upstream commit aef027db48da56b6f25d0e54c07c8401ada6ce21 ] | |
7 | ||
8 | The virtio-rng driver uses a completion called have_data to wait for a | |
9 | virtio read to be fulfilled by the hypervisor. The completion is reset | |
10 | before placing a buffer on the virtio queue and completed by the virtio | |
11 | callback once data has been written into the buffer. | |
12 | ||
13 | Prior to this commit, the driver called init_completion on this | |
14 | completion both during probe as well as when registering virtio buffers | |
15 | as part of a hwrng read operation. The second of these init_completion | |
16 | calls should instead be reinit_completion because the have_data | |
17 | completion has already been inited by probe. As described in | |
18 | Documentation/scheduler/completion.txt, "Calling init_completion() twice | |
19 | on the same completion object is most likely a bug". | |
20 | ||
21 | This bug was present in the initial implementation of virtio-rng in | |
22 | f7f510ec1957 ("virtio: An entropy device, as suggested by hpa"). Back | |
23 | then the have_data completion was a single static completion rather than | |
24 | a member of one of potentially multiple virtrng_info structs as | |
25 | implemented later by 08e53fbdb85c ("virtio-rng: support multiple | |
26 | virtio-rng devices"). The original driver incorrectly used | |
27 | init_completion rather than INIT_COMPLETION to reset have_data during | |
28 | read. | |
29 | ||
30 | Tested by running `head -c48 /dev/random | hexdump` within crosvm, the | |
31 | Chrome OS virtual machine monitor, and confirming that the virtio-rng | |
32 | driver successfully produces random bytes from the host. | |
33 | ||
34 | Signed-off-by: David Tolnay <dtolnay@gmail.com> | |
35 | Tested-by: David Tolnay <dtolnay@gmail.com> | |
36 | Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> | |
37 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
38 | --- | |
39 | drivers/char/hw_random/virtio-rng.c | 2 +- | |
40 | 1 file changed, 1 insertion(+), 1 deletion(-) | |
41 | ||
42 | diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c | |
43 | index 72295ea2fd1c..5cdc8c534ad4 100644 | |
44 | --- a/drivers/char/hw_random/virtio-rng.c | |
45 | +++ b/drivers/char/hw_random/virtio-rng.c | |
46 | @@ -74,7 +74,7 @@ static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait) | |
47 | ||
48 | if (!vi->busy) { | |
49 | vi->busy = true; | |
50 | - init_completion(&vi->have_data); | |
51 | + reinit_completion(&vi->have_data); | |
52 | register_buffer(vi, buf, size); | |
53 | } | |
54 | ||
55 | -- | |
56 | 2.19.1 | |
57 |