Commit a929cbeef7d8e5c3603a6f43b977c03c922aada3
Committed by
Herbert Xu
1 parent
ea1fd2246f
Exists in
master
and in
6 other branches
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); |