return 0;
 }
 
-static int validate_hw_breakpoint(struct perf_event *bp)
+#ifndef hw_breakpoint_arch_parse
+int hw_breakpoint_arch_parse(struct perf_event *bp,
+                            const struct perf_event_attr *attr,
+                            struct arch_hw_breakpoint *hw)
 {
-       int ret;
+       int err;
 
-       ret = arch_validate_hwbkpt_settings(bp);
-       if (ret)
-               return ret;
+       err = arch_validate_hwbkpt_settings(bp);
+       if (err)
+               return err;
+
+       *hw = bp->hw.info;
+
+       return 0;
+}
+#endif
+
+static int hw_breakpoint_parse(struct perf_event *bp,
+                              const struct perf_event_attr *attr,
+                              struct arch_hw_breakpoint *hw)
+{
+       int err;
+
+       err = hw_breakpoint_arch_parse(bp, attr, hw);
+       if (err)
+               return err;
 
        if (arch_check_bp_in_kernelspace(bp)) {
-               if (bp->attr.exclude_kernel)
+               if (attr->exclude_kernel)
                        return -EINVAL;
                /*
                 * Don't let unprivileged users set a breakpoint in the trap
 
 int register_perf_hw_breakpoint(struct perf_event *bp)
 {
-       int ret;
-
-       ret = reserve_bp_slot(bp);
-       if (ret)
-               return ret;
+       struct arch_hw_breakpoint hw;
+       int err;
 
-       ret = validate_hw_breakpoint(bp);
+       err = reserve_bp_slot(bp);
+       if (err)
+               return err;
 
-       /* if arch_validate_hwbkpt_settings() fails then release bp slot */
-       if (ret)
+       err = hw_breakpoint_parse(bp, &bp->attr, &hw);
+       if (err) {
                release_bp_slot(bp);
+               return err;
+       }
 
-       return ret;
+       bp->hw.info = hw;
+
+       return 0;
 }
 
 /**
        u64 old_len  = bp->attr.bp_len;
        int old_type = bp->attr.bp_type;
        bool modify  = attr->bp_type != old_type;
+       struct arch_hw_breakpoint hw;
        int err = 0;
 
        bp->attr.bp_addr = attr->bp_addr;
        if (check && memcmp(&bp->attr, attr, sizeof(*attr)))
                return -EINVAL;
 
-       err = validate_hw_breakpoint(bp);
+       err = hw_breakpoint_parse(bp, attr, &hw);
        if (!err && modify)
                err = modify_bp_slot(bp, old_type);
 
                return err;
        }
 
+       bp->hw.info = hw;
        bp->attr.disabled = attr->disabled;
+
        return 0;
 }