diff options
author | Brijesh Singh <brijesh.singh@amd.com> | 2017-07-06 10:59:14 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2017-07-18 05:51:19 -0400 |
commit | 720419f01832f7e697cb80480b97b2a1e96045cd (patch) | |
tree | 1275fa5e6cf63b7bb9db6ab2e191d4b7d076ca4f /drivers/crypto/ccp/sp-dev.c | |
parent | 970e8303cb8d6d8e77402345abbdd83862e800ac (diff) |
crypto: ccp - Introduce the AMD Secure Processor device
The CCP device is part of the AMD Secure Processor. In order to expand
the usage of the AMD Secure Processor, create a framework that allows
functional components of the AMD Secure Processor to be initialized and
handled appropriately.
Signed-off-by: Brijesh Singh <brijesh.singh@amd.com>
Acked-by: Gary R Hook <gary.hook@amd.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'drivers/crypto/ccp/sp-dev.c')
-rw-r--r-- | drivers/crypto/ccp/sp-dev.c | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/drivers/crypto/ccp/sp-dev.c b/drivers/crypto/ccp/sp-dev.c new file mode 100644 index 000000000000..63cc74ee6d2a --- /dev/null +++ b/drivers/crypto/ccp/sp-dev.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* | ||
2 | * AMD Secure Processor driver | ||
3 | * | ||
4 | * Copyright (C) 2017 Advanced Micro Devices, Inc. | ||
5 | * | ||
6 | * Author: Tom Lendacky <thomas.lendacky@amd.com> | ||
7 | * Author: Gary R Hook <gary.hook@amd.com> | ||
8 | * Author: Brijesh Singh <brijesh.singh@amd.com> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/module.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/kthread.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/spinlock_types.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/ccp.h> | ||
24 | |||
25 | #include "ccp-dev.h" | ||
26 | #include "sp-dev.h" | ||
27 | |||
28 | MODULE_AUTHOR("Tom Lendacky <thomas.lendacky@amd.com>"); | ||
29 | MODULE_AUTHOR("Gary R Hook <gary.hook@amd.com>"); | ||
30 | MODULE_LICENSE("GPL"); | ||
31 | MODULE_VERSION("1.1.0"); | ||
32 | MODULE_DESCRIPTION("AMD Secure Processor driver"); | ||
33 | |||
34 | /* List of SPs, SP count, read-write access lock, and access functions | ||
35 | * | ||
36 | * Lock structure: get sp_unit_lock for reading whenever we need to | ||
37 | * examine the SP list. | ||
38 | */ | ||
39 | static DEFINE_RWLOCK(sp_unit_lock); | ||
40 | static LIST_HEAD(sp_units); | ||
41 | |||
42 | /* Ever-increasing value to produce unique unit numbers */ | ||
43 | static atomic_t sp_ordinal; | ||
44 | |||
45 | static void sp_add_device(struct sp_device *sp) | ||
46 | { | ||
47 | unsigned long flags; | ||
48 | |||
49 | write_lock_irqsave(&sp_unit_lock, flags); | ||
50 | |||
51 | list_add_tail(&sp->entry, &sp_units); | ||
52 | |||
53 | write_unlock_irqrestore(&sp_unit_lock, flags); | ||
54 | } | ||
55 | |||
56 | static void sp_del_device(struct sp_device *sp) | ||
57 | { | ||
58 | unsigned long flags; | ||
59 | |||
60 | write_lock_irqsave(&sp_unit_lock, flags); | ||
61 | |||
62 | list_del(&sp->entry); | ||
63 | |||
64 | write_unlock_irqrestore(&sp_unit_lock, flags); | ||
65 | } | ||
66 | |||
67 | /** | ||
68 | * sp_alloc_struct - allocate and initialize the sp_device struct | ||
69 | * | ||
70 | * @dev: device struct of the SP | ||
71 | */ | ||
72 | struct sp_device *sp_alloc_struct(struct device *dev) | ||
73 | { | ||
74 | struct sp_device *sp; | ||
75 | |||
76 | sp = devm_kzalloc(dev, sizeof(*sp), GFP_KERNEL); | ||
77 | if (!sp) | ||
78 | return NULL; | ||
79 | |||
80 | sp->dev = dev; | ||
81 | sp->ord = atomic_inc_return(&sp_ordinal); | ||
82 | snprintf(sp->name, SP_MAX_NAME_LEN, "sp-%u", sp->ord); | ||
83 | |||
84 | return sp; | ||
85 | } | ||
86 | |||
87 | int sp_init(struct sp_device *sp) | ||
88 | { | ||
89 | sp_add_device(sp); | ||
90 | |||
91 | if (sp->dev_vdata->ccp_vdata) | ||
92 | ccp_dev_init(sp); | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | void sp_destroy(struct sp_device *sp) | ||
98 | { | ||
99 | if (sp->dev_vdata->ccp_vdata) | ||
100 | ccp_dev_destroy(sp); | ||
101 | |||
102 | sp_del_device(sp); | ||
103 | } | ||
104 | |||
105 | #ifdef CONFIG_PM | ||
106 | int sp_suspend(struct sp_device *sp, pm_message_t state) | ||
107 | { | ||
108 | int ret; | ||
109 | |||
110 | if (sp->dev_vdata->ccp_vdata) { | ||
111 | ret = ccp_dev_suspend(sp, state); | ||
112 | if (ret) | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | int sp_resume(struct sp_device *sp) | ||
120 | { | ||
121 | int ret; | ||
122 | |||
123 | if (sp->dev_vdata->ccp_vdata) { | ||
124 | ret = ccp_dev_resume(sp); | ||
125 | if (ret) | ||
126 | return ret; | ||
127 | } | ||
128 | |||
129 | return 0; | ||
130 | } | ||
131 | #endif | ||
132 | |||
133 | static int __init sp_mod_init(void) | ||
134 | { | ||
135 | #ifdef CONFIG_X86 | ||
136 | int ret; | ||
137 | |||
138 | ret = ccp_pci_init(); | ||
139 | if (ret) | ||
140 | return ret; | ||
141 | |||
142 | /* Don't leave the driver loaded if init failed */ | ||
143 | if (ccp_present() != 0) { | ||
144 | ccp_pci_exit(); | ||
145 | return -ENODEV; | ||
146 | } | ||
147 | |||
148 | return 0; | ||
149 | #endif | ||
150 | |||
151 | #ifdef CONFIG_ARM64 | ||
152 | int ret; | ||
153 | |||
154 | ret = ccp_platform_init(); | ||
155 | if (ret) | ||
156 | return ret; | ||
157 | |||
158 | /* Don't leave the driver loaded if init failed */ | ||
159 | if (ccp_present() != 0) { | ||
160 | ccp_platform_exit(); | ||
161 | return -ENODEV; | ||
162 | } | ||
163 | |||
164 | return 0; | ||
165 | #endif | ||
166 | |||
167 | return -ENODEV; | ||
168 | } | ||
169 | |||
170 | static void __exit sp_mod_exit(void) | ||
171 | { | ||
172 | #ifdef CONFIG_X86 | ||
173 | ccp_pci_exit(); | ||
174 | #endif | ||
175 | |||
176 | #ifdef CONFIG_ARM64 | ||
177 | ccp_platform_exit(); | ||
178 | #endif | ||
179 | } | ||
180 | |||
181 | module_init(sp_mod_init); | ||
182 | module_exit(sp_mod_exit); | ||