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: Scott Wood <scottwood@freescale.com> Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
This commit is contained in:
Родитель
f3fed682f7
Коммит
82a9a4809f
|
@ -425,7 +425,7 @@ int machine_check_e500mc(struct pt_regs *regs)
|
|||
unsigned long reason = mcsr;
|
||||
int recoverable = 1;
|
||||
|
||||
if (reason & MCSR_BUS_RBERR) {
|
||||
if (reason & MCSR_LD) {
|
||||
recoverable = fsl_rio_mcheck_exception(regs);
|
||||
if (recoverable == 1)
|
||||
goto silent_out;
|
||||
|
|
|
@ -283,23 +283,24 @@ static void __iomem *rio_regs_win;
|
|||
#ifdef CONFIG_E500
|
||||
int fsl_rio_mcheck_exception(struct pt_regs *regs)
|
||||
{
|
||||
const struct exception_table_entry *entry = NULL;
|
||||
unsigned long reason = mfspr(SPRN_MCSR);
|
||||
const struct exception_table_entry *entry;
|
||||
unsigned long reason;
|
||||
|
||||
if (reason & MCSR_BUS_RBERR) {
|
||||
reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
|
||||
if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
|
||||
/* Check if we are prepared to handle this fault */
|
||||
entry = search_exception_tables(regs->nip);
|
||||
if (entry) {
|
||||
pr_debug("RIO: %s - MC Exception handled\n",
|
||||
__func__);
|
||||
out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR),
|
||||
0);
|
||||
regs->msr |= MSR_RI;
|
||||
regs->nip = entry->fixup;
|
||||
return 1;
|
||||
}
|
||||
if (!rio_regs_win)
|
||||
return 0;
|
||||
|
||||
reason = in_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR));
|
||||
if (reason & (RIO_LTLEDCSR_IER | RIO_LTLEDCSR_PRT)) {
|
||||
/* Check if we are prepared to handle this fault */
|
||||
entry = search_exception_tables(regs->nip);
|
||||
if (entry) {
|
||||
pr_debug("RIO: %s - MC Exception handled\n",
|
||||
__func__);
|
||||
out_be32((u32 *)(rio_regs_win + RIO_LTLEDCSR),
|
||||
0);
|
||||
regs->msr |= MSR_RI;
|
||||
regs->nip = entry->fixup;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче