diff options
-rw-r--r-- | arch/arm/kernel/ptrace.c | 3 | ||||
-rw-r--r-- | arch/powerpc/kernel/ptrace.c | 2 | ||||
-rw-r--r-- | arch/sh/kernel/ptrace_32.c | 3 | ||||
-rw-r--r-- | arch/x86/kernel/kgdb.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/ptrace.c | 3 | ||||
-rw-r--r-- | drivers/oprofile/oprofile_perf.c | 2 | ||||
-rw-r--r-- | include/linux/hw_breakpoint.h | 10 | ||||
-rw-r--r-- | include/linux/perf_event.h | 4 | ||||
-rw-r--r-- | kernel/events/core.c | 21 | ||||
-rw-r--r-- | kernel/events/hw_breakpoint.c | 10 | ||||
-rw-r--r-- | kernel/watchdog.c | 2 | ||||
-rw-r--r-- | samples/hw_breakpoint/data_breakpoint.c | 2 |
12 files changed, 44 insertions, 20 deletions
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index 0c9b1054f790..5c199610719f 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c | |||
@@ -479,7 +479,8 @@ static struct perf_event *ptrace_hbp_create(struct task_struct *tsk, int type) | |||
479 | attr.bp_type = type; | 479 | attr.bp_type = type; |
480 | attr.disabled = 1; | 480 | attr.disabled = 1; |
481 | 481 | ||
482 | return register_user_hw_breakpoint(&attr, ptrace_hbptriggered, tsk); | 482 | return register_user_hw_breakpoint(&attr, ptrace_hbptriggered, NULL, |
483 | tsk); | ||
483 | } | 484 | } |
484 | 485 | ||
485 | static int ptrace_gethbpregs(struct task_struct *tsk, long num, | 486 | static int ptrace_gethbpregs(struct task_struct *tsk, long num, |
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index 3177617af2ef..05b7dd217f60 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c | |||
@@ -973,7 +973,7 @@ int ptrace_set_debugreg(struct task_struct *task, unsigned long addr, | |||
973 | &attr.bp_type); | 973 | &attr.bp_type); |
974 | 974 | ||
975 | thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr, | 975 | thread->ptrace_bps[0] = bp = register_user_hw_breakpoint(&attr, |
976 | ptrace_triggered, task); | 976 | ptrace_triggered, NULL, task); |
977 | if (IS_ERR(bp)) { | 977 | if (IS_ERR(bp)) { |
978 | thread->ptrace_bps[0] = NULL; | 978 | thread->ptrace_bps[0] = NULL; |
979 | ptrace_put_breakpoints(task); | 979 | ptrace_put_breakpoints(task); |
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 8051976100a6..92b3c276339a 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c | |||
@@ -91,7 +91,8 @@ static int set_single_step(struct task_struct *tsk, unsigned long addr) | |||
91 | attr.bp_len = HW_BREAKPOINT_LEN_2; | 91 | attr.bp_len = HW_BREAKPOINT_LEN_2; |
92 | attr.bp_type = HW_BREAKPOINT_R; | 92 | attr.bp_type = HW_BREAKPOINT_R; |
93 | 93 | ||
94 | bp = register_user_hw_breakpoint(&attr, ptrace_triggered, tsk); | 94 | bp = register_user_hw_breakpoint(&attr, ptrace_triggered, |
95 | NULL, tsk); | ||
95 | if (IS_ERR(bp)) | 96 | if (IS_ERR(bp)) |
96 | return PTR_ERR(bp); | 97 | return PTR_ERR(bp); |
97 | 98 | ||
diff --git a/arch/x86/kernel/kgdb.c b/arch/x86/kernel/kgdb.c index 98da6a7b5e82..00354d4919a9 100644 --- a/arch/x86/kernel/kgdb.c +++ b/arch/x86/kernel/kgdb.c | |||
@@ -638,7 +638,7 @@ void kgdb_arch_late(void) | |||
638 | for (i = 0; i < HBP_NUM; i++) { | 638 | for (i = 0; i < HBP_NUM; i++) { |
639 | if (breakinfo[i].pev) | 639 | if (breakinfo[i].pev) |
640 | continue; | 640 | continue; |
641 | breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL); | 641 | breakinfo[i].pev = register_wide_hw_breakpoint(&attr, NULL, NULL); |
642 | if (IS_ERR((void * __force)breakinfo[i].pev)) { | 642 | if (IS_ERR((void * __force)breakinfo[i].pev)) { |
643 | printk(KERN_ERR "kgdb: Could not allocate hw" | 643 | printk(KERN_ERR "kgdb: Could not allocate hw" |
644 | "breakpoints\nDisabling the kernel debugger\n"); | 644 | "breakpoints\nDisabling the kernel debugger\n"); |
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c index 11db2e9b860a..82528799c5de 100644 --- a/arch/x86/kernel/ptrace.c +++ b/arch/x86/kernel/ptrace.c | |||
@@ -715,7 +715,8 @@ static int ptrace_set_breakpoint_addr(struct task_struct *tsk, int nr, | |||
715 | attr.bp_type = HW_BREAKPOINT_W; | 715 | attr.bp_type = HW_BREAKPOINT_W; |
716 | attr.disabled = 1; | 716 | attr.disabled = 1; |
717 | 717 | ||
718 | bp = register_user_hw_breakpoint(&attr, ptrace_triggered, tsk); | 718 | bp = register_user_hw_breakpoint(&attr, ptrace_triggered, |
719 | NULL, tsk); | ||
719 | 720 | ||
720 | /* | 721 | /* |
721 | * CHECKME: the previous code returned -EIO if the addr wasn't | 722 | * CHECKME: the previous code returned -EIO if the addr wasn't |
diff --git a/drivers/oprofile/oprofile_perf.c b/drivers/oprofile/oprofile_perf.c index 9046f7b2ed79..59acf9ef78a4 100644 --- a/drivers/oprofile/oprofile_perf.c +++ b/drivers/oprofile/oprofile_perf.c | |||
@@ -79,7 +79,7 @@ static int op_create_counter(int cpu, int event) | |||
79 | 79 | ||
80 | pevent = perf_event_create_kernel_counter(&counter_config[event].attr, | 80 | pevent = perf_event_create_kernel_counter(&counter_config[event].attr, |
81 | cpu, NULL, | 81 | cpu, NULL, |
82 | op_overflow_handler); | 82 | op_overflow_handler, NULL); |
83 | 83 | ||
84 | if (IS_ERR(pevent)) | 84 | if (IS_ERR(pevent)) |
85 | return PTR_ERR(pevent); | 85 | return PTR_ERR(pevent); |
diff --git a/include/linux/hw_breakpoint.h b/include/linux/hw_breakpoint.h index d1e55fed2c7d..6ae9c631a1be 100644 --- a/include/linux/hw_breakpoint.h +++ b/include/linux/hw_breakpoint.h | |||
@@ -73,6 +73,7 @@ static inline unsigned long hw_breakpoint_len(struct perf_event *bp) | |||
73 | extern struct perf_event * | 73 | extern struct perf_event * |
74 | register_user_hw_breakpoint(struct perf_event_attr *attr, | 74 | register_user_hw_breakpoint(struct perf_event_attr *attr, |
75 | perf_overflow_handler_t triggered, | 75 | perf_overflow_handler_t triggered, |
76 | void *context, | ||
76 | struct task_struct *tsk); | 77 | struct task_struct *tsk); |
77 | 78 | ||
78 | /* FIXME: only change from the attr, and don't unregister */ | 79 | /* FIXME: only change from the attr, and don't unregister */ |
@@ -85,11 +86,13 @@ modify_user_hw_breakpoint(struct perf_event *bp, struct perf_event_attr *attr); | |||
85 | extern struct perf_event * | 86 | extern struct perf_event * |
86 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, | 87 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, |
87 | perf_overflow_handler_t triggered, | 88 | perf_overflow_handler_t triggered, |
89 | void *context, | ||
88 | int cpu); | 90 | int cpu); |
89 | 91 | ||
90 | extern struct perf_event * __percpu * | 92 | extern struct perf_event * __percpu * |
91 | register_wide_hw_breakpoint(struct perf_event_attr *attr, | 93 | register_wide_hw_breakpoint(struct perf_event_attr *attr, |
92 | perf_overflow_handler_t triggered); | 94 | perf_overflow_handler_t triggered, |
95 | void *context); | ||
93 | 96 | ||
94 | extern int register_perf_hw_breakpoint(struct perf_event *bp); | 97 | extern int register_perf_hw_breakpoint(struct perf_event *bp); |
95 | extern int __register_perf_hw_breakpoint(struct perf_event *bp); | 98 | extern int __register_perf_hw_breakpoint(struct perf_event *bp); |
@@ -115,6 +118,7 @@ static inline int __init init_hw_breakpoint(void) { return 0; } | |||
115 | static inline struct perf_event * | 118 | static inline struct perf_event * |
116 | register_user_hw_breakpoint(struct perf_event_attr *attr, | 119 | register_user_hw_breakpoint(struct perf_event_attr *attr, |
117 | perf_overflow_handler_t triggered, | 120 | perf_overflow_handler_t triggered, |
121 | void *context, | ||
118 | struct task_struct *tsk) { return NULL; } | 122 | struct task_struct *tsk) { return NULL; } |
119 | static inline int | 123 | static inline int |
120 | modify_user_hw_breakpoint(struct perf_event *bp, | 124 | modify_user_hw_breakpoint(struct perf_event *bp, |
@@ -122,10 +126,12 @@ modify_user_hw_breakpoint(struct perf_event *bp, | |||
122 | static inline struct perf_event * | 126 | static inline struct perf_event * |
123 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, | 127 | register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, |
124 | perf_overflow_handler_t triggered, | 128 | perf_overflow_handler_t triggered, |
129 | void *context, | ||
125 | int cpu) { return NULL; } | 130 | int cpu) { return NULL; } |
126 | static inline struct perf_event * __percpu * | 131 | static inline struct perf_event * __percpu * |
127 | register_wide_hw_breakpoint(struct perf_event_attr *attr, | 132 | register_wide_hw_breakpoint(struct perf_event_attr *attr, |
128 | perf_overflow_handler_t triggered) { return NULL; } | 133 | perf_overflow_handler_t triggered, |
134 | void *context) { return NULL; } | ||
129 | static inline int | 135 | static inline int |
130 | register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } | 136 | register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } |
131 | static inline int | 137 | static inline int |
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index a5f54b973bdb..2a08cacb1628 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -839,6 +839,7 @@ struct perf_event { | |||
839 | u64 id; | 839 | u64 id; |
840 | 840 | ||
841 | perf_overflow_handler_t overflow_handler; | 841 | perf_overflow_handler_t overflow_handler; |
842 | void *overflow_handler_context; | ||
842 | 843 | ||
843 | #ifdef CONFIG_EVENT_TRACING | 844 | #ifdef CONFIG_EVENT_TRACING |
844 | struct ftrace_event_call *tp_event; | 845 | struct ftrace_event_call *tp_event; |
@@ -960,7 +961,8 @@ extern struct perf_event * | |||
960 | perf_event_create_kernel_counter(struct perf_event_attr *attr, | 961 | perf_event_create_kernel_counter(struct perf_event_attr *attr, |
961 | int cpu, | 962 | int cpu, |
962 | struct task_struct *task, | 963 | struct task_struct *task, |
963 | perf_overflow_handler_t callback); | 964 | perf_overflow_handler_t callback, |
965 | void *context); | ||
964 | extern u64 perf_event_read_value(struct perf_event *event, | 966 | extern u64 perf_event_read_value(struct perf_event *event, |
965 | u64 *enabled, u64 *running); | 967 | u64 *enabled, u64 *running); |
966 | 968 | ||
diff --git a/kernel/events/core.c b/kernel/events/core.c index 81de28dcca8c..ba8e0f4a20e6 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -5745,7 +5745,8 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
5745 | struct task_struct *task, | 5745 | struct task_struct *task, |
5746 | struct perf_event *group_leader, | 5746 | struct perf_event *group_leader, |
5747 | struct perf_event *parent_event, | 5747 | struct perf_event *parent_event, |
5748 | perf_overflow_handler_t overflow_handler) | 5748 | perf_overflow_handler_t overflow_handler, |
5749 | void *context) | ||
5749 | { | 5750 | { |
5750 | struct pmu *pmu; | 5751 | struct pmu *pmu; |
5751 | struct perf_event *event; | 5752 | struct perf_event *event; |
@@ -5803,10 +5804,13 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu, | |||
5803 | #endif | 5804 | #endif |
5804 | } | 5805 | } |
5805 | 5806 | ||
5806 | if (!overflow_handler && parent_event) | 5807 | if (!overflow_handler && parent_event) { |
5807 | overflow_handler = parent_event->overflow_handler; | 5808 | overflow_handler = parent_event->overflow_handler; |
5809 | context = parent_event->overflow_handler_context; | ||
5810 | } | ||
5808 | 5811 | ||
5809 | event->overflow_handler = overflow_handler; | 5812 | event->overflow_handler = overflow_handler; |
5813 | event->overflow_handler_context = context; | ||
5810 | 5814 | ||
5811 | if (attr->disabled) | 5815 | if (attr->disabled) |
5812 | event->state = PERF_EVENT_STATE_OFF; | 5816 | event->state = PERF_EVENT_STATE_OFF; |
@@ -6073,7 +6077,8 @@ SYSCALL_DEFINE5(perf_event_open, | |||
6073 | } | 6077 | } |
6074 | } | 6078 | } |
6075 | 6079 | ||
6076 | event = perf_event_alloc(&attr, cpu, task, group_leader, NULL, NULL); | 6080 | event = perf_event_alloc(&attr, cpu, task, group_leader, NULL, |
6081 | NULL, NULL); | ||
6077 | if (IS_ERR(event)) { | 6082 | if (IS_ERR(event)) { |
6078 | err = PTR_ERR(event); | 6083 | err = PTR_ERR(event); |
6079 | goto err_task; | 6084 | goto err_task; |
@@ -6258,7 +6263,8 @@ err_fd: | |||
6258 | struct perf_event * | 6263 | struct perf_event * |
6259 | perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, | 6264 | perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, |
6260 | struct task_struct *task, | 6265 | struct task_struct *task, |
6261 | perf_overflow_handler_t overflow_handler) | 6266 | perf_overflow_handler_t overflow_handler, |
6267 | void *context) | ||
6262 | { | 6268 | { |
6263 | struct perf_event_context *ctx; | 6269 | struct perf_event_context *ctx; |
6264 | struct perf_event *event; | 6270 | struct perf_event *event; |
@@ -6268,7 +6274,8 @@ perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, | |||
6268 | * Get the target context (task or percpu): | 6274 | * Get the target context (task or percpu): |
6269 | */ | 6275 | */ |
6270 | 6276 | ||
6271 | event = perf_event_alloc(attr, cpu, task, NULL, NULL, overflow_handler); | 6277 | event = perf_event_alloc(attr, cpu, task, NULL, NULL, |
6278 | overflow_handler, context); | ||
6272 | if (IS_ERR(event)) { | 6279 | if (IS_ERR(event)) { |
6273 | err = PTR_ERR(event); | 6280 | err = PTR_ERR(event); |
6274 | goto err; | 6281 | goto err; |
@@ -6552,7 +6559,7 @@ inherit_event(struct perf_event *parent_event, | |||
6552 | parent_event->cpu, | 6559 | parent_event->cpu, |
6553 | child, | 6560 | child, |
6554 | group_leader, parent_event, | 6561 | group_leader, parent_event, |
6555 | NULL); | 6562 | NULL, NULL); |
6556 | if (IS_ERR(child_event)) | 6563 | if (IS_ERR(child_event)) |
6557 | return child_event; | 6564 | return child_event; |
6558 | get_ctx(child_ctx); | 6565 | get_ctx(child_ctx); |
@@ -6579,6 +6586,8 @@ inherit_event(struct perf_event *parent_event, | |||
6579 | 6586 | ||
6580 | child_event->ctx = child_ctx; | 6587 | child_event->ctx = child_ctx; |
6581 | child_event->overflow_handler = parent_event->overflow_handler; | 6588 | child_event->overflow_handler = parent_event->overflow_handler; |
6589 | child_event->overflow_handler_context | ||
6590 | = parent_event->overflow_handler_context; | ||
6582 | 6591 | ||
6583 | /* | 6592 | /* |
6584 | * Precalculate sample_data sizes | 6593 | * Precalculate sample_data sizes |
diff --git a/kernel/events/hw_breakpoint.c b/kernel/events/hw_breakpoint.c index 086adf25a55e..b7971d6f38bf 100644 --- a/kernel/events/hw_breakpoint.c +++ b/kernel/events/hw_breakpoint.c | |||
@@ -431,9 +431,11 @@ int register_perf_hw_breakpoint(struct perf_event *bp) | |||
431 | struct perf_event * | 431 | struct perf_event * |
432 | register_user_hw_breakpoint(struct perf_event_attr *attr, | 432 | register_user_hw_breakpoint(struct perf_event_attr *attr, |
433 | perf_overflow_handler_t triggered, | 433 | perf_overflow_handler_t triggered, |
434 | void *context, | ||
434 | struct task_struct *tsk) | 435 | struct task_struct *tsk) |
435 | { | 436 | { |
436 | return perf_event_create_kernel_counter(attr, -1, tsk, triggered); | 437 | return perf_event_create_kernel_counter(attr, -1, tsk, triggered, |
438 | context); | ||
437 | } | 439 | } |
438 | EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); | 440 | EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); |
439 | 441 | ||
@@ -502,7 +504,8 @@ EXPORT_SYMBOL_GPL(unregister_hw_breakpoint); | |||
502 | */ | 504 | */ |
503 | struct perf_event * __percpu * | 505 | struct perf_event * __percpu * |
504 | register_wide_hw_breakpoint(struct perf_event_attr *attr, | 506 | register_wide_hw_breakpoint(struct perf_event_attr *attr, |
505 | perf_overflow_handler_t triggered) | 507 | perf_overflow_handler_t triggered, |
508 | void *context) | ||
506 | { | 509 | { |
507 | struct perf_event * __percpu *cpu_events, **pevent, *bp; | 510 | struct perf_event * __percpu *cpu_events, **pevent, *bp; |
508 | long err; | 511 | long err; |
@@ -515,7 +518,8 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr, | |||
515 | get_online_cpus(); | 518 | get_online_cpus(); |
516 | for_each_online_cpu(cpu) { | 519 | for_each_online_cpu(cpu) { |
517 | pevent = per_cpu_ptr(cpu_events, cpu); | 520 | pevent = per_cpu_ptr(cpu_events, cpu); |
518 | bp = perf_event_create_kernel_counter(attr, cpu, NULL, triggered); | 521 | bp = perf_event_create_kernel_counter(attr, cpu, NULL, |
522 | triggered, context); | ||
519 | 523 | ||
520 | *pevent = bp; | 524 | *pevent = bp; |
521 | 525 | ||
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index a6708e677a0a..a933e3a0398b 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -375,7 +375,7 @@ static int watchdog_nmi_enable(int cpu) | |||
375 | hw_nmi_watchdog_set_attr(wd_attr); | 375 | hw_nmi_watchdog_set_attr(wd_attr); |
376 | 376 | ||
377 | /* Try to register using hardware perf events */ | 377 | /* Try to register using hardware perf events */ |
378 | event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback); | 378 | event = perf_event_create_kernel_counter(wd_attr, cpu, NULL, watchdog_overflow_callback, NULL); |
379 | if (!IS_ERR(event)) { | 379 | if (!IS_ERR(event)) { |
380 | printk(KERN_INFO "NMI watchdog enabled, takes one hw-pmu counter.\n"); | 380 | printk(KERN_INFO "NMI watchdog enabled, takes one hw-pmu counter.\n"); |
381 | goto out_save; | 381 | goto out_save; |
diff --git a/samples/hw_breakpoint/data_breakpoint.c b/samples/hw_breakpoint/data_breakpoint.c index 7b164d3200ff..ef7f32291852 100644 --- a/samples/hw_breakpoint/data_breakpoint.c +++ b/samples/hw_breakpoint/data_breakpoint.c | |||
@@ -60,7 +60,7 @@ static int __init hw_break_module_init(void) | |||
60 | attr.bp_len = HW_BREAKPOINT_LEN_4; | 60 | attr.bp_len = HW_BREAKPOINT_LEN_4; |
61 | attr.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; | 61 | attr.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R; |
62 | 62 | ||
63 | sample_hbp = register_wide_hw_breakpoint(&attr, sample_hbp_handler); | 63 | sample_hbp = register_wide_hw_breakpoint(&attr, sample_hbp_handler, NULL); |
64 | if (IS_ERR((void __force *)sample_hbp)) { | 64 | if (IS_ERR((void __force *)sample_hbp)) { |
65 | ret = PTR_ERR((void __force *)sample_hbp); | 65 | ret = PTR_ERR((void __force *)sample_hbp); |
66 | goto fail; | 66 | goto fail; |