diff options
| -rw-r--r-- | arch/sh/include/asm/hw_breakpoint.h | 6 | ||||
| -rw-r--r-- | arch/sh/kernel/hw_breakpoint.c | 37 |
2 files changed, 24 insertions, 19 deletions
diff --git a/arch/sh/include/asm/hw_breakpoint.h b/arch/sh/include/asm/hw_breakpoint.h index dae622d9b10b..867edcc60e8f 100644 --- a/arch/sh/include/asm/hw_breakpoint.h +++ b/arch/sh/include/asm/hw_breakpoint.h | |||
| @@ -40,6 +40,7 @@ struct sh_ubc { | |||
| 40 | struct clk *clk; /* optional interface clock / MSTP bit */ | 40 | struct clk *clk; /* optional interface clock / MSTP bit */ |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | struct perf_event_attr; | ||
| 43 | struct perf_event; | 44 | struct perf_event; |
| 44 | struct task_struct; | 45 | struct task_struct; |
| 45 | struct pmu; | 46 | struct pmu; |
| @@ -54,7 +55,10 @@ static inline int hw_breakpoint_slots(int type) | |||
| 54 | 55 | ||
| 55 | /* arch/sh/kernel/hw_breakpoint.c */ | 56 | /* arch/sh/kernel/hw_breakpoint.c */ |
| 56 | extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw); | 57 | extern int arch_check_bp_in_kernelspace(struct arch_hw_breakpoint *hw); |
| 57 | extern int arch_validate_hwbkpt_settings(struct perf_event *bp); | 58 | extern int hw_breakpoint_arch_parse(struct perf_event *bp, |
| 59 | const struct perf_event_attr *attr, | ||
| 60 | struct arch_hw_breakpoint *hw); | ||
| 61 | #define hw_breakpoint_arch_parse hw_breakpoint_arch_parse | ||
| 58 | extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, | 62 | extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused, |
| 59 | unsigned long val, void *data); | 63 | unsigned long val, void *data); |
| 60 | 64 | ||
diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c index c453a0cea3c2..d9ff3b42da7c 100644 --- a/arch/sh/kernel/hw_breakpoint.c +++ b/arch/sh/kernel/hw_breakpoint.c | |||
| @@ -173,40 +173,40 @@ int arch_bp_generic_fields(int sh_len, int sh_type, | |||
| 173 | return 0; | 173 | return 0; |
| 174 | } | 174 | } |
| 175 | 175 | ||
| 176 | static int arch_build_bp_info(struct perf_event *bp) | 176 | static int arch_build_bp_info(struct perf_event *bp, |
| 177 | const struct perf_event_attr *attr, | ||
| 178 | struct arch_hw_breakpoint *hw) | ||
| 177 | { | 179 | { |
| 178 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | 180 | hw->address = attr->bp_addr; |
| 179 | |||
| 180 | info->address = bp->attr.bp_addr; | ||
| 181 | 181 | ||
| 182 | /* Len */ | 182 | /* Len */ |
| 183 | switch (bp->attr.bp_len) { | 183 | switch (attr->bp_len) { |
| 184 | case HW_BREAKPOINT_LEN_1: | 184 | case HW_BREAKPOINT_LEN_1: |
| 185 | info->len = SH_BREAKPOINT_LEN_1; | 185 | hw->len = SH_BREAKPOINT_LEN_1; |
| 186 | break; | 186 | break; |
| 187 | case HW_BREAKPOINT_LEN_2: | 187 | case HW_BREAKPOINT_LEN_2: |
| 188 | info->len = SH_BREAKPOINT_LEN_2; | 188 | hw->len = SH_BREAKPOINT_LEN_2; |
| 189 | break; | 189 | break; |
| 190 | case HW_BREAKPOINT_LEN_4: | 190 | case HW_BREAKPOINT_LEN_4: |
| 191 | info->len = SH_BREAKPOINT_LEN_4; | 191 | hw->len = SH_BREAKPOINT_LEN_4; |
| 192 | break; | 192 | break; |
| 193 | case HW_BREAKPOINT_LEN_8: | 193 | case HW_BREAKPOINT_LEN_8: |
| 194 | info->len = SH_BREAKPOINT_LEN_8; | 194 | hw->len = SH_BREAKPOINT_LEN_8; |
| 195 | break; | 195 | break; |
| 196 | default: | 196 | default: |
| 197 | return -EINVAL; | 197 | return -EINVAL; |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | /* Type */ | 200 | /* Type */ |
| 201 | switch (bp->attr.bp_type) { | 201 | switch (attr->bp_type) { |
| 202 | case HW_BREAKPOINT_R: | 202 | case HW_BREAKPOINT_R: |
| 203 | info->type = SH_BREAKPOINT_READ; | 203 | hw->type = SH_BREAKPOINT_READ; |
| 204 | break; | 204 | break; |
| 205 | case HW_BREAKPOINT_W: | 205 | case HW_BREAKPOINT_W: |
| 206 | info->type = SH_BREAKPOINT_WRITE; | 206 | hw->type = SH_BREAKPOINT_WRITE; |
| 207 | break; | 207 | break; |
| 208 | case HW_BREAKPOINT_W | HW_BREAKPOINT_R: | 208 | case HW_BREAKPOINT_W | HW_BREAKPOINT_R: |
| 209 | info->type = SH_BREAKPOINT_RW; | 209 | hw->type = SH_BREAKPOINT_RW; |
| 210 | break; | 210 | break; |
| 211 | default: | 211 | default: |
| 212 | return -EINVAL; | 212 | return -EINVAL; |
| @@ -218,19 +218,20 @@ static int arch_build_bp_info(struct perf_event *bp) | |||
| 218 | /* | 218 | /* |
| 219 | * Validate the arch-specific HW Breakpoint register settings | 219 | * Validate the arch-specific HW Breakpoint register settings |
| 220 | */ | 220 | */ |
| 221 | int arch_validate_hwbkpt_settings(struct perf_event *bp) | 221 | int hw_breakpoint_arch_parse(struct perf_event *bp, |
| 222 | const struct perf_event_attr *attr, | ||
| 223 | struct arch_hw_breakpoint *hw) | ||
| 222 | { | 224 | { |
| 223 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
| 224 | unsigned int align; | 225 | unsigned int align; |
| 225 | int ret; | 226 | int ret; |
| 226 | 227 | ||
| 227 | ret = arch_build_bp_info(bp); | 228 | ret = arch_build_bp_info(bp, attr, hw); |
| 228 | if (ret) | 229 | if (ret) |
| 229 | return ret; | 230 | return ret; |
| 230 | 231 | ||
| 231 | ret = -EINVAL; | 232 | ret = -EINVAL; |
| 232 | 233 | ||
| 233 | switch (info->len) { | 234 | switch (hw->len) { |
| 234 | case SH_BREAKPOINT_LEN_1: | 235 | case SH_BREAKPOINT_LEN_1: |
| 235 | align = 0; | 236 | align = 0; |
| 236 | break; | 237 | break; |
| @@ -251,7 +252,7 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp) | |||
| 251 | * Check that the low-order bits of the address are appropriate | 252 | * Check that the low-order bits of the address are appropriate |
| 252 | * for the alignment implied by len. | 253 | * for the alignment implied by len. |
| 253 | */ | 254 | */ |
| 254 | if (info->address & align) | 255 | if (hw->address & align) |
| 255 | return -EINVAL; | 256 | return -EINVAL; |
| 256 | 257 | ||
| 257 | return 0; | 258 | return 0; |
