diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-20 14:14:58 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-20 14:14:58 -0400 |
commit | 277b5fb35b770792f89fbe50df03daddb3fa9521 (patch) | |
tree | 1b5558cff414274bbc07d1df6ca7cd743df20c4c | |
parent | a54769c505db4bdf01d19dca64d15cb303503d71 (diff) | |
parent | 511d63cb19329235bc9298b64010ec494b5e1408 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
Pull crypto fixes from Herbert Xu:
- Locking fix for talitos driver
- Fix 64-bit counter overflow in SHA-512
- Build fix for ixp4xx.
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6:
crypto: talitos - properly lock access to global talitos registers
crypto: ixp4xx - include fix
crypto: sha512 - Fix byte counter overflow in SHA-512
-rw-r--r-- | crypto/sha512_generic.c | 2 | ||||
-rw-r--r-- | drivers/crypto/ixp4xx_crypto.c | 1 | ||||
-rw-r--r-- | drivers/crypto/talitos.c | 20 |
3 files changed, 19 insertions, 4 deletions
diff --git a/crypto/sha512_generic.c b/crypto/sha512_generic.c index 107f6f7be5e1..dd30f40af9f5 100644 --- a/crypto/sha512_generic.c +++ b/crypto/sha512_generic.c | |||
@@ -174,7 +174,7 @@ sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len) | |||
174 | index = sctx->count[0] & 0x7f; | 174 | index = sctx->count[0] & 0x7f; |
175 | 175 | ||
176 | /* Update number of bytes */ | 176 | /* Update number of bytes */ |
177 | if (!(sctx->count[0] += len)) | 177 | if ((sctx->count[0] += len) < len) |
178 | sctx->count[1]++; | 178 | sctx->count[1]++; |
179 | 179 | ||
180 | part_len = 128 - index; | 180 | part_len = 128 - index; |
diff --git a/drivers/crypto/ixp4xx_crypto.c b/drivers/crypto/ixp4xx_crypto.c index 0053d7ebb5ca..8f3f74ce8c7f 100644 --- a/drivers/crypto/ixp4xx_crypto.c +++ b/drivers/crypto/ixp4xx_crypto.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
20 | #include <linux/gfp.h> | 20 | #include <linux/gfp.h> |
21 | #include <linux/module.h> | ||
21 | 22 | ||
22 | #include <crypto/ctr.h> | 23 | #include <crypto/ctr.h> |
23 | #include <crypto/des.h> | 24 | #include <crypto/des.h> |
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index dc641c796526..921039e56f87 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c | |||
@@ -124,6 +124,9 @@ struct talitos_private { | |||
124 | void __iomem *reg; | 124 | void __iomem *reg; |
125 | int irq[2]; | 125 | int irq[2]; |
126 | 126 | ||
127 | /* SEC global registers lock */ | ||
128 | spinlock_t reg_lock ____cacheline_aligned; | ||
129 | |||
127 | /* SEC version geometry (from device tree node) */ | 130 | /* SEC version geometry (from device tree node) */ |
128 | unsigned int num_channels; | 131 | unsigned int num_channels; |
129 | unsigned int chfifo_len; | 132 | unsigned int chfifo_len; |
@@ -412,6 +415,7 @@ static void talitos_done_##name(unsigned long data) \ | |||
412 | { \ | 415 | { \ |
413 | struct device *dev = (struct device *)data; \ | 416 | struct device *dev = (struct device *)data; \ |
414 | struct talitos_private *priv = dev_get_drvdata(dev); \ | 417 | struct talitos_private *priv = dev_get_drvdata(dev); \ |
418 | unsigned long flags; \ | ||
415 | \ | 419 | \ |
416 | if (ch_done_mask & 1) \ | 420 | if (ch_done_mask & 1) \ |
417 | flush_channel(dev, 0, 0, 0); \ | 421 | flush_channel(dev, 0, 0, 0); \ |
@@ -427,8 +431,10 @@ static void talitos_done_##name(unsigned long data) \ | |||
427 | out: \ | 431 | out: \ |
428 | /* At this point, all completed channels have been processed */ \ | 432 | /* At this point, all completed channels have been processed */ \ |
429 | /* Unmask done interrupts for channels completed later on. */ \ | 433 | /* Unmask done interrupts for channels completed later on. */ \ |
434 | spin_lock_irqsave(&priv->reg_lock, flags); \ | ||
430 | setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ | 435 | setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ |
431 | setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \ | 436 | setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \ |
437 | spin_unlock_irqrestore(&priv->reg_lock, flags); \ | ||
432 | } | 438 | } |
433 | DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE) | 439 | DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE) |
434 | DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE) | 440 | DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE) |
@@ -619,22 +625,28 @@ static irqreturn_t talitos_interrupt_##name(int irq, void *data) \ | |||
619 | struct device *dev = data; \ | 625 | struct device *dev = data; \ |
620 | struct talitos_private *priv = dev_get_drvdata(dev); \ | 626 | struct talitos_private *priv = dev_get_drvdata(dev); \ |
621 | u32 isr, isr_lo; \ | 627 | u32 isr, isr_lo; \ |
628 | unsigned long flags; \ | ||
622 | \ | 629 | \ |
630 | spin_lock_irqsave(&priv->reg_lock, flags); \ | ||
623 | isr = in_be32(priv->reg + TALITOS_ISR); \ | 631 | isr = in_be32(priv->reg + TALITOS_ISR); \ |
624 | isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \ | 632 | isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \ |
625 | /* Acknowledge interrupt */ \ | 633 | /* Acknowledge interrupt */ \ |
626 | out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \ | 634 | out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \ |
627 | out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \ | 635 | out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \ |
628 | \ | 636 | \ |
629 | if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo)) \ | 637 | if (unlikely(isr & ch_err_mask || isr_lo)) { \ |
630 | talitos_error(dev, isr, isr_lo); \ | 638 | spin_unlock_irqrestore(&priv->reg_lock, flags); \ |
631 | else \ | 639 | talitos_error(dev, isr & ch_err_mask, isr_lo); \ |
640 | } \ | ||
641 | else { \ | ||
632 | if (likely(isr & ch_done_mask)) { \ | 642 | if (likely(isr & ch_done_mask)) { \ |
633 | /* mask further done interrupts. */ \ | 643 | /* mask further done interrupts. */ \ |
634 | clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ | 644 | clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ |
635 | /* done_task will unmask done interrupts at exit */ \ | 645 | /* done_task will unmask done interrupts at exit */ \ |
636 | tasklet_schedule(&priv->done_task[tlet]); \ | 646 | tasklet_schedule(&priv->done_task[tlet]); \ |
637 | } \ | 647 | } \ |
648 | spin_unlock_irqrestore(&priv->reg_lock, flags); \ | ||
649 | } \ | ||
638 | \ | 650 | \ |
639 | return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \ | 651 | return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \ |
640 | IRQ_NONE; \ | 652 | IRQ_NONE; \ |
@@ -2719,6 +2731,8 @@ static int talitos_probe(struct platform_device *ofdev) | |||
2719 | 2731 | ||
2720 | priv->ofdev = ofdev; | 2732 | priv->ofdev = ofdev; |
2721 | 2733 | ||
2734 | spin_lock_init(&priv->reg_lock); | ||
2735 | |||
2722 | err = talitos_probe_irq(ofdev); | 2736 | err = talitos_probe_irq(ofdev); |
2723 | if (err) | 2737 | if (err) |
2724 | goto err_out; | 2738 | goto err_out; |