Migrate to the new API in order to remove arch_validate_hwbkpt_settings()
that clumsily mixes up architecture validation and commit.

Acked-by: Mark Rutland <mark.rutl...@arm.com>
Signed-off-by: Frederic Weisbecker <frede...@kernel.org>
Cc: Linus Torvalds <torva...@linux-foundation.org>
Cc: Andy Lutomirski <l...@kernel.org>
Cc: Yoshinori Sato <ys...@users.sourceforge.jp>
Cc: Rich Felker <dal...@libc.org>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Will Deacon <will.dea...@arm.com>
Cc: Mark Rutland <mark.rutl...@arm.com>
Cc: Max Filippov <jcmvb...@gmail.com>
Cc: Chris Zankel <ch...@zankel.net>
Cc: Catalin Marinas <catalin.mari...@arm.com>
Cc: Benjamin Herrenschmidt <b...@kernel.crashing.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Michael Ellerman <m...@ellerman.id.au>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
Cc: Alexander Shishkin <alexander.shish...@linux.intel.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhy...@kernel.org>
Cc: Joel Fernandes <joel.open...@gmail.com>
---
 arch/arm/include/asm/hw_breakpoint.h |  6 ++-
 arch/arm/kernel/hw_breakpoint.c      | 71 ++++++++++++++++++------------------
 2 files changed, 41 insertions(+), 36 deletions(-)

diff --git a/arch/arm/include/asm/hw_breakpoint.h 
b/arch/arm/include/asm/hw_breakpoint.h
index d5a0f52..1e02925 100644
--- a/arch/arm/include/asm/hw_breakpoint.h
+++ b/arch/arm/include/asm/hw_breakpoint.h
@@ -111,6 +111,7 @@ static inline void decode_ctrl_reg(u32 reg,
        asm volatile("mcr p14, 0, %0, " #N "," #M ", " #OP2 : : "r" (VAL));\
 } while (0)
 
+struct perf_event_attr;
 struct notifier_block;
 struct perf_event;
 struct pmu;
@@ -118,7 +119,10 @@ struct pmu;
 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 arch_hw_breakpoint *hw);
-extern int arch_validate_hwbkpt_settings(struct perf_event *bp);
+extern int hw_breakpoint_arch_parse(struct perf_event *bp,
+                                   const struct perf_event_attr *attr,
+                                   struct arch_hw_breakpoint *hw);
+#define hw_breakpoint_arch_parse hw_breakpoint_arch_parse
 extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
                                           unsigned long val, void *data);
 
diff --git a/arch/arm/kernel/hw_breakpoint.c b/arch/arm/kernel/hw_breakpoint.c
index 385dcf4..1d5fbf1 100644
--- a/arch/arm/kernel/hw_breakpoint.c
+++ b/arch/arm/kernel/hw_breakpoint.c
@@ -517,42 +517,42 @@ int arch_bp_generic_fields(struct arch_hw_breakpoint_ctrl 
ctrl,
 /*
  * Construct an arch_hw_breakpoint from a perf_event.
  */
-static int arch_build_bp_info(struct perf_event *bp)
+static int arch_build_bp_info(struct perf_event *bp,
+                             const struct perf_event_attr *attr,
+                             struct arch_hw_breakpoint *hw)
 {
-       struct arch_hw_breakpoint *info = counter_arch_bp(bp);
-
        /* Type */
-       switch (bp->attr.bp_type) {
+       switch (attr->bp_type) {
        case HW_BREAKPOINT_X:
-               info->ctrl.type = ARM_BREAKPOINT_EXECUTE;
+               hw->ctrl.type = ARM_BREAKPOINT_EXECUTE;
                break;
        case HW_BREAKPOINT_R:
-               info->ctrl.type = ARM_BREAKPOINT_LOAD;
+               hw->ctrl.type = ARM_BREAKPOINT_LOAD;
                break;
        case HW_BREAKPOINT_W:
-               info->ctrl.type = ARM_BREAKPOINT_STORE;
+               hw->ctrl.type = ARM_BREAKPOINT_STORE;
                break;
        case HW_BREAKPOINT_RW:
-               info->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
+               hw->ctrl.type = ARM_BREAKPOINT_LOAD | ARM_BREAKPOINT_STORE;
                break;
        default:
                return -EINVAL;
        }
 
        /* Len */
-       switch (bp->attr.bp_len) {
+       switch (attr->bp_len) {
        case HW_BREAKPOINT_LEN_1:
-               info->ctrl.len = ARM_BREAKPOINT_LEN_1;
+               hw->ctrl.len = ARM_BREAKPOINT_LEN_1;
                break;
        case HW_BREAKPOINT_LEN_2:
-               info->ctrl.len = ARM_BREAKPOINT_LEN_2;
+               hw->ctrl.len = ARM_BREAKPOINT_LEN_2;
                break;
        case HW_BREAKPOINT_LEN_4:
-               info->ctrl.len = ARM_BREAKPOINT_LEN_4;
+               hw->ctrl.len = ARM_BREAKPOINT_LEN_4;
                break;
        case HW_BREAKPOINT_LEN_8:
-               info->ctrl.len = ARM_BREAKPOINT_LEN_8;
-               if ((info->ctrl.type != ARM_BREAKPOINT_EXECUTE)
+               hw->ctrl.len = ARM_BREAKPOINT_LEN_8;
+               if ((hw->ctrl.type != ARM_BREAKPOINT_EXECUTE)
                        && max_watchpoint_len >= 8)
                        break;
        default:
@@ -565,24 +565,24 @@ static int arch_build_bp_info(struct perf_event *bp)
         * by the hardware and must be aligned to the appropriate number of
         * bytes.
         */
-       if (info->ctrl.type == ARM_BREAKPOINT_EXECUTE &&
-           info->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
-           info->ctrl.len != ARM_BREAKPOINT_LEN_4)
+       if (hw->ctrl.type == ARM_BREAKPOINT_EXECUTE &&
+           hw->ctrl.len != ARM_BREAKPOINT_LEN_2 &&
+           hw->ctrl.len != ARM_BREAKPOINT_LEN_4)
                return -EINVAL;
 
        /* Address */
-       info->address = bp->attr.bp_addr;
+       hw->address = attr->bp_addr;
 
        /* Privilege */
-       info->ctrl.privilege = ARM_BREAKPOINT_USER;
-       if (arch_check_bp_in_kernelspace(info))
-               info->ctrl.privilege |= ARM_BREAKPOINT_PRIV;
+       hw->ctrl.privilege = ARM_BREAKPOINT_USER;
+       if (arch_check_bp_in_kernelspace(hw))
+               hw->ctrl.privilege |= ARM_BREAKPOINT_PRIV;
 
        /* Enabled? */
-       info->ctrl.enabled = !bp->attr.disabled;
+       hw->ctrl.enabled = !attr->disabled;
 
        /* Mismatch */
-       info->ctrl.mismatch = 0;
+       hw->ctrl.mismatch = 0;
 
        return 0;
 }
@@ -590,9 +590,10 @@ static int arch_build_bp_info(struct perf_event *bp)
 /*
  * Validate the arch-specific HW Breakpoint register settings.
  */
-int arch_validate_hwbkpt_settings(struct perf_event *bp)
+int hw_breakpoint_arch_parse(struct perf_event *bp,
+                            const struct perf_event_attr *attr,
+                            struct arch_hw_breakpoint *hw)
 {
-       struct arch_hw_breakpoint *info = counter_arch_bp(bp);
        int ret = 0;
        u32 offset, alignment_mask = 0x3;
 
@@ -601,14 +602,14 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
                return -ENODEV;
 
        /* Build the arch_hw_breakpoint. */
-       ret = arch_build_bp_info(bp);
+       ret = arch_build_bp_info(bp, attr, hw);
        if (ret)
                goto out;
 
        /* Check address alignment. */
-       if (info->ctrl.len == ARM_BREAKPOINT_LEN_8)
+       if (hw->ctrl.len == ARM_BREAKPOINT_LEN_8)
                alignment_mask = 0x7;
-       offset = info->address & alignment_mask;
+       offset = hw->address & alignment_mask;
        switch (offset) {
        case 0:
                /* Aligned */
@@ -616,19 +617,19 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
        case 1:
        case 2:
                /* Allow halfword watchpoints and breakpoints. */
-               if (info->ctrl.len == ARM_BREAKPOINT_LEN_2)
+               if (hw->ctrl.len == ARM_BREAKPOINT_LEN_2)
                        break;
        case 3:
                /* Allow single byte watchpoint. */
-               if (info->ctrl.len == ARM_BREAKPOINT_LEN_1)
+               if (hw->ctrl.len == ARM_BREAKPOINT_LEN_1)
                        break;
        default:
                ret = -EINVAL;
                goto out;
        }
 
-       info->address &= ~alignment_mask;
-       info->ctrl.len <<= offset;
+       hw->address &= ~alignment_mask;
+       hw->ctrl.len <<= offset;
 
        if (is_default_overflow_handler(bp)) {
                /*
@@ -639,7 +640,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
                        return -EINVAL;
 
                /* We don't allow mismatch breakpoints in kernel space. */
-               if (arch_check_bp_in_kernelspace(info))
+               if (arch_check_bp_in_kernelspace(hw))
                        return -EPERM;
 
                /*
@@ -654,8 +655,8 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp)
                 * reports them.
                 */
                if (!debug_exception_updates_fsr() &&
-                   (info->ctrl.type == ARM_BREAKPOINT_LOAD ||
-                    info->ctrl.type == ARM_BREAKPOINT_STORE))
+                   (hw->ctrl.type == ARM_BREAKPOINT_LOAD ||
+                    hw->ctrl.type == ARM_BREAKPOINT_STORE))
                        return -EINVAL;
        }
 
-- 
2.7.4

Reply via email to