diff options
Diffstat (limited to 'kernel/hw_breakpoint.c')
-rw-r--r-- | kernel/hw_breakpoint.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/kernel/hw_breakpoint.c b/kernel/hw_breakpoint.c index 03a0773ac2b2..366eedf949c0 100644 --- a/kernel/hw_breakpoint.c +++ b/kernel/hw_breakpoint.c | |||
@@ -320,18 +320,40 @@ EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); | |||
320 | * @triggered: callback to trigger when we hit the breakpoint | 320 | * @triggered: callback to trigger when we hit the breakpoint |
321 | * @tsk: pointer to 'task_struct' of the process to which the address belongs | 321 | * @tsk: pointer to 'task_struct' of the process to which the address belongs |
322 | */ | 322 | */ |
323 | struct perf_event * | 323 | int modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr) |
324 | modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr) | ||
325 | { | 324 | { |
326 | /* | 325 | u64 old_addr = bp->attr.bp_addr; |
327 | * FIXME: do it without unregistering | 326 | int old_type = bp->attr.bp_type; |
328 | * - We don't want to lose our slot | 327 | int old_len = bp->attr.bp_len; |
329 | * - If the new bp is incorrect, don't lose the older one | 328 | int err = 0; |
330 | */ | 329 | |
331 | unregister_hw_breakpoint(bp); | 330 | perf_event_disable(bp); |
331 | |||
332 | bp->attr.bp_addr = attr->bp_addr; | ||
333 | bp->attr.bp_type = attr->bp_type; | ||
334 | bp->attr.bp_len = attr->bp_len; | ||
335 | |||
336 | if (attr->disabled) | ||
337 | goto end; | ||
332 | 338 | ||
333 | return perf_event_create_kernel_counter(attr, -1, bp->ctx->task->pid, | 339 | err = arch_validate_hwbkpt_settings(bp, bp->ctx->task); |
334 | bp->overflow_handler); | 340 | if (!err) |
341 | perf_event_enable(bp); | ||
342 | |||
343 | if (err) { | ||
344 | bp->attr.bp_addr = old_addr; | ||
345 | bp->attr.bp_type = old_type; | ||
346 | bp->attr.bp_len = old_len; | ||
347 | if (!bp->attr.disabled) | ||
348 | perf_event_enable(bp); | ||
349 | |||
350 | return err; | ||
351 | } | ||
352 | |||
353 | end: | ||
354 | bp->attr.disabled = attr->disabled; | ||
355 | |||
356 | return 0; | ||
335 | } | 357 | } |
336 | EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint); | 358 | EXPORT_SYMBOL_GPL(modify_user_hw_breakpoint); |
337 | 359 | ||