blob: 99592c27465e1156a0dce1dd2d953aef9ef3e8c8 [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
Masami Hiramatsu413d37d2009-08-13 16:35:11 -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 Hiramatsuda346342010-08-27 20:39:12 +0900224 if (!event || !is_good_name(event)) {
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
Masami Hiramatsuda346342010-08-27 20:39:12 +0900234 if (!group || !is_good_name(group)) {
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500235 ret = -EINVAL;
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400236 goto error;
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500237 }
238
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900239 tk->tp.class.system = kstrdup(group, GFP_KERNEL);
240 if (!tk->tp.class.system)
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400241 goto error;
242
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900243 dyn_event_init(&tk->devent, &trace_kprobe_ops);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900244 INIT_LIST_HEAD(&tk->tp.files);
245 return tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400246error:
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900247 kfree(tk->tp.call.name);
248 kfree(tk->symbol);
Martin KaFai Laua7636d92016-02-03 12:28:28 -0800249 free_percpu(tk->nhit);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900250 kfree(tk);
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500251 return ERR_PTR(ret);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400252}
253
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900254static void free_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400255{
256 int i;
257
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900258 if (!tk)
259 return;
260
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900261 for (i = 0; i < tk->tp.nr_args; i++)
262 traceprobe_free_probe_arg(&tk->tp.args[i]);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400263
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900264 kfree(tk->tp.call.class->system);
265 kfree(tk->tp.call.name);
266 kfree(tk->symbol);
Martin KaFai Laua7636d92016-02-03 12:28:28 -0800267 free_percpu(tk->nhit);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900268 kfree(tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400269}
270
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900271static struct trace_kprobe *find_trace_kprobe(const char *event,
272 const char *group)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400273{
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900274 struct dyn_event *pos;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900275 struct trace_kprobe *tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400276
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900277 for_each_trace_kprobe(tk, pos)
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -0400278 if (strcmp(trace_event_name(&tk->tp.call), event) == 0 &&
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900279 strcmp(tk->tp.call.class->system, group) == 0)
280 return tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400281 return NULL;
282}
283
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400284static inline int __enable_trace_kprobe(struct trace_kprobe *tk)
285{
286 int ret = 0;
287
288 if (trace_probe_is_registered(&tk->tp) && !trace_kprobe_has_gone(tk)) {
289 if (trace_kprobe_is_return(tk))
290 ret = enable_kretprobe(&tk->rp);
291 else
292 ret = enable_kprobe(&tk->rp.kp);
293 }
294
295 return ret;
296}
297
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200298/*
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900299 * Enable trace_probe
300 * if the file is NULL, enable "perf" handler, or enable "trace" handler.
301 */
302static int
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400303enable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900304{
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400305 struct event_file_link *link;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900306 int ret = 0;
307
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900308 if (file) {
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200309 link = kmalloc(sizeof(*link), GFP_KERNEL);
310 if (!link) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900311 ret = -ENOMEM;
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200312 goto out;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900313 }
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900314
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200315 link->file = file;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900316 list_add_tail_rcu(&link->list, &tk->tp.files);
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200317
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900318 tk->tp.flags |= TP_FLAG_TRACE;
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400319 ret = __enable_trace_kprobe(tk);
320 if (ret) {
321 list_del_rcu(&link->list);
Artem Savkov57ea2a32018-07-25 16:20:38 +0200322 kfree(link);
323 tk->tp.flags &= ~TP_FLAG_TRACE;
Artem Savkov57ea2a32018-07-25 16:20:38 +0200324 }
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400325
326 } else {
327 tk->tp.flags |= TP_FLAG_PROFILE;
328 ret = __enable_trace_kprobe(tk);
329 if (ret)
330 tk->tp.flags &= ~TP_FLAG_PROFILE;
Artem Savkov57ea2a32018-07-25 16:20:38 +0200331 }
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200332 out:
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900333 return ret;
334}
335
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900336/*
337 * Disable trace_probe
338 * if the file is NULL, disable "perf" handler, or disable "trace" handler.
339 */
340static int
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400341disable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900342{
Masami Hiramatsua232e272013-07-09 18:35:26 +0900343 struct event_file_link *link = NULL;
344 int wait = 0;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900345 int ret = 0;
346
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900347 if (file) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900348 link = find_event_file_link(&tk->tp, file);
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200349 if (!link) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900350 ret = -EINVAL;
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200351 goto out;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900352 }
353
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200354 list_del_rcu(&link->list);
Masami Hiramatsua232e272013-07-09 18:35:26 +0900355 wait = 1;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900356 if (!list_empty(&tk->tp.files))
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200357 goto out;
358
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900359 tk->tp.flags &= ~TP_FLAG_TRACE;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900360 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900361 tk->tp.flags &= ~TP_FLAG_PROFILE;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900362
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900363 if (!trace_probe_is_enabled(&tk->tp) && trace_probe_is_registered(&tk->tp)) {
364 if (trace_kprobe_is_return(tk))
365 disable_kretprobe(&tk->rp);
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900366 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900367 disable_kprobe(&tk->rp.kp);
Masami Hiramatsua232e272013-07-09 18:35:26 +0900368 wait = 1;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900369 }
Song Liue12f03d2017-12-06 14:45:15 -0800370
371 /*
372 * if tk is not added to any list, it must be a local trace_kprobe
373 * created with perf_event_open. We don't need to wait for these
374 * trace_kprobes
375 */
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900376 if (list_empty(&tk->devent.list))
Song Liue12f03d2017-12-06 14:45:15 -0800377 wait = 0;
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200378 out:
Masami Hiramatsua232e272013-07-09 18:35:26 +0900379 if (wait) {
380 /*
381 * Synchronize with kprobe_trace_func/kretprobe_trace_func
382 * to ensure disabled (all running handlers are finished).
383 * This is not only for kfree(), but also the caller,
384 * trace_remove_event_call() supposes it for releasing
385 * event_call related objects, which will be accessed in
386 * the kprobe_trace_func/kretprobe_trace_func.
387 */
Paul E. McKenney74401722018-11-06 18:44:52 -0800388 synchronize_rcu();
Masami Hiramatsua232e272013-07-09 18:35:26 +0900389 kfree(link); /* Ignored if link == NULL */
390 }
391
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900392 return ret;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900393}
394
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900395#if defined(CONFIG_KPROBES_ON_FTRACE) && \
396 !defined(CONFIG_KPROBE_EVENTS_ON_NOTRACE)
397static bool within_notrace_func(struct trace_kprobe *tk)
398{
399 unsigned long offset, size, addr;
400
401 addr = trace_kprobe_address(tk);
Masami Hiramatsu6bc6c772018-08-02 16:50:48 +0900402 if (!addr || !kallsyms_lookup_size_offset(addr, &size, &offset))
403 return false;
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900404
Masami Hiramatsu9161a862018-08-21 22:04:57 +0900405 /* Get the entry address of the target function */
406 addr -= offset;
407
408 /*
409 * Since ftrace_location_range() does inclusive range check, we need
410 * to subtract 1 byte from the end address.
411 */
412 return !ftrace_location_range(addr, addr + size - 1);
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900413}
414#else
415#define within_notrace_func(tk) (false)
416#endif
417
Masami Hiramatsu61424312011-06-27 16:26:56 +0900418/* Internal register function - just handle k*probes and flags */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900419static int __register_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +0900420{
Masami Hiramatsua6682812018-08-29 01:18:43 +0900421 int i, ret;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900422
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900423 if (trace_probe_is_registered(&tk->tp))
Masami Hiramatsu61424312011-06-27 16:26:56 +0900424 return -EINVAL;
425
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900426 if (within_notrace_func(tk)) {
427 pr_warn("Could not probe notrace function %s\n",
428 trace_kprobe_symbol(tk));
429 return -EINVAL;
430 }
431
Masami Hiramatsua6682812018-08-29 01:18:43 +0900432 for (i = 0; i < tk->tp.nr_args; i++) {
433 ret = traceprobe_update_arg(&tk->tp.args[i]);
434 if (ret)
435 return ret;
436 }
437
Masami Hiramatsu61424312011-06-27 16:26:56 +0900438 /* Set/clear disabled flag according to tp->flag */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900439 if (trace_probe_is_enabled(&tk->tp))
440 tk->rp.kp.flags &= ~KPROBE_FLAG_DISABLED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900441 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900442 tk->rp.kp.flags |= KPROBE_FLAG_DISABLED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900443
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900444 if (trace_kprobe_is_return(tk))
445 ret = register_kretprobe(&tk->rp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900446 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900447 ret = register_kprobe(&tk->rp.kp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900448
Masami Hiramatsu59158ec2018-08-29 01:18:15 +0900449 if (ret == 0) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900450 tk->tp.flags |= TP_FLAG_REGISTERED;
Masami Hiramatsu59158ec2018-08-29 01:18:15 +0900451 } else if (ret == -EILSEQ) {
452 pr_warn("Probing address(0x%p) is not an instruction boundary.\n",
453 tk->rp.kp.addr);
454 ret = -EINVAL;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900455 }
Masami Hiramatsu61424312011-06-27 16:26:56 +0900456 return ret;
457}
458
459/* Internal unregister function - just handle k*probes and flags */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900460static void __unregister_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +0900461{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900462 if (trace_probe_is_registered(&tk->tp)) {
463 if (trace_kprobe_is_return(tk))
464 unregister_kretprobe(&tk->rp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900465 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900466 unregister_kprobe(&tk->rp.kp);
467 tk->tp.flags &= ~TP_FLAG_REGISTERED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900468 /* Cleanup kprobe for reuse */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900469 if (tk->rp.kp.symbol_name)
470 tk->rp.kp.addr = NULL;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900471 }
472}
473
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900474/* Unregister a trace_probe and probe_event */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900475static int unregister_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400476{
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900477 /* Enabled event can not be unregistered */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900478 if (trace_probe_is_enabled(&tk->tp))
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900479 return -EBUSY;
480
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -0400481 /* Will fail if probe is being used by ftrace or perf */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900482 if (unregister_kprobe_event(tk))
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -0400483 return -EBUSY;
484
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900485 __unregister_trace_kprobe(tk);
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900486 dyn_event_remove(&tk->devent);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900487
488 return 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400489}
490
491/* Register a trace_probe and probe_event */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900492static int register_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400493{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900494 struct trace_kprobe *old_tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400495 int ret;
496
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900497 mutex_lock(&event_mutex);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400498
Masami Hiramatsu61424312011-06-27 16:26:56 +0900499 /* Delete old (same name) event if exist */
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -0400500 old_tk = find_trace_kprobe(trace_event_name(&tk->tp.call),
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -0400501 tk->tp.call.class->system);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900502 if (old_tk) {
503 ret = unregister_trace_kprobe(old_tk);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900504 if (ret < 0)
505 goto end;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900506 free_trace_kprobe(old_tk);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400507 }
Masami Hiramatsu61424312011-06-27 16:26:56 +0900508
509 /* Register new event */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900510 ret = register_kprobe_event(tk);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400511 if (ret) {
Joe Perchesa395d6a2016-03-22 14:28:09 -0700512 pr_warn("Failed to register probe event(%d)\n", ret);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400513 goto end;
514 }
515
Masami Hiramatsu61424312011-06-27 16:26:56 +0900516 /* Register k*probe */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900517 ret = __register_trace_kprobe(tk);
Masami Hiramatsu59158ec2018-08-29 01:18:15 +0900518 if (ret == -ENOENT && !trace_kprobe_module_exist(tk)) {
519 pr_warn("This probe might be able to register after target module is loaded. Continue.\n");
520 ret = 0;
521 }
522
Masami Hiramatsu61424312011-06-27 16:26:56 +0900523 if (ret < 0)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900524 unregister_kprobe_event(tk);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900525 else
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900526 dyn_event_add(&tk->devent);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900527
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400528end:
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900529 mutex_unlock(&event_mutex);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400530 return ret;
531}
532
Masami Hiramatsu61424312011-06-27 16:26:56 +0900533/* Module notifier call back, checking event on the module */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900534static int trace_kprobe_module_callback(struct notifier_block *nb,
Masami Hiramatsu61424312011-06-27 16:26:56 +0900535 unsigned long val, void *data)
536{
537 struct module *mod = data;
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900538 struct dyn_event *pos;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900539 struct trace_kprobe *tk;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900540 int ret;
541
542 if (val != MODULE_STATE_COMING)
543 return NOTIFY_DONE;
544
545 /* Update probes on coming module */
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900546 mutex_lock(&event_mutex);
547 for_each_trace_kprobe(tk, pos) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900548 if (trace_kprobe_within_module(tk, mod)) {
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900549 /* Don't need to check busy - this should have gone. */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900550 __unregister_trace_kprobe(tk);
551 ret = __register_trace_kprobe(tk);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900552 if (ret)
Joe Perchesa395d6a2016-03-22 14:28:09 -0700553 pr_warn("Failed to re-register probe %s on %s: %d\n",
554 trace_event_name(&tk->tp.call),
555 mod->name, ret);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900556 }
557 }
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900558 mutex_unlock(&event_mutex);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900559
560 return NOTIFY_DONE;
561}
562
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900563static struct notifier_block trace_kprobe_module_nb = {
564 .notifier_call = trace_kprobe_module_callback,
Masami Hiramatsu61424312011-06-27 16:26:56 +0900565 .priority = 1 /* Invoked after kprobe module callback */
566};
567
Naveen N. Raofca18a42017-07-08 00:27:30 +0530568/* Convert certain expected symbols into '_' when generating event names */
569static inline void sanitize_event_name(char *name)
570{
571 while (*name++ != '\0')
572 if (*name == ':' || *name == '.')
573 *name = '_';
574}
575
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900576static int trace_kprobe_create(int argc, const char *argv[])
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400577{
578 /*
579 * Argument syntax:
Alban Crequy696ced42017-04-03 12:36:22 +0200580 * - Add kprobe:
581 * p[:[GRP/]EVENT] [MOD:]KSYM[+OFFS]|KADDR [FETCHARGS]
582 * - Add kretprobe:
583 * r[MAXACTIVE][:[GRP/]EVENT] [MOD:]KSYM[+0] [FETCHARGS]
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400584 * Fetch args:
Masami Hiramatsu2e06ff62009-10-07 18:27:59 -0400585 * $retval : fetch return value
586 * $stack : fetch stack address
587 * $stackN : fetch Nth of stack (N:0-)
Omar Sandoval35abb672016-06-08 18:38:02 -0700588 * $comm : fetch current task comm
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400589 * @ADDR : fetch memory at ADDR (ADDR should be in kernel)
590 * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol)
591 * %REG : fetch register REG
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400592 * Dereferencing memory fetch:
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400593 * +|-offs(ARG) : fetch memory at ARG +|- offs address.
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400594 * Alias name of args:
595 * NAME=FETCHARG : set NAME as alias of FETCHARG.
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400596 * Type of args:
597 * FETCHARG:TYPE : use TYPE instead of unsigned long.
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400598 */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900599 struct trace_kprobe *tk;
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900600 int i, len, ret = 0;
601 bool is_return = false;
602 char *symbol = NULL, *tmp = NULL;
603 const char *event = NULL, *group = KPROBE_EVENT_SYSTEM;
Alban Crequy696ced42017-04-03 12:36:22 +0200604 int maxactive = 0;
Masami Hiramatsuc5d343b2018-03-17 21:38:10 +0900605 long offset = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400606 void *addr = NULL;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200607 char buf[MAX_EVENT_NAME_LEN];
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900608 unsigned int flags = TPARG_FL_KERNEL;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400609
Andrea Righi8b05a3a2019-01-11 07:01:13 +0100610 switch (argv[0][0]) {
611 case 'r':
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530612 is_return = true;
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900613 flags |= TPARG_FL_RETURN;
Andrea Righi8b05a3a2019-01-11 07:01:13 +0100614 break;
615 case 'p':
616 break;
617 default:
618 return -ECANCELED;
619 }
620 if (argc < 2)
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900621 return -ECANCELED;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400622
Alban Crequy696ced42017-04-03 12:36:22 +0200623 event = strchr(&argv[0][1], ':');
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900624 if (event)
Alban Crequy696ced42017-04-03 12:36:22 +0200625 event++;
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900626
Alban Crequy696ced42017-04-03 12:36:22 +0200627 if (is_return && isdigit(argv[0][1])) {
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900628 if (event)
629 len = event - &argv[0][1] - 1;
630 else
631 len = strlen(&argv[0][1]);
632 if (len > MAX_EVENT_NAME_LEN - 1)
633 return -E2BIG;
634 memcpy(buf, &argv[0][1], len);
635 buf[len] = '\0';
636 ret = kstrtouint(buf, 0, &maxactive);
Alban Crequy696ced42017-04-03 12:36:22 +0200637 if (ret) {
638 pr_info("Failed to parse maxactive.\n");
639 return ret;
640 }
641 /* kretprobes instances are iterated over via a list. The
642 * maximum should stay reasonable.
643 */
644 if (maxactive > KRETPROBE_MAXACTIVE_MAX) {
645 pr_info("Maxactive is too big (%d > %d).\n",
646 maxactive, KRETPROBE_MAXACTIVE_MAX);
647 return -E2BIG;
648 }
649 }
650
Sabrina Dubroca9e52b322017-06-22 11:24:42 +0200651 /* try to parse an address. if that fails, try to read the
652 * input as a symbol. */
653 if (kstrtoul(argv[1], 0, (unsigned long *)&addr)) {
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900654 /* Check whether uprobe event specified */
655 if (strchr(argv[1], '/') && strchr(argv[1], ':'))
656 return -ECANCELED;
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) {
Sabrina Dubroca9e52b322017-06-22 11:24:42 +0200664 pr_info("Failed to parse either an address or a symbol.\n");
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900665 goto out;
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)) {
Steven Rostedt (VMware)d0e02572017-02-27 11:52:04 -0500670 pr_info("Given offset is not valid for return probe.\n");
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900671 ret = -EINVAL;
672 goto out;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400673 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400674 }
Masami Hiramatsua82378d2009-08-13 16:35:18 -0400675 argc -= 2; argv += 2;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400676
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900677 if (event) {
678 ret = traceprobe_parse_event_name(&event, &group, buf);
679 if (ret)
680 goto out;
681 } 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,
695 argc, is_return);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900696 if (IS_ERR(tk)) {
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400697 pr_info("Failed to allocate trace_probe.(%d)\n",
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900698 (int)PTR_ERR(tk));
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900699 ret = PTR_ERR(tk);
700 goto out;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400701 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400702
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400703 /* parse arguments */
Masami Hiramatsua82378d2009-08-13 16:35:18 -0400704 for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900705 tmp = kstrdup(argv[i], GFP_KERNEL);
706 if (!tmp) {
Masami Hiramatsuba8665d2009-11-30 19:19:20 -0500707 ret = -ENOMEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400708 goto error;
709 }
Masami Hiramatsuda346342010-08-27 20:39:12 +0900710
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900711 ret = traceprobe_parse_probe_arg(&tk->tp, i, tmp, flags);
712 kfree(tmp);
Masami Hiramatsud00bbea92018-11-05 18:01:40 +0900713 if (ret)
Masami Hiramatsuda346342010-08-27 20:39:12 +0900714 goto error;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400715 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400716
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900717 ret = register_trace_kprobe(tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400718 if (ret)
719 goto error;
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900720out:
721 kfree(symbol);
722 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400723
724error:
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900725 free_trace_kprobe(tk);
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900726 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400727}
728
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900729static int create_or_delete_trace_kprobe(int argc, char **argv)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400730{
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900731 int ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400732
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900733 if (argv[0][0] == '-')
734 return dyn_event_release(argc, argv, &trace_kprobe_ops);
735
736 ret = trace_kprobe_create(argc, (const char **)argv);
737 return ret == -ECANCELED ? -EINVAL : ret;
738}
739
740static int trace_kprobe_release(struct dyn_event *ev)
741{
742 struct trace_kprobe *tk = to_trace_kprobe(ev);
743 int ret = unregister_trace_kprobe(tk);
744
745 if (!ret)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900746 free_trace_kprobe(tk);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900747 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400748}
749
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900750static int trace_kprobe_show(struct seq_file *m, struct dyn_event *ev)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400751{
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900752 struct trace_kprobe *tk = to_trace_kprobe(ev);
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400753 int i;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400754
Rasmus Villemoesfa6f0cc2014-11-08 21:42:10 +0100755 seq_putc(m, trace_kprobe_is_return(tk) ? 'r' : 'p');
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -0400756 seq_printf(m, ":%s/%s", tk->tp.call.class->system,
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -0400757 trace_event_name(&tk->tp.call));
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400758
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900759 if (!tk->symbol)
760 seq_printf(m, " 0x%p", tk->rp.kp.addr);
761 else if (tk->rp.kp.offset)
762 seq_printf(m, " %s+%u", trace_kprobe_symbol(tk),
763 tk->rp.kp.offset);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400764 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900765 seq_printf(m, " %s", trace_kprobe_symbol(tk));
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400766
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900767 for (i = 0; i < tk->tp.nr_args; i++)
768 seq_printf(m, " %s=%s", tk->tp.args[i].name, tk->tp.args[i].comm);
Rasmus Villemoesfa6f0cc2014-11-08 21:42:10 +0100769 seq_putc(m, '\n');
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400770
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400771 return 0;
772}
773
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900774static int probes_seq_show(struct seq_file *m, void *v)
775{
776 struct dyn_event *ev = v;
777
778 if (!is_trace_kprobe(ev))
779 return 0;
780
781 return trace_kprobe_show(m, ev);
782}
783
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400784static const struct seq_operations probes_seq_op = {
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900785 .start = dyn_event_seq_start,
786 .next = dyn_event_seq_next,
787 .stop = dyn_event_seq_stop,
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400788 .show = probes_seq_show
789};
790
791static int probes_open(struct inode *inode, struct file *file)
792{
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900793 int ret;
794
795 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900796 ret = dyn_events_release_all(&trace_kprobe_ops);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900797 if (ret < 0)
798 return ret;
799 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400800
801 return seq_open(file, &probes_seq_op);
802}
803
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400804static ssize_t probes_write(struct file *file, const char __user *buffer,
805 size_t count, loff_t *ppos)
806{
Tom Zanussi7e465ba2017-09-22 14:58:20 -0500807 return trace_parse_run_command(file, buffer, count, ppos,
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900808 create_or_delete_trace_kprobe);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400809}
810
811static const struct file_operations kprobe_events_ops = {
812 .owner = THIS_MODULE,
813 .open = probes_open,
814 .read = seq_read,
815 .llseek = seq_lseek,
816 .release = seq_release,
817 .write = probes_write,
818};
819
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400820/* Probes profiling interfaces */
821static int probes_profile_seq_show(struct seq_file *m, void *v)
822{
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900823 struct dyn_event *ev = v;
824 struct trace_kprobe *tk;
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400825
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900826 if (!is_trace_kprobe(ev))
827 return 0;
828
829 tk = to_trace_kprobe(ev);
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -0400830 seq_printf(m, " %-44s %15lu %15lu\n",
Marcin Nowakowskif18f97a2016-12-09 15:19:37 +0100831 trace_event_name(&tk->tp.call),
832 trace_kprobe_nhit(tk),
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900833 tk->rp.kp.nmissed);
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400834
835 return 0;
836}
837
838static const struct seq_operations profile_seq_op = {
Masami Hiramatsu6212dd22018-11-05 18:02:36 +0900839 .start = dyn_event_seq_start,
840 .next = dyn_event_seq_next,
841 .stop = dyn_event_seq_stop,
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400842 .show = probes_profile_seq_show
843};
844
845static int profile_open(struct inode *inode, struct file *file)
846{
847 return seq_open(file, &profile_seq_op);
848}
849
850static const struct file_operations kprobe_profile_ops = {
851 .owner = THIS_MODULE,
852 .open = profile_open,
853 .read = seq_read,
854 .llseek = seq_lseek,
855 .release = seq_release,
856};
857
Masami Hiramatsu53305922018-04-25 21:18:03 +0900858/* Kprobe specific fetch functions */
859
860/* Return the length of string -- including null terminal byte */
Masami Hiramatsu91784122018-04-25 21:19:01 +0900861static nokprobe_inline int
862fetch_store_strlen(unsigned long addr)
Masami Hiramatsu53305922018-04-25 21:18:03 +0900863{
Masami Hiramatsu53305922018-04-25 21:18:03 +0900864 int ret, len = 0;
865 u8 c;
866
Masami Hiramatsu53305922018-04-25 21:18:03 +0900867 do {
Masami Hiramatsu49ef5f42019-02-22 01:16:43 +0900868 ret = probe_kernel_read(&c, (u8 *)addr + len, 1);
Masami Hiramatsu53305922018-04-25 21:18:03 +0900869 len++;
870 } while (c && ret == 0 && len < MAX_STRING_SIZE);
871
Masami Hiramatsu91784122018-04-25 21:19:01 +0900872 return (ret < 0) ? ret : len;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900873}
874
875/*
876 * Fetch a null-terminated string. Caller MUST set *(u32 *)buf with max
877 * length and relative data location.
878 */
Masami Hiramatsu91784122018-04-25 21:19:01 +0900879static nokprobe_inline int
880fetch_store_string(unsigned long addr, void *dest, void *base)
Masami Hiramatsu53305922018-04-25 21:18:03 +0900881{
Masami Hiramatsu91784122018-04-25 21:19:01 +0900882 int maxlen = get_loc_len(*(u32 *)dest);
883 u8 *dst = get_loc_data(dest, base);
Masami Hiramatsu53305922018-04-25 21:18:03 +0900884 long ret;
885
Masami Hiramatsu91784122018-04-25 21:19:01 +0900886 if (unlikely(!maxlen))
887 return -ENOMEM;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900888 /*
889 * Try to get string again, since the string can be changed while
890 * probing.
891 */
892 ret = strncpy_from_unsafe(dst, (void *)addr, maxlen);
893
Masami Hiramatsu91784122018-04-25 21:19:01 +0900894 if (ret >= 0)
895 *(u32 *)dest = make_data_loc(ret, (void *)dst - base);
896 return ret;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900897}
898
Masami Hiramatsu9b960a32018-04-25 21:19:59 +0900899static nokprobe_inline int
900probe_mem_read(void *dest, void *src, size_t size)
901{
902 return probe_kernel_read(dest, src, size);
903}
904
Masami Hiramatsu53305922018-04-25 21:18:03 +0900905/* Note that we don't verify it, since the code does not come from user space */
906static int
907process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
Masami Hiramatsu91784122018-04-25 21:19:01 +0900908 void *base)
Masami Hiramatsu53305922018-04-25 21:18:03 +0900909{
910 unsigned long val;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900911
Masami Hiramatsua6682812018-08-29 01:18:43 +0900912retry:
Masami Hiramatsu53305922018-04-25 21:18:03 +0900913 /* 1st stage: get value from context */
914 switch (code->op) {
915 case FETCH_OP_REG:
916 val = regs_get_register(regs, code->param);
917 break;
918 case FETCH_OP_STACK:
919 val = regs_get_kernel_stack_nth(regs, code->param);
920 break;
921 case FETCH_OP_STACKP:
922 val = kernel_stack_pointer(regs);
923 break;
924 case FETCH_OP_RETVAL:
925 val = regs_return_value(regs);
926 break;
927 case FETCH_OP_IMM:
928 val = code->immediate;
929 break;
930 case FETCH_OP_COMM:
931 val = (unsigned long)current->comm;
932 break;
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900933#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
934 case FETCH_OP_ARG:
935 val = regs_get_kernel_argument(regs, code->param);
936 break;
937#endif
Masami Hiramatsua6682812018-08-29 01:18:43 +0900938 case FETCH_NOP_SYMBOL: /* Ignore a place holder */
939 code++;
940 goto retry;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900941 default:
942 return -EILSEQ;
943 }
944 code++;
945
Masami Hiramatsu9b960a32018-04-25 21:19:59 +0900946 return process_fetch_insn_bottom(code, val, dest, base);
Masami Hiramatsu53305922018-04-25 21:18:03 +0900947}
948NOKPROBE_SYMBOL(process_fetch_insn)
949
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400950/* Kprobe handler */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900951static nokprobe_inline void
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900952__kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs,
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400953 struct trace_event_file *trace_file)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400954{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400955 struct kprobe_trace_entry_head *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400956 struct ring_buffer_event *event;
Frederic Weisbecker8f8ffe22009-09-11 01:09:23 +0200957 struct ring_buffer *buffer;
Masami Hiramatsue09c8612010-07-05 15:54:45 -0300958 int size, dsize, pc;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400959 unsigned long irq_flags;
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -0400960 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400961
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400962 WARN_ON(call != trace_file->event_call);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900963
Steven Rostedt (Red Hat)09a50592015-05-13 15:21:25 -0400964 if (trace_trigger_soft_disabled(trace_file))
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -0500965 return;
Masami Hiramatsub8820082013-05-09 14:44:54 +0900966
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400967 local_save_flags(irq_flags);
968 pc = preempt_count();
969
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900970 dsize = __get_data_size(&tk->tp, regs);
971 size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400972
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400973 event = trace_event_buffer_lock_reserve(&buffer, trace_file,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900974 call->event.type,
975 size, irq_flags, pc);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400976 if (!event)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +0800977 return;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400978
979 entry = ring_buffer_event_data(event);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900980 entry->ip = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsu91784122018-04-25 21:19:01 +0900981 store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400982
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400983 event_trigger_unlock_commit_regs(trace_file, buffer, event,
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -0500984 entry, irq_flags, pc, regs);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400985}
986
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900987static void
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900988kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900989{
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200990 struct event_file_link *link;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900991
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900992 list_for_each_entry_rcu(link, &tk->tp.files, list)
993 __kprobe_trace_func(tk, regs, link->file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900994}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900995NOKPROBE_SYMBOL(kprobe_trace_func);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900996
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400997/* Kretprobe handler */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900998static nokprobe_inline void
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900999__kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001000 struct pt_regs *regs,
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001001 struct trace_event_file *trace_file)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001002{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001003 struct kretprobe_trace_entry_head *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001004 struct ring_buffer_event *event;
Frederic Weisbecker8f8ffe22009-09-11 01:09:23 +02001005 struct ring_buffer *buffer;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001006 int size, pc, dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001007 unsigned long irq_flags;
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001008 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001009
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001010 WARN_ON(call != trace_file->event_call);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001011
Steven Rostedt (Red Hat)09a50592015-05-13 15:21:25 -04001012 if (trace_trigger_soft_disabled(trace_file))
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -05001013 return;
Masami Hiramatsub8820082013-05-09 14:44:54 +09001014
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001015 local_save_flags(irq_flags);
1016 pc = preempt_count();
1017
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001018 dsize = __get_data_size(&tk->tp, regs);
1019 size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001020
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001021 event = trace_event_buffer_lock_reserve(&buffer, trace_file,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001022 call->event.type,
1023 size, irq_flags, pc);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001024 if (!event)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001025 return;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001026
1027 entry = ring_buffer_event_data(event);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001028 entry->func = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001029 entry->ret_ip = (unsigned long)ri->ret_addr;
Masami Hiramatsu91784122018-04-25 21:19:01 +09001030 store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001031
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001032 event_trigger_unlock_commit_regs(trace_file, buffer, event,
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -05001033 entry, irq_flags, pc, regs);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001034}
1035
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001036static void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001037kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001038 struct pt_regs *regs)
1039{
Oleg Nesterovb04d52e2013-06-20 19:38:14 +02001040 struct event_file_link *link;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001041
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001042 list_for_each_entry_rcu(link, &tk->tp.files, list)
1043 __kretprobe_trace_func(tk, ri, regs, link->file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001044}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001045NOKPROBE_SYMBOL(kretprobe_trace_func);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001046
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001047/* Event entry printers */
Masami Hiramatsub62fdd92013-05-13 20:58:39 +09001048static enum print_line_t
Steven Rostedta9a57762010-04-22 18:46:14 -04001049print_kprobe_event(struct trace_iterator *iter, int flags,
1050 struct trace_event *event)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001051{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001052 struct kprobe_trace_entry_head *field;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001053 struct trace_seq *s = &iter->seq;
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001054 struct trace_probe *tp;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001055
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001056 field = (struct kprobe_trace_entry_head *)iter->ent;
Steven Rostedt80decc72010-04-23 10:00:22 -04001057 tp = container_of(event, struct trace_probe, call.event);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001058
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -04001059 trace_seq_printf(s, "%s: (", trace_event_name(&tp->call));
Masami Hiramatsu6e9f23d2009-09-10 19:53:45 -04001060
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001061 if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001062 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001063
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001064 trace_seq_putc(s, ')');
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001065
Masami Hiramatsu56de7632018-04-25 21:16:36 +09001066 if (print_probe_args(s, tp->args, tp->nr_args,
1067 (u8 *)&field[1], field) < 0)
1068 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001069
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001070 trace_seq_putc(s, '\n');
1071 out:
1072 return trace_handle_return(s);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001073}
1074
Masami Hiramatsub62fdd92013-05-13 20:58:39 +09001075static enum print_line_t
Steven Rostedta9a57762010-04-22 18:46:14 -04001076print_kretprobe_event(struct trace_iterator *iter, int flags,
1077 struct trace_event *event)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001078{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001079 struct kretprobe_trace_entry_head *field;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001080 struct trace_seq *s = &iter->seq;
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001081 struct trace_probe *tp;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001082
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001083 field = (struct kretprobe_trace_entry_head *)iter->ent;
Steven Rostedt80decc72010-04-23 10:00:22 -04001084 tp = container_of(event, struct trace_probe, call.event);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001085
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -04001086 trace_seq_printf(s, "%s: (", trace_event_name(&tp->call));
Masami Hiramatsu6e9f23d2009-09-10 19:53:45 -04001087
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001088 if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001089 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001090
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001091 trace_seq_puts(s, " <- ");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001092
1093 if (!seq_print_ip_sym(s, field->func, flags & ~TRACE_ITER_SYM_OFFSET))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001094 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001095
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001096 trace_seq_putc(s, ')');
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001097
Masami Hiramatsu56de7632018-04-25 21:16:36 +09001098 if (print_probe_args(s, tp->args, tp->nr_args,
1099 (u8 *)&field[1], field) < 0)
1100 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001101
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001102 trace_seq_putc(s, '\n');
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001103
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001104 out:
1105 return trace_handle_return(s);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001106}
1107
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001108
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001109static int kprobe_event_define_fields(struct trace_event_call *event_call)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001110{
Masami Hiramatsueeb07b02018-04-25 21:17:05 +09001111 int ret;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001112 struct kprobe_trace_entry_head field;
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001113 struct trace_kprobe *tk = (struct trace_kprobe *)event_call->data;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001114
Masami Hiramatsua703d942009-10-07 18:28:07 -04001115 DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001116
Masami Hiramatsueeb07b02018-04-25 21:17:05 +09001117 return traceprobe_define_arg_fields(event_call, sizeof(field), &tk->tp);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001118}
1119
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001120static int kretprobe_event_define_fields(struct trace_event_call *event_call)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001121{
Masami Hiramatsueeb07b02018-04-25 21:17:05 +09001122 int ret;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001123 struct kretprobe_trace_entry_head field;
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001124 struct trace_kprobe *tk = (struct trace_kprobe *)event_call->data;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001125
Masami Hiramatsua703d942009-10-07 18:28:07 -04001126 DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0);
1127 DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001128
Masami Hiramatsueeb07b02018-04-25 21:17:05 +09001129 return traceprobe_define_arg_fields(event_call, sizeof(field), &tk->tp);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001130}
1131
Li Zefan07b139c2009-12-21 14:27:35 +08001132#ifdef CONFIG_PERF_EVENTS
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001133
1134/* Kprobe profile handler */
Josef Bacik9802d862017-12-11 11:36:48 -05001135static int
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001136kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs)
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001137{
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001138 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001139 struct kprobe_trace_entry_head *entry;
Peter Zijlstra1c024eca2010-05-19 14:02:22 +02001140 struct hlist_head *head;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001141 int size, __size, dsize;
Peter Zijlstra4ed7c922009-11-23 11:37:29 +01001142 int rctx;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001143
Josef Bacik9802d862017-12-11 11:36:48 -05001144 if (bpf_prog_array_valid(call)) {
Masami Hiramatsu66665ad2018-01-13 02:54:33 +09001145 unsigned long orig_ip = instruction_pointer(regs);
Josef Bacik9802d862017-12-11 11:36:48 -05001146 int ret;
1147
1148 ret = trace_call_bpf(call, regs);
1149
1150 /*
1151 * We need to check and see if we modified the pc of the
Masami Hiramatsucce188b2018-06-20 01:15:45 +09001152 * pt_regs, and if so return 1 so that we don't do the
1153 * single stepping.
Josef Bacik9802d862017-12-11 11:36:48 -05001154 */
Masami Hiramatsucce188b2018-06-20 01:15:45 +09001155 if (orig_ip != instruction_pointer(regs))
Josef Bacik9802d862017-12-11 11:36:48 -05001156 return 1;
Josef Bacik9802d862017-12-11 11:36:48 -05001157 if (!ret)
1158 return 0;
1159 }
Alexei Starovoitov25415172015-03-25 12:49:20 -07001160
Oleg Nesterov288e9842013-06-20 19:38:06 +02001161 head = this_cpu_ptr(call->perf_events);
1162 if (hlist_empty(head))
Josef Bacik9802d862017-12-11 11:36:48 -05001163 return 0;
Oleg Nesterov288e9842013-06-20 19:38:06 +02001164
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001165 dsize = __get_data_size(&tk->tp, regs);
1166 __size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu74ebb632009-09-14 16:49:28 -04001167 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1168 size -= sizeof(u32);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001169
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001170 entry = perf_trace_buf_alloc(size, NULL, &rctx);
Xiao Guangrong430ad5a2010-01-28 09:32:29 +08001171 if (!entry)
Josef Bacik9802d862017-12-11 11:36:48 -05001172 return 0;
Frederic Weisbeckerce71b9d2009-11-22 05:26:55 +01001173
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001174 entry->ip = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001175 memset(&entry[1], 0, dsize);
Masami Hiramatsu91784122018-04-25 21:19:01 +09001176 store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001177 perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs,
Peter Zijlstra8fd0fbb2017-10-11 09:45:29 +02001178 head, NULL);
Josef Bacik9802d862017-12-11 11:36:48 -05001179 return 0;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001180}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001181NOKPROBE_SYMBOL(kprobe_perf_func);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001182
1183/* Kretprobe profile handler */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001184static void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001185kretprobe_perf_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001186 struct pt_regs *regs)
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001187{
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001188 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001189 struct kretprobe_trace_entry_head *entry;
Peter Zijlstra1c024eca2010-05-19 14:02:22 +02001190 struct hlist_head *head;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001191 int size, __size, dsize;
Peter Zijlstra4ed7c922009-11-23 11:37:29 +01001192 int rctx;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001193
Yonghong Songe87c6bc2017-10-23 23:53:08 -07001194 if (bpf_prog_array_valid(call) && !trace_call_bpf(call, regs))
Alexei Starovoitov25415172015-03-25 12:49:20 -07001195 return;
1196
Oleg Nesterov288e9842013-06-20 19:38:06 +02001197 head = this_cpu_ptr(call->perf_events);
1198 if (hlist_empty(head))
1199 return;
1200
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001201 dsize = __get_data_size(&tk->tp, regs);
1202 __size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu74ebb632009-09-14 16:49:28 -04001203 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1204 size -= sizeof(u32);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001205
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001206 entry = perf_trace_buf_alloc(size, NULL, &rctx);
Xiao Guangrong430ad5a2010-01-28 09:32:29 +08001207 if (!entry)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001208 return;
Frederic Weisbeckerce71b9d2009-11-22 05:26:55 +01001209
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001210 entry->func = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsua1a138d2009-09-25 11:20:12 -07001211 entry->ret_ip = (unsigned long)ri->ret_addr;
Masami Hiramatsu91784122018-04-25 21:19:01 +09001212 store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001213 perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs,
Peter Zijlstra8fd0fbb2017-10-11 09:45:29 +02001214 head, NULL);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001215}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001216NOKPROBE_SYMBOL(kretprobe_perf_func);
Yonghong Song41bdc4b2018-05-24 11:21:09 -07001217
1218int bpf_get_kprobe_info(const struct perf_event *event, u32 *fd_type,
1219 const char **symbol, u64 *probe_offset,
1220 u64 *probe_addr, bool perf_type_tracepoint)
1221{
1222 const char *pevent = trace_event_name(event->tp_event);
1223 const char *group = event->tp_event->class->system;
1224 struct trace_kprobe *tk;
1225
1226 if (perf_type_tracepoint)
1227 tk = find_trace_kprobe(pevent, group);
1228 else
1229 tk = event->tp_event->data;
1230 if (!tk)
1231 return -EINVAL;
1232
1233 *fd_type = trace_kprobe_is_return(tk) ? BPF_FD_TYPE_KRETPROBE
1234 : BPF_FD_TYPE_KPROBE;
1235 if (tk->symbol) {
1236 *symbol = tk->symbol;
1237 *probe_offset = tk->rp.kp.offset;
1238 *probe_addr = 0;
1239 } else {
1240 *symbol = NULL;
1241 *probe_offset = 0;
1242 *probe_addr = (unsigned long)tk->rp.kp.addr;
1243 }
1244 return 0;
1245}
Li Zefan07b139c2009-12-21 14:27:35 +08001246#endif /* CONFIG_PERF_EVENTS */
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001247
Oleg Nesterov3fe3d612013-06-20 19:38:09 +02001248/*
1249 * called by perf_trace_init() or __ftrace_set_clr_event() under event_mutex.
1250 *
1251 * kprobe_trace_self_tests_init() does enable_trace_probe/disable_trace_probe
1252 * lockless, but we can't race with this __init function.
1253 */
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001254static int kprobe_register(struct trace_event_call *event,
Masami Hiramatsufbc19632014-04-17 17:18:00 +09001255 enum trace_reg type, void *data)
Steven Rostedt22392912010-04-21 12:27:06 -04001256{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001257 struct trace_kprobe *tk = (struct trace_kprobe *)event->data;
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001258 struct trace_event_file *file = data;
Masami Hiramatsu1538f882011-06-27 16:26:44 +09001259
Steven Rostedt22392912010-04-21 12:27:06 -04001260 switch (type) {
1261 case TRACE_REG_REGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001262 return enable_trace_kprobe(tk, file);
Steven Rostedt22392912010-04-21 12:27:06 -04001263 case TRACE_REG_UNREGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001264 return disable_trace_kprobe(tk, file);
Steven Rostedt22392912010-04-21 12:27:06 -04001265
1266#ifdef CONFIG_PERF_EVENTS
1267 case TRACE_REG_PERF_REGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001268 return enable_trace_kprobe(tk, NULL);
Steven Rostedt22392912010-04-21 12:27:06 -04001269 case TRACE_REG_PERF_UNREGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001270 return disable_trace_kprobe(tk, NULL);
Jiri Olsaceec0b62012-02-15 15:51:49 +01001271 case TRACE_REG_PERF_OPEN:
1272 case TRACE_REG_PERF_CLOSE:
Jiri Olsa489c75c2012-02-15 15:51:50 +01001273 case TRACE_REG_PERF_ADD:
1274 case TRACE_REG_PERF_DEL:
Jiri Olsaceec0b62012-02-15 15:51:49 +01001275 return 0;
Steven Rostedt22392912010-04-21 12:27:06 -04001276#endif
1277 }
1278 return 0;
1279}
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001280
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001281static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs)
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001282{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001283 struct trace_kprobe *tk = container_of(kp, struct trace_kprobe, rp.kp);
Josef Bacik9802d862017-12-11 11:36:48 -05001284 int ret = 0;
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001285
Martin KaFai Laua7636d92016-02-03 12:28:28 -08001286 raw_cpu_inc(*tk->nhit);
Masami Hiramatsu48182bd2013-05-09 14:44:36 +09001287
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001288 if (tk->tp.flags & TP_FLAG_TRACE)
1289 kprobe_trace_func(tk, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001290#ifdef CONFIG_PERF_EVENTS
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001291 if (tk->tp.flags & TP_FLAG_PROFILE)
Josef Bacik9802d862017-12-11 11:36:48 -05001292 ret = kprobe_perf_func(tk, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001293#endif
Josef Bacik9802d862017-12-11 11:36:48 -05001294 return ret;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001295}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001296NOKPROBE_SYMBOL(kprobe_dispatcher);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001297
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001298static int
1299kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs)
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001300{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001301 struct trace_kprobe *tk = container_of(ri->rp, struct trace_kprobe, rp);
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001302
Martin KaFai Laua7636d92016-02-03 12:28:28 -08001303 raw_cpu_inc(*tk->nhit);
Masami Hiramatsu48182bd2013-05-09 14:44:36 +09001304
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001305 if (tk->tp.flags & TP_FLAG_TRACE)
1306 kretprobe_trace_func(tk, ri, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001307#ifdef CONFIG_PERF_EVENTS
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001308 if (tk->tp.flags & TP_FLAG_PROFILE)
1309 kretprobe_perf_func(tk, ri, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001310#endif
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001311 return 0; /* We don't tweek kernel, so just return 0 */
1312}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001313NOKPROBE_SYMBOL(kretprobe_dispatcher);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001314
Steven Rostedta9a57762010-04-22 18:46:14 -04001315static struct trace_event_functions kretprobe_funcs = {
1316 .trace = print_kretprobe_event
1317};
1318
1319static struct trace_event_functions kprobe_funcs = {
1320 .trace = print_kprobe_event
1321};
1322
Song Liue12f03d2017-12-06 14:45:15 -08001323static inline void init_trace_event_call(struct trace_kprobe *tk,
1324 struct trace_event_call *call)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001325{
Li Zefanffb9f992010-05-24 16:24:52 +08001326 INIT_LIST_HEAD(&call->class->fields);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001327 if (trace_kprobe_is_return(tk)) {
Steven Rostedt80decc72010-04-23 10:00:22 -04001328 call->event.funcs = &kretprobe_funcs;
Steven Rostedt2e33af02010-04-22 10:35:55 -04001329 call->class->define_fields = kretprobe_event_define_fields;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001330 } else {
Steven Rostedt80decc72010-04-23 10:00:22 -04001331 call->event.funcs = &kprobe_funcs;
Steven Rostedt2e33af02010-04-22 10:35:55 -04001332 call->class->define_fields = kprobe_event_define_fields;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001333 }
Song Liue12f03d2017-12-06 14:45:15 -08001334
1335 call->flags = TRACE_EVENT_FL_KPROBE;
1336 call->class->reg = kprobe_register;
1337 call->data = tk;
1338}
1339
1340static int register_kprobe_event(struct trace_kprobe *tk)
1341{
1342 struct trace_event_call *call = &tk->tp.call;
1343 int ret = 0;
1344
1345 init_trace_event_call(tk, call);
1346
Masami Hiramatsu0a46c852018-04-25 21:19:30 +09001347 if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0)
Lai Jiangshana342a0282009-12-15 15:39:49 +08001348 return -ENOMEM;
Steven Rostedt (Red Hat)9023c932015-05-05 09:39:12 -04001349 ret = register_trace_event(&call->event);
Steven Rostedt32c0eda2010-04-23 10:38:03 -04001350 if (!ret) {
Lai Jiangshana342a0282009-12-15 15:39:49 +08001351 kfree(call->print_fmt);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001352 return -ENODEV;
Lai Jiangshana342a0282009-12-15 15:39:49 +08001353 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001354 ret = trace_add_event_call(call);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001355 if (ret) {
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -04001356 pr_info("Failed to register kprobe event: %s\n",
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -04001357 trace_event_name(call));
Lai Jiangshana342a0282009-12-15 15:39:49 +08001358 kfree(call->print_fmt);
Steven Rostedt (Red Hat)9023c932015-05-05 09:39:12 -04001359 unregister_trace_event(&call->event);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001360 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001361 return ret;
1362}
1363
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001364static int unregister_kprobe_event(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001365{
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -04001366 int ret;
1367
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001368 /* tp->event is unregistered in trace_remove_event_call() */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001369 ret = trace_remove_event_call(&tk->tp.call);
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -04001370 if (!ret)
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001371 kfree(tk->tp.call.print_fmt);
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -04001372 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001373}
1374
Song Liue12f03d2017-12-06 14:45:15 -08001375#ifdef CONFIG_PERF_EVENTS
1376/* create a trace_kprobe, but don't add it to global lists */
1377struct trace_event_call *
1378create_local_trace_kprobe(char *func, void *addr, unsigned long offs,
1379 bool is_return)
1380{
1381 struct trace_kprobe *tk;
1382 int ret;
1383 char *event;
1384
1385 /*
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001386 * local trace_kprobes are not added to dyn_event, so they are never
Song Liue12f03d2017-12-06 14:45:15 -08001387 * searched in find_trace_kprobe(). Therefore, there is no concern of
1388 * duplicated name here.
1389 */
1390 event = func ? func : "DUMMY_EVENT";
1391
1392 tk = alloc_trace_kprobe(KPROBE_EVENT_SYSTEM, event, (void *)addr, func,
1393 offs, 0 /* maxactive */, 0 /* nargs */,
1394 is_return);
1395
1396 if (IS_ERR(tk)) {
1397 pr_info("Failed to allocate trace_probe.(%d)\n",
1398 (int)PTR_ERR(tk));
1399 return ERR_CAST(tk);
1400 }
1401
1402 init_trace_event_call(tk, &tk->tp.call);
1403
Masami Hiramatsu0a46c852018-04-25 21:19:30 +09001404 if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) {
Song Liue12f03d2017-12-06 14:45:15 -08001405 ret = -ENOMEM;
1406 goto error;
1407 }
1408
1409 ret = __register_trace_kprobe(tk);
Jiri Olsa0fc8c352018-07-09 16:19:06 +02001410 if (ret < 0) {
1411 kfree(tk->tp.call.print_fmt);
Song Liue12f03d2017-12-06 14:45:15 -08001412 goto error;
Jiri Olsa0fc8c352018-07-09 16:19:06 +02001413 }
Song Liue12f03d2017-12-06 14:45:15 -08001414
1415 return &tk->tp.call;
1416error:
1417 free_trace_kprobe(tk);
1418 return ERR_PTR(ret);
1419}
1420
1421void destroy_local_trace_kprobe(struct trace_event_call *event_call)
1422{
1423 struct trace_kprobe *tk;
1424
1425 tk = container_of(event_call, struct trace_kprobe, tp.call);
1426
1427 if (trace_probe_is_enabled(&tk->tp)) {
1428 WARN_ON(1);
1429 return;
1430 }
1431
1432 __unregister_trace_kprobe(tk);
Jiri Olsa0fc8c352018-07-09 16:19:06 +02001433
1434 kfree(tk->tp.call.print_fmt);
Song Liue12f03d2017-12-06 14:45:15 -08001435 free_trace_kprobe(tk);
1436}
1437#endif /* CONFIG_PERF_EVENTS */
1438
Steven Rostedt (Red Hat)8434dc92015-01-20 12:13:40 -05001439/* Make a tracefs interface for controlling probe points */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001440static __init int init_kprobe_trace(void)
1441{
1442 struct dentry *d_tracer;
1443 struct dentry *entry;
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001444 int ret;
1445
1446 ret = dyn_event_register(&trace_kprobe_ops);
1447 if (ret)
1448 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001449
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001450 if (register_module_notifier(&trace_kprobe_module_nb))
Masami Hiramatsu61424312011-06-27 16:26:56 +09001451 return -EINVAL;
1452
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001453 d_tracer = tracing_init_dentry();
Steven Rostedt (Red Hat)14a5ae42015-01-20 11:14:16 -05001454 if (IS_ERR(d_tracer))
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001455 return 0;
1456
Steven Rostedt (Red Hat)8434dc92015-01-20 12:13:40 -05001457 entry = tracefs_create_file("kprobe_events", 0644, d_tracer,
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001458 NULL, &kprobe_events_ops);
1459
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001460 /* Event list interface */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001461 if (!entry)
Joe Perchesa395d6a2016-03-22 14:28:09 -07001462 pr_warn("Could not create tracefs 'kprobe_events' entry\n");
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001463
1464 /* Profile interface */
Steven Rostedt (Red Hat)8434dc92015-01-20 12:13:40 -05001465 entry = tracefs_create_file("kprobe_profile", 0444, d_tracer,
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001466 NULL, &kprobe_profile_ops);
1467
1468 if (!entry)
Joe Perchesa395d6a2016-03-22 14:28:09 -07001469 pr_warn("Could not create tracefs 'kprobe_profile' entry\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001470 return 0;
1471}
1472fs_initcall(init_kprobe_trace);
1473
1474
1475#ifdef CONFIG_FTRACE_STARTUP_TEST
Arnd Bergmann26a346f2017-02-01 17:57:56 +01001476static __init struct trace_event_file *
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001477find_trace_probe_file(struct trace_kprobe *tk, struct trace_array *tr)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001478{
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001479 struct trace_event_file *file;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001480
1481 list_for_each_entry(file, &tr->events, list)
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001482 if (file->event_call == &tk->tp.call)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001483 return file;
1484
1485 return NULL;
1486}
1487
Oleg Nesterov3fe3d612013-06-20 19:38:09 +02001488/*
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001489 * Nobody but us can call enable_trace_kprobe/disable_trace_kprobe at this
Oleg Nesterov3fe3d612013-06-20 19:38:09 +02001490 * stage, we can do this lockless.
1491 */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001492static __init int kprobe_trace_self_tests_init(void)
1493{
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001494 int ret, warn = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001495 int (*target)(int, int, int, int, int, int);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001496 struct trace_kprobe *tk;
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001497 struct trace_event_file *file;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001498
Yoshihiro YUNOMAE748ec3a2014-06-06 07:35:20 +09001499 if (tracing_is_disabled())
1500 return -ENODEV;
1501
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001502 target = kprobe_trace_selftest_target;
1503
1504 pr_info("Testing kprobe tracing: ");
1505
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001506 ret = trace_run_command("p:testprobe kprobe_trace_selftest_target $stack $stack0 +0($stack)",
1507 create_or_delete_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001508 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001509 pr_warn("error on probing function entry.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001510 warn++;
1511 } else {
1512 /* Enable trace point */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001513 tk = find_trace_kprobe("testprobe", KPROBE_EVENT_SYSTEM);
1514 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001515 pr_warn("error on getting new probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001516 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001517 } else {
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001518 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001519 if (WARN_ON_ONCE(file == NULL)) {
1520 pr_warn("error on getting probe file.\n");
1521 warn++;
1522 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001523 enable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001524 }
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001525 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001526
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001527 ret = trace_run_command("r:testprobe2 kprobe_trace_selftest_target $retval",
1528 create_or_delete_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001529 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001530 pr_warn("error on probing function return.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001531 warn++;
1532 } else {
1533 /* Enable trace point */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001534 tk = find_trace_kprobe("testprobe2", KPROBE_EVENT_SYSTEM);
1535 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001536 pr_warn("error on getting 2nd new probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001537 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001538 } else {
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001539 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001540 if (WARN_ON_ONCE(file == NULL)) {
1541 pr_warn("error on getting probe file.\n");
1542 warn++;
1543 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001544 enable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001545 }
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001546 }
1547
1548 if (warn)
1549 goto end;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001550
1551 ret = target(1, 2, 3, 4, 5, 6);
1552
Marcin Nowakowskid4d7ccc2016-12-09 15:19:38 +01001553 /*
1554 * Not expecting an error here, the check is only to prevent the
1555 * optimizer from removing the call to target() as otherwise there
1556 * are no side-effects and the call is never performed.
1557 */
1558 if (ret != 21)
1559 warn++;
1560
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001561 /* Disable trace points before removing it */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001562 tk = find_trace_kprobe("testprobe", KPROBE_EVENT_SYSTEM);
1563 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001564 pr_warn("error on getting test probe.\n");
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001565 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001566 } else {
Marcin Nowakowskid4d7ccc2016-12-09 15:19:38 +01001567 if (trace_kprobe_nhit(tk) != 1) {
1568 pr_warn("incorrect number of testprobe hits\n");
1569 warn++;
1570 }
1571
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001572 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001573 if (WARN_ON_ONCE(file == NULL)) {
1574 pr_warn("error on getting probe file.\n");
1575 warn++;
1576 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001577 disable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001578 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001579
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001580 tk = find_trace_kprobe("testprobe2", KPROBE_EVENT_SYSTEM);
1581 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001582 pr_warn("error on getting 2nd test probe.\n");
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001583 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001584 } else {
Marcin Nowakowskid4d7ccc2016-12-09 15:19:38 +01001585 if (trace_kprobe_nhit(tk) != 1) {
1586 pr_warn("incorrect number of testprobe2 hits\n");
1587 warn++;
1588 }
1589
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001590 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001591 if (WARN_ON_ONCE(file == NULL)) {
1592 pr_warn("error on getting probe file.\n");
1593 warn++;
1594 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001595 disable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001596 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001597
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001598 ret = trace_run_command("-:testprobe", create_or_delete_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001599 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001600 pr_warn("error on deleting a probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001601 warn++;
1602 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001603
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001604 ret = trace_run_command("-:testprobe2", create_or_delete_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001605 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001606 pr_warn("error on deleting a probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001607 warn++;
1608 }
1609
1610end:
Masami Hiramatsu6212dd22018-11-05 18:02:36 +09001611 ret = dyn_events_release_all(&trace_kprobe_ops);
1612 if (WARN_ON_ONCE(ret)) {
1613 pr_warn("error on cleaning up probes.\n");
1614 warn++;
1615 }
Thomas Gleixner30e7d8942017-05-17 10:19:49 +02001616 /*
1617 * Wait for the optimizer work to finish. Otherwise it might fiddle
1618 * with probes in already freed __init text.
1619 */
1620 wait_for_kprobe_optimizer();
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001621 if (warn)
1622 pr_cont("NG: Some tests are failed. Please check them.\n");
1623 else
1624 pr_cont("OK\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001625 return 0;
1626}
1627
1628late_initcall(kprobe_trace_self_tests_init);
1629
1630#endif