Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

crypto: sun4i-ss - Replace spinlock_bh by spin_lock_irq{save|restore}

The current sun4i-ss driver could generate data corruption when ciphering/deciphering.
It occurs randomly on end of handled data.
No root cause have been found and the only way to remove it is to replace
all spin_lock_bh by their irq counterparts.

Fixes: 6298e948215f ("crypto: sunxi-ss - Add Allwinner Security System crypto accelerator")
Signed-off-by: LABBE Corentin <clabbe.montjoie@gmail.com>
Cc: stable <stable@vger.kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

authored by

Corentin LABBE and committed by
Herbert Xu
bdb6cf9f 738f9823

+6 -4
+6 -4
drivers/crypto/sunxi-ss/sun4i-ss-cipher.c
··· 35 35 unsigned int todo; 36 36 struct sg_mapping_iter mi, mo; 37 37 unsigned int oi, oo; /* offset for in and out */ 38 + unsigned long flags; 38 39 39 40 if (areq->nbytes == 0) 40 41 return 0; ··· 50 49 return -EINVAL; 51 50 } 52 51 53 - spin_lock_bh(&ss->slock); 52 + spin_lock_irqsave(&ss->slock, flags); 54 53 55 54 for (i = 0; i < op->keylen; i += 4) 56 55 writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); ··· 118 117 sg_miter_stop(&mi); 119 118 sg_miter_stop(&mo); 120 119 writel(0, ss->base + SS_CTL); 121 - spin_unlock_bh(&ss->slock); 120 + spin_unlock_irqrestore(&ss->slock, flags); 122 121 return err; 123 122 } 124 123 ··· 150 149 unsigned int ob = 0; /* offset in buf */ 151 150 unsigned int obo = 0; /* offset in bufo*/ 152 151 unsigned int obl = 0; /* length of data in bufo */ 152 + unsigned long flags; 153 153 154 154 if (areq->nbytes == 0) 155 155 return 0; ··· 183 181 if (no_chunk == 1) 184 182 return sun4i_ss_opti_poll(areq); 185 183 186 - spin_lock_bh(&ss->slock); 184 + spin_lock_irqsave(&ss->slock, flags); 187 185 188 186 for (i = 0; i < op->keylen; i += 4) 189 187 writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); ··· 309 307 sg_miter_stop(&mi); 310 308 sg_miter_stop(&mo); 311 309 writel(0, ss->base + SS_CTL); 312 - spin_unlock_bh(&ss->slock); 310 + spin_unlock_irqrestore(&ss->slock, flags); 313 311 314 312 return err; 315 313 }