Commit 82a9a480 authored by Scott Wood's avatar Scott Wood Committed by Kumar Gala

powerpc/e500: fix breakage with fsl_rio_mcheck_exception

The wrong MCSR bit was being used on e500mc.  MCSR_BUS_RBERR only exists
on e500v1/v2.  Use MCSR_LD on e500mc, and remove all MCSR checking
in fsl_rio_mcheck_exception as we now no longer call that function
if the appropriate bit in MCSR is not set.

If RIO support was enabled at compile-time, but was never probed, just
return from fsl_rio_mcheck_exception rather than dereference a NULL
pointer.

TODO: There is still a remaining, though comparitively minor, issue in
that this recovery mechanism will falsely engage if there's an unrelated
MCSR_LD event at the same time as a RIO error.
Signed-off-by: default avatarScott Wood <scottwood@freescale.com>
Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
parent f3fed682
...@@ -425,7 +425,7 @@ int machine_check_e500mc(struct pt_regs *regs) ...@@ -425,7 +425,7 @@ int machine_check_e500mc(struct pt_regs *regs)
unsigned long reason = mcsr; unsigned long reason = mcsr;
int recoverable = 1; int recoverable = 1;
if (reason & MCSR_BUS_RBERR) { if (reason & MCSR_LD) {
recoverable = fsl_rio_mcheck_exception(regs); recoverable = fsl_rio_mcheck_exception(regs);
if (recoverable == 1) if (recoverable == 1)
goto silent_out; goto silent_out;
......
...@@ -283,23 +283,24 @@ static void __iomem *rio_regs_win; ...@@ -283,23 +283,24 @@ static void __iomem *rio_regs_win;
#ifdef CONFIG_E500 #ifdef CONFIG_E500
int fsl_rio_mcheck_exception(struct pt_regs *regs) int fsl_rio_mcheck_exception(struct pt_regs *regs)
{ {
const struct exception_table_entry *entry = NULL; const struct exception_table_entry *entry;
unsigned long reason = mfspr(SPRN_MCSR); unsigned long reason;
if (reason & MCSR_BUS_RBERR) { if (!rio_regs_win)
reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR)); return 0;
if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
/* Check if we are prepared to handle this fault */ reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
entry = search_exception_tables(regs->nip); if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
if (entry) { /* Check if we are prepared to handle this fault */
pr_debug("RIO: %s - MC Exception handled\n", entry = search_exception_tables(regs->nip);
__func__); if (entry) {
out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR), pr_debug("RIO: %s - MC Exception handled\n",
0); __func__);
regs->msr |= MSR_RI; out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR),
regs->nip = entry->fixup; 0);
return 1; regs->msr |= MSR_RI;
} regs->nip = entry->fixup;
return 1;
} }
} }
......
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