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