blob: c35bebe53ffe4b56b4e837b0256b68a39405069d [file] [log] [blame]
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001/*
Masami Hiramatsu77b44d12009-11-03 19:12:47 -05002 * Kprobes-based tracing events
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04003 *
4 * Created by Masami Hiramatsu <mhiramat@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include <linux/module.h>
21#include <linux/uaccess.h>
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040022
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +053023#include "trace_probe.h"
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040024
Masami Hiramatsuf52487e2009-09-10 19:53:53 -040025#define KPROBE_EVENT_SYSTEM "kprobes"
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040026
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040027/**
Masami Hiramatsu77b44d12009-11-03 19:12:47 -050028 * Kprobe event core functions
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040029 */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040030struct trace_probe {
31 struct list_head list;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +020032 struct kretprobe rp; /* Use rp.kp for kprobe use */
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -040033 unsigned long nhit;
Masami Hiramatsu50d78052009-09-14 16:49:20 -040034 unsigned int flags; /* For TP_FLAG_* */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040035 const char *symbol; /* symbol name */
Steven Rostedt22392912010-04-21 12:27:06 -040036 struct ftrace_event_class class;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040037 struct ftrace_event_call call;
Masami Hiramatsu3d1fc7b2013-05-13 20:58:37 +090038 struct ftrace_event_file * __rcu *files;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -040039 ssize_t size; /* trace entry size */
Masami Hiramatsua82378d2009-08-13 16:35:18 -040040 unsigned int nr_args;
Masami Hiramatsueca0d912009-09-10 19:53:38 -040041 struct probe_arg args[];
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040042};
43
Masami Hiramatsua82378d2009-08-13 16:35:18 -040044#define SIZEOF_TRACE_PROBE(n) \
45 (offsetof(struct trace_probe, args) + \
Masami Hiramatsueca0d912009-09-10 19:53:38 -040046 (sizeof(struct probe_arg) * (n)))
Masami Hiramatsua82378d2009-08-13 16:35:18 -040047
Masami Hiramatsu93ccae72010-04-12 13:17:08 -040048
Masami Hiramatsudb020382013-05-09 14:44:32 +090049static __kprobes bool trace_probe_is_return(struct trace_probe *tp)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040050{
Masami Hiramatsu4a846b42009-09-11 05:31:21 +020051 return tp->rp.handler != NULL;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040052}
53
Masami Hiramatsu7143f162011-06-27 16:26:36 +090054static __kprobes const char *trace_probe_symbol(struct trace_probe *tp)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040055{
56 return tp->symbol ? tp->symbol : "unknown";
57}
58
Masami Hiramatsu61424312011-06-27 16:26:56 +090059static __kprobes unsigned long trace_probe_offset(struct trace_probe *tp)
60{
61 return tp->rp.kp.offset;
62}
63
64static __kprobes bool trace_probe_is_enabled(struct trace_probe *tp)
65{
66 return !!(tp->flags & (TP_FLAG_TRACE | TP_FLAG_PROFILE));
67}
68
69static __kprobes bool trace_probe_is_registered(struct trace_probe *tp)
70{
71 return !!(tp->flags & TP_FLAG_REGISTERED);
72}
73
74static __kprobes bool trace_probe_has_gone(struct trace_probe *tp)
75{
76 return !!(kprobe_gone(&tp->rp.kp));
77}
78
79static __kprobes bool trace_probe_within_module(struct trace_probe *tp,
80 struct module *mod)
81{
82 int len = strlen(mod->name);
83 const char *name = trace_probe_symbol(tp);
84 return strncmp(mod->name, name, len) == 0 && name[len] == ':';
85}
86
87static __kprobes bool trace_probe_is_on_module(struct trace_probe *tp)
88{
89 return !!strchr(trace_probe_symbol(tp), ':');
90}
91
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040092static int register_probe_event(struct trace_probe *tp);
93static void unregister_probe_event(struct trace_probe *tp);
94
95static DEFINE_MUTEX(probe_lock);
96static LIST_HEAD(probe_list);
97
Masami Hiramatsu50d78052009-09-14 16:49:20 -040098static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs);
99static int kretprobe_dispatcher(struct kretprobe_instance *ri,
100 struct pt_regs *regs);
101
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200102/*
103 * Allocate new trace_probe and initialize it (including kprobes).
104 */
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400105static struct trace_probe *alloc_trace_probe(const char *group,
106 const char *event,
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200107 void *addr,
108 const char *symbol,
109 unsigned long offs,
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530110 int nargs, bool is_return)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400111{
112 struct trace_probe *tp;
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500113 int ret = -ENOMEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400114
Masami Hiramatsua82378d2009-08-13 16:35:18 -0400115 tp = kzalloc(SIZEOF_TRACE_PROBE(nargs), GFP_KERNEL);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400116 if (!tp)
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500117 return ERR_PTR(ret);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400118
119 if (symbol) {
120 tp->symbol = kstrdup(symbol, GFP_KERNEL);
121 if (!tp->symbol)
122 goto error;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200123 tp->rp.kp.symbol_name = tp->symbol;
124 tp->rp.kp.offset = offs;
125 } else
126 tp->rp.kp.addr = addr;
127
128 if (is_return)
Masami Hiramatsu50d78052009-09-14 16:49:20 -0400129 tp->rp.handler = kretprobe_dispatcher;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200130 else
Masami Hiramatsu50d78052009-09-14 16:49:20 -0400131 tp->rp.kp.pre_handler = kprobe_dispatcher;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200132
Masami Hiramatsuda346342010-08-27 20:39:12 +0900133 if (!event || !is_good_name(event)) {
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500134 ret = -EINVAL;
Masami Hiramatsu42635652009-08-13 16:35:26 -0400135 goto error;
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500136 }
137
Steven Rostedt22392912010-04-21 12:27:06 -0400138 tp->call.class = &tp->class;
Masami Hiramatsu42635652009-08-13 16:35:26 -0400139 tp->call.name = kstrdup(event, GFP_KERNEL);
140 if (!tp->call.name)
141 goto error;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400142
Masami Hiramatsuda346342010-08-27 20:39:12 +0900143 if (!group || !is_good_name(group)) {
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500144 ret = -EINVAL;
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400145 goto error;
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500146 }
147
Steven Rostedt22392912010-04-21 12:27:06 -0400148 tp->class.system = kstrdup(group, GFP_KERNEL);
149 if (!tp->class.system)
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400150 goto error;
151
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400152 INIT_LIST_HEAD(&tp->list);
153 return tp;
154error:
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400155 kfree(tp->call.name);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400156 kfree(tp->symbol);
157 kfree(tp);
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500158 return ERR_PTR(ret);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400159}
160
161static void free_trace_probe(struct trace_probe *tp)
162{
163 int i;
164
165 for (i = 0; i < tp->nr_args; i++)
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +0530166 traceprobe_free_probe_arg(&tp->args[i]);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400167
Steven Rostedt8f082012010-04-20 10:47:33 -0400168 kfree(tp->call.class->system);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400169 kfree(tp->call.name);
170 kfree(tp->symbol);
171 kfree(tp);
172}
173
Masami Hiramatsu7143f162011-06-27 16:26:36 +0900174static struct trace_probe *find_trace_probe(const char *event,
Masami Hiramatsudd004c42009-10-27 16:42:44 -0400175 const char *group)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400176{
177 struct trace_probe *tp;
178
179 list_for_each_entry(tp, &probe_list, list)
Masami Hiramatsudd004c42009-10-27 16:42:44 -0400180 if (strcmp(tp->call.name, event) == 0 &&
Steven Rostedt8f082012010-04-20 10:47:33 -0400181 strcmp(tp->call.class->system, group) == 0)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400182 return tp;
183 return NULL;
184}
185
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900186static int trace_probe_nr_files(struct trace_probe *tp)
187{
Masami Hiramatsuc02c7e62013-05-13 20:58:34 +0900188 struct ftrace_event_file **file;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900189 int ret = 0;
190
Masami Hiramatsuc02c7e62013-05-13 20:58:34 +0900191 /*
192 * Since all tp->files updater is protected by probe_enable_lock,
193 * we don't need to lock an rcu_read_lock.
194 */
195 file = rcu_dereference_raw(tp->files);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900196 if (file)
197 while (*(file++))
198 ret++;
199
200 return ret;
201}
202
203static DEFINE_MUTEX(probe_enable_lock);
204
205/*
206 * Enable trace_probe
207 * if the file is NULL, enable "perf" handler, or enable "trace" handler.
208 */
209static int
210enable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file)
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900211{
212 int ret = 0;
213
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900214 mutex_lock(&probe_enable_lock);
215
216 if (file) {
Masami Hiramatsuc02c7e62013-05-13 20:58:34 +0900217 struct ftrace_event_file **new, **old;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900218 int n = trace_probe_nr_files(tp);
219
Masami Hiramatsuc02c7e62013-05-13 20:58:34 +0900220 old = rcu_dereference_raw(tp->files);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900221 /* 1 is for new one and 1 is for stopper */
222 new = kzalloc((n + 2) * sizeof(struct ftrace_event_file *),
223 GFP_KERNEL);
224 if (!new) {
225 ret = -ENOMEM;
226 goto out_unlock;
227 }
228 memcpy(new, old, n * sizeof(struct ftrace_event_file *));
229 new[n] = file;
230 /* The last one keeps a NULL */
231
232 rcu_assign_pointer(tp->files, new);
233 tp->flags |= TP_FLAG_TRACE;
234
235 if (old) {
236 /* Make sure the probe is done with old files */
237 synchronize_sched();
238 kfree(old);
239 }
240 } else
241 tp->flags |= TP_FLAG_PROFILE;
242
zhangwei(Jovi)195a84d2013-06-14 10:10:38 +0800243 if (trace_probe_is_registered(tp) && !trace_probe_has_gone(tp)) {
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900244 if (trace_probe_is_return(tp))
245 ret = enable_kretprobe(&tp->rp);
246 else
247 ret = enable_kprobe(&tp->rp.kp);
248 }
249
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900250 out_unlock:
251 mutex_unlock(&probe_enable_lock);
252
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900253 return ret;
254}
255
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900256static int
257trace_probe_file_index(struct trace_probe *tp, struct ftrace_event_file *file)
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900258{
Masami Hiramatsuc02c7e62013-05-13 20:58:34 +0900259 struct ftrace_event_file **files;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900260 int i;
261
Masami Hiramatsuc02c7e62013-05-13 20:58:34 +0900262 /*
263 * Since all tp->files updater is protected by probe_enable_lock,
264 * we don't need to lock an rcu_read_lock.
265 */
266 files = rcu_dereference_raw(tp->files);
267 if (files) {
268 for (i = 0; files[i]; i++)
269 if (files[i] == file)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900270 return i;
271 }
272
273 return -1;
274}
275
276/*
277 * Disable trace_probe
278 * if the file is NULL, disable "perf" handler, or disable "trace" handler.
279 */
280static int
281disable_trace_probe(struct trace_probe *tp, struct ftrace_event_file *file)
282{
283 int ret = 0;
284
285 mutex_lock(&probe_enable_lock);
286
287 if (file) {
Masami Hiramatsuc02c7e62013-05-13 20:58:34 +0900288 struct ftrace_event_file **new, **old;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900289 int n = trace_probe_nr_files(tp);
290 int i, j;
291
Masami Hiramatsuc02c7e62013-05-13 20:58:34 +0900292 old = rcu_dereference_raw(tp->files);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900293 if (n == 0 || trace_probe_file_index(tp, file) < 0) {
294 ret = -EINVAL;
295 goto out_unlock;
296 }
297
298 if (n == 1) { /* Remove the last file */
299 tp->flags &= ~TP_FLAG_TRACE;
300 new = NULL;
301 } else {
302 new = kzalloc(n * sizeof(struct ftrace_event_file *),
303 GFP_KERNEL);
304 if (!new) {
305 ret = -ENOMEM;
306 goto out_unlock;
307 }
308
309 /* This copy & check loop copies the NULL stopper too */
310 for (i = 0, j = 0; j < n && i < n + 1; i++)
311 if (old[i] != file)
312 new[j++] = old[i];
313 }
314
315 rcu_assign_pointer(tp->files, new);
316
317 /* Make sure the probe is done with old files */
318 synchronize_sched();
319 kfree(old);
320 } else
321 tp->flags &= ~TP_FLAG_PROFILE;
322
Masami Hiramatsu61424312011-06-27 16:26:56 +0900323 if (!trace_probe_is_enabled(tp) && trace_probe_is_registered(tp)) {
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900324 if (trace_probe_is_return(tp))
325 disable_kretprobe(&tp->rp);
326 else
327 disable_kprobe(&tp->rp.kp);
328 }
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900329
330 out_unlock:
331 mutex_unlock(&probe_enable_lock);
332
333 return ret;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900334}
335
Masami Hiramatsu61424312011-06-27 16:26:56 +0900336/* Internal register function - just handle k*probes and flags */
337static int __register_trace_probe(struct trace_probe *tp)
338{
Masami Hiramatsu7f6878a2011-06-27 16:27:03 +0900339 int i, ret;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900340
341 if (trace_probe_is_registered(tp))
342 return -EINVAL;
343
Masami Hiramatsu7f6878a2011-06-27 16:27:03 +0900344 for (i = 0; i < tp->nr_args; i++)
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +0530345 traceprobe_update_arg(&tp->args[i]);
Masami Hiramatsu7f6878a2011-06-27 16:27:03 +0900346
Masami Hiramatsu61424312011-06-27 16:26:56 +0900347 /* Set/clear disabled flag according to tp->flag */
348 if (trace_probe_is_enabled(tp))
349 tp->rp.kp.flags &= ~KPROBE_FLAG_DISABLED;
350 else
351 tp->rp.kp.flags |= KPROBE_FLAG_DISABLED;
352
353 if (trace_probe_is_return(tp))
354 ret = register_kretprobe(&tp->rp);
355 else
356 ret = register_kprobe(&tp->rp.kp);
357
358 if (ret == 0)
359 tp->flags |= TP_FLAG_REGISTERED;
360 else {
361 pr_warning("Could not insert probe at %s+%lu: %d\n",
362 trace_probe_symbol(tp), trace_probe_offset(tp), ret);
363 if (ret == -ENOENT && trace_probe_is_on_module(tp)) {
364 pr_warning("This probe might be able to register after"
365 "target module is loaded. Continue.\n");
366 ret = 0;
367 } else if (ret == -EILSEQ) {
368 pr_warning("Probing address(0x%p) is not an "
369 "instruction boundary.\n",
370 tp->rp.kp.addr);
371 ret = -EINVAL;
372 }
373 }
374
375 return ret;
376}
377
378/* Internal unregister function - just handle k*probes and flags */
379static void __unregister_trace_probe(struct trace_probe *tp)
380{
381 if (trace_probe_is_registered(tp)) {
382 if (trace_probe_is_return(tp))
383 unregister_kretprobe(&tp->rp);
384 else
385 unregister_kprobe(&tp->rp.kp);
386 tp->flags &= ~TP_FLAG_REGISTERED;
387 /* Cleanup kprobe for reuse */
388 if (tp->rp.kp.symbol_name)
389 tp->rp.kp.addr = NULL;
390 }
391}
392
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400393/* Unregister a trace_probe and probe_event: call with locking probe_lock */
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900394static int unregister_trace_probe(struct trace_probe *tp)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400395{
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900396 /* Enabled event can not be unregistered */
397 if (trace_probe_is_enabled(tp))
398 return -EBUSY;
399
Masami Hiramatsu61424312011-06-27 16:26:56 +0900400 __unregister_trace_probe(tp);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400401 list_del(&tp->list);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400402 unregister_probe_event(tp);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900403
404 return 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400405}
406
407/* Register a trace_probe and probe_event */
408static int register_trace_probe(struct trace_probe *tp)
409{
410 struct trace_probe *old_tp;
411 int ret;
412
413 mutex_lock(&probe_lock);
414
Masami Hiramatsu61424312011-06-27 16:26:56 +0900415 /* Delete old (same name) event if exist */
Masami Hiramatsu7143f162011-06-27 16:26:36 +0900416 old_tp = find_trace_probe(tp->call.name, tp->call.class->system);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400417 if (old_tp) {
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900418 ret = unregister_trace_probe(old_tp);
419 if (ret < 0)
420 goto end;
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400421 free_trace_probe(old_tp);
422 }
Masami Hiramatsu61424312011-06-27 16:26:56 +0900423
424 /* Register new event */
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400425 ret = register_probe_event(tp);
426 if (ret) {
Paul Bolle426d3102010-08-07 12:30:03 +0200427 pr_warning("Failed to register probe event(%d)\n", ret);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400428 goto end;
429 }
430
Masami Hiramatsu61424312011-06-27 16:26:56 +0900431 /* Register k*probe */
432 ret = __register_trace_probe(tp);
433 if (ret < 0)
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400434 unregister_probe_event(tp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900435 else
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400436 list_add_tail(&tp->list, &probe_list);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900437
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400438end:
439 mutex_unlock(&probe_lock);
440 return ret;
441}
442
Masami Hiramatsu61424312011-06-27 16:26:56 +0900443/* Module notifier call back, checking event on the module */
444static int trace_probe_module_callback(struct notifier_block *nb,
445 unsigned long val, void *data)
446{
447 struct module *mod = data;
448 struct trace_probe *tp;
449 int ret;
450
451 if (val != MODULE_STATE_COMING)
452 return NOTIFY_DONE;
453
454 /* Update probes on coming module */
455 mutex_lock(&probe_lock);
456 list_for_each_entry(tp, &probe_list, list) {
457 if (trace_probe_within_module(tp, mod)) {
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900458 /* Don't need to check busy - this should have gone. */
Masami Hiramatsu61424312011-06-27 16:26:56 +0900459 __unregister_trace_probe(tp);
460 ret = __register_trace_probe(tp);
461 if (ret)
462 pr_warning("Failed to re-register probe %s on"
463 "%s: %d\n",
464 tp->call.name, mod->name, ret);
465 }
466 }
467 mutex_unlock(&probe_lock);
468
469 return NOTIFY_DONE;
470}
471
472static struct notifier_block trace_probe_module_nb = {
473 .notifier_call = trace_probe_module_callback,
474 .priority = 1 /* Invoked after kprobe module callback */
475};
476
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400477static int create_trace_probe(int argc, char **argv)
478{
479 /*
480 * Argument syntax:
Masami Hiramatsu61424312011-06-27 16:26:56 +0900481 * - Add kprobe: p[:[GRP/]EVENT] [MOD:]KSYM[+OFFS]|KADDR [FETCHARGS]
482 * - Add kretprobe: r[:[GRP/]EVENT] [MOD:]KSYM[+0] [FETCHARGS]
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400483 * Fetch args:
Masami Hiramatsu2e06ff62009-10-07 18:27:59 -0400484 * $retval : fetch return value
485 * $stack : fetch stack address
486 * $stackN : fetch Nth of stack (N:0-)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400487 * @ADDR : fetch memory at ADDR (ADDR should be in kernel)
488 * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol)
489 * %REG : fetch register REG
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400490 * Dereferencing memory fetch:
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400491 * +|-offs(ARG) : fetch memory at ARG +|- offs address.
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400492 * Alias name of args:
493 * NAME=FETCHARG : set NAME as alias of FETCHARG.
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400494 * Type of args:
495 * FETCHARG:TYPE : use TYPE instead of unsigned long.
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400496 */
497 struct trace_probe *tp;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400498 int i, ret = 0;
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530499 bool is_return = false, is_delete = false;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400500 char *symbol = NULL, *event = NULL, *group = NULL;
Masami Hiramatsuda346342010-08-27 20:39:12 +0900501 char *arg;
Masami Hiramatsu2fba0c82009-09-10 19:53:14 -0400502 unsigned long offset = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400503 void *addr = NULL;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200504 char buf[MAX_EVENT_NAME_LEN];
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400505
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500506 /* argc must be >= 1 */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400507 if (argv[0][0] == 'p')
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530508 is_return = false;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400509 else if (argv[0][0] == 'r')
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530510 is_return = true;
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500511 else if (argv[0][0] == '-')
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530512 is_delete = true;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400513 else {
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500514 pr_info("Probe definition must be started with 'p', 'r' or"
515 " '-'.\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400516 return -EINVAL;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400517 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400518
519 if (argv[0][1] == ':') {
520 event = &argv[0][2];
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400521 if (strchr(event, '/')) {
522 group = event;
523 event = strchr(group, '/') + 1;
524 event[-1] = '\0';
525 if (strlen(group) == 0) {
Wenji Huanga5efd922010-02-24 15:40:23 +0800526 pr_info("Group name is not specified\n");
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400527 return -EINVAL;
528 }
529 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400530 if (strlen(event) == 0) {
Wenji Huanga5efd922010-02-24 15:40:23 +0800531 pr_info("Event name is not specified\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400532 return -EINVAL;
533 }
534 }
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500535 if (!group)
536 group = KPROBE_EVENT_SYSTEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400537
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500538 if (is_delete) {
539 if (!event) {
540 pr_info("Delete command needs an event name.\n");
541 return -EINVAL;
542 }
Srikar Dronamraju9da79ab2010-06-30 14:15:48 +0530543 mutex_lock(&probe_lock);
Masami Hiramatsu7143f162011-06-27 16:26:36 +0900544 tp = find_trace_probe(event, group);
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500545 if (!tp) {
Srikar Dronamraju9da79ab2010-06-30 14:15:48 +0530546 mutex_unlock(&probe_lock);
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500547 pr_info("Event %s/%s doesn't exist.\n", group, event);
548 return -ENOENT;
549 }
550 /* delete an event */
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900551 ret = unregister_trace_probe(tp);
552 if (ret == 0)
553 free_trace_probe(tp);
Srikar Dronamraju9da79ab2010-06-30 14:15:48 +0530554 mutex_unlock(&probe_lock);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900555 return ret;
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500556 }
557
558 if (argc < 2) {
559 pr_info("Probe point is not specified.\n");
560 return -EINVAL;
561 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400562 if (isdigit(argv[1][0])) {
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400563 if (is_return) {
564 pr_info("Return probe point must be a symbol.\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400565 return -EINVAL;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400566 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400567 /* an address specified */
Daniel Walterbcd83ea2012-09-26 22:08:38 +0200568 ret = kstrtoul(&argv[1][0], 0, (unsigned long *)&addr);
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400569 if (ret) {
570 pr_info("Failed to parse address.\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400571 return ret;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400572 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400573 } else {
574 /* a symbol specified */
575 symbol = argv[1];
576 /* TODO: support .init module functions */
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +0530577 ret = traceprobe_split_symbol_offset(symbol, &offset);
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400578 if (ret) {
579 pr_info("Failed to parse symbol.\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400580 return ret;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400581 }
582 if (offset && is_return) {
583 pr_info("Return probe must be used without offset.\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400584 return -EINVAL;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400585 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400586 }
Masami Hiramatsua82378d2009-08-13 16:35:18 -0400587 argc -= 2; argv += 2;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400588
589 /* setup a probe */
Masami Hiramatsu42635652009-08-13 16:35:26 -0400590 if (!event) {
591 /* Make a new event name */
Masami Hiramatsu42635652009-08-13 16:35:26 -0400592 if (symbol)
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500593 snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_%ld",
Masami Hiramatsu42635652009-08-13 16:35:26 -0400594 is_return ? 'r' : 'p', symbol, offset);
595 else
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500596 snprintf(buf, MAX_EVENT_NAME_LEN, "%c_0x%p",
Masami Hiramatsu42635652009-08-13 16:35:26 -0400597 is_return ? 'r' : 'p', addr);
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200598 event = buf;
599 }
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400600 tp = alloc_trace_probe(group, event, addr, symbol, offset, argc,
601 is_return);
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400602 if (IS_ERR(tp)) {
603 pr_info("Failed to allocate trace_probe.(%d)\n",
604 (int)PTR_ERR(tp));
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400605 return PTR_ERR(tp);
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400606 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400607
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400608 /* parse arguments */
Masami Hiramatsua82378d2009-08-13 16:35:18 -0400609 ret = 0;
610 for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
Masami Hiramatsu61a52732010-08-27 20:38:46 +0900611 /* Increment count for freeing args in error case */
612 tp->nr_args++;
613
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400614 /* Parse argument name */
615 arg = strchr(argv[i], '=');
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900616 if (arg) {
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400617 *arg++ = '\0';
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900618 tp->args[i].name = kstrdup(argv[i], GFP_KERNEL);
619 } else {
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400620 arg = argv[i];
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900621 /* If argument name is omitted, set "argN" */
622 snprintf(buf, MAX_EVENT_NAME_LEN, "arg%d", i + 1);
623 tp->args[i].name = kstrdup(buf, GFP_KERNEL);
624 }
Masami Hiramatsua703d942009-10-07 18:28:07 -0400625
Masami Hiramatsuba8665d2009-11-30 19:19:20 -0500626 if (!tp->args[i].name) {
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900627 pr_info("Failed to allocate argument[%d] name.\n", i);
Masami Hiramatsuba8665d2009-11-30 19:19:20 -0500628 ret = -ENOMEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400629 goto error;
630 }
Masami Hiramatsuda346342010-08-27 20:39:12 +0900631
632 if (!is_good_name(tp->args[i].name)) {
633 pr_info("Invalid argument[%d] name: %s\n",
634 i, tp->args[i].name);
635 ret = -EINVAL;
636 goto error;
637 }
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400638
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +0530639 if (traceprobe_conflict_field_name(tp->args[i].name,
640 tp->args, i)) {
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900641 pr_info("Argument[%d] name '%s' conflicts with "
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400642 "another field.\n", i, argv[i]);
643 ret = -EINVAL;
644 goto error;
645 }
Masami Hiramatsuba8665d2009-11-30 19:19:20 -0500646
647 /* Parse fetch argument */
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +0530648 ret = traceprobe_parse_probe_arg(arg, &tp->size, &tp->args[i],
Srikar Dronamrajuf3f096c2012-04-11 16:00:43 +0530649 is_return, true);
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400650 if (ret) {
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900651 pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400652 goto error;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400653 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400654 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400655
656 ret = register_trace_probe(tp);
657 if (ret)
658 goto error;
659 return 0;
660
661error:
662 free_trace_probe(tp);
663 return ret;
664}
665
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900666static int release_all_trace_probes(void)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400667{
668 struct trace_probe *tp;
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900669 int ret = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400670
671 mutex_lock(&probe_lock);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900672 /* Ensure no probe is in use. */
673 list_for_each_entry(tp, &probe_list, list)
674 if (trace_probe_is_enabled(tp)) {
675 ret = -EBUSY;
676 goto end;
677 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400678 /* TODO: Use batch unregistration */
679 while (!list_empty(&probe_list)) {
680 tp = list_entry(probe_list.next, struct trace_probe, list);
681 unregister_trace_probe(tp);
682 free_trace_probe(tp);
683 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900684
685end:
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400686 mutex_unlock(&probe_lock);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900687
688 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400689}
690
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400691/* Probes listing interfaces */
692static void *probes_seq_start(struct seq_file *m, loff_t *pos)
693{
694 mutex_lock(&probe_lock);
695 return seq_list_start(&probe_list, *pos);
696}
697
698static void *probes_seq_next(struct seq_file *m, void *v, loff_t *pos)
699{
700 return seq_list_next(v, &probe_list, pos);
701}
702
703static void probes_seq_stop(struct seq_file *m, void *v)
704{
705 mutex_unlock(&probe_lock);
706}
707
708static int probes_seq_show(struct seq_file *m, void *v)
709{
710 struct trace_probe *tp = v;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400711 int i;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400712
Masami Hiramatsu7143f162011-06-27 16:26:36 +0900713 seq_printf(m, "%c", trace_probe_is_return(tp) ? 'r' : 'p');
Steven Rostedt8f082012010-04-20 10:47:33 -0400714 seq_printf(m, ":%s/%s", tp->call.class->system, tp->call.name);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400715
Lai Jiangshan52a11f32009-11-25 16:33:15 +0800716 if (!tp->symbol)
717 seq_printf(m, " 0x%p", tp->rp.kp.addr);
718 else if (tp->rp.kp.offset)
Masami Hiramatsu7143f162011-06-27 16:26:36 +0900719 seq_printf(m, " %s+%u", trace_probe_symbol(tp),
720 tp->rp.kp.offset);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400721 else
Masami Hiramatsu7143f162011-06-27 16:26:36 +0900722 seq_printf(m, " %s", trace_probe_symbol(tp));
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400723
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400724 for (i = 0; i < tp->nr_args; i++)
725 seq_printf(m, " %s=%s", tp->args[i].name, tp->args[i].comm);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400726 seq_printf(m, "\n");
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400727
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400728 return 0;
729}
730
731static const struct seq_operations probes_seq_op = {
732 .start = probes_seq_start,
733 .next = probes_seq_next,
734 .stop = probes_seq_stop,
735 .show = probes_seq_show
736};
737
738static int probes_open(struct inode *inode, struct file *file)
739{
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900740 int ret;
741
742 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
743 ret = release_all_trace_probes();
744 if (ret < 0)
745 return ret;
746 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400747
748 return seq_open(file, &probes_seq_op);
749}
750
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400751static ssize_t probes_write(struct file *file, const char __user *buffer,
752 size_t count, loff_t *ppos)
753{
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +0530754 return traceprobe_probes_write(file, buffer, count, ppos,
755 create_trace_probe);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400756}
757
758static const struct file_operations kprobe_events_ops = {
759 .owner = THIS_MODULE,
760 .open = probes_open,
761 .read = seq_read,
762 .llseek = seq_lseek,
763 .release = seq_release,
764 .write = probes_write,
765};
766
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400767/* Probes profiling interfaces */
768static int probes_profile_seq_show(struct seq_file *m, void *v)
769{
770 struct trace_probe *tp = v;
771
772 seq_printf(m, " %-44s %15lu %15lu\n", tp->call.name, tp->nhit,
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200773 tp->rp.kp.nmissed);
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400774
775 return 0;
776}
777
778static const struct seq_operations profile_seq_op = {
779 .start = probes_seq_start,
780 .next = probes_seq_next,
781 .stop = probes_seq_stop,
782 .show = probes_profile_seq_show
783};
784
785static int profile_open(struct inode *inode, struct file *file)
786{
787 return seq_open(file, &profile_seq_op);
788}
789
790static const struct file_operations kprobe_profile_ops = {
791 .owner = THIS_MODULE,
792 .open = profile_open,
793 .read = seq_read,
794 .llseek = seq_lseek,
795 .release = seq_release,
796};
797
Masami Hiramatsue09c8612010-07-05 15:54:45 -0300798/* Sum up total data length for dynamic arraies (strings) */
799static __kprobes int __get_data_size(struct trace_probe *tp,
800 struct pt_regs *regs)
801{
802 int i, ret = 0;
803 u32 len;
804
805 for (i = 0; i < tp->nr_args; i++)
806 if (unlikely(tp->args[i].fetch_size.fn)) {
807 call_fetch(&tp->args[i].fetch_size, regs, &len);
808 ret += len;
809 }
810
811 return ret;
812}
813
814/* Store the value of each argument */
815static __kprobes void store_trace_args(int ent_size, struct trace_probe *tp,
816 struct pt_regs *regs,
817 u8 *data, int maxlen)
818{
819 int i;
820 u32 end = tp->size;
821 u32 *dl; /* Data (relative) location */
822
823 for (i = 0; i < tp->nr_args; i++) {
824 if (unlikely(tp->args[i].fetch_size.fn)) {
825 /*
826 * First, we set the relative location and
827 * maximum data length to *dl
828 */
829 dl = (u32 *)(data + tp->args[i].offset);
830 *dl = make_data_rloc(maxlen, end - tp->args[i].offset);
831 /* Then try to fetch string or dynamic array data */
832 call_fetch(&tp->args[i].fetch, regs, dl);
833 /* Reduce maximum length */
834 end += get_rloc_len(*dl);
835 maxlen -= get_rloc_len(*dl);
836 /* Trick here, convert data_rloc to data_loc */
837 *dl = convert_rloc_to_loc(*dl,
838 ent_size + tp->args[i].offset);
839 } else
840 /* Just fetching data normally */
841 call_fetch(&tp->args[i].fetch, regs,
842 data + tp->args[i].offset);
843 }
844}
845
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400846/* Kprobe handler */
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +0900847static __kprobes void
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900848__kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs,
849 struct ftrace_event_file *ftrace_file)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400850{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400851 struct kprobe_trace_entry_head *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400852 struct ring_buffer_event *event;
Frederic Weisbecker8f8ffe22009-09-11 01:09:23 +0200853 struct ring_buffer *buffer;
Masami Hiramatsue09c8612010-07-05 15:54:45 -0300854 int size, dsize, pc;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400855 unsigned long irq_flags;
Masami Hiramatsu42635652009-08-13 16:35:26 -0400856 struct ftrace_event_call *call = &tp->call;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400857
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900858 WARN_ON(call != ftrace_file->event_call);
859
Masami Hiramatsub8820082013-05-09 14:44:54 +0900860 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
861 return;
862
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400863 local_save_flags(irq_flags);
864 pc = preempt_count();
865
Masami Hiramatsue09c8612010-07-05 15:54:45 -0300866 dsize = __get_data_size(tp, regs);
867 size = sizeof(*entry) + tp->size + dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400868
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900869 event = trace_event_buffer_lock_reserve(&buffer, ftrace_file,
870 call->event.type,
871 size, irq_flags, pc);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400872 if (!event)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +0800873 return;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400874
875 entry = ring_buffer_event_data(event);
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +0900876 entry->ip = (unsigned long)tp->rp.kp.addr;
Masami Hiramatsue09c8612010-07-05 15:54:45 -0300877 store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400878
Frederic Weisbecker8f8ffe22009-09-11 01:09:23 +0200879 if (!filter_current_check_discard(buffer, call, entry, event))
Steven Rostedt0d5c6e12012-11-01 20:54:21 -0400880 trace_buffer_unlock_commit_regs(buffer, event,
881 irq_flags, pc, regs);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400882}
883
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900884static __kprobes void
885kprobe_trace_func(struct trace_probe *tp, struct pt_regs *regs)
886{
Masami Hiramatsuc02c7e62013-05-13 20:58:34 +0900887 /*
888 * Note: preempt is already disabled around the kprobe handler.
889 * However, we still need an smp_read_barrier_depends() corresponding
890 * to smp_wmb() in rcu_assign_pointer() to access the pointer.
891 */
892 struct ftrace_event_file **file = rcu_dereference_raw(tp->files);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900893
Masami Hiramatsuc02c7e62013-05-13 20:58:34 +0900894 if (unlikely(!file))
895 return;
896
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900897 while (*file) {
898 __kprobe_trace_func(tp, regs, *file);
899 file++;
900 }
901}
902
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400903/* Kretprobe handler */
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +0900904static __kprobes void
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900905__kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri,
906 struct pt_regs *regs,
907 struct ftrace_event_file *ftrace_file)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400908{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400909 struct kretprobe_trace_entry_head *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400910 struct ring_buffer_event *event;
Frederic Weisbecker8f8ffe22009-09-11 01:09:23 +0200911 struct ring_buffer *buffer;
Masami Hiramatsue09c8612010-07-05 15:54:45 -0300912 int size, pc, dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400913 unsigned long irq_flags;
Masami Hiramatsu42635652009-08-13 16:35:26 -0400914 struct ftrace_event_call *call = &tp->call;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400915
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900916 WARN_ON(call != ftrace_file->event_call);
917
Masami Hiramatsub8820082013-05-09 14:44:54 +0900918 if (test_bit(FTRACE_EVENT_FL_SOFT_DISABLED_BIT, &ftrace_file->flags))
919 return;
920
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400921 local_save_flags(irq_flags);
922 pc = preempt_count();
923
Masami Hiramatsue09c8612010-07-05 15:54:45 -0300924 dsize = __get_data_size(tp, regs);
925 size = sizeof(*entry) + tp->size + dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400926
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900927 event = trace_event_buffer_lock_reserve(&buffer, ftrace_file,
928 call->event.type,
929 size, irq_flags, pc);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400930 if (!event)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +0800931 return;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400932
933 entry = ring_buffer_event_data(event);
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200934 entry->func = (unsigned long)tp->rp.kp.addr;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400935 entry->ret_ip = (unsigned long)ri->ret_addr;
Masami Hiramatsue09c8612010-07-05 15:54:45 -0300936 store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400937
Frederic Weisbecker8f8ffe22009-09-11 01:09:23 +0200938 if (!filter_current_check_discard(buffer, call, entry, event))
Steven Rostedt0d5c6e12012-11-01 20:54:21 -0400939 trace_buffer_unlock_commit_regs(buffer, event,
940 irq_flags, pc, regs);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400941}
942
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900943static __kprobes void
944kretprobe_trace_func(struct trace_probe *tp, struct kretprobe_instance *ri,
945 struct pt_regs *regs)
946{
Masami Hiramatsuc02c7e62013-05-13 20:58:34 +0900947 /*
948 * Note: preempt is already disabled around the kprobe handler.
949 * However, we still need an smp_read_barrier_depends() corresponding
950 * to smp_wmb() in rcu_assign_pointer() to access the pointer.
951 */
952 struct ftrace_event_file **file = rcu_dereference_raw(tp->files);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900953
Masami Hiramatsuc02c7e62013-05-13 20:58:34 +0900954 if (unlikely(!file))
955 return;
956
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900957 while (*file) {
958 __kretprobe_trace_func(tp, ri, regs, *file);
959 file++;
960 }
961}
962
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400963/* Event entry printers */
Masami Hiramatsub62fdd92013-05-13 20:58:39 +0900964static enum print_line_t
Steven Rostedta9a57762010-04-22 18:46:14 -0400965print_kprobe_event(struct trace_iterator *iter, int flags,
966 struct trace_event *event)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400967{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400968 struct kprobe_trace_entry_head *field;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400969 struct trace_seq *s = &iter->seq;
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400970 struct trace_probe *tp;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400971 u8 *data;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400972 int i;
973
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400974 field = (struct kprobe_trace_entry_head *)iter->ent;
Steven Rostedt80decc72010-04-23 10:00:22 -0400975 tp = container_of(event, struct trace_probe, call.event);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400976
Masami Hiramatsu6e9f23d2009-09-10 19:53:45 -0400977 if (!trace_seq_printf(s, "%s: (", tp->call.name))
978 goto partial;
979
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400980 if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET))
981 goto partial;
982
Masami Hiramatsu6e9f23d2009-09-10 19:53:45 -0400983 if (!trace_seq_puts(s, ")"))
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400984 goto partial;
985
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400986 data = (u8 *)&field[1];
987 for (i = 0; i < tp->nr_args; i++)
988 if (!tp->args[i].type->print(s, tp->args[i].name,
Masami Hiramatsue09c8612010-07-05 15:54:45 -0300989 data + tp->args[i].offset, field))
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400990 goto partial;
991
992 if (!trace_seq_puts(s, "\n"))
993 goto partial;
994
995 return TRACE_TYPE_HANDLED;
996partial:
997 return TRACE_TYPE_PARTIAL_LINE;
998}
999
Masami Hiramatsub62fdd92013-05-13 20:58:39 +09001000static enum print_line_t
Steven Rostedta9a57762010-04-22 18:46:14 -04001001print_kretprobe_event(struct trace_iterator *iter, int flags,
1002 struct trace_event *event)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001003{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001004 struct kretprobe_trace_entry_head *field;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001005 struct trace_seq *s = &iter->seq;
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001006 struct trace_probe *tp;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001007 u8 *data;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001008 int i;
1009
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001010 field = (struct kretprobe_trace_entry_head *)iter->ent;
Steven Rostedt80decc72010-04-23 10:00:22 -04001011 tp = container_of(event, struct trace_probe, call.event);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001012
Masami Hiramatsu6e9f23d2009-09-10 19:53:45 -04001013 if (!trace_seq_printf(s, "%s: (", tp->call.name))
1014 goto partial;
1015
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001016 if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET))
1017 goto partial;
1018
1019 if (!trace_seq_puts(s, " <- "))
1020 goto partial;
1021
1022 if (!seq_print_ip_sym(s, field->func, flags & ~TRACE_ITER_SYM_OFFSET))
1023 goto partial;
1024
Masami Hiramatsu6e9f23d2009-09-10 19:53:45 -04001025 if (!trace_seq_puts(s, ")"))
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001026 goto partial;
1027
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001028 data = (u8 *)&field[1];
1029 for (i = 0; i < tp->nr_args; i++)
1030 if (!tp->args[i].type->print(s, tp->args[i].name,
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001031 data + tp->args[i].offset, field))
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001032 goto partial;
1033
1034 if (!trace_seq_puts(s, "\n"))
1035 goto partial;
1036
1037 return TRACE_TYPE_HANDLED;
1038partial:
1039 return TRACE_TYPE_PARTIAL_LINE;
1040}
1041
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001042
1043static int kprobe_event_define_fields(struct ftrace_event_call *event_call)
1044{
1045 int ret, i;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001046 struct kprobe_trace_entry_head field;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001047 struct trace_probe *tp = (struct trace_probe *)event_call->data;
1048
Masami Hiramatsua703d942009-10-07 18:28:07 -04001049 DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001050 /* Set argument names as fields */
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001051 for (i = 0; i < tp->nr_args; i++) {
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001052 ret = trace_define_field(event_call, tp->args[i].type->fmttype,
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001053 tp->args[i].name,
1054 sizeof(field) + tp->args[i].offset,
1055 tp->args[i].type->size,
1056 tp->args[i].type->is_signed,
1057 FILTER_OTHER);
1058 if (ret)
1059 return ret;
1060 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001061 return 0;
1062}
1063
1064static int kretprobe_event_define_fields(struct ftrace_event_call *event_call)
1065{
1066 int ret, i;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001067 struct kretprobe_trace_entry_head field;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001068 struct trace_probe *tp = (struct trace_probe *)event_call->data;
1069
Masami Hiramatsua703d942009-10-07 18:28:07 -04001070 DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0);
1071 DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0);
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001072 /* Set argument names as fields */
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001073 for (i = 0; i < tp->nr_args; i++) {
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001074 ret = trace_define_field(event_call, tp->args[i].type->fmttype,
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001075 tp->args[i].name,
1076 sizeof(field) + tp->args[i].offset,
1077 tp->args[i].type->size,
1078 tp->args[i].type->is_signed,
1079 FILTER_OTHER);
1080 if (ret)
1081 return ret;
1082 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001083 return 0;
1084}
1085
Lai Jiangshana342a0282009-12-15 15:39:49 +08001086static int __set_print_fmt(struct trace_probe *tp, char *buf, int len)
1087{
1088 int i;
1089 int pos = 0;
1090
1091 const char *fmt, *arg;
1092
Masami Hiramatsu7143f162011-06-27 16:26:36 +09001093 if (!trace_probe_is_return(tp)) {
Lai Jiangshana342a0282009-12-15 15:39:49 +08001094 fmt = "(%lx)";
1095 arg = "REC->" FIELD_STRING_IP;
1096 } else {
1097 fmt = "(%lx <- %lx)";
1098 arg = "REC->" FIELD_STRING_FUNC ", REC->" FIELD_STRING_RETIP;
1099 }
1100
1101 /* When len=0, we just calculate the needed length */
1102#define LEN_OR_ZERO (len ? len - pos : 0)
1103
1104 pos += snprintf(buf + pos, LEN_OR_ZERO, "\"%s", fmt);
1105
1106 for (i = 0; i < tp->nr_args; i++) {
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001107 pos += snprintf(buf + pos, LEN_OR_ZERO, " %s=%s",
1108 tp->args[i].name, tp->args[i].type->fmt);
Lai Jiangshana342a0282009-12-15 15:39:49 +08001109 }
1110
1111 pos += snprintf(buf + pos, LEN_OR_ZERO, "\", %s", arg);
1112
1113 for (i = 0; i < tp->nr_args; i++) {
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001114 if (strcmp(tp->args[i].type->name, "string") == 0)
1115 pos += snprintf(buf + pos, LEN_OR_ZERO,
1116 ", __get_str(%s)",
1117 tp->args[i].name);
1118 else
1119 pos += snprintf(buf + pos, LEN_OR_ZERO, ", REC->%s",
1120 tp->args[i].name);
Lai Jiangshana342a0282009-12-15 15:39:49 +08001121 }
1122
1123#undef LEN_OR_ZERO
1124
1125 /* return the length of print_fmt */
1126 return pos;
1127}
1128
1129static int set_print_fmt(struct trace_probe *tp)
1130{
1131 int len;
1132 char *print_fmt;
1133
1134 /* First: called with 0 length to calculate the needed length */
1135 len = __set_print_fmt(tp, NULL, 0);
1136 print_fmt = kmalloc(len + 1, GFP_KERNEL);
1137 if (!print_fmt)
1138 return -ENOMEM;
1139
1140 /* Second: actually write the @print_fmt */
1141 __set_print_fmt(tp, print_fmt, len + 1);
1142 tp->call.print_fmt = print_fmt;
1143
1144 return 0;
1145}
1146
Li Zefan07b139c2009-12-21 14:27:35 +08001147#ifdef CONFIG_PERF_EVENTS
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001148
1149/* Kprobe profile handler */
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001150static __kprobes void
1151kprobe_perf_func(struct trace_probe *tp, struct pt_regs *regs)
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001152{
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001153 struct ftrace_event_call *call = &tp->call;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001154 struct kprobe_trace_entry_head *entry;
Peter Zijlstra1c024eca2010-05-19 14:02:22 +02001155 struct hlist_head *head;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001156 int size, __size, dsize;
Peter Zijlstra4ed7c922009-11-23 11:37:29 +01001157 int rctx;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001158
Oleg Nesterov288e9842013-06-20 19:38:06 +02001159 head = this_cpu_ptr(call->perf_events);
1160 if (hlist_empty(head))
1161 return;
1162
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001163 dsize = __get_data_size(tp, regs);
1164 __size = sizeof(*entry) + tp->size + dsize;
Masami Hiramatsu74ebb632009-09-14 16:49:28 -04001165 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1166 size -= sizeof(u32);
Frederic Weisbecker97d5a222010-03-05 05:35:37 +01001167 if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
Masami Hiramatsua1a138d2009-09-25 11:20:12 -07001168 "profile buffer not large enough"))
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001169 return;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001170
Steven Rostedtff5f1492010-05-21 11:49:57 -04001171 entry = perf_trace_buf_prepare(size, call->event.type, regs, &rctx);
Xiao Guangrong430ad5a2010-01-28 09:32:29 +08001172 if (!entry)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001173 return;
Frederic Weisbeckerce71b9d2009-11-22 05:26:55 +01001174
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001175 entry->ip = (unsigned long)tp->rp.kp.addr;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001176 memset(&entry[1], 0, dsize);
1177 store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
Andrew Vagine6dab5f2012-07-11 18:14:58 +04001178 perf_trace_buf_submit(entry, size, rctx,
1179 entry->ip, 1, regs, head, NULL);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001180}
1181
1182/* Kretprobe profile handler */
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001183static __kprobes void
1184kretprobe_perf_func(struct trace_probe *tp, struct kretprobe_instance *ri,
1185 struct pt_regs *regs)
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001186{
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001187 struct ftrace_event_call *call = &tp->call;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001188 struct kretprobe_trace_entry_head *entry;
Peter Zijlstra1c024eca2010-05-19 14:02:22 +02001189 struct hlist_head *head;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001190 int size, __size, dsize;
Peter Zijlstra4ed7c922009-11-23 11:37:29 +01001191 int rctx;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001192
Oleg Nesterov288e9842013-06-20 19:38:06 +02001193 head = this_cpu_ptr(call->perf_events);
1194 if (hlist_empty(head))
1195 return;
1196
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001197 dsize = __get_data_size(tp, regs);
1198 __size = sizeof(*entry) + tp->size + dsize;
Masami Hiramatsu74ebb632009-09-14 16:49:28 -04001199 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1200 size -= sizeof(u32);
Frederic Weisbecker97d5a222010-03-05 05:35:37 +01001201 if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
Masami Hiramatsua1a138d2009-09-25 11:20:12 -07001202 "profile buffer not large enough"))
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001203 return;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001204
Steven Rostedtff5f1492010-05-21 11:49:57 -04001205 entry = perf_trace_buf_prepare(size, call->event.type, regs, &rctx);
Xiao Guangrong430ad5a2010-01-28 09:32:29 +08001206 if (!entry)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001207 return;
Frederic Weisbeckerce71b9d2009-11-22 05:26:55 +01001208
Masami Hiramatsua1a138d2009-09-25 11:20:12 -07001209 entry->func = (unsigned long)tp->rp.kp.addr;
1210 entry->ret_ip = (unsigned long)ri->ret_addr;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001211 store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
Andrew Vagine6dab5f2012-07-11 18:14:58 +04001212 perf_trace_buf_submit(entry, size, rctx,
1213 entry->ret_ip, 1, regs, head, NULL);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001214}
Li Zefan07b139c2009-12-21 14:27:35 +08001215#endif /* CONFIG_PERF_EVENTS */
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001216
Steven Rostedt22392912010-04-21 12:27:06 -04001217static __kprobes
Jiri Olsaceec0b62012-02-15 15:51:49 +01001218int kprobe_register(struct ftrace_event_call *event,
1219 enum trace_reg type, void *data)
Steven Rostedt22392912010-04-21 12:27:06 -04001220{
Masami Hiramatsu1538f882011-06-27 16:26:44 +09001221 struct trace_probe *tp = (struct trace_probe *)event->data;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001222 struct ftrace_event_file *file = data;
Masami Hiramatsu1538f882011-06-27 16:26:44 +09001223
Steven Rostedt22392912010-04-21 12:27:06 -04001224 switch (type) {
1225 case TRACE_REG_REGISTER:
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001226 return enable_trace_probe(tp, file);
Steven Rostedt22392912010-04-21 12:27:06 -04001227 case TRACE_REG_UNREGISTER:
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001228 return disable_trace_probe(tp, file);
Steven Rostedt22392912010-04-21 12:27:06 -04001229
1230#ifdef CONFIG_PERF_EVENTS
1231 case TRACE_REG_PERF_REGISTER:
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001232 return enable_trace_probe(tp, NULL);
Steven Rostedt22392912010-04-21 12:27:06 -04001233 case TRACE_REG_PERF_UNREGISTER:
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001234 return disable_trace_probe(tp, NULL);
Jiri Olsaceec0b62012-02-15 15:51:49 +01001235 case TRACE_REG_PERF_OPEN:
1236 case TRACE_REG_PERF_CLOSE:
Jiri Olsa489c75c2012-02-15 15:51:50 +01001237 case TRACE_REG_PERF_ADD:
1238 case TRACE_REG_PERF_DEL:
Jiri Olsaceec0b62012-02-15 15:51:49 +01001239 return 0;
Steven Rostedt22392912010-04-21 12:27:06 -04001240#endif
1241 }
1242 return 0;
1243}
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001244
1245static __kprobes
1246int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs)
1247{
1248 struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp);
1249
Masami Hiramatsu48182bd2013-05-09 14:44:36 +09001250 tp->nhit++;
1251
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001252 if (tp->flags & TP_FLAG_TRACE)
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001253 kprobe_trace_func(tp, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001254#ifdef CONFIG_PERF_EVENTS
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001255 if (tp->flags & TP_FLAG_PROFILE)
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001256 kprobe_perf_func(tp, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001257#endif
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001258 return 0; /* We don't tweek kernel, so just return 0 */
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001259}
1260
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001261static __kprobes
1262int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs)
1263{
1264 struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp);
1265
Masami Hiramatsu48182bd2013-05-09 14:44:36 +09001266 tp->nhit++;
1267
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001268 if (tp->flags & TP_FLAG_TRACE)
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001269 kretprobe_trace_func(tp, ri, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001270#ifdef CONFIG_PERF_EVENTS
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001271 if (tp->flags & TP_FLAG_PROFILE)
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001272 kretprobe_perf_func(tp, ri, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001273#endif
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001274 return 0; /* We don't tweek kernel, so just return 0 */
1275}
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001276
Steven Rostedta9a57762010-04-22 18:46:14 -04001277static struct trace_event_functions kretprobe_funcs = {
1278 .trace = print_kretprobe_event
1279};
1280
1281static struct trace_event_functions kprobe_funcs = {
1282 .trace = print_kprobe_event
1283};
1284
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001285static int register_probe_event(struct trace_probe *tp)
1286{
1287 struct ftrace_event_call *call = &tp->call;
1288 int ret;
1289
1290 /* Initialize ftrace_event_call */
Li Zefanffb9f992010-05-24 16:24:52 +08001291 INIT_LIST_HEAD(&call->class->fields);
Masami Hiramatsu7143f162011-06-27 16:26:36 +09001292 if (trace_probe_is_return(tp)) {
Steven Rostedt80decc72010-04-23 10:00:22 -04001293 call->event.funcs = &kretprobe_funcs;
Steven Rostedt2e33af02010-04-22 10:35:55 -04001294 call->class->define_fields = kretprobe_event_define_fields;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001295 } else {
Steven Rostedt80decc72010-04-23 10:00:22 -04001296 call->event.funcs = &kprobe_funcs;
Steven Rostedt2e33af02010-04-22 10:35:55 -04001297 call->class->define_fields = kprobe_event_define_fields;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001298 }
Lai Jiangshana342a0282009-12-15 15:39:49 +08001299 if (set_print_fmt(tp) < 0)
1300 return -ENOMEM;
Steven Rostedt32c0eda2010-04-23 10:38:03 -04001301 ret = register_ftrace_event(&call->event);
1302 if (!ret) {
Lai Jiangshana342a0282009-12-15 15:39:49 +08001303 kfree(call->print_fmt);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001304 return -ENODEV;
Lai Jiangshana342a0282009-12-15 15:39:49 +08001305 }
Steven Rostedt553552c2010-04-23 11:12:36 -04001306 call->flags = 0;
Steven Rostedt22392912010-04-21 12:27:06 -04001307 call->class->reg = kprobe_register;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001308 call->data = tp;
1309 ret = trace_add_event_call(call);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001310 if (ret) {
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001311 pr_info("Failed to register kprobe event: %s\n", call->name);
Lai Jiangshana342a0282009-12-15 15:39:49 +08001312 kfree(call->print_fmt);
Steven Rostedt80decc72010-04-23 10:00:22 -04001313 unregister_ftrace_event(&call->event);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001314 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001315 return ret;
1316}
1317
1318static void unregister_probe_event(struct trace_probe *tp)
1319{
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001320 /* tp->event is unregistered in trace_remove_event_call() */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001321 trace_remove_event_call(&tp->call);
Lai Jiangshana342a0282009-12-15 15:39:49 +08001322 kfree(tp->call.print_fmt);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001323}
1324
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001325/* Make a debugfs interface for controlling probe points */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001326static __init int init_kprobe_trace(void)
1327{
1328 struct dentry *d_tracer;
1329 struct dentry *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001330
Masami Hiramatsu61424312011-06-27 16:26:56 +09001331 if (register_module_notifier(&trace_probe_module_nb))
1332 return -EINVAL;
1333
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001334 d_tracer = tracing_init_dentry();
1335 if (!d_tracer)
1336 return 0;
1337
1338 entry = debugfs_create_file("kprobe_events", 0644, d_tracer,
1339 NULL, &kprobe_events_ops);
1340
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001341 /* Event list interface */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001342 if (!entry)
1343 pr_warning("Could not create debugfs "
1344 "'kprobe_events' entry\n");
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001345
1346 /* Profile interface */
1347 entry = debugfs_create_file("kprobe_profile", 0444, d_tracer,
1348 NULL, &kprobe_profile_ops);
1349
1350 if (!entry)
1351 pr_warning("Could not create debugfs "
1352 "'kprobe_profile' entry\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001353 return 0;
1354}
1355fs_initcall(init_kprobe_trace);
1356
1357
1358#ifdef CONFIG_FTRACE_STARTUP_TEST
1359
Steven Rostedt265a5b72011-06-06 22:35:13 -04001360/*
1361 * The "__used" keeps gcc from removing the function symbol
1362 * from the kallsyms table.
1363 */
1364static __used int kprobe_trace_selftest_target(int a1, int a2, int a3,
1365 int a4, int a5, int a6)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001366{
1367 return a1 + a2 + a3 + a4 + a5 + a6;
1368}
1369
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001370static struct ftrace_event_file *
1371find_trace_probe_file(struct trace_probe *tp, struct trace_array *tr)
1372{
1373 struct ftrace_event_file *file;
1374
1375 list_for_each_entry(file, &tr->events, list)
1376 if (file->event_call == &tp->call)
1377 return file;
1378
1379 return NULL;
1380}
1381
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001382static __init int kprobe_trace_self_tests_init(void)
1383{
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001384 int ret, warn = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001385 int (*target)(int, int, int, int, int, int);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001386 struct trace_probe *tp;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001387 struct ftrace_event_file *file;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001388
1389 target = kprobe_trace_selftest_target;
1390
1391 pr_info("Testing kprobe tracing: ");
1392
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +05301393 ret = traceprobe_command("p:testprobe kprobe_trace_selftest_target "
1394 "$stack $stack0 +0($stack)",
1395 create_trace_probe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001396 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001397 pr_warn("error on probing function entry.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001398 warn++;
1399 } else {
1400 /* Enable trace point */
Masami Hiramatsu7143f162011-06-27 16:26:36 +09001401 tp = find_trace_probe("testprobe", KPROBE_EVENT_SYSTEM);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001402 if (WARN_ON_ONCE(tp == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001403 pr_warn("error on getting new probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001404 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001405 } else {
1406 file = find_trace_probe_file(tp, top_trace_array());
1407 if (WARN_ON_ONCE(file == NULL)) {
1408 pr_warn("error on getting probe file.\n");
1409 warn++;
1410 } else
1411 enable_trace_probe(tp, file);
1412 }
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001413 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001414
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +05301415 ret = traceprobe_command("r:testprobe2 kprobe_trace_selftest_target "
1416 "$retval", create_trace_probe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001417 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001418 pr_warn("error on probing function return.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001419 warn++;
1420 } else {
1421 /* Enable trace point */
Masami Hiramatsu7143f162011-06-27 16:26:36 +09001422 tp = find_trace_probe("testprobe2", KPROBE_EVENT_SYSTEM);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001423 if (WARN_ON_ONCE(tp == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001424 pr_warn("error on getting 2nd new probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001425 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001426 } else {
1427 file = find_trace_probe_file(tp, top_trace_array());
1428 if (WARN_ON_ONCE(file == NULL)) {
1429 pr_warn("error on getting probe file.\n");
1430 warn++;
1431 } else
1432 enable_trace_probe(tp, file);
1433 }
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001434 }
1435
1436 if (warn)
1437 goto end;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001438
1439 ret = target(1, 2, 3, 4, 5, 6);
1440
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001441 /* Disable trace points before removing it */
1442 tp = find_trace_probe("testprobe", KPROBE_EVENT_SYSTEM);
1443 if (WARN_ON_ONCE(tp == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001444 pr_warn("error on getting test probe.\n");
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001445 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001446 } else {
1447 file = find_trace_probe_file(tp, top_trace_array());
1448 if (WARN_ON_ONCE(file == NULL)) {
1449 pr_warn("error on getting probe file.\n");
1450 warn++;
1451 } else
1452 disable_trace_probe(tp, file);
1453 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001454
1455 tp = find_trace_probe("testprobe2", KPROBE_EVENT_SYSTEM);
1456 if (WARN_ON_ONCE(tp == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001457 pr_warn("error on getting 2nd test probe.\n");
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001458 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001459 } else {
1460 file = find_trace_probe_file(tp, top_trace_array());
1461 if (WARN_ON_ONCE(file == NULL)) {
1462 pr_warn("error on getting probe file.\n");
1463 warn++;
1464 } else
1465 disable_trace_probe(tp, file);
1466 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001467
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +05301468 ret = traceprobe_command("-:testprobe", create_trace_probe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001469 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001470 pr_warn("error on deleting a probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001471 warn++;
1472 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001473
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +05301474 ret = traceprobe_command("-:testprobe2", create_trace_probe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001475 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001476 pr_warn("error on deleting a probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001477 warn++;
1478 }
1479
1480end:
Masami Hiramatsu7143f162011-06-27 16:26:36 +09001481 release_all_trace_probes();
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001482 if (warn)
1483 pr_cont("NG: Some tests are failed. Please check them.\n");
1484 else
1485 pr_cont("OK\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001486 return 0;
1487}
1488
1489late_initcall(kprobe_trace_self_tests_init);
1490
1491#endif