#include <linux/stddef.h>
 #include <linux/stringify.h>
 #include <asm/asm.h>
+#include <asm/ptrace.h>
 
 /*
  * Alternative inline assembly for SMP.
  * inconsistent instruction while you patch.
  */
 extern void *text_poke(void *addr, const void *opcode, size_t len);
+extern int poke_int3_handler(struct pt_regs *regs);
 extern void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler);
 
 #endif /* _ASM_X86_ALTERNATIVE_H */
 
 static bool bp_patching_in_progress;
 static void *bp_int3_handler, *bp_int3_addr;
 
-static int int3_notify(struct notifier_block *self, unsigned long val, void *data)
+int poke_int3_handler(struct pt_regs *regs)
 {
-       struct die_args *args = data;
-
        /* bp_patching_in_progress */
        smp_rmb();
 
        if (likely(!bp_patching_in_progress))
-               return NOTIFY_DONE;
+               return 0;
 
-       /* we are not interested in non-int3 faults and ring > 0 faults */
-       if (val != DIE_INT3 || !args->regs || user_mode_vm(args->regs)
-                           || args->regs->ip != (unsigned long)bp_int3_addr)
-               return NOTIFY_DONE;
+       if (user_mode_vm(regs) || regs->ip != (unsigned long)bp_int3_addr)
+               return 0;
 
        /* set up the specified breakpoint handler */
-       args->regs->ip = (unsigned long) bp_int3_handler;
+       regs->ip = (unsigned long) bp_int3_handler;
+
+       return 1;
 
-       return NOTIFY_STOP;
 }
+
 /**
  * text_poke_bp() -- update instructions on live kernel on SMP
  * @addr:      address to patch
        return addr;
 }
 
-/* this one needs to run before anything else handles it as a
- * regular exception */
-static struct notifier_block int3_nb = {
-       .priority = 0x7fffffff,
-       .notifier_call = int3_notify
-};
-
-static int __init int3_init(void)
-{
-       return register_die_notifier(&int3_nb);
-}
-
-arch_initcall(int3_init);
 
 #include <asm/mce.h>
 #include <asm/fixmap.h>
 #include <asm/mach_traps.h>
+#include <asm/alternative.h>
 
 #ifdef CONFIG_X86_64
 #include <asm/x86_init.h>
            ftrace_int3_handler(regs))
                return;
 #endif
+       if (poke_int3_handler(regs))
+               return;
+
        prev_state = exception_enter();
 #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
        if (kgdb_ll_trap(DIE_INT3, "int3", regs, error_code, X86_TRAP_BP,
 
 
 static struct notifier_block kprobe_exceptions_nb = {
        .notifier_call = kprobe_exceptions_notify,
-       .priority = 0x7ffffff0 /* High priority, but not first.  */
+       .priority = 0x7fffffff /* we need to be notified first */
 };
 
 unsigned long __weak arch_deref_entry_point(void *entry)