Skip to content

Commit 7795c0b

Browse files
toromanoSTMherbertx
authored andcommitted
crypto: stm32/crc32 - protect from concurrent accesses
Protect STM32 CRC device from concurrent accesses. As we create a spinlocked section that increase with buffer size, we provide a module parameter to release the pressure by splitting critical section in chunks. Size of each chunk is defined in burst_size module parameter. By default burst_size=0, i.e. don't split incoming buffer. Signed-off-by: Nicolas Toromanoff <[email protected]> Signed-off-by: Herbert Xu <[email protected]>
1 parent 100f84b commit 7795c0b

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

drivers/crypto/stm32/stm32-crc32.c

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,16 @@
3535

3636
#define CRC_AUTOSUSPEND_DELAY 50
3737

38+
static unsigned int burst_size;
39+
module_param(burst_size, uint, 0644);
40+
MODULE_PARM_DESC(burst_size, "Select burst byte size (0 unlimited)");
41+
3842
struct stm32_crc {
3943
struct list_head list;
4044
struct device *dev;
4145
void __iomem *regs;
4246
struct clk *clk;
47+
spinlock_t lock;
4348
};
4449

4550
struct stm32_crc_list {
@@ -109,13 +114,16 @@ static int stm32_crc_init(struct shash_desc *desc)
109114
struct stm32_crc_desc_ctx *ctx = shash_desc_ctx(desc);
110115
struct stm32_crc_ctx *mctx = crypto_shash_ctx(desc->tfm);
111116
struct stm32_crc *crc;
117+
unsigned long flags;
112118

113119
crc = stm32_crc_get_next_crc();
114120
if (!crc)
115121
return -ENODEV;
116122

117123
pm_runtime_get_sync(crc->dev);
118124

125+
spin_lock_irqsave(&crc->lock, flags);
126+
119127
/* Reset, set key, poly and configure in bit reverse mode */
120128
writel_relaxed(bitrev32(mctx->key), crc->regs + CRC_INIT);
121129
writel_relaxed(bitrev32(mctx->poly), crc->regs + CRC_POL);
@@ -125,25 +133,30 @@ static int stm32_crc_init(struct shash_desc *desc)
125133
/* Store partial result */
126134
ctx->partial = readl_relaxed(crc->regs + CRC_DR);
127135

136+
spin_unlock_irqrestore(&crc->lock, flags);
137+
128138
pm_runtime_mark_last_busy(crc->dev);
129139
pm_runtime_put_autosuspend(crc->dev);
130140

131141
return 0;
132142
}
133143

134-
static int stm32_crc_update(struct shash_desc *desc, const u8 *d8,
135-
unsigned int length)
144+
static int burst_update(struct shash_desc *desc, const u8 *d8,
145+
size_t length)
136146
{
137147
struct stm32_crc_desc_ctx *ctx = shash_desc_ctx(desc);
138148
struct stm32_crc_ctx *mctx = crypto_shash_ctx(desc->tfm);
139149
struct stm32_crc *crc;
150+
unsigned long flags;
140151

141152
crc = stm32_crc_get_next_crc();
142153
if (!crc)
143154
return -ENODEV;
144155

145156
pm_runtime_get_sync(crc->dev);
146157

158+
spin_lock_irqsave(&crc->lock, flags);
159+
147160
/*
148161
* Restore previously calculated CRC for this context as init value
149162
* Restore polynomial configuration
@@ -182,12 +195,40 @@ static int stm32_crc_update(struct shash_desc *desc, const u8 *d8,
182195
/* Store partial result */
183196
ctx->partial = readl_relaxed(crc->regs + CRC_DR);
184197

198+
spin_unlock_irqrestore(&crc->lock, flags);
199+
185200
pm_runtime_mark_last_busy(crc->dev);
186201
pm_runtime_put_autosuspend(crc->dev);
187202

188203
return 0;
189204
}
190205

206+
static int stm32_crc_update(struct shash_desc *desc, const u8 *d8,
207+
unsigned int length)
208+
{
209+
const unsigned int burst_sz = burst_size;
210+
unsigned int rem_sz;
211+
const u8 *cur;
212+
size_t size;
213+
int ret;
214+
215+
if (!burst_sz)
216+
return burst_update(desc, d8, length);
217+
218+
/* Digest first bytes not 32bit aligned at first pass in the loop */
219+
size = min(length,
220+
burst_sz + (unsigned int)d8 - ALIGN_DOWN((unsigned int)d8,
221+
sizeof(u32)));
222+
for (rem_sz = length, cur = d8; rem_sz;
223+
rem_sz -= size, cur += size, size = min(rem_sz, burst_sz)) {
224+
ret = burst_update(desc, cur, size);
225+
if (ret)
226+
return ret;
227+
}
228+
229+
return 0;
230+
}
231+
191232
static int stm32_crc_final(struct shash_desc *desc, u8 *out)
192233
{
193234
struct stm32_crc_desc_ctx *ctx = shash_desc_ctx(desc);
@@ -300,6 +341,8 @@ static int stm32_crc_probe(struct platform_device *pdev)
300341
pm_runtime_irq_safe(dev);
301342
pm_runtime_enable(dev);
302343

344+
spin_lock_init(&crc->lock);
345+
303346
platform_set_drvdata(pdev, crc);
304347

305348
spin_lock(&crc_list.lock);

0 commit comments

Comments
 (0)