diff options
Diffstat (limited to 'arch/sh/kernel')
-rw-r--r-- | arch/sh/kernel/hw_breakpoint.c | 34 |
1 files changed, 7 insertions, 27 deletions
diff --git a/arch/sh/kernel/hw_breakpoint.c b/arch/sh/kernel/hw_breakpoint.c index 675eea7785d9..1f2cf6229862 100644 --- a/arch/sh/kernel/hw_breakpoint.c +++ b/arch/sh/kernel/hw_breakpoint.c | |||
@@ -120,25 +120,16 @@ static int get_hbp_len(u16 hbp_len) | |||
120 | } | 120 | } |
121 | 121 | ||
122 | /* | 122 | /* |
123 | * Check for virtual address in user space. | ||
124 | */ | ||
125 | int arch_check_va_in_userspace(unsigned long va, u16 hbp_len) | ||
126 | { | ||
127 | unsigned int len; | ||
128 | |||
129 | len = get_hbp_len(hbp_len); | ||
130 | |||
131 | return (va <= TASK_SIZE - len); | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * Check for virtual address in kernel space. | 123 | * Check for virtual address in kernel space. |
136 | */ | 124 | */ |
137 | static int arch_check_va_in_kernelspace(unsigned long va, u8 hbp_len) | 125 | int arch_check_bp_in_kernelspace(struct perf_event *bp) |
138 | { | 126 | { |
139 | unsigned int len; | 127 | unsigned int len; |
128 | unsigned long va; | ||
129 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | ||
140 | 130 | ||
141 | len = get_hbp_len(hbp_len); | 131 | va = info->address; |
132 | len = get_hbp_len(info->len); | ||
142 | 133 | ||
143 | return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); | 134 | return (va >= TASK_SIZE) && ((va + len - 1) >= TASK_SIZE); |
144 | } | 135 | } |
@@ -226,8 +217,7 @@ static int arch_build_bp_info(struct perf_event *bp) | |||
226 | /* | 217 | /* |
227 | * Validate the arch-specific HW Breakpoint register settings | 218 | * Validate the arch-specific HW Breakpoint register settings |
228 | */ | 219 | */ |
229 | int arch_validate_hwbkpt_settings(struct perf_event *bp, | 220 | int arch_validate_hwbkpt_settings(struct perf_event *bp) |
230 | struct task_struct *tsk) | ||
231 | { | 221 | { |
232 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); | 222 | struct arch_hw_breakpoint *info = counter_arch_bp(bp); |
233 | unsigned int align; | 223 | unsigned int align; |
@@ -270,15 +260,6 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp, | |||
270 | if (info->address & align) | 260 | if (info->address & align) |
271 | return -EINVAL; | 261 | return -EINVAL; |
272 | 262 | ||
273 | /* Check that the virtual address is in the proper range */ | ||
274 | if (tsk) { | ||
275 | if (!arch_check_va_in_userspace(info->address, info->len)) | ||
276 | return -EFAULT; | ||
277 | } else { | ||
278 | if (!arch_check_va_in_kernelspace(info->address, info->len)) | ||
279 | return -EFAULT; | ||
280 | } | ||
281 | |||
282 | return 0; | 263 | return 0; |
283 | } | 264 | } |
284 | 265 | ||
@@ -363,8 +344,7 @@ static int __kprobes hw_breakpoint_handler(struct die_args *args) | |||
363 | perf_bp_event(bp, args->regs); | 344 | perf_bp_event(bp, args->regs); |
364 | 345 | ||
365 | /* Deliver the signal to userspace */ | 346 | /* Deliver the signal to userspace */ |
366 | if (arch_check_va_in_userspace(bp->attr.bp_addr, | 347 | if (!arch_check_bp_in_kernelspace(bp)) { |
367 | bp->attr.bp_len)) { | ||
368 | siginfo_t info; | 348 | siginfo_t info; |
369 | 349 | ||
370 | info.si_signo = args->signr; | 350 | info.si_signo = args->signr; |