1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2d3123599STom Lendacky /*
3d3123599STom Lendacky * AMD Cryptographic Coprocessor (CCP) crypto API support
4d3123599STom Lendacky *
568cc652fSGary R Hook * Copyright (C) 2013,2017 Advanced Micro Devices, Inc.
6d3123599STom Lendacky *
7d3123599STom Lendacky * Author: Tom Lendacky <thomas.lendacky@amd.com>
8d3123599STom Lendacky */
9d3123599STom Lendacky
10d3123599STom Lendacky #include <linux/module.h>
11d81ed653STom Lendacky #include <linux/moduleparam.h>
12d3123599STom Lendacky #include <linux/kernel.h>
13d3123599STom Lendacky #include <linux/list.h>
14d3123599STom Lendacky #include <linux/ccp.h>
15d3123599STom Lendacky #include <linux/scatterlist.h>
16d3123599STom Lendacky #include <crypto/internal/hash.h>
17ceeec0afSGary R Hook #include <crypto/internal/akcipher.h>
18d3123599STom Lendacky
19d3123599STom Lendacky #include "ccp-crypto.h"
20d3123599STom Lendacky
21d3123599STom Lendacky MODULE_AUTHOR("Tom Lendacky <thomas.lendacky@amd.com>");
22d3123599STom Lendacky MODULE_LICENSE("GPL");
23d3123599STom Lendacky MODULE_VERSION("1.0.0");
24d3123599STom Lendacky MODULE_DESCRIPTION("AMD Cryptographic Coprocessor crypto API support");
25d3123599STom Lendacky
26d81ed653STom Lendacky static unsigned int aes_disable;
27d81ed653STom Lendacky module_param(aes_disable, uint, 0444);
28d81ed653STom Lendacky MODULE_PARM_DESC(aes_disable, "Disable use of AES - any non-zero value");
29d81ed653STom Lendacky
30d81ed653STom Lendacky static unsigned int sha_disable;
31d81ed653STom Lendacky module_param(sha_disable, uint, 0444);
32d81ed653STom Lendacky MODULE_PARM_DESC(sha_disable, "Disable use of SHA - any non-zero value");
33d81ed653STom Lendacky
34990672d4SGary R Hook static unsigned int des3_disable;
35990672d4SGary R Hook module_param(des3_disable, uint, 0444);
36990672d4SGary R Hook MODULE_PARM_DESC(des3_disable, "Disable use of 3DES - any non-zero value");
37990672d4SGary R Hook
38ceeec0afSGary R Hook static unsigned int rsa_disable;
39ceeec0afSGary R Hook module_param(rsa_disable, uint, 0444);
40ceeec0afSGary R Hook MODULE_PARM_DESC(rsa_disable, "Disable use of RSA - any non-zero value");
41ceeec0afSGary R Hook
42d3123599STom Lendacky /* List heads for the supported algorithms */
43d3123599STom Lendacky static LIST_HEAD(hash_algs);
44be9fe620SArd Biesheuvel static LIST_HEAD(skcipher_algs);
4536cf515bSGary R Hook static LIST_HEAD(aead_algs);
46ceeec0afSGary R Hook static LIST_HEAD(akcipher_algs);
47d3123599STom Lendacky
48bc385447STom Lendacky /* For any tfm, requests for that tfm must be returned on the order
49bc385447STom Lendacky * received. With multiple queues available, the CCP can process more
50bc385447STom Lendacky * than one cmd at a time. Therefore we must maintain a cmd list to insure
51bc385447STom Lendacky * the proper ordering of requests on a given tfm.
52d3123599STom Lendacky */
53bc385447STom Lendacky struct ccp_crypto_queue {
54d3123599STom Lendacky struct list_head cmds;
55d3123599STom Lendacky struct list_head *backlog;
56d3123599STom Lendacky unsigned int cmd_count;
57d3123599STom Lendacky };
588db88467STom Lendacky
59bc385447STom Lendacky #define CCP_CRYPTO_MAX_QLEN 100
60d3123599STom Lendacky
61bc385447STom Lendacky static struct ccp_crypto_queue req_queue;
6263655b62STang Yizhou static DEFINE_SPINLOCK(req_queue_lock);
63d3123599STom Lendacky
64d3123599STom Lendacky struct ccp_crypto_cmd {
65d3123599STom Lendacky struct list_head entry;
66d3123599STom Lendacky
67d3123599STom Lendacky struct ccp_cmd *cmd;
68d3123599STom Lendacky
69d3123599STom Lendacky /* Save the crypto_tfm and crypto_async_request addresses
70d3123599STom Lendacky * separately to avoid any reference to a possibly invalid
71d3123599STom Lendacky * crypto_async_request structure after invoking the request
72d3123599STom Lendacky * callback
73d3123599STom Lendacky */
74d3123599STom Lendacky struct crypto_async_request *req;
75d3123599STom Lendacky struct crypto_tfm *tfm;
76d3123599STom Lendacky
77d3123599STom Lendacky /* Used for held command processing to determine state */
78d3123599STom Lendacky int ret;
79d3123599STom Lendacky };
80d3123599STom Lendacky
ccp_crypto_success(int err)81d3123599STom Lendacky static inline bool ccp_crypto_success(int err)
82d3123599STom Lendacky {
83d3123599STom Lendacky if (err && (err != -EINPROGRESS) && (err != -EBUSY))
84d3123599STom Lendacky return false;
85d3123599STom Lendacky
86d3123599STom Lendacky return true;
87d3123599STom Lendacky }
88d3123599STom Lendacky
ccp_crypto_cmd_complete(struct ccp_crypto_cmd * crypto_cmd,struct ccp_crypto_cmd ** backlog)89d3123599STom Lendacky static struct ccp_crypto_cmd *ccp_crypto_cmd_complete(
90d3123599STom Lendacky struct ccp_crypto_cmd *crypto_cmd, struct ccp_crypto_cmd **backlog)
91d3123599STom Lendacky {
92d3123599STom Lendacky struct ccp_crypto_cmd *held = NULL, *tmp;
93bc385447STom Lendacky unsigned long flags;
94d3123599STom Lendacky
95d3123599STom Lendacky *backlog = NULL;
96d3123599STom Lendacky
97bc385447STom Lendacky spin_lock_irqsave(&req_queue_lock, flags);
98d3123599STom Lendacky
99d3123599STom Lendacky /* Held cmds will be after the current cmd in the queue so start
100d3123599STom Lendacky * searching for a cmd with a matching tfm for submission.
101d3123599STom Lendacky */
102d3123599STom Lendacky tmp = crypto_cmd;
103bc385447STom Lendacky list_for_each_entry_continue(tmp, &req_queue.cmds, entry) {
104d3123599STom Lendacky if (crypto_cmd->tfm != tmp->tfm)
105d3123599STom Lendacky continue;
106d3123599STom Lendacky held = tmp;
107d3123599STom Lendacky break;
108d3123599STom Lendacky }
109d3123599STom Lendacky
110d3123599STom Lendacky /* Process the backlog:
111d3123599STom Lendacky * Because cmds can be executed from any point in the cmd list
112d3123599STom Lendacky * special precautions have to be taken when handling the backlog.
113d3123599STom Lendacky */
114bc385447STom Lendacky if (req_queue.backlog != &req_queue.cmds) {
115d3123599STom Lendacky /* Skip over this cmd if it is the next backlog cmd */
116bc385447STom Lendacky if (req_queue.backlog == &crypto_cmd->entry)
117bc385447STom Lendacky req_queue.backlog = crypto_cmd->entry.next;
118d3123599STom Lendacky
119bc385447STom Lendacky *backlog = container_of(req_queue.backlog,
120d3123599STom Lendacky struct ccp_crypto_cmd, entry);
121bc385447STom Lendacky req_queue.backlog = req_queue.backlog->next;
122d3123599STom Lendacky
123d3123599STom Lendacky /* Skip over this cmd if it is now the next backlog cmd */
124bc385447STom Lendacky if (req_queue.backlog == &crypto_cmd->entry)
125bc385447STom Lendacky req_queue.backlog = crypto_cmd->entry.next;
126d3123599STom Lendacky }
127d3123599STom Lendacky
128d3123599STom Lendacky /* Remove the cmd entry from the list of cmds */
129bc385447STom Lendacky req_queue.cmd_count--;
130d3123599STom Lendacky list_del(&crypto_cmd->entry);
131d3123599STom Lendacky
132bc385447STom Lendacky spin_unlock_irqrestore(&req_queue_lock, flags);
133bc385447STom Lendacky
134d3123599STom Lendacky return held;
135d3123599STom Lendacky }
136d3123599STom Lendacky
ccp_crypto_complete(void * data,int err)137bc385447STom Lendacky static void ccp_crypto_complete(void *data, int err)
138d3123599STom Lendacky {
139bc385447STom Lendacky struct ccp_crypto_cmd *crypto_cmd = data;
140d3123599STom Lendacky struct ccp_crypto_cmd *held, *next, *backlog;
141d3123599STom Lendacky struct crypto_async_request *req = crypto_cmd->req;
14299c6b20eSHerbert Xu struct ccp_ctx *ctx = crypto_tfm_ctx_dma(req->tfm);
143bc385447STom Lendacky int ret;
144d3123599STom Lendacky
145bc385447STom Lendacky if (err == -EINPROGRESS) {
1468db88467STom Lendacky /* Only propagate the -EINPROGRESS if necessary */
147d3123599STom Lendacky if (crypto_cmd->ret == -EBUSY) {
148d3123599STom Lendacky crypto_cmd->ret = -EINPROGRESS;
149*0c18d054SHerbert Xu crypto_request_complete(req, -EINPROGRESS);
150d3123599STom Lendacky }
151d3123599STom Lendacky
152bc385447STom Lendacky return;
153d3123599STom Lendacky }
154d3123599STom Lendacky
155d3123599STom Lendacky /* Operation has completed - update the queue before invoking
156d3123599STom Lendacky * the completion callbacks and retrieve the next cmd (cmd with
157d3123599STom Lendacky * a matching tfm) that can be submitted to the CCP.
158d3123599STom Lendacky */
159d3123599STom Lendacky held = ccp_crypto_cmd_complete(crypto_cmd, &backlog);
160d3123599STom Lendacky if (backlog) {
161d3123599STom Lendacky backlog->ret = -EINPROGRESS;
162*0c18d054SHerbert Xu crypto_request_complete(backlog->req, -EINPROGRESS);
163d3123599STom Lendacky }
164d3123599STom Lendacky
165d3123599STom Lendacky /* Transition the state from -EBUSY to -EINPROGRESS first */
166d3123599STom Lendacky if (crypto_cmd->ret == -EBUSY)
167*0c18d054SHerbert Xu crypto_request_complete(req, -EINPROGRESS);
168d3123599STom Lendacky
169d3123599STom Lendacky /* Completion callbacks */
170bc385447STom Lendacky ret = err;
171d3123599STom Lendacky if (ctx->complete)
172d3123599STom Lendacky ret = ctx->complete(req, ret);
173*0c18d054SHerbert Xu crypto_request_complete(req, ret);
174d3123599STom Lendacky
175d3123599STom Lendacky /* Submit the next cmd */
176d3123599STom Lendacky while (held) {
1770611451bSTom Lendacky /* Since we have already queued the cmd, we must indicate that
1780611451bSTom Lendacky * we can backlog so as not to "lose" this request.
1790611451bSTom Lendacky */
1800611451bSTom Lendacky held->cmd->flags |= CCP_CMD_MAY_BACKLOG;
181d3123599STom Lendacky ret = ccp_enqueue_cmd(held->cmd);
182d3123599STom Lendacky if (ccp_crypto_success(ret))
183d3123599STom Lendacky break;
184d3123599STom Lendacky
185d3123599STom Lendacky /* Error occurred, report it and get the next entry */
18699c6b20eSHerbert Xu ctx = crypto_tfm_ctx_dma(held->req->tfm);
187950b10baSTom Lendacky if (ctx->complete)
188950b10baSTom Lendacky ret = ctx->complete(held->req, ret);
189*0c18d054SHerbert Xu crypto_request_complete(held->req, ret);
190d3123599STom Lendacky
191d3123599STom Lendacky next = ccp_crypto_cmd_complete(held, &backlog);
192d3123599STom Lendacky if (backlog) {
193d3123599STom Lendacky backlog->ret = -EINPROGRESS;
194*0c18d054SHerbert Xu crypto_request_complete(backlog->req, -EINPROGRESS);
195d3123599STom Lendacky }
196d3123599STom Lendacky
197d3123599STom Lendacky kfree(held);
198d3123599STom Lendacky held = next;
199d3123599STom Lendacky }
200d3123599STom Lendacky
201d3123599STom Lendacky kfree(crypto_cmd);
202d3123599STom Lendacky }
203d3123599STom Lendacky
ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd * crypto_cmd)204d3123599STom Lendacky static int ccp_crypto_enqueue_cmd(struct ccp_crypto_cmd *crypto_cmd)
205d3123599STom Lendacky {
206d3123599STom Lendacky struct ccp_crypto_cmd *active = NULL, *tmp;
207bc385447STom Lendacky unsigned long flags;
208c65a52f8STom Lendacky bool free_cmd = true;
209bc385447STom Lendacky int ret;
210d3123599STom Lendacky
211bc385447STom Lendacky spin_lock_irqsave(&req_queue_lock, flags);
212d3123599STom Lendacky
213d3123599STom Lendacky /* Check if the cmd can/should be queued */
214bc385447STom Lendacky if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
215cfba73d2SGilad Ben-Yossef if (!(crypto_cmd->cmd->flags & CCP_CMD_MAY_BACKLOG)) {
216cfba73d2SGilad Ben-Yossef ret = -ENOSPC;
217bc385447STom Lendacky goto e_lock;
218d3123599STom Lendacky }
219cfba73d2SGilad Ben-Yossef }
220d3123599STom Lendacky
221d3123599STom Lendacky /* Look for an entry with the same tfm. If there is a cmd
222bc385447STom Lendacky * with the same tfm in the list then the current cmd cannot
223bc385447STom Lendacky * be submitted to the CCP yet.
224d3123599STom Lendacky */
225bc385447STom Lendacky list_for_each_entry(tmp, &req_queue.cmds, entry) {
226d3123599STom Lendacky if (crypto_cmd->tfm != tmp->tfm)
227d3123599STom Lendacky continue;
228d3123599STom Lendacky active = tmp;
229d3123599STom Lendacky break;
230d3123599STom Lendacky }
231d3123599STom Lendacky
232d3123599STom Lendacky ret = -EINPROGRESS;
233d3123599STom Lendacky if (!active) {
234d3123599STom Lendacky ret = ccp_enqueue_cmd(crypto_cmd->cmd);
235d3123599STom Lendacky if (!ccp_crypto_success(ret))
236c65a52f8STom Lendacky goto e_lock; /* Error, don't queue it */
237d3123599STom Lendacky }
238d3123599STom Lendacky
239bc385447STom Lendacky if (req_queue.cmd_count >= CCP_CRYPTO_MAX_QLEN) {
240d3123599STom Lendacky ret = -EBUSY;
241bc385447STom Lendacky if (req_queue.backlog == &req_queue.cmds)
242bc385447STom Lendacky req_queue.backlog = &crypto_cmd->entry;
243d3123599STom Lendacky }
244d3123599STom Lendacky crypto_cmd->ret = ret;
245d3123599STom Lendacky
246bc385447STom Lendacky req_queue.cmd_count++;
247bc385447STom Lendacky list_add_tail(&crypto_cmd->entry, &req_queue.cmds);
248d3123599STom Lendacky
249c65a52f8STom Lendacky free_cmd = false;
250c65a52f8STom Lendacky
251bc385447STom Lendacky e_lock:
252bc385447STom Lendacky spin_unlock_irqrestore(&req_queue_lock, flags);
253d3123599STom Lendacky
254c65a52f8STom Lendacky if (free_cmd)
255c65a52f8STom Lendacky kfree(crypto_cmd);
256c65a52f8STom Lendacky
257d3123599STom Lendacky return ret;
258d3123599STom Lendacky }
259d3123599STom Lendacky
260d3123599STom Lendacky /**
261d3123599STom Lendacky * ccp_crypto_enqueue_request - queue an crypto async request for processing
262d3123599STom Lendacky * by the CCP
263d3123599STom Lendacky *
264d3123599STom Lendacky * @req: crypto_async_request struct to be processed
265d3123599STom Lendacky * @cmd: ccp_cmd struct to be sent to the CCP
266d3123599STom Lendacky */
ccp_crypto_enqueue_request(struct crypto_async_request * req,struct ccp_cmd * cmd)267d3123599STom Lendacky int ccp_crypto_enqueue_request(struct crypto_async_request *req,
268d3123599STom Lendacky struct ccp_cmd *cmd)
269d3123599STom Lendacky {
270d3123599STom Lendacky struct ccp_crypto_cmd *crypto_cmd;
271d3123599STom Lendacky gfp_t gfp;
272d3123599STom Lendacky
273d3123599STom Lendacky gfp = req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC;
274d3123599STom Lendacky
275d3123599STom Lendacky crypto_cmd = kzalloc(sizeof(*crypto_cmd), gfp);
276d3123599STom Lendacky if (!crypto_cmd)
277d3123599STom Lendacky return -ENOMEM;
278d3123599STom Lendacky
279d3123599STom Lendacky /* The tfm pointer must be saved and not referenced from the
280d3123599STom Lendacky * crypto_async_request (req) pointer because it is used after
281d3123599STom Lendacky * completion callback for the request and the req pointer
282d3123599STom Lendacky * might not be valid anymore.
283d3123599STom Lendacky */
284d3123599STom Lendacky crypto_cmd->cmd = cmd;
285d3123599STom Lendacky crypto_cmd->req = req;
286d3123599STom Lendacky crypto_cmd->tfm = req->tfm;
287d3123599STom Lendacky
288d3123599STom Lendacky cmd->callback = ccp_crypto_complete;
289d3123599STom Lendacky cmd->data = crypto_cmd;
290d3123599STom Lendacky
291d3123599STom Lendacky if (req->flags & CRYPTO_TFM_REQ_MAY_BACKLOG)
292d3123599STom Lendacky cmd->flags |= CCP_CMD_MAY_BACKLOG;
293d3123599STom Lendacky else
294d3123599STom Lendacky cmd->flags &= ~CCP_CMD_MAY_BACKLOG;
295d3123599STom Lendacky
296c65a52f8STom Lendacky return ccp_crypto_enqueue_cmd(crypto_cmd);
297d3123599STom Lendacky }
298d3123599STom Lendacky
ccp_crypto_sg_table_add(struct sg_table * table,struct scatterlist * sg_add)299d3123599STom Lendacky struct scatterlist *ccp_crypto_sg_table_add(struct sg_table *table,
300d3123599STom Lendacky struct scatterlist *sg_add)
301d3123599STom Lendacky {
302d3123599STom Lendacky struct scatterlist *sg, *sg_last = NULL;
303d3123599STom Lendacky
304d3123599STom Lendacky for (sg = table->sgl; sg; sg = sg_next(sg))
305d3123599STom Lendacky if (!sg_page(sg))
306d3123599STom Lendacky break;
307355eba5dSTom Lendacky if (WARN_ON(!sg))
308355eba5dSTom Lendacky return NULL;
309d3123599STom Lendacky
310d3123599STom Lendacky for (; sg && sg_add; sg = sg_next(sg), sg_add = sg_next(sg_add)) {
311d3123599STom Lendacky sg_set_page(sg, sg_page(sg_add), sg_add->length,
312d3123599STom Lendacky sg_add->offset);
313d3123599STom Lendacky sg_last = sg;
314d3123599STom Lendacky }
315355eba5dSTom Lendacky if (WARN_ON(sg_add))
316355eba5dSTom Lendacky return NULL;
317d3123599STom Lendacky
318d3123599STom Lendacky return sg_last;
319d3123599STom Lendacky }
320d3123599STom Lendacky
ccp_register_algs(void)321d3123599STom Lendacky static int ccp_register_algs(void)
322d3123599STom Lendacky {
323d3123599STom Lendacky int ret;
324d3123599STom Lendacky
325d81ed653STom Lendacky if (!aes_disable) {
326be9fe620SArd Biesheuvel ret = ccp_register_aes_algs(&skcipher_algs);
327d3123599STom Lendacky if (ret)
328d3123599STom Lendacky return ret;
329d3123599STom Lendacky
330d3123599STom Lendacky ret = ccp_register_aes_cmac_algs(&hash_algs);
331d3123599STom Lendacky if (ret)
332d3123599STom Lendacky return ret;
333d3123599STom Lendacky
334be9fe620SArd Biesheuvel ret = ccp_register_aes_xts_algs(&skcipher_algs);
335d3123599STom Lendacky if (ret)
336d3123599STom Lendacky return ret;
33736cf515bSGary R Hook
33836cf515bSGary R Hook ret = ccp_register_aes_aeads(&aead_algs);
33936cf515bSGary R Hook if (ret)
34036cf515bSGary R Hook return ret;
341d81ed653STom Lendacky }
342d3123599STom Lendacky
343990672d4SGary R Hook if (!des3_disable) {
344be9fe620SArd Biesheuvel ret = ccp_register_des3_algs(&skcipher_algs);
345990672d4SGary R Hook if (ret)
346990672d4SGary R Hook return ret;
347990672d4SGary R Hook }
348990672d4SGary R Hook
349d81ed653STom Lendacky if (!sha_disable) {
350d3123599STom Lendacky ret = ccp_register_sha_algs(&hash_algs);
351d3123599STom Lendacky if (ret)
352d3123599STom Lendacky return ret;
353d81ed653STom Lendacky }
354d3123599STom Lendacky
355ceeec0afSGary R Hook if (!rsa_disable) {
356ceeec0afSGary R Hook ret = ccp_register_rsa_algs(&akcipher_algs);
357ceeec0afSGary R Hook if (ret)
358ceeec0afSGary R Hook return ret;
359ceeec0afSGary R Hook }
360ceeec0afSGary R Hook
361d3123599STom Lendacky return 0;
362d3123599STom Lendacky }
363d3123599STom Lendacky
ccp_unregister_algs(void)364d3123599STom Lendacky static void ccp_unregister_algs(void)
365d3123599STom Lendacky {
366d3123599STom Lendacky struct ccp_crypto_ahash_alg *ahash_alg, *ahash_tmp;
367be9fe620SArd Biesheuvel struct ccp_crypto_skcipher_alg *ablk_alg, *ablk_tmp;
36836cf515bSGary R Hook struct ccp_crypto_aead *aead_alg, *aead_tmp;
369ceeec0afSGary R Hook struct ccp_crypto_akcipher_alg *akc_alg, *akc_tmp;
370d3123599STom Lendacky
371d3123599STom Lendacky list_for_each_entry_safe(ahash_alg, ahash_tmp, &hash_algs, entry) {
372d3123599STom Lendacky crypto_unregister_ahash(&ahash_alg->alg);
373d3123599STom Lendacky list_del(&ahash_alg->entry);
374d3123599STom Lendacky kfree(ahash_alg);
375d3123599STom Lendacky }
376d3123599STom Lendacky
377be9fe620SArd Biesheuvel list_for_each_entry_safe(ablk_alg, ablk_tmp, &skcipher_algs, entry) {
378be9fe620SArd Biesheuvel crypto_unregister_skcipher(&ablk_alg->alg);
379d3123599STom Lendacky list_del(&ablk_alg->entry);
380d3123599STom Lendacky kfree(ablk_alg);
381d3123599STom Lendacky }
38236cf515bSGary R Hook
38336cf515bSGary R Hook list_for_each_entry_safe(aead_alg, aead_tmp, &aead_algs, entry) {
38436cf515bSGary R Hook crypto_unregister_aead(&aead_alg->alg);
38536cf515bSGary R Hook list_del(&aead_alg->entry);
38636cf515bSGary R Hook kfree(aead_alg);
38736cf515bSGary R Hook }
388ceeec0afSGary R Hook
389ceeec0afSGary R Hook list_for_each_entry_safe(akc_alg, akc_tmp, &akcipher_algs, entry) {
390ceeec0afSGary R Hook crypto_unregister_akcipher(&akc_alg->alg);
391ceeec0afSGary R Hook list_del(&akc_alg->entry);
392ceeec0afSGary R Hook kfree(akc_alg);
393ceeec0afSGary R Hook }
394d3123599STom Lendacky }
395d3123599STom Lendacky
ccp_crypto_init(void)396237f9eceSruanjinjie static int __init ccp_crypto_init(void)
397d3123599STom Lendacky {
398d3123599STom Lendacky int ret;
399d3123599STom Lendacky
400c9f21cb6STom Lendacky ret = ccp_present();
401f6ebfd78SGary R Hook if (ret) {
402f6ebfd78SGary R Hook pr_err("Cannot load: there are no available CCPs\n");
403c9f21cb6STom Lendacky return ret;
404f6ebfd78SGary R Hook }
405c9f21cb6STom Lendacky
406bc385447STom Lendacky INIT_LIST_HEAD(&req_queue.cmds);
407bc385447STom Lendacky req_queue.backlog = &req_queue.cmds;
408bc385447STom Lendacky req_queue.cmd_count = 0;
409d3123599STom Lendacky
410d3123599STom Lendacky ret = ccp_register_algs();
411bc385447STom Lendacky if (ret)
412d3123599STom Lendacky ccp_unregister_algs();
413d3123599STom Lendacky
414d3123599STom Lendacky return ret;
415d3123599STom Lendacky }
416d3123599STom Lendacky
ccp_crypto_exit(void)417237f9eceSruanjinjie static void __exit ccp_crypto_exit(void)
418d3123599STom Lendacky {
419d3123599STom Lendacky ccp_unregister_algs();
420d3123599STom Lendacky }
421d3123599STom Lendacky
422d3123599STom Lendacky module_init(ccp_crypto_init);
423d3123599STom Lendacky module_exit(ccp_crypto_exit);
424