diff options
author | Corentin LABBE <clabbe.montjoie@gmail.com> | 2016-03-23 11:11:24 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2016-04-05 08:35:53 -0400 |
commit | bdb6cf9f6fe6d9af905ea34b7c4bb78ea601329e (patch) | |
tree | ec44080f2ebbc0320c6f68f72ff18cda0cafb326 | |
parent | 738f98233b94db55607f97a76f9699efc4217276 (diff) |
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>
-rw-r--r-- | drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c index 7be3fbcd8d78..3830d7c4e138 100644 --- a/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c +++ b/drivers/crypto/sunxi-ss/sun4i-ss-cipher.c | |||
@@ -35,6 +35,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq) | |||
35 | unsigned int todo; | 35 | unsigned int todo; |
36 | struct sg_mapping_iter mi, mo; | 36 | struct sg_mapping_iter mi, mo; |
37 | unsigned int oi, oo; /* offset for in and out */ | 37 | unsigned int oi, oo; /* offset for in and out */ |
38 | unsigned long flags; | ||
38 | 39 | ||
39 | if (areq->nbytes == 0) | 40 | if (areq->nbytes == 0) |
40 | return 0; | 41 | return 0; |
@@ -49,7 +50,7 @@ static int sun4i_ss_opti_poll(struct ablkcipher_request *areq) | |||
49 | return -EINVAL; | 50 | return -EINVAL; |
50 | } | 51 | } |
51 | 52 | ||
52 | spin_lock_bh(&ss->slock); | 53 | spin_lock_irqsave(&ss->slock, flags); |
53 | 54 | ||
54 | for (i = 0; i < op->keylen; i += 4) | 55 | for (i = 0; i < op->keylen; i += 4) |
55 | writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); | 56 | writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); |
@@ -117,7 +118,7 @@ release_ss: | |||
117 | sg_miter_stop(&mi); | 118 | sg_miter_stop(&mi); |
118 | sg_miter_stop(&mo); | 119 | sg_miter_stop(&mo); |
119 | writel(0, ss->base + SS_CTL); | 120 | writel(0, ss->base + SS_CTL); |
120 | spin_unlock_bh(&ss->slock); | 121 | spin_unlock_irqrestore(&ss->slock, flags); |
121 | return err; | 122 | return err; |
122 | } | 123 | } |
123 | 124 | ||
@@ -149,6 +150,7 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq) | |||
149 | unsigned int ob = 0; /* offset in buf */ | 150 | unsigned int ob = 0; /* offset in buf */ |
150 | unsigned int obo = 0; /* offset in bufo*/ | 151 | unsigned int obo = 0; /* offset in bufo*/ |
151 | unsigned int obl = 0; /* length of data in bufo */ | 152 | unsigned int obl = 0; /* length of data in bufo */ |
153 | unsigned long flags; | ||
152 | 154 | ||
153 | if (areq->nbytes == 0) | 155 | if (areq->nbytes == 0) |
154 | return 0; | 156 | return 0; |
@@ -181,7 +183,7 @@ static int sun4i_ss_cipher_poll(struct ablkcipher_request *areq) | |||
181 | if (no_chunk == 1) | 183 | if (no_chunk == 1) |
182 | return sun4i_ss_opti_poll(areq); | 184 | return sun4i_ss_opti_poll(areq); |
183 | 185 | ||
184 | spin_lock_bh(&ss->slock); | 186 | spin_lock_irqsave(&ss->slock, flags); |
185 | 187 | ||
186 | for (i = 0; i < op->keylen; i += 4) | 188 | for (i = 0; i < op->keylen; i += 4) |
187 | writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); | 189 | writel(*(op->key + i / 4), ss->base + SS_KEY0 + i); |
@@ -307,7 +309,7 @@ release_ss: | |||
307 | sg_miter_stop(&mi); | 309 | sg_miter_stop(&mi); |
308 | sg_miter_stop(&mo); | 310 | sg_miter_stop(&mo); |
309 | writel(0, ss->base + SS_CTL); | 311 | writel(0, ss->base + SS_CTL); |
310 | spin_unlock_bh(&ss->slock); | 312 | spin_unlock_irqrestore(&ss->slock, flags); |
311 | 313 | ||
312 | return err; | 314 | return err; |
313 | } | 315 | } |