Upgrade to 4.4.50-rt62
[kvmfornfv.git] / kernel / arch / arm64 / kernel / traps.c
index e9b9b53..ca7f0ac 100644 (file)
@@ -434,16 +434,33 @@ 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)
 {
-       siginfo_t info;
-       void __user *pc = (void __user *)instruction_pointer(regs);
        console_verbose();
 
        pr_crit("Bad mode in %s handler detected, code 0x%08x -- %s\n",
                handler[reason], 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);
 
        info.si_signo = SIGILL;
@@ -451,7 +468,10 @@ asmlinkage void bad_mode(struct pt_regs *regs, int reason, unsigned int esr)
        info.si_code  = ILL_ILLOPC;
        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)