|
@@ -519,9 +519,58 @@ do_DataAbort(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
|
|
|
arm_notify_die("", regs, &info, fsr, 0);
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+static struct fsr_info ifsr_info[] = {
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 0" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 1" },
|
|
|
+ { do_bad, SIGBUS, 0, "debug event" },
|
|
|
+ { do_bad, SIGSEGV, SEGV_ACCERR, "section access flag fault" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 4" },
|
|
|
+ { do_translation_fault, SIGSEGV, SEGV_MAPERR, "section translation fault" },
|
|
|
+ { do_bad, SIGSEGV, SEGV_ACCERR, "page access flag fault" },
|
|
|
+ { do_page_fault, SIGSEGV, SEGV_MAPERR, "page translation fault" },
|
|
|
+ { do_bad, SIGBUS, 0, "external abort on non-linefetch" },
|
|
|
+ { do_bad, SIGSEGV, SEGV_ACCERR, "section domain fault" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 10" },
|
|
|
+ { do_bad, SIGSEGV, SEGV_ACCERR, "page domain fault" },
|
|
|
+ { do_bad, SIGBUS, 0, "external abort on translation" },
|
|
|
+ { do_sect_fault, SIGSEGV, SEGV_ACCERR, "section permission fault" },
|
|
|
+ { do_bad, SIGBUS, 0, "external abort on translation" },
|
|
|
+ { do_page_fault, SIGSEGV, SEGV_ACCERR, "page permission fault" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 16" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 17" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 18" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 19" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 20" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 21" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 22" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 23" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 24" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 25" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 26" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 27" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 28" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 29" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 30" },
|
|
|
+ { do_bad, SIGBUS, 0, "unknown 31" },
|
|
|
+};
|
|
|
+
|
|
|
asmlinkage void __exception
|
|
|
do_PrefetchAbort(unsigned long addr, unsigned int ifsr, struct pt_regs *regs)
|
|
|
{
|
|
|
- do_translation_fault(addr, FSR_LNX_PF, regs);
|
|
|
+ const struct fsr_info *inf = ifsr_info + fsr_fs(ifsr);
|
|
|
+ struct siginfo info;
|
|
|
+
|
|
|
+ if (!inf->fn(addr, ifsr | FSR_LNX_PF, regs))
|
|
|
+ return;
|
|
|
+
|
|
|
+ printk(KERN_ALERT "Unhandled prefetch abort: %s (0x%03x) at 0x%08lx\n",
|
|
|
+ inf->name, ifsr, addr);
|
|
|
+
|
|
|
+ info.si_signo = inf->sig;
|
|
|
+ info.si_errno = 0;
|
|
|
+ info.si_code = inf->code;
|
|
|
+ info.si_addr = (void __user *)addr;
|
|
|
+ arm_notify_die("", regs, &info, ifsr, 0);
|
|
|
}
|
|
|
|