|
@@ -604,17 +604,34 @@ const char *esr_get_class_string(u32 esr)
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
- * bad_mode handles the impossible case in the exception vector.
|
|
|
|
|
|
+ * bad_mode handles the impossible case in the exception vector. This is always
|
|
|
|
+ * fatal.
|
|
*/
|
|
*/
|
|
asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
|
|
asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
|
|
{
|
|
{
|
|
- siginfo_t info;
|
|
|
|
- void __user *pc = (void __user *)instruction_pointer(regs);
|
|
|
|
console_verbose();
|
|
console_verbose();
|
|
|
|
|
|
pr_crit("Bad mode in %s handler detected on CPU%d, code 0x%08x -- %s\n",
|
|
pr_crit("Bad mode in %s handler detected on CPU%d, code 0x%08x -- %s\n",
|
|
handler[reason], smp_processor_id(), esr,
|
|
handler[reason], smp_processor_id(), esr,
|
|
esr_get_class_string(esr));
|
|
esr_get_class_string(esr));
|
|
|
|
+
|
|
|
|
+ die("Oops - bad mode", regs, 0);
|
|
|
|
+ local_irq_disable();
|
|
|
|
+ panic("bad mode");
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/*
|
|
|
|
+ * bad_el0_sync handles unexpected, but potentially recoverable synchronous
|
|
|
|
+ * exceptions taken from EL0. Unlike bad_mode, this returns.
|
|
|
|
+ */
|
|
|
|
+asmlinkage void bad_el0_sync(struct pt_regs *regs, int reason, unsigned int esr)
|
|
|
|
+{
|
|
|
|
+ siginfo_t info;
|
|
|
|
+ void __user *pc = (void __user *)instruction_pointer(regs);
|
|
|
|
+ console_verbose();
|
|
|
|
+
|
|
|
|
+ pr_crit("Bad EL0 synchronous exception detected on CPU%d, code 0x%08x -- %s\n",
|
|
|
|
+ smp_processor_id(), esr, esr_get_class_string(esr));
|
|
__show_regs(regs);
|
|
__show_regs(regs);
|
|
|
|
|
|
info.si_signo = SIGILL;
|
|
info.si_signo = SIGILL;
|
|
@@ -622,7 +639,10 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
|
|
info.si_code = ILL_ILLOPC;
|
|
info.si_code = ILL_ILLOPC;
|
|
info.si_addr = pc;
|
|
info.si_addr = pc;
|
|
|
|
|
|
- arm64_notify_die("Oops - bad mode", regs, &info, 0);
|
|
|
|
|
|
+ current->thread.fault_address = 0;
|
|
|
|
+ current->thread.fault_code = 0;
|
|
|
|
+
|
|
|
|
+ force_sig_info(info.si_signo, &info, current);
|
|
}
|
|
}
|
|
|
|
|
|
void __pte_error(const char *file, int line, unsigned long val)
|
|
void __pte_error(const char *file, int line, unsigned long val)
|