Commit 277b5fb3 authored by Linus Torvalds's avatar Linus Torvalds

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
parents a54769c5 511d63cb
...@@ -174,7 +174,7 @@ sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len) ...@@ -174,7 +174,7 @@ sha512_update(struct shash_desc *desc, const u8 *data, unsigned int len)
index = sctx->count[0] & 0x7f; index = sctx->count[0] & 0x7f;
/* Update number of bytes */ /* Update number of bytes */
if (!(sctx->count[0] += len)) if ((sctx->count[0] += len) < len)
sctx->count[1]++; sctx->count[1]++;
part_len = 128 - index; part_len = 128 - index;
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/module.h>
#include <crypto/ctr.h> #include <crypto/ctr.h>
#include <crypto/des.h> #include <crypto/des.h>
......
...@@ -124,6 +124,9 @@ struct talitos_private { ...@@ -124,6 +124,9 @@ struct talitos_private {
void __iomem *reg; void __iomem *reg;
int irq[2]; int irq[2];
/* SEC global registers lock */
spinlock_t reg_lock ____cacheline_aligned;
/* SEC version geometry (from device tree node) */ /* SEC version geometry (from device tree node) */
unsigned int num_channels; unsigned int num_channels;
unsigned int chfifo_len; unsigned int chfifo_len;
...@@ -412,6 +415,7 @@ static void talitos_done_##name(unsigned long data) \ ...@@ -412,6 +415,7 @@ static void talitos_done_##name(unsigned long data) \
{ \ { \
struct device *dev = (struct device *)data; \ struct device *dev = (struct device *)data; \
struct talitos_private *priv = dev_get_drvdata(dev); \ struct talitos_private *priv = dev_get_drvdata(dev); \
unsigned long flags; \
\ \
if (ch_done_mask & 1) \ if (ch_done_mask & 1) \
flush_channel(dev, 0, 0, 0); \ flush_channel(dev, 0, 0, 0); \
...@@ -427,8 +431,10 @@ static void talitos_done_##name(unsigned long data) \ ...@@ -427,8 +431,10 @@ static void talitos_done_##name(unsigned long data) \
out: \ out: \
/* At this point, all completed channels have been processed */ \ /* At this point, all completed channels have been processed */ \
/* Unmask done interrupts for channels completed later on. */ \ /* Unmask done interrupts for channels completed later on. */ \
spin_lock_irqsave(&priv->reg_lock, flags); \
setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ setbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \ setbits32(priv->reg + TALITOS_IMR_LO, TALITOS_IMR_LO_INIT); \
spin_unlock_irqrestore(&priv->reg_lock, flags); \
} }
DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE) DEF_TALITOS_DONE(4ch, TALITOS_ISR_4CHDONE)
DEF_TALITOS_DONE(ch0_2, TALITOS_ISR_CH_0_2_DONE) 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,22 +625,28 @@ static irqreturn_t talitos_interrupt_##name(int irq, void *data) \
struct device *dev = data; \ struct device *dev = data; \
struct talitos_private *priv = dev_get_drvdata(dev); \ struct talitos_private *priv = dev_get_drvdata(dev); \
u32 isr, isr_lo; \ u32 isr, isr_lo; \
unsigned long flags; \
\ \
spin_lock_irqsave(&priv->reg_lock, flags); \
isr = in_be32(priv->reg + TALITOS_ISR); \ isr = in_be32(priv->reg + TALITOS_ISR); \
isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \ isr_lo = in_be32(priv->reg + TALITOS_ISR_LO); \
/* Acknowledge interrupt */ \ /* Acknowledge interrupt */ \
out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \ out_be32(priv->reg + TALITOS_ICR, isr & (ch_done_mask | ch_err_mask)); \
out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \ out_be32(priv->reg + TALITOS_ICR_LO, isr_lo); \
\ \
if (unlikely((isr & ~TALITOS_ISR_4CHDONE) & ch_err_mask || isr_lo)) \ if (unlikely(isr & ch_err_mask || isr_lo)) { \
talitos_error(dev, isr, isr_lo); \ spin_unlock_irqrestore(&priv->reg_lock, flags); \
else \ talitos_error(dev, isr & ch_err_mask, isr_lo); \
} \
else { \
if (likely(isr & ch_done_mask)) { \ if (likely(isr & ch_done_mask)) { \
/* mask further done interrupts. */ \ /* mask further done interrupts. */ \
clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \ clrbits32(priv->reg + TALITOS_IMR, ch_done_mask); \
/* done_task will unmask done interrupts at exit */ \ /* done_task will unmask done interrupts at exit */ \
tasklet_schedule(&priv->done_task[tlet]); \ tasklet_schedule(&priv->done_task[tlet]); \
} \ } \
spin_unlock_irqrestore(&priv->reg_lock, flags); \
} \
\ \
return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \ return (isr & (ch_done_mask | ch_err_mask) || isr_lo) ? IRQ_HANDLED : \
IRQ_NONE; \ IRQ_NONE; \
...@@ -2719,6 +2731,8 @@ static int talitos_probe(struct platform_device *ofdev) ...@@ -2719,6 +2731,8 @@ static int talitos_probe(struct platform_device *ofdev)
priv->ofdev = ofdev; priv->ofdev = ofdev;
spin_lock_init(&priv->reg_lock);
err = talitos_probe_irq(ofdev); err = talitos_probe_irq(ofdev);
if (err) if (err)
goto err_out; goto err_out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment