Line data Source code
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 <linux/err.h>
8 : #include <linux/hw_random.h>
9 : #include <linux/scatterlist.h>
10 : #include <linux/spinlock.h>
11 : #include <linux/virtio.h>
12 : #include <linux/virtio_rng.h>
13 : #include <linux/module.h>
14 : #include <linux/slab.h>
15 :
16 : static DEFINE_IDA(rng_index_ida);
17 :
18 : struct virtrng_info {
19 : struct hwrng hwrng;
20 : struct virtqueue *vq;
21 : struct completion have_data;
22 : char name[25];
23 : unsigned int data_avail;
24 : int index;
25 : bool busy;
26 : bool hwrng_register_done;
27 : bool hwrng_removed;
28 : };
29 :
30 0 : static void random_recv_done(struct virtqueue *vq)
31 : {
32 0 : struct virtrng_info *vi = vq->vdev->priv;
33 :
34 : /* We can get spurious callbacks, e.g. shared IRQs + virtio_pci. */
35 0 : if (!virtqueue_get_buf(vi->vq, &vi->data_avail))
36 : return;
37 :
38 0 : complete(&vi->have_data);
39 : }
40 :
41 : /* The host will fill any buffer we give it with sweet, sweet randomness. */
42 0 : static void register_buffer(struct virtrng_info *vi, u8 *buf, size_t size)
43 : {
44 0 : struct scatterlist sg;
45 :
46 0 : sg_init_one(&sg, buf, size);
47 :
48 : /* There should always be room for one buffer. */
49 0 : virtqueue_add_inbuf(vi->vq, &sg, 1, buf, GFP_KERNEL);
50 :
51 0 : virtqueue_kick(vi->vq);
52 0 : }
53 :
54 0 : static int virtio_read(struct hwrng *rng, void *buf, size_t size, bool wait)
55 : {
56 0 : int ret;
57 0 : struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
58 :
59 0 : if (vi->hwrng_removed)
60 : return -ENODEV;
61 :
62 0 : if (!vi->busy) {
63 0 : vi->busy = true;
64 0 : reinit_completion(&vi->have_data);
65 0 : register_buffer(vi, buf, size);
66 : }
67 :
68 0 : if (!wait)
69 : return 0;
70 :
71 0 : ret = wait_for_completion_killable(&vi->have_data);
72 0 : if (ret < 0)
73 : return ret;
74 :
75 0 : vi->busy = false;
76 :
77 0 : return vi->data_avail;
78 : }
79 :
80 0 : static void virtio_cleanup(struct hwrng *rng)
81 : {
82 0 : struct virtrng_info *vi = (struct virtrng_info *)rng->priv;
83 :
84 0 : if (vi->busy)
85 0 : wait_for_completion(&vi->have_data);
86 0 : }
87 :
88 0 : static int probe_common(struct virtio_device *vdev)
89 : {
90 0 : int err, index;
91 0 : struct virtrng_info *vi = NULL;
92 :
93 0 : vi = kzalloc(sizeof(struct virtrng_info), GFP_KERNEL);
94 0 : if (!vi)
95 : return -ENOMEM;
96 :
97 0 : vi->index = index = ida_simple_get(&rng_index_ida, 0, 0, GFP_KERNEL);
98 0 : if (index < 0) {
99 0 : err = index;
100 0 : goto err_ida;
101 : }
102 0 : sprintf(vi->name, "virtio_rng.%d", index);
103 0 : init_completion(&vi->have_data);
104 :
105 0 : vi->hwrng = (struct hwrng) {
106 : .read = virtio_read,
107 : .cleanup = virtio_cleanup,
108 0 : .priv = (unsigned long)vi,
109 : .name = vi->name,
110 : .quality = 1000,
111 : };
112 0 : vdev->priv = vi;
113 :
114 : /* We expect a single virtqueue. */
115 0 : vi->vq = virtio_find_single_vq(vdev, random_recv_done, "input");
116 0 : if (IS_ERR(vi->vq)) {
117 0 : err = PTR_ERR(vi->vq);
118 0 : goto err_find;
119 : }
120 :
121 : return 0;
122 :
123 0 : err_find:
124 0 : ida_simple_remove(&rng_index_ida, index);
125 0 : err_ida:
126 0 : kfree(vi);
127 0 : return err;
128 : }
129 :
130 0 : static void remove_common(struct virtio_device *vdev)
131 : {
132 0 : struct virtrng_info *vi = vdev->priv;
133 :
134 0 : vi->hwrng_removed = true;
135 0 : vi->data_avail = 0;
136 0 : complete(&vi->have_data);
137 0 : vdev->config->reset(vdev);
138 0 : vi->busy = false;
139 0 : if (vi->hwrng_register_done)
140 0 : hwrng_unregister(&vi->hwrng);
141 0 : vdev->config->del_vqs(vdev);
142 0 : ida_simple_remove(&rng_index_ida, vi->index);
143 0 : kfree(vi);
144 0 : }
145 :
146 0 : static int virtrng_probe(struct virtio_device *vdev)
147 : {
148 0 : return probe_common(vdev);
149 : }
150 :
151 0 : static void virtrng_remove(struct virtio_device *vdev)
152 : {
153 0 : remove_common(vdev);
154 0 : }
155 :
156 0 : static void virtrng_scan(struct virtio_device *vdev)
157 : {
158 0 : struct virtrng_info *vi = vdev->priv;
159 0 : int err;
160 :
161 0 : err = hwrng_register(&vi->hwrng);
162 0 : if (!err)
163 0 : vi->hwrng_register_done = true;
164 0 : }
165 :
166 : #ifdef CONFIG_PM_SLEEP
167 : static int virtrng_freeze(struct virtio_device *vdev)
168 : {
169 : remove_common(vdev);
170 : return 0;
171 : }
172 :
173 : static int virtrng_restore(struct virtio_device *vdev)
174 : {
175 : int err;
176 :
177 : err = probe_common(vdev);
178 : if (!err) {
179 : struct virtrng_info *vi = vdev->priv;
180 :
181 : /*
182 : * Set hwrng_removed to ensure that virtio_read()
183 : * does not block waiting for data before the
184 : * registration is complete.
185 : */
186 : vi->hwrng_removed = true;
187 : err = hwrng_register(&vi->hwrng);
188 : if (!err) {
189 : vi->hwrng_register_done = true;
190 : vi->hwrng_removed = false;
191 : }
192 : }
193 :
194 : return err;
195 : }
196 : #endif
197 :
198 : static const struct virtio_device_id id_table[] = {
199 : { VIRTIO_ID_RNG, VIRTIO_DEV_ANY_ID },
200 : { 0 },
201 : };
202 :
203 : static struct virtio_driver virtio_rng_driver = {
204 : .driver.name = KBUILD_MODNAME,
205 : .driver.owner = THIS_MODULE,
206 : .id_table = id_table,
207 : .probe = virtrng_probe,
208 : .remove = virtrng_remove,
209 : .scan = virtrng_scan,
210 : #ifdef CONFIG_PM_SLEEP
211 : .freeze = virtrng_freeze,
212 : .restore = virtrng_restore,
213 : #endif
214 : };
215 :
216 1 : module_virtio_driver(virtio_rng_driver);
217 : MODULE_DEVICE_TABLE(virtio, id_table);
218 : MODULE_DESCRIPTION("Virtio random number driver");
219 : MODULE_LICENSE("GPL");
|