hc
2024-02-20 e636c8d336489bf3eed5878299e6cc045bbad077
kernel/drivers/crypto/ccp/ccp-dev.c
....@@ -1,16 +1,14 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * AMD Cryptographic Coprocessor (CCP) driver
34 *
4
- * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
5
+ * Copyright (C) 2013,2019 Advanced Micro Devices, Inc.
56 *
67 * Author: Tom Lendacky <thomas.lendacky@amd.com>
78 * Author: Gary R Hook <gary.hook@amd.com>
8
- *
9
- * This program is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License version 2 as
11
- * published by the Free Software Foundation.
129 */
1310
11
+#include <linux/module.h>
1412 #include <linux/kernel.h>
1513 #include <linux/kthread.h>
1614 #include <linux/sched.h>
....@@ -22,12 +20,26 @@
2220 #include <linux/delay.h>
2321 #include <linux/hw_random.h>
2422 #include <linux/cpu.h>
23
+#include <linux/atomic.h>
2524 #ifdef CONFIG_X86
2625 #include <asm/cpu_device_id.h>
2726 #endif
2827 #include <linux/ccp.h>
2928
3029 #include "ccp-dev.h"
30
+
31
+#define MAX_CCPS 32
32
+
33
+/* Limit CCP use to a specifed number of queues per device */
34
+static unsigned int nqueues = 0;
35
+module_param(nqueues, uint, 0444);
36
+MODULE_PARM_DESC(nqueues, "Number of queues per CCP (minimum 1; default: all available)");
37
+
38
+/* Limit the maximum number of configured CCPs */
39
+static atomic_t dev_count = ATOMIC_INIT(0);
40
+static unsigned int max_devs = MAX_CCPS;
41
+module_param(max_devs, uint, 0444);
42
+MODULE_PARM_DESC(max_devs, "Maximum number of CCPs to enable (default: all; 0 disables all CCPs)");
3143
3244 struct ccp_tasklet_data {
3345 struct completion completion;
....@@ -519,7 +531,6 @@
519531 return len;
520532 }
521533
522
-#ifdef CONFIG_PM
523534 bool ccp_queues_suspended(struct ccp_device *ccp)
524535 {
525536 unsigned int suspended = 0;
....@@ -537,7 +548,7 @@
537548 return ccp->cmd_q_count == suspended;
538549 }
539550
540
-int ccp_dev_suspend(struct sp_device *sp, pm_message_t state)
551
+int ccp_dev_suspend(struct sp_device *sp)
541552 {
542553 struct ccp_device *ccp = sp->ccp_data;
543554 unsigned long flags;
....@@ -589,7 +600,6 @@
589600
590601 return 0;
591602 }
592
-#endif
593603
594604 int ccp_dev_init(struct sp_device *sp)
595605 {
....@@ -597,11 +607,23 @@
597607 struct ccp_device *ccp;
598608 int ret;
599609
610
+ /*
611
+ * Check how many we have so far, and stop after reaching
612
+ * that number
613
+ */
614
+ if (atomic_inc_return(&dev_count) > max_devs)
615
+ return 0; /* don't fail the load */
616
+
600617 ret = -ENOMEM;
601618 ccp = ccp_alloc_struct(sp);
602619 if (!ccp)
603620 goto e_err;
604621 sp->ccp_data = ccp;
622
+
623
+ if (!nqueues || (nqueues > MAX_HW_QUEUES))
624
+ ccp->max_q_count = MAX_HW_QUEUES;
625
+ else
626
+ ccp->max_q_count = nqueues;
605627
606628 ccp->vdata = (struct ccp_vdata *)sp->dev_vdata->ccp_vdata;
607629 if (!ccp->vdata || !ccp->vdata->version) {
....@@ -617,18 +639,27 @@
617639 ccp->vdata->setup(ccp);
618640
619641 ret = ccp->vdata->perform->init(ccp);
620
- if (ret)
642
+ if (ret) {
643
+ /* A positive number means that the device cannot be initialized,
644
+ * but no additional message is required.
645
+ */
646
+ if (ret > 0)
647
+ goto e_quiet;
648
+
649
+ /* An unexpected problem occurred, and should be reported in the log */
621650 goto e_err;
651
+ }
622652
623653 dev_notice(dev, "ccp enabled\n");
624654
625655 return 0;
626656
627657 e_err:
628
- sp->ccp_data = NULL;
629
-
630658 dev_notice(dev, "ccp initialization failed\n");
631659
660
+e_quiet:
661
+ sp->ccp_data = NULL;
662
+
632663 return ret;
633664 }
634665