Implement trace_uprobe_filter_func() and change probe_event_enable() to setup uprobe_consumer->filter() if necessary.
Also change uprobe_dispatcher() to skip the tasks we do not want to probe and return UPROBE_HANDLER_REMOVE to indicate that this "int3" should be removed unless there is another consumer which wants to trace this task. Signed-off-by: Oleg Nesterov <o...@redhat.com> --- kernel/trace/trace_uprobe.c | 48 +++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 48 insertions(+), 0 deletions(-) diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index f7a2dcb..78e918f 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c @@ -112,6 +112,50 @@ static void probes_seq_show_filter(struct trace_uprobe_filter *filter, seq_printf(m, " pid=%d", pid_vnr(filter->tgid)); } +static bool trace_uprobe_filter_current(struct trace_uprobe_filter *filter) +{ + return !filter->tgid || filter->tgid == task_tgid(current); +} + +static bool trace_uprobe_filter_func(struct uprobe_consumer *uc, + enum uprobe_filter_ctx ctx, + struct mm_struct *mm) +{ + struct uprobe_trace_consumer *utc; + struct trace_uprobe_filter *filter; + struct task_struct *p, *t; + bool ret; + + utc = container_of(uc, struct uprobe_trace_consumer, cons); + filter = &utc->tu->filter; + + if (ctx == UPROBE_FILTER_MMAP) + return trace_uprobe_filter_current(filter); + + ret = false; + rcu_read_lock(); + p = pid_task(filter->tgid, PIDTYPE_PID); + if (p) { + t = p; + do { + if (t->mm) { + ret = (t->mm == mm); + break; + } + } while_each_thread(p, t); + } + rcu_read_unlock(); + + return ret; +} + +static inline void set_trace_uprobe_filter_func(struct uprobe_consumer *uc, + struct trace_uprobe_filter *filter) +{ + if (filter->tgid) + uc->filter = trace_uprobe_filter_func; +} + /* * Allocate new trace_uprobe and initialize it (including uprobes). */ @@ -613,6 +657,7 @@ static int probe_event_enable(struct trace_uprobe *tu, int flag) if (!utc) return -EINTR; + set_trace_uprobe_filter_func(&utc->cons, &tu->filter); utc->cons.handler = uprobe_dispatcher; utc->tu = tu; tu->consumer = utc; @@ -784,6 +829,9 @@ static int uprobe_dispatcher(struct uprobe_consumer *con, struct pt_regs *regs) if (!tu || tu->consumer != utc) return 0; + if (!trace_uprobe_filter_current(&tu->filter)) + return UPROBE_HANDLER_REMOVE; + if (tu->flags & TP_FLAG_TRACE) uprobe_trace_func(tu, regs); -- 1.5.5.1 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/