]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/crypto/virtio/virtio_crypto_core.c
0aa2f045543b5b7726f946bf2404f38ba593dd46
[karo-tx-linux.git] / drivers / crypto / virtio / virtio_crypto_core.c
1  /* Driver for Virtio crypto device.
2   *
3   * Copyright 2016 HUAWEI TECHNOLOGIES CO., LTD.
4   *
5   * This program is free software; you can redistribute it and/or modify
6   * it under the terms of the GNU General Public License as published by
7   * the Free Software Foundation; either version 2 of the License, or
8   * (at your option) any later version.
9   *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, see <http://www.gnu.org/licenses/>.
17   */
18
19 #include <linux/err.h>
20 #include <linux/module.h>
21 #include <linux/virtio_config.h>
22 #include <linux/cpu.h>
23
24 #include <uapi/linux/virtio_crypto.h>
25 #include "virtio_crypto_common.h"
26
27
28 static void
29 virtcrypto_clear_request(struct virtio_crypto_request *vc_req)
30 {
31         if (vc_req) {
32                 kzfree(vc_req->iv);
33                 kzfree(vc_req->req_data);
34                 kfree(vc_req->sgs);
35         }
36 }
37
38 static void virtcrypto_dataq_callback(struct virtqueue *vq)
39 {
40         struct virtio_crypto *vcrypto = vq->vdev->priv;
41         struct virtio_crypto_request *vc_req;
42         unsigned long flags;
43         unsigned int len;
44         struct ablkcipher_request *ablk_req;
45         int error;
46         unsigned int qid = vq->index;
47
48         spin_lock_irqsave(&vcrypto->data_vq[qid].lock, flags);
49         do {
50                 virtqueue_disable_cb(vq);
51                 while ((vc_req = virtqueue_get_buf(vq, &len)) != NULL) {
52                         if (vc_req->type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
53                                 switch (vc_req->status) {
54                                 case VIRTIO_CRYPTO_OK:
55                                         error = 0;
56                                         break;
57                                 case VIRTIO_CRYPTO_INVSESS:
58                                 case VIRTIO_CRYPTO_ERR:
59                                         error = -EINVAL;
60                                         break;
61                                 case VIRTIO_CRYPTO_BADMSG:
62                                         error = -EBADMSG;
63                                         break;
64                                 default:
65                                         error = -EIO;
66                                         break;
67                                 }
68                                 ablk_req = vc_req->ablkcipher_req;
69                                 virtcrypto_clear_request(vc_req);
70
71                                 spin_unlock_irqrestore(
72                                         &vcrypto->data_vq[qid].lock, flags);
73                                 /* Finish the encrypt or decrypt process */
74                                 ablk_req->base.complete(&ablk_req->base, error);
75                                 spin_lock_irqsave(
76                                         &vcrypto->data_vq[qid].lock, flags);
77                         }
78                 }
79         } while (!virtqueue_enable_cb(vq));
80         spin_unlock_irqrestore(&vcrypto->data_vq[qid].lock, flags);
81 }
82
83 static int virtcrypto_find_vqs(struct virtio_crypto *vi)
84 {
85         vq_callback_t **callbacks;
86         struct virtqueue **vqs;
87         int ret = -ENOMEM;
88         int i, total_vqs;
89         const char **names;
90
91         /*
92          * We expect 1 data virtqueue, followed by
93          * possible N-1 data queues used in multiqueue mode,
94          * followed by control vq.
95          */
96         total_vqs = vi->max_data_queues + 1;
97
98         /* Allocate space for find_vqs parameters */
99         vqs = kcalloc(total_vqs, sizeof(*vqs), GFP_KERNEL);
100         if (!vqs)
101                 goto err_vq;
102         callbacks = kcalloc(total_vqs, sizeof(*callbacks), GFP_KERNEL);
103         if (!callbacks)
104                 goto err_callback;
105         names = kcalloc(total_vqs, sizeof(*names), GFP_KERNEL);
106         if (!names)
107                 goto err_names;
108
109         /* Parameters for control virtqueue */
110         callbacks[total_vqs - 1] = NULL;
111         names[total_vqs - 1] = "controlq";
112
113         /* Allocate/initialize parameters for data virtqueues */
114         for (i = 0; i < vi->max_data_queues; i++) {
115                 callbacks[i] = virtcrypto_dataq_callback;
116                 snprintf(vi->data_vq[i].name, sizeof(vi->data_vq[i].name),
117                                 "dataq.%d", i);
118                 names[i] = vi->data_vq[i].name;
119         }
120
121         ret = vi->vdev->config->find_vqs(vi->vdev, total_vqs, vqs, callbacks,
122                                          names, NULL);
123         if (ret)
124                 goto err_find;
125
126         vi->ctrl_vq = vqs[total_vqs - 1];
127
128         for (i = 0; i < vi->max_data_queues; i++) {
129                 spin_lock_init(&vi->data_vq[i].lock);
130                 vi->data_vq[i].vq = vqs[i];
131         }
132
133         kfree(names);
134         kfree(callbacks);
135         kfree(vqs);
136
137         return 0;
138
139 err_find:
140         kfree(names);
141 err_names:
142         kfree(callbacks);
143 err_callback:
144         kfree(vqs);
145 err_vq:
146         return ret;
147 }
148
149 static int virtcrypto_alloc_queues(struct virtio_crypto *vi)
150 {
151         vi->data_vq = kcalloc(vi->max_data_queues, sizeof(*vi->data_vq),
152                                 GFP_KERNEL);
153         if (!vi->data_vq)
154                 return -ENOMEM;
155
156         return 0;
157 }
158
159 static void virtcrypto_clean_affinity(struct virtio_crypto *vi, long hcpu)
160 {
161         int i;
162
163         if (vi->affinity_hint_set) {
164                 for (i = 0; i < vi->max_data_queues; i++)
165                         virtqueue_set_affinity(vi->data_vq[i].vq, -1);
166
167                 vi->affinity_hint_set = false;
168         }
169 }
170
171 static void virtcrypto_set_affinity(struct virtio_crypto *vcrypto)
172 {
173         int i = 0;
174         int cpu;
175
176         /*
177          * In single queue mode, we don't set the cpu affinity.
178          */
179         if (vcrypto->curr_queue == 1 || vcrypto->max_data_queues == 1) {
180                 virtcrypto_clean_affinity(vcrypto, -1);
181                 return;
182         }
183
184         /*
185          * In multiqueue mode, we let the queue to be private to one cpu
186          * by setting the affinity hint to eliminate the contention.
187          *
188          * TODO: adds cpu hotplug support by register cpu notifier.
189          *
190          */
191         for_each_online_cpu(cpu) {
192                 virtqueue_set_affinity(vcrypto->data_vq[i].vq, cpu);
193                 if (++i >= vcrypto->max_data_queues)
194                         break;
195         }
196
197         vcrypto->affinity_hint_set = true;
198 }
199
200 static void virtcrypto_free_queues(struct virtio_crypto *vi)
201 {
202         kfree(vi->data_vq);
203 }
204
205 static int virtcrypto_init_vqs(struct virtio_crypto *vi)
206 {
207         int ret;
208
209         /* Allocate send & receive queues */
210         ret = virtcrypto_alloc_queues(vi);
211         if (ret)
212                 goto err;
213
214         ret = virtcrypto_find_vqs(vi);
215         if (ret)
216                 goto err_free;
217
218         get_online_cpus();
219         virtcrypto_set_affinity(vi);
220         put_online_cpus();
221
222         return 0;
223
224 err_free:
225         virtcrypto_free_queues(vi);
226 err:
227         return ret;
228 }
229
230 static int virtcrypto_update_status(struct virtio_crypto *vcrypto)
231 {
232         u32 status;
233         int err;
234
235         virtio_cread(vcrypto->vdev,
236             struct virtio_crypto_config, status, &status);
237
238         /*
239          * Unknown status bits would be a host error and the driver
240          * should consider the device to be broken.
241          */
242         if (status & (~VIRTIO_CRYPTO_S_HW_READY)) {
243                 dev_warn(&vcrypto->vdev->dev,
244                                 "Unknown status bits: 0x%x\n", status);
245
246                 virtio_break_device(vcrypto->vdev);
247                 return -EPERM;
248         }
249
250         if (vcrypto->status == status)
251                 return 0;
252
253         vcrypto->status = status;
254
255         if (vcrypto->status & VIRTIO_CRYPTO_S_HW_READY) {
256                 err = virtcrypto_dev_start(vcrypto);
257                 if (err) {
258                         dev_err(&vcrypto->vdev->dev,
259                                 "Failed to start virtio crypto device.\n");
260
261                         return -EPERM;
262                 }
263                 dev_info(&vcrypto->vdev->dev, "Accelerator is ready\n");
264         } else {
265                 virtcrypto_dev_stop(vcrypto);
266                 dev_info(&vcrypto->vdev->dev, "Accelerator is not ready\n");
267         }
268
269         return 0;
270 }
271
272 static void virtcrypto_del_vqs(struct virtio_crypto *vcrypto)
273 {
274         struct virtio_device *vdev = vcrypto->vdev;
275
276         virtcrypto_clean_affinity(vcrypto, -1);
277
278         vdev->config->del_vqs(vdev);
279
280         virtcrypto_free_queues(vcrypto);
281 }
282
283 static int virtcrypto_probe(struct virtio_device *vdev)
284 {
285         int err = -EFAULT;
286         struct virtio_crypto *vcrypto;
287         u32 max_data_queues = 0, max_cipher_key_len = 0;
288         u32 max_auth_key_len = 0;
289         u64 max_size = 0;
290
291         if (!virtio_has_feature(vdev, VIRTIO_F_VERSION_1))
292                 return -ENODEV;
293
294         if (!vdev->config->get) {
295                 dev_err(&vdev->dev, "%s failure: config access disabled\n",
296                         __func__);
297                 return -EINVAL;
298         }
299
300         if (num_possible_nodes() > 1 && dev_to_node(&vdev->dev) < 0) {
301                 /*
302                  * If the accelerator is connected to a node with no memory
303                  * there is no point in using the accelerator since the remote
304                  * memory transaction will be very slow.
305                  */
306                 dev_err(&vdev->dev, "Invalid NUMA configuration.\n");
307                 return -EINVAL;
308         }
309
310         vcrypto = kzalloc_node(sizeof(*vcrypto), GFP_KERNEL,
311                                         dev_to_node(&vdev->dev));
312         if (!vcrypto)
313                 return -ENOMEM;
314
315         virtio_cread(vdev, struct virtio_crypto_config,
316                         max_dataqueues, &max_data_queues);
317         if (max_data_queues < 1)
318                 max_data_queues = 1;
319
320         virtio_cread(vdev, struct virtio_crypto_config,
321                 max_cipher_key_len, &max_cipher_key_len);
322         virtio_cread(vdev, struct virtio_crypto_config,
323                 max_auth_key_len, &max_auth_key_len);
324         virtio_cread(vdev, struct virtio_crypto_config,
325                 max_size, &max_size);
326
327         /* Add virtio crypto device to global table */
328         err = virtcrypto_devmgr_add_dev(vcrypto);
329         if (err) {
330                 dev_err(&vdev->dev, "Failed to add new virtio crypto device.\n");
331                 goto free;
332         }
333         vcrypto->owner = THIS_MODULE;
334         vcrypto = vdev->priv = vcrypto;
335         vcrypto->vdev = vdev;
336
337         spin_lock_init(&vcrypto->ctrl_lock);
338
339         /* Use single data queue as default */
340         vcrypto->curr_queue = 1;
341         vcrypto->max_data_queues = max_data_queues;
342         vcrypto->max_cipher_key_len = max_cipher_key_len;
343         vcrypto->max_auth_key_len = max_auth_key_len;
344         vcrypto->max_size = max_size;
345
346         dev_info(&vdev->dev,
347                 "max_queues: %u, max_cipher_key_len: %u, max_auth_key_len: %u, max_size 0x%llx\n",
348                 vcrypto->max_data_queues,
349                 vcrypto->max_cipher_key_len,
350                 vcrypto->max_auth_key_len,
351                 vcrypto->max_size);
352
353         err = virtcrypto_init_vqs(vcrypto);
354         if (err) {
355                 dev_err(&vdev->dev, "Failed to initialize vqs.\n");
356                 goto free_dev;
357         }
358         virtio_device_ready(vdev);
359
360         err = virtcrypto_update_status(vcrypto);
361         if (err)
362                 goto free_vqs;
363
364         return 0;
365
366 free_vqs:
367         vcrypto->vdev->config->reset(vdev);
368         virtcrypto_del_vqs(vcrypto);
369 free_dev:
370         virtcrypto_devmgr_rm_dev(vcrypto);
371 free:
372         kfree(vcrypto);
373         return err;
374 }
375
376 static void virtcrypto_free_unused_reqs(struct virtio_crypto *vcrypto)
377 {
378         struct virtio_crypto_request *vc_req;
379         int i;
380         struct virtqueue *vq;
381
382         for (i = 0; i < vcrypto->max_data_queues; i++) {
383                 vq = vcrypto->data_vq[i].vq;
384                 while ((vc_req = virtqueue_detach_unused_buf(vq)) != NULL) {
385                         kfree(vc_req->req_data);
386                         kfree(vc_req->sgs);
387                 }
388         }
389 }
390
391 static void virtcrypto_remove(struct virtio_device *vdev)
392 {
393         struct virtio_crypto *vcrypto = vdev->priv;
394
395         dev_info(&vdev->dev, "Start virtcrypto_remove.\n");
396
397         if (virtcrypto_dev_started(vcrypto))
398                 virtcrypto_dev_stop(vcrypto);
399         vdev->config->reset(vdev);
400         virtcrypto_free_unused_reqs(vcrypto);
401         virtcrypto_del_vqs(vcrypto);
402         virtcrypto_devmgr_rm_dev(vcrypto);
403         kfree(vcrypto);
404 }
405
406 static void virtcrypto_config_changed(struct virtio_device *vdev)
407 {
408         struct virtio_crypto *vcrypto = vdev->priv;
409
410         virtcrypto_update_status(vcrypto);
411 }
412
413 #ifdef CONFIG_PM_SLEEP
414 static int virtcrypto_freeze(struct virtio_device *vdev)
415 {
416         struct virtio_crypto *vcrypto = vdev->priv;
417
418         vdev->config->reset(vdev);
419         virtcrypto_free_unused_reqs(vcrypto);
420         if (virtcrypto_dev_started(vcrypto))
421                 virtcrypto_dev_stop(vcrypto);
422
423         virtcrypto_del_vqs(vcrypto);
424         return 0;
425 }
426
427 static int virtcrypto_restore(struct virtio_device *vdev)
428 {
429         struct virtio_crypto *vcrypto = vdev->priv;
430         int err;
431
432         err = virtcrypto_init_vqs(vcrypto);
433         if (err)
434                 return err;
435
436         virtio_device_ready(vdev);
437         err = virtcrypto_dev_start(vcrypto);
438         if (err) {
439                 dev_err(&vdev->dev, "Failed to start virtio crypto device.\n");
440                 return -EFAULT;
441         }
442
443         return 0;
444 }
445 #endif
446
447 static unsigned int features[] = {
448         /* none */
449 };
450
451 static struct virtio_device_id id_table[] = {
452         { VIRTIO_ID_CRYPTO, VIRTIO_DEV_ANY_ID },
453         { 0 },
454 };
455
456 static struct virtio_driver virtio_crypto_driver = {
457         .driver.name         = KBUILD_MODNAME,
458         .driver.owner        = THIS_MODULE,
459         .feature_table       = features,
460         .feature_table_size  = ARRAY_SIZE(features),
461         .id_table            = id_table,
462         .probe               = virtcrypto_probe,
463         .remove              = virtcrypto_remove,
464         .config_changed = virtcrypto_config_changed,
465 #ifdef CONFIG_PM_SLEEP
466         .freeze = virtcrypto_freeze,
467         .restore = virtcrypto_restore,
468 #endif
469 };
470
471 module_virtio_driver(virtio_crypto_driver);
472
473 MODULE_DEVICE_TABLE(virtio, id_table);
474 MODULE_DESCRIPTION("virtio crypto device driver");
475 MODULE_LICENSE("GPL");
476 MODULE_AUTHOR("Gonglei <arei.gonglei@huawei.com>");