extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
                                  int *gen_len, int *gen_type);
-extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
 extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
                                           unsigned long val, void *data);
 
 /*
  * Check whether bp virtual address is in kernel space.
  */
-int arch_check_bp_in_kernelspace(struct perf_event *bp)
+int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
 {
        unsigned int len;
        unsigned long va;
-       struct arch_hw_breakpoint *info = counter_arch_bp(bp);
 
-       va = info->address;
-       len = get_hbp_len(info->ctrl.len);
+       va = hw->address;
+       len = get_hbp_len(hw->ctrl.len);
 
        return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
 }
 
        /* Privilege */
        info->ctrl.privilege = ARM_BREAKPOINT_USER;
-       if (arch_check_bp_in_kernelspace(bp))
+       if (arch_check_bp_in_kernelspace(info))
                info->ctrl.privilege |= ARM_BREAKPOINT_PRIV;
 
        /* Enabled? */
                        return -EINVAL;
 
                /* We don't allow mismatch breakpoints in kernel space. */
-               if (arch_check_bp_in_kernelspace(bp))
+               if (arch_check_bp_in_kernelspace(info))
                        return -EPERM;
 
                /*
 
 
 extern int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl ctrl,
                                  int *gen_len, int *gen_type, int *offset);
-extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
 extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
                                           unsigned long val, void *data);
 
 /*
  * Check whether bp virtual address is in kernel space.
  */
-int arch_check_bp_in_kernelspace(struct perf_event *bp)
+int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
 {
        unsigned int len;
        unsigned long va;
-       struct arch_hw_breakpoint *info = counter_arch_bp(bp);
 
-       va = info->address;
-       len = get_hbp_len(info->ctrl.len);
+       va = hw->address;
+       len = get_hbp_len(hw->ctrl.len);
 
        return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
 }
         * Note that we disallow combined EL0/EL1 breakpoints because
         * that would complicate the stepping code.
         */
-       if (arch_check_bp_in_kernelspace(bp))
+       if (arch_check_bp_in_kernelspace(info))
                info->ctrl.privilege = AARCH64_BREAKPOINT_EL1;
        else
                info->ctrl.privilege = AARCH64_BREAKPOINT_EL0;
 
 
 extern int hw_breakpoint_slots(int type);
 extern int arch_bp_generic_fields(int type, int *gen_bp_type);
-extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
 extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
                                                unsigned long val, void *data);
 
 /*
  * Check for virtual address in kernel space.
  */
-int arch_check_bp_in_kernelspace(struct perf_event *bp)
+int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
 {
-       struct arch_hw_breakpoint *info = counter_arch_bp(bp);
-
-       return is_kernel_addr(info->address);
+       return is_kernel_addr(hw->address);
 }
 
 int arch_bp_generic_fields(int type, int *gen_bp_type)
 
 }
 
 /* arch/sh/kernel/hw_breakpoint.c */
-extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
 extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
                                           unsigned long val, void *data);
 
 /*
  * Check for virtual address in kernel space.
  */
-int arch_check_bp_in_kernelspace(struct perf_event *bp)
+int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
 {
        unsigned int len;
        unsigned long va;
-       struct arch_hw_breakpoint *info = counter_arch_bp(bp);
 
-       va = info->address;
-       len = get_hbp_len(info->len);
+       va = hw->address;
+       len = get_hbp_len(hw->len);
 
        return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
 }
                perf_bp_event(bp, args->regs);
 
                /* Deliver the signal to userspace */
-               if (!arch_check_bp_in_kernelspace(bp)) {
+               if (!arch_check_bp_in_kernelspace(&bp->hw.info)) {
                        force_sig_fault(SIGTRAP, TRAP_HWBKPT,
                                        (void __user *)NULL, current);
                }
 
 struct perf_event;
 struct pmu;
 
-extern int arch_check_bp_in_kernelspace(struct perf_event *bp);
+extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
 extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
                                           unsigned long val, void *data);
 
                set_dr_addr_mask(0, i);
 }
 
-/*
- * Check for virtual address in kernel space.
- */
-int arch_check_bp_in_kernelspace(struct perf_event *bp)
+static int arch_bp_generic_len(int x86_len)
 {
-       unsigned int len;
-       unsigned long va;
-       struct arch_hw_breakpoint *info = counter_arch_bp(bp);
-
-       va = info->address;
-       len = bp->attr.bp_len;
-
-       /*
-        * We don't need to worry about va + len - 1 overflowing:
-        * we already require that va is aligned to a multiple of len.
-        */
-       return (va >= TASK_SIZE_MAX) || ((va + len - 1) >= TASK_SIZE_MAX);
+       switch (x86_len) {
+       case X86_BREAKPOINT_LEN_1:
+               return HW_BREAKPOINT_LEN_1;
+       case X86_BREAKPOINT_LEN_2:
+               return HW_BREAKPOINT_LEN_2;
+       case X86_BREAKPOINT_LEN_4:
+               return HW_BREAKPOINT_LEN_4;
+#ifdef CONFIG_X86_64
+       case X86_BREAKPOINT_LEN_8:
+               return HW_BREAKPOINT_LEN_8;
+#endif
+       default:
+               return -EINVAL;
+       }
 }
 
 int arch_bp_generic_fields(int x86_len, int x86_type,
                           int *gen_len, int *gen_type)
 {
+       int len;
+
        /* Type */
        switch (x86_type) {
        case X86_BREAKPOINT_EXECUTE:
        }
 
        /* Len */
-       switch (x86_len) {
-       case X86_BREAKPOINT_LEN_1:
-               *gen_len = HW_BREAKPOINT_LEN_1;
-               break;
-       case X86_BREAKPOINT_LEN_2:
-               *gen_len = HW_BREAKPOINT_LEN_2;
-               break;
-       case X86_BREAKPOINT_LEN_4:
-               *gen_len = HW_BREAKPOINT_LEN_4;
-               break;
-#ifdef CONFIG_X86_64
-       case X86_BREAKPOINT_LEN_8:
-               *gen_len = HW_BREAKPOINT_LEN_8;
-               break;
-#endif
-       default:
+       len = arch_bp_generic_len(x86_len);
+       if (len < 0)
                return -EINVAL;
-       }
+       *gen_len = len;
 
        return 0;
 }
 
+/*
+ * Check for virtual address in kernel space.
+ */
+int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
+{
+       unsigned long va;
+       int len;
+
+       va = hw->address;
+       len = arch_bp_generic_len(hw->len);
+       WARN_ON_ONCE(len < 0);
+
+       /*
+        * We don't need to worry about va + len - 1 overflowing:
+        * we already require that va is aligned to a multiple of len.
+        */
+       return (va >= TASK_SIZE_MAX) || ((va + len - 1) >= TASK_SIZE_MAX);
+}
 
 static int arch_build_bp_info(struct perf_event *bp)
 {
 
 struct task_struct;
 
 int hw_breakpoint_slots(int type);
-int arch_check_bp_in_kernelspace(struct perf_event *bp);
+int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw);
 int arch_validate_hwbkpt_settings(struct perf_event *bp);
 int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
                                    unsigned long val, void *data);
 
        }
 }
 
-int arch_check_bp_in_kernelspace(struct perf_event *bp)
+int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw)
 {
        unsigned int len;
        unsigned long va;
-       struct arch_hw_breakpoint *info = counter_arch_bp(bp);
 
-       va = info->address;
-       len = bp->attr.bp_len;
+       va = hw->address;
+       len = hw->len;
 
        return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE);
 }
 
        if (err)
                return err;
 
-       if (arch_check_bp_in_kernelspace(bp)) {
+       if (arch_check_bp_in_kernelspace(hw)) {
                if (attr->exclude_kernel)
                        return -EINVAL;
                /*