Commit 3e721aeb authored by Kim Phillips's avatar Kim Phillips Committed by Herbert Xu

crypto: talitos - handle descriptor not found in error path

The CDPR (Current Descriptor Pointer Register) can be unreliable
when trying to locate an offending descriptor.  Handle that case by
(a) not OOPSing, and (b) reverting to the machine internal copy of
the descriptor header in order to report the correct execution unit
error.

Note: printing all execution units' ISRs is not effective because it
results in an internal time out (ITO) error and the EU resetting its
ISR value (at least when specifying an invalid key length on an SEC
2.2/MPC8313E).
Reported-by: default avatarSven Schnelle <svens@stackframe.org>
Signed-off-by: default avatarKim Phillips <kim.phillips@freescale.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent e6ea64ec
...@@ -416,7 +416,7 @@ static void talitos_done(unsigned long data) ...@@ -416,7 +416,7 @@ static void talitos_done(unsigned long data)
/* /*
* locate current (offending) descriptor * locate current (offending) descriptor
*/ */
static struct talitos_desc *current_desc(struct device *dev, int ch) static u32 current_desc_hdr(struct device *dev, int ch)
{ {
struct talitos_private *priv = dev_get_drvdata(dev); struct talitos_private *priv = dev_get_drvdata(dev);
int tail = priv->chan[ch].tail; int tail = priv->chan[ch].tail;
...@@ -428,23 +428,25 @@ static struct talitos_desc *current_desc(struct device *dev, int ch) ...@@ -428,23 +428,25 @@ static struct talitos_desc *current_desc(struct device *dev, int ch)
tail = (tail + 1) & (priv->fifo_len - 1); tail = (tail + 1) & (priv->fifo_len - 1);
if (tail == priv->chan[ch].tail) { if (tail == priv->chan[ch].tail) {
dev_err(dev, "couldn't locate current descriptor\n"); dev_err(dev, "couldn't locate current descriptor\n");
return NULL; return 0;
} }
} }
return priv->chan[ch].fifo[tail].desc; return priv->chan[ch].fifo[tail].desc->hdr;
} }
/* /*
* user diagnostics; report root cause of error based on execution unit status * user diagnostics; report root cause of error based on execution unit status
*/ */
static void report_eu_error(struct device *dev, int ch, static void report_eu_error(struct device *dev, int ch, u32 desc_hdr)
struct talitos_desc *desc)
{ {
struct talitos_private *priv = dev_get_drvdata(dev); struct talitos_private *priv = dev_get_drvdata(dev);
int i; int i;
switch (desc->hdr & DESC_HDR_SEL0_MASK) { if (!desc_hdr)
desc_hdr = in_be32(priv->reg + TALITOS_DESCBUF(ch));
switch (desc_hdr & DESC_HDR_SEL0_MASK) {
case DESC_HDR_SEL0_AFEU: case DESC_HDR_SEL0_AFEU:
dev_err(dev, "AFEUISR 0x%08x_%08x\n", dev_err(dev, "AFEUISR 0x%08x_%08x\n",
in_be32(priv->reg + TALITOS_AFEUISR), in_be32(priv->reg + TALITOS_AFEUISR),
...@@ -488,7 +490,7 @@ static void report_eu_error(struct device *dev, int ch, ...@@ -488,7 +490,7 @@ static void report_eu_error(struct device *dev, int ch,
break; break;
} }
switch (desc->hdr & DESC_HDR_SEL1_MASK) { switch (desc_hdr & DESC_HDR_SEL1_MASK) {
case DESC_HDR_SEL1_MDEUA: case DESC_HDR_SEL1_MDEUA:
case DESC_HDR_SEL1_MDEUB: case DESC_HDR_SEL1_MDEUB:
dev_err(dev, "MDEUISR 0x%08x_%08x\n", dev_err(dev, "MDEUISR 0x%08x_%08x\n",
...@@ -550,7 +552,7 @@ static void talitos_error(unsigned long data, u32 isr, u32 isr_lo) ...@@ -550,7 +552,7 @@ static void talitos_error(unsigned long data, u32 isr, u32 isr_lo)
if (v_lo & TALITOS_CCPSR_LO_IEU) if (v_lo & TALITOS_CCPSR_LO_IEU)
dev_err(dev, "invalid execution unit error\n"); dev_err(dev, "invalid execution unit error\n");
if (v_lo & TALITOS_CCPSR_LO_EU) if (v_lo & TALITOS_CCPSR_LO_EU)
report_eu_error(dev, ch, current_desc(dev, ch)); report_eu_error(dev, ch, current_desc_hdr(dev, ch));
if (v_lo & TALITOS_CCPSR_LO_GB) if (v_lo & TALITOS_CCPSR_LO_GB)
dev_err(dev, "gather boundary error\n"); dev_err(dev, "gather boundary error\n");
if (v_lo & TALITOS_CCPSR_LO_GRL) if (v_lo & TALITOS_CCPSR_LO_GRL)
......
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