blob: f2374172ba7b88ae5cec2a029f4e0409b49c9ffc [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 Hiramatsu2e06ff632009-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
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001159 dsize = __get_data_size(tp, regs);
1160 __size = sizeof(*entry) + tp->size + dsize;
Masami Hiramatsu74ebb632009-09-14 16:49:28 -04001161 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1162 size -= sizeof(u32);
Frederic Weisbecker97d5a222010-03-05 05:35:37 +01001163 if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
Masami Hiramatsua1a138d2009-09-25 11:20:12 -07001164 "profile buffer not large enough"))
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001165 return;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001166
Steven Rostedtff5f1492010-05-21 11:49:57 -04001167 entry = perf_trace_buf_prepare(size, call->event.type, regs, &rctx);
Xiao Guangrong430ad5a2010-01-28 09:32:29 +08001168 if (!entry)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001169 return;
Frederic Weisbeckerce71b9d2009-11-22 05:26:55 +01001170
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001171 entry->ip = (unsigned long)tp->rp.kp.addr;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001172 memset(&entry[1], 0, dsize);
1173 store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
Frederic Weisbecker444a2a32009-11-06 04:13:05 +01001174
Peter Zijlstra3771f072010-05-21 12:31:09 +02001175 head = this_cpu_ptr(call->perf_events);
Andrew Vagine6dab5f2012-07-11 18:14:58 +04001176 perf_trace_buf_submit(entry, size, rctx,
1177 entry->ip, 1, regs, head, NULL);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001178}
1179
1180/* Kretprobe profile handler */
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001181static __kprobes void
1182kretprobe_perf_func(struct trace_probe *tp, struct kretprobe_instance *ri,
1183 struct pt_regs *regs)
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001184{
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001185 struct ftrace_event_call *call = &tp->call;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001186 struct kretprobe_trace_entry_head *entry;
Peter Zijlstra1c024eca2010-05-19 14:02:22 +02001187 struct hlist_head *head;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001188 int size, __size, dsize;
Peter Zijlstra4ed7c922009-11-23 11:37:29 +01001189 int rctx;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001190
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001191 dsize = __get_data_size(tp, regs);
1192 __size = sizeof(*entry) + tp->size + dsize;
Masami Hiramatsu74ebb632009-09-14 16:49:28 -04001193 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1194 size -= sizeof(u32);
Frederic Weisbecker97d5a222010-03-05 05:35:37 +01001195 if (WARN_ONCE(size > PERF_MAX_TRACE_SIZE,
Masami Hiramatsua1a138d2009-09-25 11:20:12 -07001196 "profile buffer not large enough"))
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001197 return;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001198
Steven Rostedtff5f1492010-05-21 11:49:57 -04001199 entry = perf_trace_buf_prepare(size, call->event.type, regs, &rctx);
Xiao Guangrong430ad5a2010-01-28 09:32:29 +08001200 if (!entry)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001201 return;
Frederic Weisbeckerce71b9d2009-11-22 05:26:55 +01001202
Masami Hiramatsua1a138d2009-09-25 11:20:12 -07001203 entry->func = (unsigned long)tp->rp.kp.addr;
1204 entry->ret_ip = (unsigned long)ri->ret_addr;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001205 store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize);
Frederic Weisbecker444a2a32009-11-06 04:13:05 +01001206
Peter Zijlstra3771f072010-05-21 12:31:09 +02001207 head = this_cpu_ptr(call->perf_events);
Andrew Vagine6dab5f2012-07-11 18:14:58 +04001208 perf_trace_buf_submit(entry, size, rctx,
1209 entry->ret_ip, 1, regs, head, NULL);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001210}
Li Zefan07b139c2009-12-21 14:27:35 +08001211#endif /* CONFIG_PERF_EVENTS */
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001212
Steven Rostedt22392912010-04-21 12:27:06 -04001213static __kprobes
Jiri Olsaceec0b62012-02-15 15:51:49 +01001214int kprobe_register(struct ftrace_event_call *event,
1215 enum trace_reg type, void *data)
Steven Rostedt22392912010-04-21 12:27:06 -04001216{
Masami Hiramatsu1538f882011-06-27 16:26:44 +09001217 struct trace_probe *tp = (struct trace_probe *)event->data;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001218 struct ftrace_event_file *file = data;
Masami Hiramatsu1538f882011-06-27 16:26:44 +09001219
Steven Rostedt22392912010-04-21 12:27:06 -04001220 switch (type) {
1221 case TRACE_REG_REGISTER:
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001222 return enable_trace_probe(tp, file);
Steven Rostedt22392912010-04-21 12:27:06 -04001223 case TRACE_REG_UNREGISTER:
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001224 return disable_trace_probe(tp, file);
Steven Rostedt22392912010-04-21 12:27:06 -04001225
1226#ifdef CONFIG_PERF_EVENTS
1227 case TRACE_REG_PERF_REGISTER:
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001228 return enable_trace_probe(tp, NULL);
Steven Rostedt22392912010-04-21 12:27:06 -04001229 case TRACE_REG_PERF_UNREGISTER:
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001230 return disable_trace_probe(tp, NULL);
Jiri Olsaceec0b62012-02-15 15:51:49 +01001231 case TRACE_REG_PERF_OPEN:
1232 case TRACE_REG_PERF_CLOSE:
Jiri Olsa489c75c2012-02-15 15:51:50 +01001233 case TRACE_REG_PERF_ADD:
1234 case TRACE_REG_PERF_DEL:
Jiri Olsaceec0b62012-02-15 15:51:49 +01001235 return 0;
Steven Rostedt22392912010-04-21 12:27:06 -04001236#endif
1237 }
1238 return 0;
1239}
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001240
1241static __kprobes
1242int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs)
1243{
1244 struct trace_probe *tp = container_of(kp, struct trace_probe, rp.kp);
1245
Masami Hiramatsu48182bd2013-05-09 14:44:36 +09001246 tp->nhit++;
1247
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001248 if (tp->flags & TP_FLAG_TRACE)
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001249 kprobe_trace_func(tp, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001250#ifdef CONFIG_PERF_EVENTS
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001251 if (tp->flags & TP_FLAG_PROFILE)
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001252 kprobe_perf_func(tp, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001253#endif
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001254 return 0; /* We don't tweek kernel, so just return 0 */
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001255}
1256
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001257static __kprobes
1258int kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs)
1259{
1260 struct trace_probe *tp = container_of(ri->rp, struct trace_probe, rp);
1261
Masami Hiramatsu48182bd2013-05-09 14:44:36 +09001262 tp->nhit++;
1263
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001264 if (tp->flags & TP_FLAG_TRACE)
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001265 kretprobe_trace_func(tp, ri, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001266#ifdef CONFIG_PERF_EVENTS
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001267 if (tp->flags & TP_FLAG_PROFILE)
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001268 kretprobe_perf_func(tp, ri, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001269#endif
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001270 return 0; /* We don't tweek kernel, so just return 0 */
1271}
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001272
Steven Rostedta9a57762010-04-22 18:46:14 -04001273static struct trace_event_functions kretprobe_funcs = {
1274 .trace = print_kretprobe_event
1275};
1276
1277static struct trace_event_functions kprobe_funcs = {
1278 .trace = print_kprobe_event
1279};
1280
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001281static int register_probe_event(struct trace_probe *tp)
1282{
1283 struct ftrace_event_call *call = &tp->call;
1284 int ret;
1285
1286 /* Initialize ftrace_event_call */
Li Zefanffb9f992010-05-24 16:24:52 +08001287 INIT_LIST_HEAD(&call->class->fields);
Masami Hiramatsu7143f162011-06-27 16:26:36 +09001288 if (trace_probe_is_return(tp)) {
Steven Rostedt80decc72010-04-23 10:00:22 -04001289 call->event.funcs = &kretprobe_funcs;
Steven Rostedt2e33af02010-04-22 10:35:55 -04001290 call->class->define_fields = kretprobe_event_define_fields;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001291 } else {
Steven Rostedt80decc72010-04-23 10:00:22 -04001292 call->event.funcs = &kprobe_funcs;
Steven Rostedt2e33af02010-04-22 10:35:55 -04001293 call->class->define_fields = kprobe_event_define_fields;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001294 }
Lai Jiangshana342a0282009-12-15 15:39:49 +08001295 if (set_print_fmt(tp) < 0)
1296 return -ENOMEM;
Steven Rostedt32c0eda2010-04-23 10:38:03 -04001297 ret = register_ftrace_event(&call->event);
1298 if (!ret) {
Lai Jiangshana342a0282009-12-15 15:39:49 +08001299 kfree(call->print_fmt);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001300 return -ENODEV;
Lai Jiangshana342a0282009-12-15 15:39:49 +08001301 }
Steven Rostedt553552c2010-04-23 11:12:36 -04001302 call->flags = 0;
Steven Rostedt22392912010-04-21 12:27:06 -04001303 call->class->reg = kprobe_register;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001304 call->data = tp;
1305 ret = trace_add_event_call(call);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001306 if (ret) {
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001307 pr_info("Failed to register kprobe event: %s\n", call->name);
Lai Jiangshana342a0282009-12-15 15:39:49 +08001308 kfree(call->print_fmt);
Steven Rostedt80decc72010-04-23 10:00:22 -04001309 unregister_ftrace_event(&call->event);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001310 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001311 return ret;
1312}
1313
1314static void unregister_probe_event(struct trace_probe *tp)
1315{
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001316 /* tp->event is unregistered in trace_remove_event_call() */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001317 trace_remove_event_call(&tp->call);
Lai Jiangshana342a0282009-12-15 15:39:49 +08001318 kfree(tp->call.print_fmt);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001319}
1320
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001321/* Make a debugfs interface for controlling probe points */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001322static __init int init_kprobe_trace(void)
1323{
1324 struct dentry *d_tracer;
1325 struct dentry *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001326
Masami Hiramatsu61424312011-06-27 16:26:56 +09001327 if (register_module_notifier(&trace_probe_module_nb))
1328 return -EINVAL;
1329
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001330 d_tracer = tracing_init_dentry();
1331 if (!d_tracer)
1332 return 0;
1333
1334 entry = debugfs_create_file("kprobe_events", 0644, d_tracer,
1335 NULL, &kprobe_events_ops);
1336
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001337 /* Event list interface */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001338 if (!entry)
1339 pr_warning("Could not create debugfs "
1340 "'kprobe_events' entry\n");
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001341
1342 /* Profile interface */
1343 entry = debugfs_create_file("kprobe_profile", 0444, d_tracer,
1344 NULL, &kprobe_profile_ops);
1345
1346 if (!entry)
1347 pr_warning("Could not create debugfs "
1348 "'kprobe_profile' entry\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001349 return 0;
1350}
1351fs_initcall(init_kprobe_trace);
1352
1353
1354#ifdef CONFIG_FTRACE_STARTUP_TEST
1355
Steven Rostedt265a5b72011-06-06 22:35:13 -04001356/*
1357 * The "__used" keeps gcc from removing the function symbol
1358 * from the kallsyms table.
1359 */
1360static __used int kprobe_trace_selftest_target(int a1, int a2, int a3,
1361 int a4, int a5, int a6)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001362{
1363 return a1 + a2 + a3 + a4 + a5 + a6;
1364}
1365
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001366static struct ftrace_event_file *
1367find_trace_probe_file(struct trace_probe *tp, struct trace_array *tr)
1368{
1369 struct ftrace_event_file *file;
1370
1371 list_for_each_entry(file, &tr->events, list)
1372 if (file->event_call == &tp->call)
1373 return file;
1374
1375 return NULL;
1376}
1377
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001378static __init int kprobe_trace_self_tests_init(void)
1379{
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001380 int ret, warn = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001381 int (*target)(int, int, int, int, int, int);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001382 struct trace_probe *tp;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001383 struct ftrace_event_file *file;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001384
1385 target = kprobe_trace_selftest_target;
1386
1387 pr_info("Testing kprobe tracing: ");
1388
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +05301389 ret = traceprobe_command("p:testprobe kprobe_trace_selftest_target "
1390 "$stack $stack0 +0($stack)",
1391 create_trace_probe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001392 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001393 pr_warn("error on probing function entry.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001394 warn++;
1395 } else {
1396 /* Enable trace point */
Masami Hiramatsu7143f162011-06-27 16:26:36 +09001397 tp = find_trace_probe("testprobe", KPROBE_EVENT_SYSTEM);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001398 if (WARN_ON_ONCE(tp == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001399 pr_warn("error on getting new probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001400 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001401 } else {
1402 file = find_trace_probe_file(tp, top_trace_array());
1403 if (WARN_ON_ONCE(file == NULL)) {
1404 pr_warn("error on getting probe file.\n");
1405 warn++;
1406 } else
1407 enable_trace_probe(tp, file);
1408 }
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001409 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001410
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +05301411 ret = traceprobe_command("r:testprobe2 kprobe_trace_selftest_target "
1412 "$retval", create_trace_probe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001413 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001414 pr_warn("error on probing function return.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001415 warn++;
1416 } else {
1417 /* Enable trace point */
Masami Hiramatsu7143f162011-06-27 16:26:36 +09001418 tp = find_trace_probe("testprobe2", KPROBE_EVENT_SYSTEM);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001419 if (WARN_ON_ONCE(tp == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001420 pr_warn("error on getting 2nd new probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001421 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001422 } else {
1423 file = find_trace_probe_file(tp, top_trace_array());
1424 if (WARN_ON_ONCE(file == NULL)) {
1425 pr_warn("error on getting probe file.\n");
1426 warn++;
1427 } else
1428 enable_trace_probe(tp, file);
1429 }
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001430 }
1431
1432 if (warn)
1433 goto end;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001434
1435 ret = target(1, 2, 3, 4, 5, 6);
1436
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001437 /* Disable trace points before removing it */
1438 tp = find_trace_probe("testprobe", KPROBE_EVENT_SYSTEM);
1439 if (WARN_ON_ONCE(tp == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001440 pr_warn("error on getting test probe.\n");
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001441 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001442 } else {
1443 file = find_trace_probe_file(tp, top_trace_array());
1444 if (WARN_ON_ONCE(file == NULL)) {
1445 pr_warn("error on getting probe file.\n");
1446 warn++;
1447 } else
1448 disable_trace_probe(tp, file);
1449 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001450
1451 tp = find_trace_probe("testprobe2", KPROBE_EVENT_SYSTEM);
1452 if (WARN_ON_ONCE(tp == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001453 pr_warn("error on getting 2nd test probe.\n");
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001454 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001455 } else {
1456 file = find_trace_probe_file(tp, top_trace_array());
1457 if (WARN_ON_ONCE(file == NULL)) {
1458 pr_warn("error on getting probe file.\n");
1459 warn++;
1460 } else
1461 disable_trace_probe(tp, file);
1462 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001463
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +05301464 ret = traceprobe_command("-:testprobe", create_trace_probe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001465 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001466 pr_warn("error on deleting a probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001467 warn++;
1468 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001469
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +05301470 ret = traceprobe_command("-:testprobe2", create_trace_probe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001471 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001472 pr_warn("error on deleting a probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001473 warn++;
1474 }
1475
1476end:
Masami Hiramatsu7143f162011-06-27 16:26:36 +09001477 release_all_trace_probes();
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001478 if (warn)
1479 pr_cont("NG: Some tests are failed. Please check them.\n");
1480 else
1481 pr_cont("OK\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001482 return 0;
1483}
1484
1485late_initcall(kprobe_trace_self_tests_init);
1486
1487#endif