blob: 7d736248a070b2f633349856345e2013d4a3cd34 [file] [log] [blame]
Steven Rostedt (VMware)bcea3f92018-08-16 11:23:53 -04001// SPDX-License-Identifier: GPL-2.0
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04002/*
Masami Hiramatsu77b44d12009-11-03 19:12:47 -05003 * Kprobes-based tracing events
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04004 *
5 * Created by Masami Hiramatsu <mhiramat@redhat.com>
6 *
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04007 */
Masami Hiramatsu72576342017-02-07 20:21:28 +09008#define pr_fmt(fmt) "trace_kprobe: " fmt
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04009
10#include <linux/module.h>
11#include <linux/uaccess.h>
Ingo Molnarb2d09102017-02-04 01:27:20 +010012#include <linux/rculist.h>
Masami Hiramatsu540adea2018-01-13 02:55:03 +090013#include <linux/error-injection.h>
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040014
Masami Hiramatsu6212dd22018-11-05 18:02:36 +090015#include "trace_dynevent.h"
Francis Deslauriersd8999262018-07-30 19:20:42 +090016#include "trace_kprobe_selftest.h"
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +053017#include "trace_probe.h"
Masami Hiramatsu53305922018-04-25 21:18:03 +090018#include "trace_probe_tmpl.h"
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040019
Masami Hiramatsuf52487e2009-09-10 19:53:53 -040020#define KPROBE_EVENT_SYSTEM "kprobes"
Alban Crequy696ced42017-04-03 12:36:22 +020021#define KRETPROBE_MAXACTIVE_MAX 4096
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040022
Masami Hiramatsu6212dd22018-11-05 18:02:36 +090023static int trace_kprobe_create(int argc, const char **argv);
24static int trace_kprobe_show(struct seq_file *m, struct dyn_event *ev);
25static int trace_kprobe_release(struct dyn_event *ev);
26static bool trace_kprobe_is_busy(struct dyn_event *ev);
27static bool trace_kprobe_match(const char *system, const char *event,
28 struct dyn_event *ev);
29
30static struct dyn_event_operations trace_kprobe_ops = {
31 .create = trace_kprobe_create,
32 .show = trace_kprobe_show,
33 .is_busy = trace_kprobe_is_busy,
34 .free = trace_kprobe_release,
35 .match = trace_kprobe_match,
36};
37
Valdis Klētniekscede6662019-03-12 04:58:32 -040038/*
Masami Hiramatsu77b44d12009-11-03 19:12:47 -050039 * Kprobe event core functions
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040040 */
Namhyung Kimc31ffb32013-07-03 13:50:51 +090041struct trace_kprobe {
Masami Hiramatsu6212dd22018-11-05 18:02:36 +090042 struct dyn_event devent;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +020043 struct kretprobe rp; /* Use rp.kp for kprobe use */
Martin KaFai Laua7636d92016-02-03 12:28:28 -080044 unsigned long __percpu *nhit;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040045 const char *symbol; /* symbol name */
Namhyung Kimc31ffb32013-07-03 13:50:51 +090046 struct trace_probe tp;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040047};
48
Masami Hiramatsu6212dd22018-11-05 18:02:36 +090049static bool is_trace_kprobe(struct dyn_event *ev)
50{
51 return ev->ops == &trace_kprobe_ops;
52}
53
54static struct trace_kprobe *to_trace_kprobe(struct dyn_event *ev)
55{
56 return container_of(ev, struct trace_kprobe, devent);
57}
58
59/**
60 * for_each_trace_kprobe - iterate over the trace_kprobe list
61 * @pos: the struct trace_kprobe * for each entry
62 * @dpos: the struct dyn_event * to use as a loop cursor
63 */
64#define for_each_trace_kprobe(pos, dpos) \
65 for_each_dyn_event(dpos) \
66 if (is_trace_kprobe(dpos) && (pos = to_trace_kprobe(dpos)))
67
Namhyung Kimc31ffb32013-07-03 13:50:51 +090068#define SIZEOF_TRACE_KPROBE(n) \
69 (offsetof(struct trace_kprobe, tp.args) + \
Masami Hiramatsueca0d912009-09-10 19:53:38 -040070 (sizeof(struct probe_arg) * (n)))
Masami Hiramatsua82378d2009-08-13 16:35:18 -040071
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090072static nokprobe_inline bool trace_kprobe_is_return(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040073{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090074 return tk->rp.handler != NULL;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040075}
76
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090077static nokprobe_inline const char *trace_kprobe_symbol(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040078{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090079 return tk->symbol ? tk->symbol : "unknown";
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040080}
81
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090082static nokprobe_inline unsigned long trace_kprobe_offset(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +090083{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090084 return tk->rp.kp.offset;
Masami Hiramatsu61424312011-06-27 16:26:56 +090085}
86
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090087static nokprobe_inline bool trace_kprobe_has_gone(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +090088{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090089 return !!(kprobe_gone(&tk->rp.kp));
Masami Hiramatsu61424312011-06-27 16:26:56 +090090}
91
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090092static nokprobe_inline bool trace_kprobe_within_module(struct trace_kprobe *tk,
Namhyung Kimc31ffb32013-07-03 13:50:51 +090093 struct module *mod)
Masami Hiramatsu61424312011-06-27 16:26:56 +090094{
95 int len = strlen(mod->name);
Namhyung Kimc31ffb32013-07-03 13:50:51 +090096 const char *name = trace_kprobe_symbol(tk);
Masami Hiramatsu61424312011-06-27 16:26:56 +090097 return strncmp(mod->name, name, len) == 0 && name[len] == ':';
98}
99
Masami Hiramatsu59158ec2018-08-29 01:18:15 +0900100static nokprobe_inline bool trace_kprobe_module_exist(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +0900101{
Masami Hiramatsu59158ec2018-08-29 01:18:15 +0900102 char *p;
103 bool ret;
104
105 if (!tk->symbol)
106 return false;
107 p = strchr(tk->symbol, ':');
108 if (!p)
109 return true;
110 *p = '\0';
111 mutex_lock(&module_mutex);
112 ret = !!find_module(tk->symbol);
113 mutex_unlock(&module_mutex);
114 *p = ':';
115
116 return ret;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900117}
118
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900119static bool trace_kprobe_is_busy(struct dyn_event *ev)
120{
121 struct trace_kprobe *tk = to_trace_kprobe(ev);
122
123 return trace_probe_is_enabled(&tk->tp);
124}
125
126static bool trace_kprobe_match(const char *system, const char *event,
127 struct dyn_event *ev)
128{
129 struct trace_kprobe *tk = to_trace_kprobe(ev);
130
131 return strcmp(trace_event_name(&tk->tp.call), event) == 0 &&
132 (!system || strcmp(tk->tp.call.class->system, system) == 0);
133}
134
Marcin Nowakowskif18f97a2016-12-09 15:19:37 +0100135static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk)
136{
137 unsigned long nhit = 0;
138 int cpu;
139
140 for_each_possible_cpu(cpu)
141 nhit += *per_cpu_ptr(tk->nhit, cpu);
142
143 return nhit;
144}
145
Masami Hiramatsu6bc6c772018-08-02 16:50:48 +0900146/* Return 0 if it fails to find the symbol address */
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900147static nokprobe_inline
148unsigned long trace_kprobe_address(struct trace_kprobe *tk)
149{
150 unsigned long addr;
151
152 if (tk->symbol) {
153 addr = (unsigned long)
154 kallsyms_lookup_name(trace_kprobe_symbol(tk));
Masami Hiramatsu6bc6c772018-08-02 16:50:48 +0900155 if (addr)
156 addr += tk->rp.kp.offset;
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900157 } else {
158 addr = (unsigned long)tk->rp.kp.addr;
159 }
160 return addr;
161}
162
Masami Hiramatsub4da3342018-01-13 02:54:04 +0900163bool trace_kprobe_on_func_entry(struct trace_event_call *call)
Josef Bacik9802d862017-12-11 11:36:48 -0500164{
165 struct trace_kprobe *tk = (struct trace_kprobe *)call->data;
Masami Hiramatsub4da3342018-01-13 02:54:04 +0900166
167 return kprobe_on_func_entry(tk->rp.kp.addr,
168 tk->rp.kp.addr ? NULL : tk->rp.kp.symbol_name,
169 tk->rp.kp.addr ? 0 : tk->rp.kp.offset);
Josef Bacik9802d862017-12-11 11:36:48 -0500170}
171
Masami Hiramatsub4da3342018-01-13 02:54:04 +0900172bool trace_kprobe_error_injectable(struct trace_event_call *call)
Josef Bacik9802d862017-12-11 11:36:48 -0500173{
174 struct trace_kprobe *tk = (struct trace_kprobe *)call->data;
Josef Bacik9802d862017-12-11 11:36:48 -0500175
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900176 return within_error_injection_list(trace_kprobe_address(tk));
Josef Bacik9802d862017-12-11 11:36:48 -0500177}
178
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900179static int register_kprobe_event(struct trace_kprobe *tk);
180static int unregister_kprobe_event(struct trace_kprobe *tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400181
Masami Hiramatsu50d78052009-09-14 16:49:20 -0400182static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs);
183static int kretprobe_dispatcher(struct kretprobe_instance *ri,
184 struct pt_regs *regs);
185
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200186/*
187 * Allocate new trace_probe and initialize it (including kprobes).
188 */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900189static struct trace_kprobe *alloc_trace_kprobe(const char *group,
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400190 const char *event,
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200191 void *addr,
192 const char *symbol,
193 unsigned long offs,
Alban Crequy696ced42017-04-03 12:36:22 +0200194 int maxactive,
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530195 int nargs, bool is_return)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400196{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900197 struct trace_kprobe *tk;
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500198 int ret = -ENOMEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400199
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900200 tk = kzalloc(SIZEOF_TRACE_KPROBE(nargs), GFP_KERNEL);
201 if (!tk)
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500202 return ERR_PTR(ret);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400203
Martin KaFai Laua7636d92016-02-03 12:28:28 -0800204 tk->nhit = alloc_percpu(unsigned long);
205 if (!tk->nhit)
206 goto error;
207
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400208 if (symbol) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900209 tk->symbol = kstrdup(symbol, GFP_KERNEL);
210 if (!tk->symbol)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400211 goto error;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900212 tk->rp.kp.symbol_name = tk->symbol;
213 tk->rp.kp.offset = offs;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200214 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900215 tk->rp.kp.addr = addr;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200216
217 if (is_return)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900218 tk->rp.handler = kretprobe_dispatcher;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200219 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900220 tk->rp.kp.pre_handler = kprobe_dispatcher;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200221
Alban Crequy696ced42017-04-03 12:36:22 +0200222 tk->rp.maxactive = maxactive;
223
Masami Hiramatsu5b7a9622019-03-14 13:30:40 +0900224 if (!event || !group) {
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500225 ret = -EINVAL;
Masami Hiramatsu42635652009-08-13 16:35:26 -0400226 goto error;
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500227 }
228
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900229 tk->tp.call.class = &tk->tp.class;
230 tk->tp.call.name = kstrdup(event, GFP_KERNEL);
231 if (!tk->tp.call.name)
Masami Hiramatsu42635652009-08-13 16:35:26 -0400232 goto error;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400233
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900234 tk->tp.class.system = kstrdup(group, GFP_KERNEL);
235 if (!tk->tp.class.system)
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400236 goto error;
237
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900238 dyn_event_init(&tk->devent, &trace_kprobe_ops);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900239 INIT_LIST_HEAD(&tk->tp.files);
240 return tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400241error:
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900242 kfree(tk->tp.call.name);
243 kfree(tk->symbol);
Martin KaFai Laua7636d92016-02-03 12:28:28 -0800244 free_percpu(tk->nhit);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900245 kfree(tk);
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500246 return ERR_PTR(ret);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400247}
248
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900249static void free_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400250{
251 int i;
252
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900253 if (!tk)
254 return;
255
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900256 for (i = 0; i < tk->tp.nr_args; i++)
257 traceprobe_free_probe_arg(&tk->tp.args[i]);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400258
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900259 kfree(tk->tp.call.class->system);
260 kfree(tk->tp.call.name);
261 kfree(tk->symbol);
Martin KaFai Laua7636d92016-02-03 12:28:28 -0800262 free_percpu(tk->nhit);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900263 kfree(tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400264}
265
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900266static struct trace_kprobe *find_trace_kprobe(const char *event,
267 const char *group)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400268{
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900269 struct dyn_event *pos;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900270 struct trace_kprobe *tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400271
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900272 for_each_trace_kprobe(tk, pos)
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -0400273 if (strcmp(trace_event_name(&tk->tp.call), event) == 0 &&
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900274 strcmp(tk->tp.call.class->system, group) == 0)
275 return tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400276 return NULL;
277}
278
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400279static inline int __enable_trace_kprobe(struct trace_kprobe *tk)
280{
281 int ret = 0;
282
283 if (trace_probe_is_registered(&tk->tp) && !trace_kprobe_has_gone(tk)) {
284 if (trace_kprobe_is_return(tk))
285 ret = enable_kretprobe(&tk->rp);
286 else
287 ret = enable_kprobe(&tk->rp.kp);
288 }
289
290 return ret;
291}
292
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200293/*
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900294 * Enable trace_probe
295 * if the file is NULL, enable "perf" handler, or enable "trace" handler.
296 */
297static int
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400298enable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900299{
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400300 struct event_file_link *link;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900301 int ret = 0;
302
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900303 if (file) {
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200304 link = kmalloc(sizeof(*link), GFP_KERNEL);
305 if (!link) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900306 ret = -ENOMEM;
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200307 goto out;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900308 }
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900309
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200310 link->file = file;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900311 list_add_tail_rcu(&link->list, &tk->tp.files);
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200312
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900313 tk->tp.flags |= TP_FLAG_TRACE;
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400314 ret = __enable_trace_kprobe(tk);
315 if (ret) {
316 list_del_rcu(&link->list);
Artem Savkov57ea2a32018-07-25 16:20:38 +0200317 kfree(link);
318 tk->tp.flags &= ~TP_FLAG_TRACE;
Artem Savkov57ea2a32018-07-25 16:20:38 +0200319 }
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400320
321 } else {
322 tk->tp.flags |= TP_FLAG_PROFILE;
323 ret = __enable_trace_kprobe(tk);
324 if (ret)
325 tk->tp.flags &= ~TP_FLAG_PROFILE;
Artem Savkov57ea2a32018-07-25 16:20:38 +0200326 }
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200327 out:
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900328 return ret;
329}
330
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900331/*
332 * Disable trace_probe
333 * if the file is NULL, disable "perf" handler, or disable "trace" handler.
334 */
335static int
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400336disable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900337{
Masami Hiramatsua232e272013-07-09 18:35:26 +0900338 struct event_file_link *link = NULL;
339 int wait = 0;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900340 int ret = 0;
341
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900342 if (file) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900343 link = find_event_file_link(&tk->tp, file);
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200344 if (!link) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900345 ret = -EINVAL;
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200346 goto out;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900347 }
348
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200349 list_del_rcu(&link->list);
Masami Hiramatsua232e272013-07-09 18:35:26 +0900350 wait = 1;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900351 if (!list_empty(&tk->tp.files))
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200352 goto out;
353
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900354 tk->tp.flags &= ~TP_FLAG_TRACE;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900355 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900356 tk->tp.flags &= ~TP_FLAG_PROFILE;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900357
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900358 if (!trace_probe_is_enabled(&tk->tp) && trace_probe_is_registered(&tk->tp)) {
359 if (trace_kprobe_is_return(tk))
360 disable_kretprobe(&tk->rp);
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900361 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900362 disable_kprobe(&tk->rp.kp);
Masami Hiramatsua232e272013-07-09 18:35:26 +0900363 wait = 1;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900364 }
Song Liue12f03d2017-12-06 14:45:15 -0800365
366 /*
367 * if tk is not added to any list, it must be a local trace_kprobe
368 * created with perf_event_open. We don't need to wait for these
369 * trace_kprobes
370 */
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900371 if (list_empty(&tk->devent.list))
Song Liue12f03d2017-12-06 14:45:15 -0800372 wait = 0;
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200373 out:
Masami Hiramatsua232e272013-07-09 18:35:26 +0900374 if (wait) {
375 /*
376 * Synchronize with kprobe_trace_func/kretprobe_trace_func
377 * to ensure disabled (all running handlers are finished).
378 * This is not only for kfree(), but also the caller,
379 * trace_remove_event_call() supposes it for releasing
380 * event_call related objects, which will be accessed in
381 * the kprobe_trace_func/kretprobe_trace_func.
382 */
Paul E. McKenney74401722018-11-06 18:44:52 -0800383 synchronize_rcu();
Masami Hiramatsua232e272013-07-09 18:35:26 +0900384 kfree(link); /* Ignored if link == NULL */
385 }
386
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900387 return ret;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900388}
389
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900390#if defined(CONFIG_KPROBES_ON_FTRACE) && \
391 !defined(CONFIG_KPROBE_EVENTS_ON_NOTRACE)
392static bool within_notrace_func(struct trace_kprobe *tk)
393{
394 unsigned long offset, size, addr;
395
396 addr = trace_kprobe_address(tk);
Masami Hiramatsu6bc6c772018-08-02 16:50:48 +0900397 if (!addr || !kallsyms_lookup_size_offset(addr, &size, &offset))
398 return false;
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900399
Masami Hiramatsu9161a8642018-08-21 22:04:57 +0900400 /* Get the entry address of the target function */
401 addr -= offset;
402
403 /*
404 * Since ftrace_location_range() does inclusive range check, we need
405 * to subtract 1 byte from the end address.
406 */
407 return !ftrace_location_range(addr, addr + size - 1);
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900408}
409#else
410#define within_notrace_func(tk) (false)
411#endif
412
Masami Hiramatsu61424312011-06-27 16:26:56 +0900413/* Internal register function - just handle k*probes and flags */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900414static int __register_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +0900415{
Masami Hiramatsua6682812018-08-29 01:18:43 +0900416 int i, ret;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900417
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900418 if (trace_probe_is_registered(&tk->tp))
Masami Hiramatsu61424312011-06-27 16:26:56 +0900419 return -EINVAL;
420
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900421 if (within_notrace_func(tk)) {
422 pr_warn("Could not probe notrace function %s\n",
423 trace_kprobe_symbol(tk));
424 return -EINVAL;
425 }
426
Masami Hiramatsua6682812018-08-29 01:18:43 +0900427 for (i = 0; i < tk->tp.nr_args; i++) {
428 ret = traceprobe_update_arg(&tk->tp.args[i]);
429 if (ret)
430 return ret;
431 }
432
Masami Hiramatsu61424312011-06-27 16:26:56 +0900433 /* Set/clear disabled flag according to tp->flag */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900434 if (trace_probe_is_enabled(&tk->tp))
435 tk->rp.kp.flags &= ~KPROBE_FLAG_DISABLED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900436 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900437 tk->rp.kp.flags |= KPROBE_FLAG_DISABLED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900438
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900439 if (trace_kprobe_is_return(tk))
440 ret = register_kretprobe(&tk->rp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900441 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900442 ret = register_kprobe(&tk->rp.kp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900443
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500444 if (ret == 0)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900445 tk->tp.flags |= TP_FLAG_REGISTERED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900446 return ret;
447}
448
449/* Internal unregister function - just handle k*probes and flags */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900450static void __unregister_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +0900451{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900452 if (trace_probe_is_registered(&tk->tp)) {
453 if (trace_kprobe_is_return(tk))
454 unregister_kretprobe(&tk->rp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900455 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900456 unregister_kprobe(&tk->rp.kp);
457 tk->tp.flags &= ~TP_FLAG_REGISTERED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900458 /* Cleanup kprobe for reuse */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900459 if (tk->rp.kp.symbol_name)
460 tk->rp.kp.addr = NULL;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900461 }
462}
463
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900464/* Unregister a trace_probe and probe_event */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900465static int unregister_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400466{
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900467 /* Enabled event can not be unregistered */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900468 if (trace_probe_is_enabled(&tk->tp))
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900469 return -EBUSY;
470
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -0400471 /* Will fail if probe is being used by ftrace or perf */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900472 if (unregister_kprobe_event(tk))
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -0400473 return -EBUSY;
474
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900475 __unregister_trace_kprobe(tk);
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900476 dyn_event_remove(&tk->devent);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900477
478 return 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400479}
480
481/* Register a trace_probe and probe_event */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900482static int register_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400483{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900484 struct trace_kprobe *old_tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400485 int ret;
486
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900487 mutex_lock(&event_mutex);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400488
Masami Hiramatsu61424312011-06-27 16:26:56 +0900489 /* Delete old (same name) event if exist */
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -0400490 old_tk = find_trace_kprobe(trace_event_name(&tk->tp.call),
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -0400491 tk->tp.call.class->system);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900492 if (old_tk) {
493 ret = unregister_trace_kprobe(old_tk);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900494 if (ret < 0)
495 goto end;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900496 free_trace_kprobe(old_tk);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400497 }
Masami Hiramatsu61424312011-06-27 16:26:56 +0900498
499 /* Register new event */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900500 ret = register_kprobe_event(tk);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400501 if (ret) {
Joe Perchesa395d6a2016-03-22 14:28:09 -0700502 pr_warn("Failed to register probe event(%d)\n", ret);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400503 goto end;
504 }
505
Masami Hiramatsu61424312011-06-27 16:26:56 +0900506 /* Register k*probe */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900507 ret = __register_trace_kprobe(tk);
Masami Hiramatsu59158ec2018-08-29 01:18:15 +0900508 if (ret == -ENOENT && !trace_kprobe_module_exist(tk)) {
509 pr_warn("This probe might be able to register after target module is loaded. Continue.\n");
510 ret = 0;
511 }
512
Masami Hiramatsu61424312011-06-27 16:26:56 +0900513 if (ret < 0)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900514 unregister_kprobe_event(tk);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900515 else
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900516 dyn_event_add(&tk->devent);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900517
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400518end:
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900519 mutex_unlock(&event_mutex);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400520 return ret;
521}
522
Masami Hiramatsu61424312011-06-27 16:26:56 +0900523/* Module notifier call back, checking event on the module */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900524static int trace_kprobe_module_callback(struct notifier_block *nb,
Masami Hiramatsu61424312011-06-27 16:26:56 +0900525 unsigned long val, void *data)
526{
527 struct module *mod = data;
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900528 struct dyn_event *pos;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900529 struct trace_kprobe *tk;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900530 int ret;
531
532 if (val != MODULE_STATE_COMING)
533 return NOTIFY_DONE;
534
535 /* Update probes on coming module */
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900536 mutex_lock(&event_mutex);
537 for_each_trace_kprobe(tk, pos) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900538 if (trace_kprobe_within_module(tk, mod)) {
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900539 /* Don't need to check busy - this should have gone. */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900540 __unregister_trace_kprobe(tk);
541 ret = __register_trace_kprobe(tk);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900542 if (ret)
Joe Perchesa395d6a2016-03-22 14:28:09 -0700543 pr_warn("Failed to re-register probe %s on %s: %d\n",
544 trace_event_name(&tk->tp.call),
545 mod->name, ret);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900546 }
547 }
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900548 mutex_unlock(&event_mutex);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900549
550 return NOTIFY_DONE;
551}
552
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900553static struct notifier_block trace_kprobe_module_nb = {
554 .notifier_call = trace_kprobe_module_callback,
Masami Hiramatsu61424312011-06-27 16:26:56 +0900555 .priority = 1 /* Invoked after kprobe module callback */
556};
557
Naveen N. Raofca18a42017-07-08 00:27:30 +0530558/* Convert certain expected symbols into '_' when generating event names */
559static inline void sanitize_event_name(char *name)
560{
561 while (*name++ != '\0')
562 if (*name == ':' || *name == '.')
563 *name = '_';
564}
565
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900566static int trace_kprobe_create(int argc, const char *argv[])
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400567{
568 /*
569 * Argument syntax:
Alban Crequy696ced42017-04-03 12:36:22 +0200570 * - Add kprobe:
571 * p[:[GRP/]EVENT] [MOD:]KSYM[+OFFS]|KADDR [FETCHARGS]
572 * - Add kretprobe:
573 * r[MAXACTIVE][:[GRP/]EVENT] [MOD:]KSYM[+0] [FETCHARGS]
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400574 * Fetch args:
Masami Hiramatsu2e06ff62009-10-07 18:27:59 -0400575 * $retval : fetch return value
576 * $stack : fetch stack address
577 * $stackN : fetch Nth of stack (N:0-)
Omar Sandoval35abb672016-06-08 18:38:02 -0700578 * $comm : fetch current task comm
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400579 * @ADDR : fetch memory at ADDR (ADDR should be in kernel)
580 * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol)
581 * %REG : fetch register REG
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400582 * Dereferencing memory fetch:
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400583 * +|-offs(ARG) : fetch memory at ARG +|- offs address.
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400584 * Alias name of args:
585 * NAME=FETCHARG : set NAME as alias of FETCHARG.
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400586 * Type of args:
587 * FETCHARG:TYPE : use TYPE instead of unsigned long.
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400588 */
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500589 struct trace_kprobe *tk = NULL;
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900590 int i, len, ret = 0;
591 bool is_return = false;
592 char *symbol = NULL, *tmp = NULL;
593 const char *event = NULL, *group = KPROBE_EVENT_SYSTEM;
Alban Crequy696ced42017-04-03 12:36:22 +0200594 int maxactive = 0;
Masami Hiramatsuc5d343b2018-03-17 21:38:10 +0900595 long offset = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400596 void *addr = NULL;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200597 char buf[MAX_EVENT_NAME_LEN];
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900598 unsigned int flags = TPARG_FL_KERNEL;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400599
Andrea Righi8b05a3a2019-01-11 07:01:13 +0100600 switch (argv[0][0]) {
601 case 'r':
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530602 is_return = true;
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900603 flags |= TPARG_FL_RETURN;
Andrea Righi8b05a3a2019-01-11 07:01:13 +0100604 break;
605 case 'p':
606 break;
607 default:
608 return -ECANCELED;
609 }
610 if (argc < 2)
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900611 return -ECANCELED;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400612
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500613 trace_probe_log_init("trace_kprobe", argc, argv);
614
Alban Crequy696ced42017-04-03 12:36:22 +0200615 event = strchr(&argv[0][1], ':');
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900616 if (event)
Alban Crequy696ced42017-04-03 12:36:22 +0200617 event++;
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900618
Masami Hiramatsu287c0382019-03-14 13:30:09 +0900619 if (isdigit(argv[0][1])) {
620 if (!is_return) {
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500621 trace_probe_log_err(1, MAXACT_NO_KPROBE);
622 goto parse_error;
Masami Hiramatsu287c0382019-03-14 13:30:09 +0900623 }
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900624 if (event)
625 len = event - &argv[0][1] - 1;
626 else
627 len = strlen(&argv[0][1]);
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500628 if (len > MAX_EVENT_NAME_LEN - 1) {
629 trace_probe_log_err(1, BAD_MAXACT);
630 goto parse_error;
631 }
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900632 memcpy(buf, &argv[0][1], len);
633 buf[len] = '\0';
634 ret = kstrtouint(buf, 0, &maxactive);
Masami Hiramatsu287c0382019-03-14 13:30:09 +0900635 if (ret || !maxactive) {
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500636 trace_probe_log_err(1, BAD_MAXACT);
637 goto parse_error;
Alban Crequy696ced42017-04-03 12:36:22 +0200638 }
639 /* kretprobes instances are iterated over via a list. The
640 * maximum should stay reasonable.
641 */
642 if (maxactive > KRETPROBE_MAXACTIVE_MAX) {
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500643 trace_probe_log_err(1, MAXACT_TOO_BIG);
644 goto parse_error;
Alban Crequy696ced42017-04-03 12:36:22 +0200645 }
646 }
647
Sabrina Dubroca9e52b322017-06-22 11:24:42 +0200648 /* try to parse an address. if that fails, try to read the
649 * input as a symbol. */
650 if (kstrtoul(argv[1], 0, (unsigned long *)&addr)) {
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500651 trace_probe_log_set_index(1);
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900652 /* Check whether uprobe event specified */
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500653 if (strchr(argv[1], '/') && strchr(argv[1], ':')) {
654 ret = -ECANCELED;
655 goto error;
656 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400657 /* a symbol specified */
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900658 symbol = kstrdup(argv[1], GFP_KERNEL);
659 if (!symbol)
660 return -ENOMEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400661 /* TODO: support .init module functions */
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +0530662 ret = traceprobe_split_symbol_offset(symbol, &offset);
Masami Hiramatsuc5d343b2018-03-17 21:38:10 +0900663 if (ret || offset < 0 || offset > UINT_MAX) {
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500664 trace_probe_log_err(0, BAD_PROBE_ADDR);
665 goto parse_error;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400666 }
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900667 if (kprobe_on_func_entry(NULL, symbol, offset))
668 flags |= TPARG_FL_FENTRY;
669 if (offset && is_return && !(flags & TPARG_FL_FENTRY)) {
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500670 trace_probe_log_err(0, BAD_RETPROBE);
671 goto parse_error;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400672 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400673 }
674
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500675 trace_probe_log_set_index(0);
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900676 if (event) {
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500677 ret = traceprobe_parse_event_name(&event, &group, buf,
678 event - argv[0]);
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900679 if (ret)
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500680 goto parse_error;
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900681 } else {
Masami Hiramatsu42635652009-08-13 16:35:26 -0400682 /* Make a new event name */
Masami Hiramatsu42635652009-08-13 16:35:26 -0400683 if (symbol)
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500684 snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_%ld",
Masami Hiramatsu42635652009-08-13 16:35:26 -0400685 is_return ? 'r' : 'p', symbol, offset);
686 else
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500687 snprintf(buf, MAX_EVENT_NAME_LEN, "%c_0x%p",
Masami Hiramatsu42635652009-08-13 16:35:26 -0400688 is_return ? 'r' : 'p', addr);
Naveen N. Raofca18a42017-07-08 00:27:30 +0530689 sanitize_event_name(buf);
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200690 event = buf;
691 }
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900692
693 /* setup a probe */
Alban Crequy696ced42017-04-03 12:36:22 +0200694 tk = alloc_trace_kprobe(group, event, addr, symbol, offset, maxactive,
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500695 argc - 2, is_return);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900696 if (IS_ERR(tk)) {
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900697 ret = PTR_ERR(tk);
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500698 /* This must return -ENOMEM, else there is a bug */
Masami Hiramatsua0394802019-03-14 13:30:50 +0900699 WARN_ON_ONCE(ret != -ENOMEM);
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500700 goto out; /* We know tk is not allocated */
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400701 }
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500702 argc -= 2; argv += 2;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400703
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400704 /* parse arguments */
Masami Hiramatsua82378d2009-08-13 16:35:18 -0400705 for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900706 tmp = kstrdup(argv[i], GFP_KERNEL);
707 if (!tmp) {
Masami Hiramatsuba8665d2009-11-30 19:19:20 -0500708 ret = -ENOMEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400709 goto error;
710 }
Masami Hiramatsuda346342010-08-27 20:39:12 +0900711
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500712 trace_probe_log_set_index(i + 2);
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900713 ret = traceprobe_parse_probe_arg(&tk->tp, i, tmp, flags);
714 kfree(tmp);
Masami Hiramatsud00bbea92018-11-05 18:01:40 +0900715 if (ret)
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500716 goto error; /* This can be -ENOMEM */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400717 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400718
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900719 ret = register_trace_kprobe(tk);
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500720 if (ret) {
721 trace_probe_log_set_index(1);
722 if (ret == -EILSEQ)
723 trace_probe_log_err(0, BAD_INSN_BNDRY);
724 else if (ret == -ENOENT)
725 trace_probe_log_err(0, BAD_PROBE_ADDR);
726 else if (ret != -ENOMEM)
727 trace_probe_log_err(0, FAIL_REG_PROBE);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400728 goto error;
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500729 }
730
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900731out:
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500732 trace_probe_log_clear();
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900733 kfree(symbol);
734 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400735
Masami Hiramatsuab105a42019-03-31 18:48:19 -0500736parse_error:
737 ret = -EINVAL;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400738error:
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900739 free_trace_kprobe(tk);
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900740 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400741}
742
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900743static int create_or_delete_trace_kprobe(int argc, char **argv)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400744{
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900745 int ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400746
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900747 if (argv[0][0] == '-')
748 return dyn_event_release(argc, argv, &trace_kprobe_ops);
749
750 ret = trace_kprobe_create(argc, (const char **)argv);
751 return ret == -ECANCELED ? -EINVAL : ret;
752}
753
754static int trace_kprobe_release(struct dyn_event *ev)
755{
756 struct trace_kprobe *tk = to_trace_kprobe(ev);
757 int ret = unregister_trace_kprobe(tk);
758
759 if (!ret)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900760 free_trace_kprobe(tk);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900761 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400762}
763
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900764static int trace_kprobe_show(struct seq_file *m, struct dyn_event *ev)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400765{
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900766 struct trace_kprobe *tk = to_trace_kprobe(ev);
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400767 int i;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400768
Rasmus Villemoesfa6f0cc2014-11-08 21:42:10 +0100769 seq_putc(m, trace_kprobe_is_return(tk) ? 'r' : 'p');
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -0400770 seq_printf(m, ":%s/%s", tk->tp.call.class->system,
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -0400771 trace_event_name(&tk->tp.call));
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400772
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900773 if (!tk->symbol)
774 seq_printf(m, " 0x%p", tk->rp.kp.addr);
775 else if (tk->rp.kp.offset)
776 seq_printf(m, " %s+%u", trace_kprobe_symbol(tk),
777 tk->rp.kp.offset);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400778 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900779 seq_printf(m, " %s", trace_kprobe_symbol(tk));
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400780
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900781 for (i = 0; i < tk->tp.nr_args; i++)
782 seq_printf(m, " %s=%s", tk->tp.args[i].name, tk->tp.args[i].comm);
Rasmus Villemoesfa6f0cc2014-11-08 21:42:10 +0100783 seq_putc(m, '\n');
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400784
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400785 return 0;
786}
787
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900788static int probes_seq_show(struct seq_file *m, void *v)
789{
790 struct dyn_event *ev = v;
791
792 if (!is_trace_kprobe(ev))
793 return 0;
794
795 return trace_kprobe_show(m, ev);
796}
797
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400798static const struct seq_operations probes_seq_op = {
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900799 .start = dyn_event_seq_start,
800 .next = dyn_event_seq_next,
801 .stop = dyn_event_seq_stop,
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400802 .show = probes_seq_show
803};
804
805static int probes_open(struct inode *inode, struct file *file)
806{
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900807 int ret;
808
809 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900810 ret = dyn_events_release_all(&trace_kprobe_ops);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900811 if (ret < 0)
812 return ret;
813 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400814
815 return seq_open(file, &probes_seq_op);
816}
817
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400818static ssize_t probes_write(struct file *file, const char __user *buffer,
819 size_t count, loff_t *ppos)
820{
Tom Zanussi7e465ba2017-09-22 14:58:20 -0500821 return trace_parse_run_command(file, buffer, count, ppos,
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900822 create_or_delete_trace_kprobe);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400823}
824
825static const struct file_operations kprobe_events_ops = {
826 .owner = THIS_MODULE,
827 .open = probes_open,
828 .read = seq_read,
829 .llseek = seq_lseek,
830 .release = seq_release,
831 .write = probes_write,
832};
833
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400834/* Probes profiling interfaces */
835static int probes_profile_seq_show(struct seq_file *m, void *v)
836{
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900837 struct dyn_event *ev = v;
838 struct trace_kprobe *tk;
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400839
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900840 if (!is_trace_kprobe(ev))
841 return 0;
842
843 tk = to_trace_kprobe(ev);
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -0400844 seq_printf(m, " %-44s %15lu %15lu\n",
Marcin Nowakowskif18f97a2016-12-09 15:19:37 +0100845 trace_event_name(&tk->tp.call),
846 trace_kprobe_nhit(tk),
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900847 tk->rp.kp.nmissed);
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400848
849 return 0;
850}
851
852static const struct seq_operations profile_seq_op = {
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900853 .start = dyn_event_seq_start,
854 .next = dyn_event_seq_next,
855 .stop = dyn_event_seq_stop,
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400856 .show = probes_profile_seq_show
857};
858
859static int profile_open(struct inode *inode, struct file *file)
860{
861 return seq_open(file, &profile_seq_op);
862}
863
864static const struct file_operations kprobe_profile_ops = {
865 .owner = THIS_MODULE,
866 .open = profile_open,
867 .read = seq_read,
868 .llseek = seq_lseek,
869 .release = seq_release,
870};
871
Masami Hiramatsu53305922018-04-25 21:18:03 +0900872/* Kprobe specific fetch functions */
873
874/* Return the length of string -- including null terminal byte */
Masami Hiramatsu91784122018-04-25 21:19:01 +0900875static nokprobe_inline int
876fetch_store_strlen(unsigned long addr)
Masami Hiramatsu53305922018-04-25 21:18:03 +0900877{
Masami Hiramatsu53305922018-04-25 21:18:03 +0900878 int ret, len = 0;
879 u8 c;
880
Masami Hiramatsu53305922018-04-25 21:18:03 +0900881 do {
Masami Hiramatsu49ef5f42019-02-22 01:16:43 +0900882 ret = probe_kernel_read(&c, (u8 *)addr + len, 1);
Masami Hiramatsu53305922018-04-25 21:18:03 +0900883 len++;
884 } while (c && ret == 0 && len < MAX_STRING_SIZE);
885
Masami Hiramatsu91784122018-04-25 21:19:01 +0900886 return (ret < 0) ? ret : len;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900887}
888
889/*
890 * Fetch a null-terminated string. Caller MUST set *(u32 *)buf with max
891 * length and relative data location.
892 */
Masami Hiramatsu91784122018-04-25 21:19:01 +0900893static nokprobe_inline int
894fetch_store_string(unsigned long addr, void *dest, void *base)
Masami Hiramatsu53305922018-04-25 21:18:03 +0900895{
Masami Hiramatsu91784122018-04-25 21:19:01 +0900896 int maxlen = get_loc_len(*(u32 *)dest);
897 u8 *dst = get_loc_data(dest, base);
Masami Hiramatsu53305922018-04-25 21:18:03 +0900898 long ret;
899
Masami Hiramatsu91784122018-04-25 21:19:01 +0900900 if (unlikely(!maxlen))
901 return -ENOMEM;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900902 /*
903 * Try to get string again, since the string can be changed while
904 * probing.
905 */
906 ret = strncpy_from_unsafe(dst, (void *)addr, maxlen);
907
Masami Hiramatsu91784122018-04-25 21:19:01 +0900908 if (ret >= 0)
909 *(u32 *)dest = make_data_loc(ret, (void *)dst - base);
910 return ret;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900911}
912
Masami Hiramatsu9b960a32018-04-25 21:19:59 +0900913static nokprobe_inline int
914probe_mem_read(void *dest, void *src, size_t size)
915{
916 return probe_kernel_read(dest, src, size);
917}
918
Masami Hiramatsu53305922018-04-25 21:18:03 +0900919/* Note that we don't verify it, since the code does not come from user space */
920static int
921process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
Masami Hiramatsu91784122018-04-25 21:19:01 +0900922 void *base)
Masami Hiramatsu53305922018-04-25 21:18:03 +0900923{
924 unsigned long val;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900925
Masami Hiramatsua6682812018-08-29 01:18:43 +0900926retry:
Masami Hiramatsu53305922018-04-25 21:18:03 +0900927 /* 1st stage: get value from context */
928 switch (code->op) {
929 case FETCH_OP_REG:
930 val = regs_get_register(regs, code->param);
931 break;
932 case FETCH_OP_STACK:
933 val = regs_get_kernel_stack_nth(regs, code->param);
934 break;
935 case FETCH_OP_STACKP:
936 val = kernel_stack_pointer(regs);
937 break;
938 case FETCH_OP_RETVAL:
939 val = regs_return_value(regs);
940 break;
941 case FETCH_OP_IMM:
942 val = code->immediate;
943 break;
944 case FETCH_OP_COMM:
945 val = (unsigned long)current->comm;
946 break;
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900947#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
948 case FETCH_OP_ARG:
949 val = regs_get_kernel_argument(regs, code->param);
950 break;
951#endif
Masami Hiramatsua6682812018-08-29 01:18:43 +0900952 case FETCH_NOP_SYMBOL: /* Ignore a place holder */
953 code++;
954 goto retry;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900955 default:
956 return -EILSEQ;
957 }
958 code++;
959
Masami Hiramatsu9b960a32018-04-25 21:19:59 +0900960 return process_fetch_insn_bottom(code, val, dest, base);
Masami Hiramatsu53305922018-04-25 21:18:03 +0900961}
962NOKPROBE_SYMBOL(process_fetch_insn)
963
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400964/* Kprobe handler */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900965static nokprobe_inline void
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900966__kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs,
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400967 struct trace_event_file *trace_file)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400968{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400969 struct kprobe_trace_entry_head *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400970 struct ring_buffer_event *event;
Frederic Weisbecker8f8ffe22009-09-11 01:09:23 +0200971 struct ring_buffer *buffer;
Masami Hiramatsue09c8612010-07-05 15:54:45 -0300972 int size, dsize, pc;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400973 unsigned long irq_flags;
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -0400974 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400975
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400976 WARN_ON(call != trace_file->event_call);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900977
Steven Rostedt (Red Hat)09a50592015-05-13 15:21:25 -0400978 if (trace_trigger_soft_disabled(trace_file))
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -0500979 return;
Masami Hiramatsub8820082013-05-09 14:44:54 +0900980
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400981 local_save_flags(irq_flags);
982 pc = preempt_count();
983
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900984 dsize = __get_data_size(&tk->tp, regs);
985 size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400986
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400987 event = trace_event_buffer_lock_reserve(&buffer, trace_file,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900988 call->event.type,
989 size, irq_flags, pc);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400990 if (!event)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +0800991 return;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400992
993 entry = ring_buffer_event_data(event);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900994 entry->ip = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsu91784122018-04-25 21:19:01 +0900995 store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400996
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400997 event_trigger_unlock_commit_regs(trace_file, buffer, event,
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -0500998 entry, irq_flags, pc, regs);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400999}
1000
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001001static void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001002kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001003{
Oleg Nesterovb04d52e2013-06-20 19:38:14 +02001004 struct event_file_link *link;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001005
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001006 list_for_each_entry_rcu(link, &tk->tp.files, list)
1007 __kprobe_trace_func(tk, regs, link->file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001008}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001009NOKPROBE_SYMBOL(kprobe_trace_func);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001010
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001011/* Kretprobe handler */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001012static nokprobe_inline void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001013__kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001014 struct pt_regs *regs,
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001015 struct trace_event_file *trace_file)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001016{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001017 struct kretprobe_trace_entry_head *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001018 struct ring_buffer_event *event;
Frederic Weisbecker8f8ffe22009-09-11 01:09:23 +02001019 struct ring_buffer *buffer;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001020 int size, pc, dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001021 unsigned long irq_flags;
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001022 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001023
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001024 WARN_ON(call != trace_file->event_call);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001025
Steven Rostedt (Red Hat)09a50592015-05-13 15:21:25 -04001026 if (trace_trigger_soft_disabled(trace_file))
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -05001027 return;
Masami Hiramatsub8820082013-05-09 14:44:54 +09001028
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001029 local_save_flags(irq_flags);
1030 pc = preempt_count();
1031
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001032 dsize = __get_data_size(&tk->tp, regs);
1033 size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001034
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001035 event = trace_event_buffer_lock_reserve(&buffer, trace_file,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001036 call->event.type,
1037 size, irq_flags, pc);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001038 if (!event)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001039 return;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001040
1041 entry = ring_buffer_event_data(event);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001042 entry->func = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001043 entry->ret_ip = (unsigned long)ri->ret_addr;
Masami Hiramatsu91784122018-04-25 21:19:01 +09001044 store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001045
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001046 event_trigger_unlock_commit_regs(trace_file, buffer, event,
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -05001047 entry, irq_flags, pc, regs);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001048}
1049
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001050static void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001051kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001052 struct pt_regs *regs)
1053{
Oleg Nesterovb04d52e2013-06-20 19:38:14 +02001054 struct event_file_link *link;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001055
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001056 list_for_each_entry_rcu(link, &tk->tp.files, list)
1057 __kretprobe_trace_func(tk, ri, regs, link->file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001058}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001059NOKPROBE_SYMBOL(kretprobe_trace_func);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001060
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001061/* Event entry printers */
Masami Hiramatsub62fdd92013-05-13 20:58:39 +09001062static enum print_line_t
Steven Rostedta9a57762010-04-22 18:46:14 -04001063print_kprobe_event(struct trace_iterator *iter, int flags,
1064 struct trace_event *event)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001065{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001066 struct kprobe_trace_entry_head *field;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001067 struct trace_seq *s = &iter->seq;
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001068 struct trace_probe *tp;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001069
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001070 field = (struct kprobe_trace_entry_head *)iter->ent;
Steven Rostedt80decc72010-04-23 10:00:22 -04001071 tp = container_of(event, struct trace_probe, call.event);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001072
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -04001073 trace_seq_printf(s, "%s: (", trace_event_name(&tp->call));
Masami Hiramatsu6e9f23d2009-09-10 19:53:45 -04001074
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001075 if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001076 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001077
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001078 trace_seq_putc(s, ')');
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001079
Masami Hiramatsu56de7632018-04-25 21:16:36 +09001080 if (print_probe_args(s, tp->args, tp->nr_args,
1081 (u8 *)&field[1], field) < 0)
1082 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001083
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001084 trace_seq_putc(s, '\n');
1085 out:
1086 return trace_handle_return(s);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001087}
1088
Masami Hiramatsub62fdd92013-05-13 20:58:39 +09001089static enum print_line_t
Steven Rostedta9a57762010-04-22 18:46:14 -04001090print_kretprobe_event(struct trace_iterator *iter, int flags,
1091 struct trace_event *event)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001092{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001093 struct kretprobe_trace_entry_head *field;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001094 struct trace_seq *s = &iter->seq;
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001095 struct trace_probe *tp;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001096
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001097 field = (struct kretprobe_trace_entry_head *)iter->ent;
Steven Rostedt80decc72010-04-23 10:00:22 -04001098 tp = container_of(event, struct trace_probe, call.event);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001099
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -04001100 trace_seq_printf(s, "%s: (", trace_event_name(&tp->call));
Masami Hiramatsu6e9f23d2009-09-10 19:53:45 -04001101
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001102 if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001103 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001104
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001105 trace_seq_puts(s, " <- ");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001106
1107 if (!seq_print_ip_sym(s, field->func, flags & ~TRACE_ITER_SYM_OFFSET))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001108 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001109
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001110 trace_seq_putc(s, ')');
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001111
Masami Hiramatsu56de7632018-04-25 21:16:36 +09001112 if (print_probe_args(s, tp->args, tp->nr_args,
1113 (u8 *)&field[1], field) < 0)
1114 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001115
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001116 trace_seq_putc(s, '\n');
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001117
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001118 out:
1119 return trace_handle_return(s);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001120}
1121
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001122
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001123static int kprobe_event_define_fields(struct trace_event_call *event_call)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001124{
Masami Hiramatsueeb07b02018-04-25 21:17:05 +09001125 int ret;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001126 struct kprobe_trace_entry_head field;
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001127 struct trace_kprobe *tk = (struct trace_kprobe *)event_call->data;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001128
Masami Hiramatsua703d942009-10-07 18:28:07 -04001129 DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001130
Masami Hiramatsueeb07b02018-04-25 21:17:05 +09001131 return traceprobe_define_arg_fields(event_call, sizeof(field), &tk->tp);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001132}
1133
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001134static int kretprobe_event_define_fields(struct trace_event_call *event_call)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001135{
Masami Hiramatsueeb07b02018-04-25 21:17:05 +09001136 int ret;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001137 struct kretprobe_trace_entry_head field;
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001138 struct trace_kprobe *tk = (struct trace_kprobe *)event_call->data;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001139
Masami Hiramatsua703d942009-10-07 18:28:07 -04001140 DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0);
1141 DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001142
Masami Hiramatsueeb07b02018-04-25 21:17:05 +09001143 return traceprobe_define_arg_fields(event_call, sizeof(field), &tk->tp);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001144}
1145
Li Zefan07b139c2009-12-21 14:27:35 +08001146#ifdef CONFIG_PERF_EVENTS
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001147
1148/* Kprobe profile handler */
Josef Bacik9802d862017-12-11 11:36:48 -05001149static int
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001150kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs)
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001151{
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001152 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001153 struct kprobe_trace_entry_head *entry;
Peter Zijlstra1c024eca2010-05-19 14:02:22 +02001154 struct hlist_head *head;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001155 int size, __size, dsize;
Peter Zijlstra4ed7c922009-11-23 11:37:29 +01001156 int rctx;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001157
Josef Bacik9802d862017-12-11 11:36:48 -05001158 if (bpf_prog_array_valid(call)) {
Masami Hiramatsu66665ad2018-01-13 02:54:33 +09001159 unsigned long orig_ip = instruction_pointer(regs);
Josef Bacik9802d862017-12-11 11:36:48 -05001160 int ret;
1161
1162 ret = trace_call_bpf(call, regs);
1163
1164 /*
1165 * We need to check and see if we modified the pc of the
Masami Hiramatsucce188b2018-06-20 01:15:45 +09001166 * pt_regs, and if so return 1 so that we don't do the
1167 * single stepping.
Josef Bacik9802d862017-12-11 11:36:48 -05001168 */
Masami Hiramatsucce188b2018-06-20 01:15:45 +09001169 if (orig_ip != instruction_pointer(regs))
Josef Bacik9802d862017-12-11 11:36:48 -05001170 return 1;
Josef Bacik9802d862017-12-11 11:36:48 -05001171 if (!ret)
1172 return 0;
1173 }
Alexei Starovoitov25415172015-03-25 12:49:20 -07001174
Oleg Nesterov288e9842013-06-20 19:38:06 +02001175 head = this_cpu_ptr(call->perf_events);
1176 if (hlist_empty(head))
Josef Bacik9802d862017-12-11 11:36:48 -05001177 return 0;
Oleg Nesterov288e9842013-06-20 19:38:06 +02001178
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001179 dsize = __get_data_size(&tk->tp, regs);
1180 __size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu74ebb632009-09-14 16:49:28 -04001181 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1182 size -= sizeof(u32);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001183
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001184 entry = perf_trace_buf_alloc(size, NULL, &rctx);
Xiao Guangrong430ad5a2010-01-28 09:32:29 +08001185 if (!entry)
Josef Bacik9802d862017-12-11 11:36:48 -05001186 return 0;
Frederic Weisbeckerce71b9d2009-11-22 05:26:55 +01001187
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001188 entry->ip = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001189 memset(&entry[1], 0, dsize);
Masami Hiramatsu91784122018-04-25 21:19:01 +09001190 store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001191 perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs,
Peter Zijlstra8fd0fbb2017-10-11 09:45:29 +02001192 head, NULL);
Josef Bacik9802d862017-12-11 11:36:48 -05001193 return 0;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001194}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001195NOKPROBE_SYMBOL(kprobe_perf_func);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001196
1197/* Kretprobe profile handler */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001198static void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001199kretprobe_perf_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001200 struct pt_regs *regs)
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001201{
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001202 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001203 struct kretprobe_trace_entry_head *entry;
Peter Zijlstra1c024eca2010-05-19 14:02:22 +02001204 struct hlist_head *head;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001205 int size, __size, dsize;
Peter Zijlstra4ed7c922009-11-23 11:37:29 +01001206 int rctx;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001207
Yonghong Songe87c6bc382017-10-23 23:53:08 -07001208 if (bpf_prog_array_valid(call) && !trace_call_bpf(call, regs))
Alexei Starovoitov25415172015-03-25 12:49:20 -07001209 return;
1210
Oleg Nesterov288e9842013-06-20 19:38:06 +02001211 head = this_cpu_ptr(call->perf_events);
1212 if (hlist_empty(head))
1213 return;
1214
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001215 dsize = __get_data_size(&tk->tp, regs);
1216 __size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu74ebb632009-09-14 16:49:28 -04001217 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1218 size -= sizeof(u32);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001219
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001220 entry = perf_trace_buf_alloc(size, NULL, &rctx);
Xiao Guangrong430ad5a2010-01-28 09:32:29 +08001221 if (!entry)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001222 return;
Frederic Weisbeckerce71b9d2009-11-22 05:26:55 +01001223
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001224 entry->func = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsua1a138d2009-09-25 11:20:12 -07001225 entry->ret_ip = (unsigned long)ri->ret_addr;
Masami Hiramatsu91784122018-04-25 21:19:01 +09001226 store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001227 perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs,
Peter Zijlstra8fd0fbb2017-10-11 09:45:29 +02001228 head, NULL);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001229}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001230NOKPROBE_SYMBOL(kretprobe_perf_func);
Yonghong Song41bdc4b2018-05-24 11:21:09 -07001231
1232int bpf_get_kprobe_info(const struct perf_event *event, u32 *fd_type,
1233 const char **symbol, u64 *probe_offset,
1234 u64 *probe_addr, bool perf_type_tracepoint)
1235{
1236 const char *pevent = trace_event_name(event->tp_event);
1237 const char *group = event->tp_event->class->system;
1238 struct trace_kprobe *tk;
1239
1240 if (perf_type_tracepoint)
1241 tk = find_trace_kprobe(pevent, group);
1242 else
1243 tk = event->tp_event->data;
1244 if (!tk)
1245 return -EINVAL;
1246
1247 *fd_type = trace_kprobe_is_return(tk) ? BPF_FD_TYPE_KRETPROBE
1248 : BPF_FD_TYPE_KPROBE;
1249 if (tk->symbol) {
1250 *symbol = tk->symbol;
1251 *probe_offset = tk->rp.kp.offset;
1252 *probe_addr = 0;
1253 } else {
1254 *symbol = NULL;
1255 *probe_offset = 0;
1256 *probe_addr = (unsigned long)tk->rp.kp.addr;
1257 }
1258 return 0;
1259}
Li Zefan07b139c2009-12-21 14:27:35 +08001260#endif /* CONFIG_PERF_EVENTS */
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001261
Oleg Nesterov3fe3d612013-06-20 19:38:09 +02001262/*
1263 * called by perf_trace_init() or __ftrace_set_clr_event() under event_mutex.
1264 *
1265 * kprobe_trace_self_tests_init() does enable_trace_probe/disable_trace_probe
1266 * lockless, but we can't race with this __init function.
1267 */
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001268static int kprobe_register(struct trace_event_call *event,
Masami Hiramatsufbc19632014-04-17 17:18:00 +09001269 enum trace_reg type, void *data)
Steven Rostedt22392912010-04-21 12:27:06 -04001270{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001271 struct trace_kprobe *tk = (struct trace_kprobe *)event->data;
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001272 struct trace_event_file *file = data;
Masami Hiramatsu1538f882011-06-27 16:26:44 +09001273
Steven Rostedt22392912010-04-21 12:27:06 -04001274 switch (type) {
1275 case TRACE_REG_REGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001276 return enable_trace_kprobe(tk, file);
Steven Rostedt22392912010-04-21 12:27:06 -04001277 case TRACE_REG_UNREGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001278 return disable_trace_kprobe(tk, file);
Steven Rostedt22392912010-04-21 12:27:06 -04001279
1280#ifdef CONFIG_PERF_EVENTS
1281 case TRACE_REG_PERF_REGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001282 return enable_trace_kprobe(tk, NULL);
Steven Rostedt22392912010-04-21 12:27:06 -04001283 case TRACE_REG_PERF_UNREGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001284 return disable_trace_kprobe(tk, NULL);
Jiri Olsaceec0b62012-02-15 15:51:49 +01001285 case TRACE_REG_PERF_OPEN:
1286 case TRACE_REG_PERF_CLOSE:
Jiri Olsa489c75c2012-02-15 15:51:50 +01001287 case TRACE_REG_PERF_ADD:
1288 case TRACE_REG_PERF_DEL:
Jiri Olsaceec0b62012-02-15 15:51:49 +01001289 return 0;
Steven Rostedt22392912010-04-21 12:27:06 -04001290#endif
1291 }
1292 return 0;
1293}
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001294
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001295static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs)
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001296{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001297 struct trace_kprobe *tk = container_of(kp, struct trace_kprobe, rp.kp);
Josef Bacik9802d862017-12-11 11:36:48 -05001298 int ret = 0;
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001299
Martin KaFai Laua7636d92016-02-03 12:28:28 -08001300 raw_cpu_inc(*tk->nhit);
Masami Hiramatsu48182bd22013-05-09 14:44:36 +09001301
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001302 if (tk->tp.flags & TP_FLAG_TRACE)
1303 kprobe_trace_func(tk, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001304#ifdef CONFIG_PERF_EVENTS
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001305 if (tk->tp.flags & TP_FLAG_PROFILE)
Josef Bacik9802d862017-12-11 11:36:48 -05001306 ret = kprobe_perf_func(tk, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001307#endif
Josef Bacik9802d862017-12-11 11:36:48 -05001308 return ret;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001309}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001310NOKPROBE_SYMBOL(kprobe_dispatcher);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001311
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001312static int
1313kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs)
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001314{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001315 struct trace_kprobe *tk = container_of(ri->rp, struct trace_kprobe, rp);
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001316
Martin KaFai Laua7636d92016-02-03 12:28:28 -08001317 raw_cpu_inc(*tk->nhit);
Masami Hiramatsu48182bd22013-05-09 14:44:36 +09001318
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001319 if (tk->tp.flags & TP_FLAG_TRACE)
1320 kretprobe_trace_func(tk, ri, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001321#ifdef CONFIG_PERF_EVENTS
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001322 if (tk->tp.flags & TP_FLAG_PROFILE)
1323 kretprobe_perf_func(tk, ri, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001324#endif
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001325 return 0; /* We don't tweek kernel, so just return 0 */
1326}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001327NOKPROBE_SYMBOL(kretprobe_dispatcher);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001328
Steven Rostedta9a57762010-04-22 18:46:14 -04001329static struct trace_event_functions kretprobe_funcs = {
1330 .trace = print_kretprobe_event
1331};
1332
1333static struct trace_event_functions kprobe_funcs = {
1334 .trace = print_kprobe_event
1335};
1336
Song Liue12f03d2017-12-06 14:45:15 -08001337static inline void init_trace_event_call(struct trace_kprobe *tk,
1338 struct trace_event_call *call)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001339{
Li Zefanffb9f992010-05-24 16:24:52 +08001340 INIT_LIST_HEAD(&call->class->fields);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001341 if (trace_kprobe_is_return(tk)) {
Steven Rostedt80decc72010-04-23 10:00:22 -04001342 call->event.funcs = &kretprobe_funcs;
Steven Rostedt2e33af02010-04-22 10:35:55 -04001343 call->class->define_fields = kretprobe_event_define_fields;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001344 } else {
Steven Rostedt80decc72010-04-23 10:00:22 -04001345 call->event.funcs = &kprobe_funcs;
Steven Rostedt2e33af02010-04-22 10:35:55 -04001346 call->class->define_fields = kprobe_event_define_fields;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001347 }
Song Liue12f03d2017-12-06 14:45:15 -08001348
1349 call->flags = TRACE_EVENT_FL_KPROBE;
1350 call->class->reg = kprobe_register;
1351 call->data = tk;
1352}
1353
1354static int register_kprobe_event(struct trace_kprobe *tk)
1355{
1356 struct trace_event_call *call = &tk->tp.call;
1357 int ret = 0;
1358
1359 init_trace_event_call(tk, call);
1360
Masami Hiramatsu0a46c852018-04-25 21:19:30 +09001361 if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0)
Lai Jiangshana342a0282009-12-15 15:39:49 +08001362 return -ENOMEM;
Steven Rostedt (Red Hat)9023c932015-05-05 09:39:12 -04001363 ret = register_trace_event(&call->event);
Steven Rostedt32c0eda2010-04-23 10:38:03 -04001364 if (!ret) {
Lai Jiangshana342a0282009-12-15 15:39:49 +08001365 kfree(call->print_fmt);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001366 return -ENODEV;
Lai Jiangshana342a0282009-12-15 15:39:49 +08001367 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001368 ret = trace_add_event_call(call);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001369 if (ret) {
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -04001370 pr_info("Failed to register kprobe event: %s\n",
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -04001371 trace_event_name(call));
Lai Jiangshana342a0282009-12-15 15:39:49 +08001372 kfree(call->print_fmt);
Steven Rostedt (Red Hat)9023c932015-05-05 09:39:12 -04001373 unregister_trace_event(&call->event);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001374 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001375 return ret;
1376}
1377
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001378static int unregister_kprobe_event(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001379{
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -04001380 int ret;
1381
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001382 /* tp->event is unregistered in trace_remove_event_call() */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001383 ret = trace_remove_event_call(&tk->tp.call);
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -04001384 if (!ret)
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001385 kfree(tk->tp.call.print_fmt);
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -04001386 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001387}
1388
Song Liue12f03d2017-12-06 14:45:15 -08001389#ifdef CONFIG_PERF_EVENTS
1390/* create a trace_kprobe, but don't add it to global lists */
1391struct trace_event_call *
1392create_local_trace_kprobe(char *func, void *addr, unsigned long offs,
1393 bool is_return)
1394{
1395 struct trace_kprobe *tk;
1396 int ret;
1397 char *event;
1398
1399 /*
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001400 * local trace_kprobes are not added to dyn_event, so they are never
Song Liue12f03d2017-12-06 14:45:15 -08001401 * searched in find_trace_kprobe(). Therefore, there is no concern of
1402 * duplicated name here.
1403 */
1404 event = func ? func : "DUMMY_EVENT";
1405
1406 tk = alloc_trace_kprobe(KPROBE_EVENT_SYSTEM, event, (void *)addr, func,
1407 offs, 0 /* maxactive */, 0 /* nargs */,
1408 is_return);
1409
1410 if (IS_ERR(tk)) {
1411 pr_info("Failed to allocate trace_probe.(%d)\n",
1412 (int)PTR_ERR(tk));
1413 return ERR_CAST(tk);
1414 }
1415
1416 init_trace_event_call(tk, &tk->tp.call);
1417
Masami Hiramatsu0a46c852018-04-25 21:19:30 +09001418 if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) {
Song Liue12f03d2017-12-06 14:45:15 -08001419 ret = -ENOMEM;
1420 goto error;
1421 }
1422
1423 ret = __register_trace_kprobe(tk);
Jiri Olsa0fc8c352018-07-09 16:19:06 +02001424 if (ret < 0) {
1425 kfree(tk->tp.call.print_fmt);
Song Liue12f03d2017-12-06 14:45:15 -08001426 goto error;
Jiri Olsa0fc8c352018-07-09 16:19:06 +02001427 }
Song Liue12f03d2017-12-06 14:45:15 -08001428
1429 return &tk->tp.call;
1430error:
1431 free_trace_kprobe(tk);
1432 return ERR_PTR(ret);
1433}
1434
1435void destroy_local_trace_kprobe(struct trace_event_call *event_call)
1436{
1437 struct trace_kprobe *tk;
1438
1439 tk = container_of(event_call, struct trace_kprobe, tp.call);
1440
1441 if (trace_probe_is_enabled(&tk->tp)) {
1442 WARN_ON(1);
1443 return;
1444 }
1445
1446 __unregister_trace_kprobe(tk);
Jiri Olsa0fc8c352018-07-09 16:19:06 +02001447
1448 kfree(tk->tp.call.print_fmt);
Song Liue12f03d2017-12-06 14:45:15 -08001449 free_trace_kprobe(tk);
1450}
1451#endif /* CONFIG_PERF_EVENTS */
1452
Steven Rostedt (Red Hat)8434dc92015-01-20 12:13:40 -05001453/* Make a tracefs interface for controlling probe points */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001454static __init int init_kprobe_trace(void)
1455{
1456 struct dentry *d_tracer;
1457 struct dentry *entry;
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001458 int ret;
1459
1460 ret = dyn_event_register(&trace_kprobe_ops);
1461 if (ret)
1462 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001463
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001464 if (register_module_notifier(&trace_kprobe_module_nb))
Masami Hiramatsu61424312011-06-27 16:26:56 +09001465 return -EINVAL;
1466
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001467 d_tracer = tracing_init_dentry();
Steven Rostedt (Red Hat)14a5ae42015-01-20 11:14:16 -05001468 if (IS_ERR(d_tracer))
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001469 return 0;
1470
Steven Rostedt (Red Hat)8434dc92015-01-20 12:13:40 -05001471 entry = tracefs_create_file("kprobe_events", 0644, d_tracer,
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001472 NULL, &kprobe_events_ops);
1473
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001474 /* Event list interface */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001475 if (!entry)
Joe Perchesa395d6a2016-03-22 14:28:09 -07001476 pr_warn("Could not create tracefs 'kprobe_events' entry\n");
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001477
1478 /* Profile interface */
Steven Rostedt (Red Hat)8434dc92015-01-20 12:13:40 -05001479 entry = tracefs_create_file("kprobe_profile", 0444, d_tracer,
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001480 NULL, &kprobe_profile_ops);
1481
1482 if (!entry)
Joe Perchesa395d6a2016-03-22 14:28:09 -07001483 pr_warn("Could not create tracefs 'kprobe_profile' entry\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001484 return 0;
1485}
1486fs_initcall(init_kprobe_trace);
1487
1488
1489#ifdef CONFIG_FTRACE_STARTUP_TEST
Arnd Bergmann26a346f2017-02-01 17:57:56 +01001490static __init struct trace_event_file *
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001491find_trace_probe_file(struct trace_kprobe *tk, struct trace_array *tr)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001492{
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001493 struct trace_event_file *file;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001494
1495 list_for_each_entry(file, &tr->events, list)
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001496 if (file->event_call == &tk->tp.call)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001497 return file;
1498
1499 return NULL;
1500}
1501
Oleg Nesterov3fe3d612013-06-20 19:38:09 +02001502/*
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001503 * Nobody but us can call enable_trace_kprobe/disable_trace_kprobe at this
Oleg Nesterov3fe3d612013-06-20 19:38:09 +02001504 * stage, we can do this lockless.
1505 */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001506static __init int kprobe_trace_self_tests_init(void)
1507{
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001508 int ret, warn = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001509 int (*target)(int, int, int, int, int, int);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001510 struct trace_kprobe *tk;
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001511 struct trace_event_file *file;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001512
Yoshihiro YUNOMAE748ec3a2014-06-06 07:35:20 +09001513 if (tracing_is_disabled())
1514 return -ENODEV;
1515
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001516 target = kprobe_trace_selftest_target;
1517
1518 pr_info("Testing kprobe tracing: ");
1519
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001520 ret = trace_run_command("p:testprobe kprobe_trace_selftest_target $stack $stack0 +0($stack)",
1521 create_or_delete_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001522 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001523 pr_warn("error on probing function entry.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001524 warn++;
1525 } else {
1526 /* Enable trace point */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001527 tk = find_trace_kprobe("testprobe", KPROBE_EVENT_SYSTEM);
1528 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001529 pr_warn("error on getting new probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001530 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001531 } else {
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001532 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001533 if (WARN_ON_ONCE(file == NULL)) {
1534 pr_warn("error on getting probe file.\n");
1535 warn++;
1536 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001537 enable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001538 }
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001539 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001540
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001541 ret = trace_run_command("r:testprobe2 kprobe_trace_selftest_target $retval",
1542 create_or_delete_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001543 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001544 pr_warn("error on probing function return.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001545 warn++;
1546 } else {
1547 /* Enable trace point */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001548 tk = find_trace_kprobe("testprobe2", KPROBE_EVENT_SYSTEM);
1549 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001550 pr_warn("error on getting 2nd new probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001551 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001552 } else {
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001553 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001554 if (WARN_ON_ONCE(file == NULL)) {
1555 pr_warn("error on getting probe file.\n");
1556 warn++;
1557 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001558 enable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001559 }
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001560 }
1561
1562 if (warn)
1563 goto end;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001564
1565 ret = target(1, 2, 3, 4, 5, 6);
1566
Marcin Nowakowskid4d7ccc2016-12-09 15:19:38 +01001567 /*
1568 * Not expecting an error here, the check is only to prevent the
1569 * optimizer from removing the call to target() as otherwise there
1570 * are no side-effects and the call is never performed.
1571 */
1572 if (ret != 21)
1573 warn++;
1574
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001575 /* Disable trace points before removing it */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001576 tk = find_trace_kprobe("testprobe", KPROBE_EVENT_SYSTEM);
1577 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001578 pr_warn("error on getting test probe.\n");
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001579 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001580 } else {
Marcin Nowakowskid4d7ccc2016-12-09 15:19:38 +01001581 if (trace_kprobe_nhit(tk) != 1) {
1582 pr_warn("incorrect number of testprobe hits\n");
1583 warn++;
1584 }
1585
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001586 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001587 if (WARN_ON_ONCE(file == NULL)) {
1588 pr_warn("error on getting probe file.\n");
1589 warn++;
1590 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001591 disable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001592 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001593
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001594 tk = find_trace_kprobe("testprobe2", KPROBE_EVENT_SYSTEM);
1595 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001596 pr_warn("error on getting 2nd test probe.\n");
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001597 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001598 } else {
Marcin Nowakowskid4d7ccc2016-12-09 15:19:38 +01001599 if (trace_kprobe_nhit(tk) != 1) {
1600 pr_warn("incorrect number of testprobe2 hits\n");
1601 warn++;
1602 }
1603
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001604 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001605 if (WARN_ON_ONCE(file == NULL)) {
1606 pr_warn("error on getting probe file.\n");
1607 warn++;
1608 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001609 disable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001610 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001611
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001612 ret = trace_run_command("-:testprobe", create_or_delete_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001613 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001614 pr_warn("error on deleting a probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001615 warn++;
1616 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001617
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001618 ret = trace_run_command("-:testprobe2", create_or_delete_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001619 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001620 pr_warn("error on deleting a probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001621 warn++;
1622 }
1623
1624end:
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001625 ret = dyn_events_release_all(&trace_kprobe_ops);
1626 if (WARN_ON_ONCE(ret)) {
1627 pr_warn("error on cleaning up probes.\n");
1628 warn++;
1629 }
Thomas Gleixner30e7d8942017-05-17 10:19:49 +02001630 /*
1631 * Wait for the optimizer work to finish. Otherwise it might fiddle
1632 * with probes in already freed __init text.
1633 */
1634 wait_for_kprobe_optimizer();
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001635 if (warn)
1636 pr_cont("NG: Some tests are failed. Please check them.\n");
1637 else
1638 pr_cont("OK\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001639 return 0;
1640}
1641
1642late_initcall(kprobe_trace_self_tests_init);
1643
1644#endif