xref: /linux/drivers/char/hw_random/virtio-rng.c (revision e3046eeada299f917a8ad883af4434bfb86556b1)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Randomness driver for virtio
4  *  Copyright (C) 2007, 2008 Rusty Russell IBM Corporation
5  */
6 
7 #include <asm/barrier.h>
8 #include <linux/err.h>
9 #include <linux/hw_random.h>
10 #include <linux/nospec.h>
11 #include <linux/scatterlist.h>
12 #include <linux/spinlock.h>
13 #include <linux/virtio.h>
14 #include <linux/virtio_rng.h>
15 #include <linux/dma-mapping.h>
16 #include <linux/module.h>
17 #include <linux/slab.h>
18 
19 static DEFINE_IDA(rng_index_ida);
20 
21 struct virtrng_info {
22 	struct hwrng hwrng;
23 	struct virtqueue *vq;
24 	char name[25];
25 	int index;
26 	bool hwrng_register_done;
27 	bool hwrng_removed;
28 	/* data transfer */
29 	struct completion have_data;
30 	unsigned int data_avail;
31 	unsigned int data_idx;
32 	/* minimal size returned by rng_buffer_size() */
33 	__dma_from_device_group_begin();
34 #if SMP_CACHE_BYTES < 32
35 	u8 data[32];
36 #else
37 	u8 data[SMP_CACHE_BYTES];
38 #endif
39 	__dma_from_device_group_end();
40 };
41 
42 static void random_recv_done(struct virtqueue *vq)
43 {
44 	struct virtrng_info *vi = vq->vdev->priv;
45 	unsigned int len;
46 
47 	/* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
48 	if (!virtqueue_get_buf(vi->vq, &len))
49 		return;
50 
51 	smp_store_release(&vi->data_avail, len);
52 	complete(&vi->have_data);
53 }
54 
55 static void request_entropy(struct virtrng_info *vi)
56 {
57 	struct scatterlist sg;
58 
59 	reinit_completion(&vi->have_data);
60 	vi->data_idx = 0;
61 
62 	sg_init_one(&sg, vi->data, sizeof(vi->data));
63 
64 	/* There should always be room for one buffer. */
65 	virtqueue_add_inbuf(vi->vq, &sg, 1, vi->data, GFP_KERNEL);
66 
67 	virtqueue_kick(vi->vq);
68 }
69 
70 static unsigned int copy_data(struct virtrng_info *vi, void *buf,
71 			      unsigned int size)
72 {
73 	unsigned int idx, avail;
74 
75 	/*
76 	 * vi->data_avail was set from the device-reported used.len and
77 	 * vi->data_idx was advanced by previous copy_data() calls.  A
78 	 * malicious or buggy virtio-rng backend can drive either past
79 	 * sizeof(vi->data).  Clamp at point of use and harden the index
80 	 * with array_index_nospec() so the memcpy() below cannot be
81 	 * steered into adjacent slab memory, including under
82 	 * speculation.
83 	 */
84 	avail = min_t(unsigned int, vi->data_avail, sizeof(vi->data));
85 	if (vi->data_idx >= avail) {
86 		vi->data_avail = 0;
87 		request_entropy(vi);
88 		return 0;
89 	}
90 	size = min_t(unsigned int, size, avail - vi->data_idx);
91 	idx = array_index_nospec(vi->data_idx, sizeof(vi->data));
92 	memcpy(buf, vi->data + idx, size);
93 	vi->data_idx += size;
94 	vi->data_avail -= size;
95 	if (vi->data_avail == 0)
96 		request_entropy(vi);
97 	return size;
98 }
99 
100 static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
101 {
102 	int ret;
103 	struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
104 	unsigned int chunk;
105 	size_t read;
106 
107 	if (vi->hwrng_removed)
108 		return -ENODEV;
109 
110 	read = 0;
111 
112 	/* copy available data */
113 	if (smp_load_acquire(&vi->data_avail)) {
114 		chunk = copy_data(vi, buf, size);
115 		size -= chunk;
116 		read += chunk;
117 	}
118 
119 	if (!wait)
120 		return read;
121 
122 	/* We have already copied available entropy,
123 	 * so either size is 0 or data_avail is 0
124 	 */
125 	while (size != 0) {
126 		/* data_avail is 0 but a request is pending */
127 		ret = wait_for_completion_killable(&vi->have_data);
128 		if (ret < 0)
129 			return ret;
130 		/* if vi->data_avail is 0, we have been interrupted
131 		 * by a cleanup, but buffer stays in the queue
132 		 */
133 		if (vi->data_avail == 0)
134 			return read;
135 
136 		chunk = copy_data(vi, buf + read, size);
137 		size -= chunk;
138 		read += chunk;
139 	}
140 
141 	return read;
142 }
143 
144 static void virtio_cleanup(struct hwrng *rng)
145 {
146 	struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
147 
148 	complete(&vi->have_data);
149 }
150 
151 static int probe_common(struct virtio_device *vdev)
152 {
153 	int err, index;
154 	struct virtrng_info *vi = NULL;
155 
156 	vi = kzalloc_obj(struct virtrng_info);
157 	if (!vi)
158 		return -ENOMEM;
159 
160 	vi->index = index = ida_alloc(&rng_index_ida, GFP_KERNEL);
161 	if (index < 0) {
162 		err = index;
163 		goto err_ida;
164 	}
165 	sprintf(vi->name, "virtio_rng.%d", index);
166 	init_completion(&vi->have_data);
167 
168 	vi->hwrng = (struct hwrng) {
169 		.read = virtio_read,
170 		.cleanup = virtio_cleanup,
171 		.priv = (unsigned long)vi,
172 		.name = vi->name,
173 	};
174 	vdev->priv = vi;
175 
176 	/* We expect a single virtqueue. */
177 	vi->vq = virtio_find_single_vq(vdev, random_recv_done, "input");
178 	if (IS_ERR(vi->vq)) {
179 		err = PTR_ERR(vi->vq);
180 		goto err_find;
181 	}
182 
183 	virtio_device_ready(vdev);
184 
185 	/* we always have a pending entropy request */
186 	request_entropy(vi);
187 
188 	return 0;
189 
190 err_find:
191 	ida_free(&rng_index_ida, index);
192 err_ida:
193 	kfree(vi);
194 	return err;
195 }
196 
197 static void remove_common(struct virtio_device *vdev)
198 {
199 	struct virtrng_info *vi = vdev->priv;
200 
201 	vi->hwrng_removed = true;
202 	vi->data_avail = 0;
203 	vi->data_idx = 0;
204 	complete(&vi->have_data);
205 	if (vi->hwrng_register_done)
206 		hwrng_unregister(&vi->hwrng);
207 	virtio_reset_device(vdev);
208 	vdev->config->del_vqs(vdev);
209 	ida_free(&rng_index_ida, vi->index);
210 	kfree(vi);
211 }
212 
213 static int virtrng_probe(struct virtio_device *vdev)
214 {
215 	return probe_common(vdev);
216 }
217 
218 static void virtrng_remove(struct virtio_device *vdev)
219 {
220 	remove_common(vdev);
221 }
222 
223 static void virtrng_scan(struct virtio_device *vdev)
224 {
225 	struct virtrng_info *vi = vdev->priv;
226 	int err;
227 
228 	err = hwrng_register(&vi->hwrng);
229 	if (!err)
230 		vi->hwrng_register_done = true;
231 }
232 
233 static int virtrng_freeze(struct virtio_device *vdev)
234 {
235 	remove_common(vdev);
236 	return 0;
237 }
238 
239 static int virtrng_restore(struct virtio_device *vdev)
240 {
241 	int err;
242 
243 	err = probe_common(vdev);
244 	if (!err) {
245 		struct virtrng_info *vi = vdev->priv;
246 
247 		/*
248 		 * Set hwrng_removed to ensure that virtio_read()
249 		 * does not block waiting for data before the
250 		 * registration is complete.
251 		 */
252 		vi->hwrng_removed = true;
253 		err = hwrng_register(&vi->hwrng);
254 		if (!err) {
255 			vi->hwrng_register_done = true;
256 			vi->hwrng_removed = false;
257 		}
258 	}
259 
260 	return err;
261 }
262 
263 static const struct virtio_device_id id_table[] = {
264 	{ VIRTIO_ID_RNG, VIRTIO_DEV_ANY_ID },
265 	{ 0 },
266 };
267 
268 static struct virtio_driver virtio_rng_driver = {
269 	.driver.name =	KBUILD_MODNAME,
270 	.id_table =	id_table,
271 	.probe =	virtrng_probe,
272 	.remove =	virtrng_remove,
273 	.scan =		virtrng_scan,
274 	.freeze =	pm_sleep_ptr(virtrng_freeze),
275 	.restore =	pm_sleep_ptr(virtrng_restore),
276 };
277 
278 module_virtio_driver(virtio_rng_driver);
279 MODULE_DEVICE_TABLE(virtio, id_table);
280 MODULE_DESCRIPTION("Virtio random number driver");
281 MODULE_LICENSE("GPL");
282