arm64: Kprobes with single stepping support
[firefly-linux-kernel-4.4.55.git] / arch / arm64 / kernel / debug-monitors.c
index c8875b64be909f4e1c15c9be6060a1da988f972f..17a4d3798cc458ab891a181e5b2fcb3a91233f24 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/hardirq.h>
 #include <linux/init.h>
 #include <linux/ptrace.h>
+#include <linux/kprobes.h>
 #include <linux/stat.h>
 #include <linux/uaccess.h>
 
@@ -253,6 +254,10 @@ static int single_step_handler(unsigned long addr, unsigned int esr,
                 */
                user_rewind_single_step(current);
        } else {
+#ifdef CONFIG_KPROBES
+               if (kprobe_single_step_handler(regs, esr) == DBG_HOOK_HANDLED)
+                       return 0;
+#endif
                if (call_step_hook(regs, esr) == DBG_HOOK_HANDLED)
                        return 0;
 
@@ -318,8 +323,15 @@ static int brk_handler(unsigned long addr, unsigned int esr,
                };
 
                force_sig_info(SIGTRAP, &info, current);
-       } else if (call_break_hook(regs, esr) != DBG_HOOK_HANDLED) {
-               pr_warning("Unexpected kernel BRK exception at EL1\n");
+       }
+#ifdef CONFIG_KPROBES
+       else if ((esr & BRK64_ESR_MASK) == BRK64_ESR_KPROBES) {
+               if (kprobe_breakpoint_handler(regs, esr) != DBG_HOOK_HANDLED)
+                       return -EFAULT;
+       }
+#endif
+       else if (call_break_hook(regs, esr) != DBG_HOOK_HANDLED) {
+               pr_warn("Unexpected kernel BRK exception at EL1\n");
                return -EFAULT;
        }