Skip to content

Commit 10b89c4

Browse files
toromanoSTMherbertx
authored andcommitted
crypto: stm32/crc32 - fix multi-instance
Ensure CRC algorithm is registered only once in crypto framework when there are several instances of CRC devices. Update the CRC device list management to avoid that only the first CRC instance is used. Fixes: b51dbe9 ("crypto: stm32 - Support for STM32 CRC32 crypto module") Signed-off-by: Nicolas Toromanoff <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent a8cc312 commit 10b89c4

File tree

1 file changed

+36
-12
lines changed

1 file changed

+36
-12
lines changed

drivers/crypto/stm32/stm32-crc32.c

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -91,16 +91,29 @@ static int stm32_crc_setkey(struct crypto_shash *tfm, const u8 *key,
9191
return 0;
9292
}
9393

94-
static int stm32_crc_init(struct shash_desc *desc)
94+
static struct stm32_crc *stm32_crc_get_next_crc(void)
9595
{
96-
struct stm32_crc_desc_ctx *ctx = shash_desc_ctx(desc);
97-
struct stm32_crc_ctx *mctx = crypto_shash_ctx(desc->tfm);
9896
struct stm32_crc *crc;
9997

10098
spin_lock_bh(&crc_list.lock);
10199
crc = list_first_entry(&crc_list.dev_list, struct stm32_crc, list);
100+
if (crc)
101+
list_move_tail(&crc->list, &crc_list.dev_list);
102102
spin_unlock_bh(&crc_list.lock);
103103

104+
return crc;
105+
}
106+
107+
static int stm32_crc_init(struct shash_desc *desc)
108+
{
109+
struct stm32_crc_desc_ctx *ctx = shash_desc_ctx(desc);
110+
struct stm32_crc_ctx *mctx = crypto_shash_ctx(desc->tfm);
111+
struct stm32_crc *crc;
112+
113+
crc = stm32_crc_get_next_crc();
114+
if (!crc)
115+
return -ENODEV;
116+
104117
pm_runtime_get_sync(crc->dev);
105118

106119
/* Reset, set key, poly and configure in bit reverse mode */
@@ -125,9 +138,9 @@ static int stm32_crc_update(struct shash_desc *desc, const u8 *d8,
125138
struct stm32_crc_ctx *mctx = crypto_shash_ctx(desc->tfm);
126139
struct stm32_crc *crc;
127140

128-
spin_lock_bh(&crc_list.lock);
129-
crc = list_first_entry(&crc_list.dev_list, struct stm32_crc, list);
130-
spin_unlock_bh(&crc_list.lock);
141+
crc = stm32_crc_get_next_crc();
142+
if (!crc)
143+
return -ENODEV;
131144

132145
pm_runtime_get_sync(crc->dev);
133146

@@ -200,6 +213,8 @@ static int stm32_crc_digest(struct shash_desc *desc, const u8 *data,
200213
return stm32_crc_init(desc) ?: stm32_crc_finup(desc, data, length, out);
201214
}
202215

216+
static unsigned int refcnt;
217+
static DEFINE_MUTEX(refcnt_lock);
203218
static struct shash_alg algs[] = {
204219
/* CRC-32 */
205220
{
@@ -290,12 +305,18 @@ static int stm32_crc_probe(struct platform_device *pdev)
290305
list_add(&crc->list, &crc_list.dev_list);
291306
spin_unlock(&crc_list.lock);
292307

293-
ret = crypto_register_shashes(algs, ARRAY_SIZE(algs));
294-
if (ret) {
295-
dev_err(dev, "Failed to register\n");
296-
clk_disable_unprepare(crc->clk);
297-
return ret;
308+
mutex_lock(&refcnt_lock);
309+
if (!refcnt) {
310+
ret = crypto_register_shashes(algs, ARRAY_SIZE(algs));
311+
if (ret) {
312+
mutex_unlock(&refcnt_lock);
313+
dev_err(dev, "Failed to register\n");
314+
clk_disable_unprepare(crc->clk);
315+
return ret;
316+
}
298317
}
318+
refcnt++;
319+
mutex_unlock(&refcnt_lock);
299320

300321
dev_info(dev, "Initialized\n");
301322

@@ -316,7 +337,10 @@ static int stm32_crc_remove(struct platform_device *pdev)
316337
list_del(&crc->list);
317338
spin_unlock(&crc_list.lock);
318339

319-
crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
340+
mutex_lock(&refcnt_lock);
341+
if (!--refcnt)
342+
crypto_unregister_shashes(algs, ARRAY_SIZE(algs));
343+
mutex_unlock(&refcnt_lock);
320344

321345
pm_runtime_disable(crc->dev);
322346
pm_runtime_put_noidle(crc->dev);

0 commit comments

Comments
 (0)