|
@@ -555,20 +555,33 @@ asmlinkage int __exception do_debug_exception(unsigned long addr,
|
|
{
|
|
{
|
|
const struct fault_info *inf = debug_fault_info + DBG_ESR_EVT(esr);
|
|
const struct fault_info *inf = debug_fault_info + DBG_ESR_EVT(esr);
|
|
struct siginfo info;
|
|
struct siginfo info;
|
|
|
|
+ int rv;
|
|
|
|
|
|
- if (!inf->fn(addr, esr, regs))
|
|
|
|
- return 1;
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Tell lockdep we disabled irqs in entry.S. Do nothing if they were
|
|
|
|
+ * already disabled to preserve the last enabled/disabled addresses.
|
|
|
|
+ */
|
|
|
|
+ if (interrupts_enabled(regs))
|
|
|
|
+ trace_hardirqs_off();
|
|
|
|
|
|
- pr_alert("Unhandled debug exception: %s (0x%08x) at 0x%016lx\n",
|
|
|
|
- inf->name, esr, addr);
|
|
|
|
|
|
+ if (!inf->fn(addr, esr, regs)) {
|
|
|
|
+ rv = 1;
|
|
|
|
+ } else {
|
|
|
|
+ pr_alert("Unhandled debug exception: %s (0x%08x) at 0x%016lx\n",
|
|
|
|
+ inf->name, esr, addr);
|
|
|
|
+
|
|
|
|
+ info.si_signo = inf->sig;
|
|
|
|
+ info.si_errno = 0;
|
|
|
|
+ info.si_code = inf->code;
|
|
|
|
+ info.si_addr = (void __user *)addr;
|
|
|
|
+ arm64_notify_die("", regs, &info, 0);
|
|
|
|
+ rv = 0;
|
|
|
|
+ }
|
|
|
|
|
|
- info.si_signo = inf->sig;
|
|
|
|
- info.si_errno = 0;
|
|
|
|
- info.si_code = inf->code;
|
|
|
|
- info.si_addr = (void __user *)addr;
|
|
|
|
- arm64_notify_die("", regs, &info, 0);
|
|
|
|
|
|
+ if (interrupts_enabled(regs))
|
|
|
|
+ trace_hardirqs_on();
|
|
|
|
|
|
- return 0;
|
|
|
|
|
|
+ return rv;
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_ARM64_PAN
|
|
#ifdef CONFIG_ARM64_PAN
|