aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/kernel/ptrace.c3
-rw-r--r--arch/powerpc/kernel/ptrace.c2
-rw-r--r--arch/sh/kernel/ptrace_32.c3
-rw-r--r--arch/x86/kernel/kgdb.c2
-rw-r--r--arch/x86/kernel/ptrace.c3
-rw-r--r--drivers/oprofile/oprofile_perf.c2
-rw-r--r--include/linux/hw_breakpoint.h10
-rw-r--r--include/linux/perf_event.h4
-rw-r--r--kernel/events/core.c21
-rw-r--r--kernel/events/hw_breakpoint.c10
-rw-r--r--kernel/watchdog.c2
-rw-r--r--samples/hw_breakpoint/data_breakpoint.c2
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
485static int ptrace_gethbpregs(struct task_struct *tsk, long num, 486static 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)
73extern struct perf_event * 73extern struct perf_event *
74register_user_hw_breakpoint(struct perf_event_attr *attr, 74register_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);
85extern struct perf_event * 86extern struct perf_event *
86register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, 87register_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
90extern struct perf_event * __percpu * 92extern struct perf_event * __percpu *
91register_wide_hw_breakpoint(struct perf_event_attr *attr, 93register_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
94extern int register_perf_hw_breakpoint(struct perf_event *bp); 97extern int register_perf_hw_breakpoint(struct perf_event *bp);
95extern int __register_perf_hw_breakpoint(struct perf_event *bp); 98extern int __register_perf_hw_breakpoint(struct perf_event *bp);
@@ -115,6 +118,7 @@ static inline int __init init_hw_breakpoint(void) { return 0; }
115static inline struct perf_event * 118static inline struct perf_event *
116register_user_hw_breakpoint(struct perf_event_attr *attr, 119register_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; }
119static inline int 123static inline int
120modify_user_hw_breakpoint(struct perf_event *bp, 124modify_user_hw_breakpoint(struct perf_event *bp,
@@ -122,10 +126,12 @@ modify_user_hw_breakpoint(struct perf_event *bp,
122static inline struct perf_event * 126static inline struct perf_event *
123register_wide_hw_breakpoint_cpu(struct perf_event_attr *attr, 127register_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; }
126static inline struct perf_event * __percpu * 131static inline struct perf_event * __percpu *
127register_wide_hw_breakpoint(struct perf_event_attr *attr, 132register_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; }
129static inline int 135static inline int
130register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; } 136register_perf_hw_breakpoint(struct perf_event *bp) { return -ENOSYS; }
131static inline int 137static 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 *
960perf_event_create_kernel_counter(struct perf_event_attr *attr, 961perf_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);
964extern u64 perf_event_read_value(struct perf_event *event, 966extern 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:
6258struct perf_event * 6263struct perf_event *
6259perf_event_create_kernel_counter(struct perf_event_attr *attr, int cpu, 6264perf_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)
431struct perf_event * 431struct perf_event *
432register_user_hw_breakpoint(struct perf_event_attr *attr, 432register_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}
438EXPORT_SYMBOL_GPL(register_user_hw_breakpoint); 440EXPORT_SYMBOL_GPL(register_user_hw_breakpoint);
439 441
@@ -502,7 +504,8 @@ EXPORT_SYMBOL_GPL(unregister_hw_breakpoint);
502 */ 504 */
503struct perf_event * __percpu * 505struct perf_event * __percpu *
504register_wide_hw_breakpoint(struct perf_event_attr *attr, 506register_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;