Commit a929cbeef7d8e5c3603a6f43b977c03c922aada3

Authored by Dmitry Kasatkin
Committed by Herbert Xu
1 parent ea1fd2246f

crypto: omap-sham - replace flags operation with atomic bit operations

Some flags are changed in interrupt handlers and verified in the tasklet.
There might be a race condition when tasklet is interrupted or another
cpu/core will run IRQ handler and tasklet in parallel.
Atomic bitops functions are now used instead of bitmask operations.

Signed-off-by: Dmitry Kasatkin <dmitry.kasatkin@nokia.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Showing 1 changed file with 13 additions and 16 deletions Side-by-side Diff

drivers/crypto/omap-sham.c
... ... @@ -240,7 +240,7 @@
240 240 {
241 241 clk_enable(dd->iclk);
242 242  
243   - if (!(dd->flags & BIT(FLAGS_INIT))) {
  243 + if (!test_bit(FLAGS_INIT, &dd->flags)) {
244 244 omap_sham_write_mask(dd, SHA_REG_MASK,
245 245 SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET);
246 246  
... ... @@ -248,7 +248,7 @@
248 248 SHA_REG_SYSSTATUS_RESETDONE))
249 249 return -ETIMEDOUT;
250 250  
251   - dd->flags |= BIT(FLAGS_INIT);
  251 + set_bit(FLAGS_INIT, &dd->flags);
252 252 dd->err = 0;
253 253 }
254 254  
... ... @@ -303,7 +303,7 @@
303 303 return -ETIMEDOUT;
304 304  
305 305 if (final)
306   - ctx->flags |= BIT(FLAGS_FINAL); /* catch last interrupt */
  306 + set_bit(FLAGS_FINAL, &ctx->flags); /* catch last interrupt */
307 307  
308 308 len32 = DIV_ROUND_UP(length, sizeof(u32));
309 309  
310 310  
... ... @@ -336,9 +336,9 @@
336 336 ctx->digcnt += length;
337 337  
338 338 if (final)
339   - ctx->flags |= BIT(FLAGS_FINAL); /* catch last interrupt */
  339 + set_bit(FLAGS_FINAL, &ctx->flags); /* catch last interrupt */
340 340  
341   - dd->flags |= BIT(FLAGS_DMA_ACTIVE);
  341 + set_bit(FLAGS_DMA_ACTIVE, &dd->flags);
342 342  
343 343 omap_start_dma(dd->dma_lch);
344 344  
... ... @@ -642,7 +642,7 @@
642 642  
643 643 if (!err) {
644 644 omap_sham_copy_hash(req, 1);
645   - if (ctx->flags & BIT(FLAGS_FINAL))
  645 + if (test_bit(FLAGS_FINAL, &ctx->flags))
646 646 err = omap_sham_finish(req);
647 647 } else {
648 648 ctx->flags |= BIT(FLAGS_ERROR);
649 649  
... ... @@ -666,14 +666,14 @@
666 666 spin_lock_irqsave(&dd->lock, flags);
667 667 if (req)
668 668 ret = ahash_enqueue_request(&dd->queue, req);
669   - if (dd->flags & BIT(FLAGS_BUSY)) {
  669 + if (test_bit(FLAGS_BUSY, &dd->flags)) {
670 670 spin_unlock_irqrestore(&dd->lock, flags);
671 671 return ret;
672 672 }
673 673 backlog = crypto_get_backlog(&dd->queue);
674 674 async_req = crypto_dequeue_request(&dd->queue);
675 675 if (async_req)
676   - dd->flags |= BIT(FLAGS_BUSY);
  676 + set_bit(FLAGS_BUSY, &dd->flags);
677 677 spin_unlock_irqrestore(&dd->lock, flags);
678 678  
679 679 if (!async_req)
680 680  
681 681  
... ... @@ -1037,13 +1037,10 @@
1037 1037 struct omap_sham_reqctx *ctx = ahash_request_ctx(req);
1038 1038 int ready = 0, err = 0;
1039 1039  
1040   - if (ctx->flags & BIT(FLAGS_OUTPUT_READY)) {
1041   - ctx->flags &= ~BIT(FLAGS_OUTPUT_READY);
  1040 + if (test_and_clear_bit(FLAGS_OUTPUT_READY, &ctx->flags))
1042 1041 ready = 1;
1043   - }
1044 1042  
1045   - if (dd->flags & BIT(FLAGS_DMA_ACTIVE)) {
1046   - dd->flags &= ~BIT(FLAGS_DMA_ACTIVE);
  1043 + if (test_and_clear_bit(FLAGS_DMA_ACTIVE, &dd->flags)) {
1047 1044 omap_sham_update_dma_stop(dd);
1048 1045 if (!dd->err)
1049 1046 err = omap_sham_update_dma_start(dd);
... ... @@ -1077,7 +1074,7 @@
1077 1074 return IRQ_HANDLED;
1078 1075 }
1079 1076  
1080   - if (unlikely(ctx->flags & BIT(FLAGS_FINAL)))
  1077 + if (unlikely(test_bit(FLAGS_FINAL, &ctx->flags)))
1081 1078 /* final -> allow device to go to power-saving mode */
1082 1079 omap_sham_write_mask(dd, SHA_REG_CTRL, 0, SHA_REG_CTRL_LENGTH);
1083 1080  
... ... @@ -1085,7 +1082,7 @@
1085 1082 SHA_REG_CTRL_OUTPUT_READY);
1086 1083 omap_sham_read(dd, SHA_REG_CTRL);
1087 1084  
1088   - ctx->flags |= BIT(FLAGS_OUTPUT_READY);
  1085 + set_bit(FLAGS_OUTPUT_READY, &ctx->flags);
1089 1086 dd->err = 0;
1090 1087 tasklet_schedule(&dd->done_task);
1091 1088  
... ... @@ -1099,7 +1096,7 @@
1099 1096 if (ch_status != OMAP_DMA_BLOCK_IRQ) {
1100 1097 pr_err("omap-sham DMA error status: 0x%hx\n", ch_status);
1101 1098 dd->err = -EIO;
1102   - dd->flags &= ~BIT(FLAGS_INIT); /* request to re-initialize */
  1099 + clear_bit(FLAGS_INIT, &dd->flags);/* request to re-initialize */
1103 1100 }
1104 1101  
1105 1102 tasklet_schedule(&dd->done_task);