blob: fec67188c4d28542f0b88f9ca9aca5fee5668e8d [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
Francis Deslauriersd8999262018-07-30 19:20:42 +090015#include "trace_kprobe_selftest.h"
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +053016#include "trace_probe.h"
Masami Hiramatsu53305922018-04-25 21:18:03 +090017#include "trace_probe_tmpl.h"
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040018
Masami Hiramatsuf52487e2009-09-10 19:53:53 -040019#define KPROBE_EVENT_SYSTEM "kprobes"
Alban Crequy696ced42017-04-03 12:36:22 +020020#define KRETPROBE_MAXACTIVE_MAX 4096
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040021
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040022/**
Masami Hiramatsu77b44d12009-11-03 19:12:47 -050023 * Kprobe event core functions
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040024 */
Namhyung Kimc31ffb32013-07-03 13:50:51 +090025struct trace_kprobe {
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040026 struct list_head list;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +020027 struct kretprobe rp; /* Use rp.kp for kprobe use */
Martin KaFai Laua7636d92016-02-03 12:28:28 -080028 unsigned long __percpu *nhit;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040029 const char *symbol; /* symbol name */
Namhyung Kimc31ffb32013-07-03 13:50:51 +090030 struct trace_probe tp;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040031};
32
Namhyung Kimc31ffb32013-07-03 13:50:51 +090033#define SIZEOF_TRACE_KPROBE(n) \
34 (offsetof(struct trace_kprobe, tp.args) + \
Masami Hiramatsueca0d912009-09-10 19:53:38 -040035 (sizeof(struct probe_arg) * (n)))
Masami Hiramatsua82378d2009-08-13 16:35:18 -040036
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090037static nokprobe_inline bool trace_kprobe_is_return(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040038{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090039 return tk->rp.handler != NULL;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040040}
41
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090042static nokprobe_inline const char *trace_kprobe_symbol(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040043{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090044 return tk->symbol ? tk->symbol : "unknown";
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040045}
46
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090047static nokprobe_inline unsigned long trace_kprobe_offset(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +090048{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090049 return tk->rp.kp.offset;
Masami Hiramatsu61424312011-06-27 16:26:56 +090050}
51
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090052static nokprobe_inline bool trace_kprobe_has_gone(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +090053{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090054 return !!(kprobe_gone(&tk->rp.kp));
Masami Hiramatsu61424312011-06-27 16:26:56 +090055}
56
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090057static nokprobe_inline bool trace_kprobe_within_module(struct trace_kprobe *tk,
Namhyung Kimc31ffb32013-07-03 13:50:51 +090058 struct module *mod)
Masami Hiramatsu61424312011-06-27 16:26:56 +090059{
60 int len = strlen(mod->name);
Namhyung Kimc31ffb32013-07-03 13:50:51 +090061 const char *name = trace_kprobe_symbol(tk);
Masami Hiramatsu61424312011-06-27 16:26:56 +090062 return strncmp(mod->name, name, len) == 0 && name[len] == ':';
63}
64
Masami Hiramatsu59158ec2018-08-29 01:18:15 +090065static nokprobe_inline bool trace_kprobe_module_exist(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +090066{
Masami Hiramatsu59158ec2018-08-29 01:18:15 +090067 char *p;
68 bool ret;
69
70 if (!tk->symbol)
71 return false;
72 p = strchr(tk->symbol, ':');
73 if (!p)
74 return true;
75 *p = '\0';
76 mutex_lock(&module_mutex);
77 ret = !!find_module(tk->symbol);
78 mutex_unlock(&module_mutex);
79 *p = ':';
80
81 return ret;
Masami Hiramatsu61424312011-06-27 16:26:56 +090082}
83
Marcin Nowakowskif18f97a2016-12-09 15:19:37 +010084static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk)
85{
86 unsigned long nhit = 0;
87 int cpu;
88
89 for_each_possible_cpu(cpu)
90 nhit += *per_cpu_ptr(tk->nhit, cpu);
91
92 return nhit;
93}
94
Masami Hiramatsu6bc6c772018-08-02 16:50:48 +090095/* Return 0 if it fails to find the symbol address */
Masami Hiramatsu45408c42018-07-30 19:20:14 +090096static nokprobe_inline
97unsigned long trace_kprobe_address(struct trace_kprobe *tk)
98{
99 unsigned long addr;
100
101 if (tk->symbol) {
102 addr = (unsigned long)
103 kallsyms_lookup_name(trace_kprobe_symbol(tk));
Masami Hiramatsu6bc6c772018-08-02 16:50:48 +0900104 if (addr)
105 addr += tk->rp.kp.offset;
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900106 } else {
107 addr = (unsigned long)tk->rp.kp.addr;
108 }
109 return addr;
110}
111
Masami Hiramatsub4da3342018-01-13 02:54:04 +0900112bool trace_kprobe_on_func_entry(struct trace_event_call *call)
Josef Bacik9802d862017-12-11 11:36:48 -0500113{
114 struct trace_kprobe *tk = (struct trace_kprobe *)call->data;
Masami Hiramatsub4da3342018-01-13 02:54:04 +0900115
116 return kprobe_on_func_entry(tk->rp.kp.addr,
117 tk->rp.kp.addr ? NULL : tk->rp.kp.symbol_name,
118 tk->rp.kp.addr ? 0 : tk->rp.kp.offset);
Josef Bacik9802d862017-12-11 11:36:48 -0500119}
120
Masami Hiramatsub4da3342018-01-13 02:54:04 +0900121bool trace_kprobe_error_injectable(struct trace_event_call *call)
Josef Bacik9802d862017-12-11 11:36:48 -0500122{
123 struct trace_kprobe *tk = (struct trace_kprobe *)call->data;
Josef Bacik9802d862017-12-11 11:36:48 -0500124
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900125 return within_error_injection_list(trace_kprobe_address(tk));
Josef Bacik9802d862017-12-11 11:36:48 -0500126}
127
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900128static int register_kprobe_event(struct trace_kprobe *tk);
129static int unregister_kprobe_event(struct trace_kprobe *tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400130
131static DEFINE_MUTEX(probe_lock);
132static LIST_HEAD(probe_list);
133
Masami Hiramatsu50d78052009-09-14 16:49:20 -0400134static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs);
135static int kretprobe_dispatcher(struct kretprobe_instance *ri,
136 struct pt_regs *regs);
137
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200138/*
139 * Allocate new trace_probe and initialize it (including kprobes).
140 */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900141static struct trace_kprobe *alloc_trace_kprobe(const char *group,
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400142 const char *event,
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200143 void *addr,
144 const char *symbol,
145 unsigned long offs,
Alban Crequy696ced42017-04-03 12:36:22 +0200146 int maxactive,
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530147 int nargs, bool is_return)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400148{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900149 struct trace_kprobe *tk;
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500150 int ret = -ENOMEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400151
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900152 tk = kzalloc(SIZEOF_TRACE_KPROBE(nargs), GFP_KERNEL);
153 if (!tk)
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500154 return ERR_PTR(ret);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400155
Martin KaFai Laua7636d92016-02-03 12:28:28 -0800156 tk->nhit = alloc_percpu(unsigned long);
157 if (!tk->nhit)
158 goto error;
159
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400160 if (symbol) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900161 tk->symbol = kstrdup(symbol, GFP_KERNEL);
162 if (!tk->symbol)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400163 goto error;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900164 tk->rp.kp.symbol_name = tk->symbol;
165 tk->rp.kp.offset = offs;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200166 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900167 tk->rp.kp.addr = addr;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200168
169 if (is_return)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900170 tk->rp.handler = kretprobe_dispatcher;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200171 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900172 tk->rp.kp.pre_handler = kprobe_dispatcher;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200173
Alban Crequy696ced42017-04-03 12:36:22 +0200174 tk->rp.maxactive = maxactive;
175
Masami Hiramatsuda34634f2010-08-27 20:39:12 +0900176 if (!event || !is_good_name(event)) {
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500177 ret = -EINVAL;
Masami Hiramatsu42635652009-08-13 16:35:26 -0400178 goto error;
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500179 }
180
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900181 tk->tp.call.class = &tk->tp.class;
182 tk->tp.call.name = kstrdup(event, GFP_KERNEL);
183 if (!tk->tp.call.name)
Masami Hiramatsu42635652009-08-13 16:35:26 -0400184 goto error;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400185
Masami Hiramatsuda34634f2010-08-27 20:39:12 +0900186 if (!group || !is_good_name(group)) {
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500187 ret = -EINVAL;
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400188 goto error;
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500189 }
190
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900191 tk->tp.class.system = kstrdup(group, GFP_KERNEL);
192 if (!tk->tp.class.system)
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400193 goto error;
194
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900195 INIT_LIST_HEAD(&tk->list);
196 INIT_LIST_HEAD(&tk->tp.files);
197 return tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400198error:
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900199 kfree(tk->tp.call.name);
200 kfree(tk->symbol);
Martin KaFai Laua7636d92016-02-03 12:28:28 -0800201 free_percpu(tk->nhit);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900202 kfree(tk);
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500203 return ERR_PTR(ret);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400204}
205
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900206static void free_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400207{
208 int i;
209
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900210 for (i = 0; i < tk->tp.nr_args; i++)
211 traceprobe_free_probe_arg(&tk->tp.args[i]);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400212
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900213 kfree(tk->tp.call.class->system);
214 kfree(tk->tp.call.name);
215 kfree(tk->symbol);
Martin KaFai Laua7636d92016-02-03 12:28:28 -0800216 free_percpu(tk->nhit);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900217 kfree(tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400218}
219
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900220static struct trace_kprobe *find_trace_kprobe(const char *event,
221 const char *group)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400222{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900223 struct trace_kprobe *tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400224
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900225 list_for_each_entry(tk, &probe_list, list)
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -0400226 if (strcmp(trace_event_name(&tk->tp.call), event) == 0 &&
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900227 strcmp(tk->tp.call.class->system, group) == 0)
228 return tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400229 return NULL;
230}
231
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400232static inline int __enable_trace_kprobe(struct trace_kprobe *tk)
233{
234 int ret = 0;
235
236 if (trace_probe_is_registered(&tk->tp) && !trace_kprobe_has_gone(tk)) {
237 if (trace_kprobe_is_return(tk))
238 ret = enable_kretprobe(&tk->rp);
239 else
240 ret = enable_kprobe(&tk->rp.kp);
241 }
242
243 return ret;
244}
245
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200246/*
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900247 * Enable trace_probe
248 * if the file is NULL, enable "perf" handler, or enable "trace" handler.
249 */
250static int
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400251enable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900252{
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400253 struct event_file_link *link;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900254 int ret = 0;
255
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900256 if (file) {
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200257 link = kmalloc(sizeof(*link), GFP_KERNEL);
258 if (!link) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900259 ret = -ENOMEM;
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200260 goto out;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900261 }
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900262
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200263 link->file = file;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900264 list_add_tail_rcu(&link->list, &tk->tp.files);
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200265
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900266 tk->tp.flags |= TP_FLAG_TRACE;
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400267 ret = __enable_trace_kprobe(tk);
268 if (ret) {
269 list_del_rcu(&link->list);
Artem Savkov57ea2a32018-07-25 16:20:38 +0200270 kfree(link);
271 tk->tp.flags &= ~TP_FLAG_TRACE;
Artem Savkov57ea2a32018-07-25 16:20:38 +0200272 }
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400273
274 } else {
275 tk->tp.flags |= TP_FLAG_PROFILE;
276 ret = __enable_trace_kprobe(tk);
277 if (ret)
278 tk->tp.flags &= ~TP_FLAG_PROFILE;
Artem Savkov57ea2a32018-07-25 16:20:38 +0200279 }
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200280 out:
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900281 return ret;
282}
283
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900284/*
285 * Disable trace_probe
286 * if the file is NULL, disable "perf" handler, or disable "trace" handler.
287 */
288static int
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400289disable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900290{
Masami Hiramatsua232e272013-07-09 18:35:26 +0900291 struct event_file_link *link = NULL;
292 int wait = 0;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900293 int ret = 0;
294
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900295 if (file) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900296 link = find_event_file_link(&tk->tp, file);
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200297 if (!link) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900298 ret = -EINVAL;
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200299 goto out;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900300 }
301
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200302 list_del_rcu(&link->list);
Masami Hiramatsua232e272013-07-09 18:35:26 +0900303 wait = 1;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900304 if (!list_empty(&tk->tp.files))
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200305 goto out;
306
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900307 tk->tp.flags &= ~TP_FLAG_TRACE;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900308 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900309 tk->tp.flags &= ~TP_FLAG_PROFILE;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900310
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900311 if (!trace_probe_is_enabled(&tk->tp) && trace_probe_is_registered(&tk->tp)) {
312 if (trace_kprobe_is_return(tk))
313 disable_kretprobe(&tk->rp);
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900314 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900315 disable_kprobe(&tk->rp.kp);
Masami Hiramatsua232e272013-07-09 18:35:26 +0900316 wait = 1;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900317 }
Song Liue12f03d2017-12-06 14:45:15 -0800318
319 /*
320 * if tk is not added to any list, it must be a local trace_kprobe
321 * created with perf_event_open. We don't need to wait for these
322 * trace_kprobes
323 */
324 if (list_empty(&tk->list))
325 wait = 0;
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200326 out:
Masami Hiramatsua232e272013-07-09 18:35:26 +0900327 if (wait) {
328 /*
329 * Synchronize with kprobe_trace_func/kretprobe_trace_func
330 * to ensure disabled (all running handlers are finished).
331 * This is not only for kfree(), but also the caller,
332 * trace_remove_event_call() supposes it for releasing
333 * event_call related objects, which will be accessed in
334 * the kprobe_trace_func/kretprobe_trace_func.
335 */
336 synchronize_sched();
337 kfree(link); /* Ignored if link == NULL */
338 }
339
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900340 return ret;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900341}
342
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900343#if defined(CONFIG_KPROBES_ON_FTRACE) && \
344 !defined(CONFIG_KPROBE_EVENTS_ON_NOTRACE)
345static bool within_notrace_func(struct trace_kprobe *tk)
346{
347 unsigned long offset, size, addr;
348
349 addr = trace_kprobe_address(tk);
Masami Hiramatsu6bc6c772018-08-02 16:50:48 +0900350 if (!addr || !kallsyms_lookup_size_offset(addr, &size, &offset))
351 return false;
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900352
Masami Hiramatsu9161a862018-08-21 22:04:57 +0900353 /* Get the entry address of the target function */
354 addr -= offset;
355
356 /*
357 * Since ftrace_location_range() does inclusive range check, we need
358 * to subtract 1 byte from the end address.
359 */
360 return !ftrace_location_range(addr, addr + size - 1);
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900361}
362#else
363#define within_notrace_func(tk) (false)
364#endif
365
Masami Hiramatsu61424312011-06-27 16:26:56 +0900366/* Internal register function - just handle k*probes and flags */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900367static int __register_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +0900368{
Masami Hiramatsua6682812018-08-29 01:18:43 +0900369 int i, ret;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900370
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900371 if (trace_probe_is_registered(&tk->tp))
Masami Hiramatsu61424312011-06-27 16:26:56 +0900372 return -EINVAL;
373
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900374 if (within_notrace_func(tk)) {
375 pr_warn("Could not probe notrace function %s\n",
376 trace_kprobe_symbol(tk));
377 return -EINVAL;
378 }
379
Masami Hiramatsua6682812018-08-29 01:18:43 +0900380 for (i = 0; i < tk->tp.nr_args; i++) {
381 ret = traceprobe_update_arg(&tk->tp.args[i]);
382 if (ret)
383 return ret;
384 }
385
Masami Hiramatsu61424312011-06-27 16:26:56 +0900386 /* Set/clear disabled flag according to tp->flag */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900387 if (trace_probe_is_enabled(&tk->tp))
388 tk->rp.kp.flags &= ~KPROBE_FLAG_DISABLED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900389 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900390 tk->rp.kp.flags |= KPROBE_FLAG_DISABLED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900391
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900392 if (trace_kprobe_is_return(tk))
393 ret = register_kretprobe(&tk->rp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900394 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900395 ret = register_kprobe(&tk->rp.kp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900396
Masami Hiramatsu59158ec2018-08-29 01:18:15 +0900397 if (ret == 0) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900398 tk->tp.flags |= TP_FLAG_REGISTERED;
Masami Hiramatsu59158ec2018-08-29 01:18:15 +0900399 } else if (ret == -EILSEQ) {
400 pr_warn("Probing address(0x%p) is not an instruction boundary.\n",
401 tk->rp.kp.addr);
402 ret = -EINVAL;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900403 }
Masami Hiramatsu61424312011-06-27 16:26:56 +0900404 return ret;
405}
406
407/* Internal unregister function - just handle k*probes and flags */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900408static void __unregister_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +0900409{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900410 if (trace_probe_is_registered(&tk->tp)) {
411 if (trace_kprobe_is_return(tk))
412 unregister_kretprobe(&tk->rp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900413 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900414 unregister_kprobe(&tk->rp.kp);
415 tk->tp.flags &= ~TP_FLAG_REGISTERED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900416 /* Cleanup kprobe for reuse */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900417 if (tk->rp.kp.symbol_name)
418 tk->rp.kp.addr = NULL;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900419 }
420}
421
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400422/* Unregister a trace_probe and probe_event: call with locking probe_lock */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900423static int unregister_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400424{
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900425 /* Enabled event can not be unregistered */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900426 if (trace_probe_is_enabled(&tk->tp))
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900427 return -EBUSY;
428
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -0400429 /* Will fail if probe is being used by ftrace or perf */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900430 if (unregister_kprobe_event(tk))
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -0400431 return -EBUSY;
432
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900433 __unregister_trace_kprobe(tk);
434 list_del(&tk->list);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900435
436 return 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400437}
438
439/* Register a trace_probe and probe_event */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900440static int register_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400441{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900442 struct trace_kprobe *old_tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400443 int ret;
444
445 mutex_lock(&probe_lock);
446
Masami Hiramatsu61424312011-06-27 16:26:56 +0900447 /* Delete old (same name) event if exist */
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -0400448 old_tk = find_trace_kprobe(trace_event_name(&tk->tp.call),
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -0400449 tk->tp.call.class->system);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900450 if (old_tk) {
451 ret = unregister_trace_kprobe(old_tk);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900452 if (ret < 0)
453 goto end;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900454 free_trace_kprobe(old_tk);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400455 }
Masami Hiramatsu61424312011-06-27 16:26:56 +0900456
457 /* Register new event */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900458 ret = register_kprobe_event(tk);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400459 if (ret) {
Joe Perchesa395d6a2016-03-22 14:28:09 -0700460 pr_warn("Failed to register probe event(%d)\n", ret);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400461 goto end;
462 }
463
Masami Hiramatsu61424312011-06-27 16:26:56 +0900464 /* Register k*probe */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900465 ret = __register_trace_kprobe(tk);
Masami Hiramatsu59158ec2018-08-29 01:18:15 +0900466 if (ret == -ENOENT && !trace_kprobe_module_exist(tk)) {
467 pr_warn("This probe might be able to register after target module is loaded. Continue.\n");
468 ret = 0;
469 }
470
Masami Hiramatsu61424312011-06-27 16:26:56 +0900471 if (ret < 0)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900472 unregister_kprobe_event(tk);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900473 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900474 list_add_tail(&tk->list, &probe_list);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900475
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400476end:
477 mutex_unlock(&probe_lock);
478 return ret;
479}
480
Masami Hiramatsu61424312011-06-27 16:26:56 +0900481/* Module notifier call back, checking event on the module */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900482static int trace_kprobe_module_callback(struct notifier_block *nb,
Masami Hiramatsu61424312011-06-27 16:26:56 +0900483 unsigned long val, void *data)
484{
485 struct module *mod = data;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900486 struct trace_kprobe *tk;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900487 int ret;
488
489 if (val != MODULE_STATE_COMING)
490 return NOTIFY_DONE;
491
492 /* Update probes on coming module */
493 mutex_lock(&probe_lock);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900494 list_for_each_entry(tk, &probe_list, list) {
495 if (trace_kprobe_within_module(tk, mod)) {
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900496 /* Don't need to check busy - this should have gone. */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900497 __unregister_trace_kprobe(tk);
498 ret = __register_trace_kprobe(tk);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900499 if (ret)
Joe Perchesa395d6a2016-03-22 14:28:09 -0700500 pr_warn("Failed to re-register probe %s on %s: %d\n",
501 trace_event_name(&tk->tp.call),
502 mod->name, ret);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900503 }
504 }
505 mutex_unlock(&probe_lock);
506
507 return NOTIFY_DONE;
508}
509
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900510static struct notifier_block trace_kprobe_module_nb = {
511 .notifier_call = trace_kprobe_module_callback,
Masami Hiramatsu61424312011-06-27 16:26:56 +0900512 .priority = 1 /* Invoked after kprobe module callback */
513};
514
Naveen N. Raofca18a42017-07-08 00:27:30 +0530515/* Convert certain expected symbols into '_' when generating event names */
516static inline void sanitize_event_name(char *name)
517{
518 while (*name++ != '\0')
519 if (*name == ':' || *name == '.')
520 *name = '_';
521}
522
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900523static int create_trace_kprobe(int argc, char **argv)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400524{
525 /*
526 * Argument syntax:
Alban Crequy696ced42017-04-03 12:36:22 +0200527 * - Add kprobe:
528 * p[:[GRP/]EVENT] [MOD:]KSYM[+OFFS]|KADDR [FETCHARGS]
529 * - Add kretprobe:
530 * r[MAXACTIVE][:[GRP/]EVENT] [MOD:]KSYM[+0] [FETCHARGS]
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400531 * Fetch args:
Masami Hiramatsu2e06ff62009-10-07 18:27:59 -0400532 * $retval : fetch return value
533 * $stack : fetch stack address
534 * $stackN : fetch Nth of stack (N:0-)
Omar Sandoval35abb672016-06-08 18:38:02 -0700535 * $comm : fetch current task comm
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400536 * @ADDR : fetch memory at ADDR (ADDR should be in kernel)
537 * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol)
538 * %REG : fetch register REG
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400539 * Dereferencing memory fetch:
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400540 * +|-offs(ARG) : fetch memory at ARG +|- offs address.
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400541 * Alias name of args:
542 * NAME=FETCHARG : set NAME as alias of FETCHARG.
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400543 * Type of args:
544 * FETCHARG:TYPE : use TYPE instead of unsigned long.
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400545 */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900546 struct trace_kprobe *tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400547 int i, ret = 0;
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530548 bool is_return = false, is_delete = false;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400549 char *symbol = NULL, *event = NULL, *group = NULL;
Alban Crequy696ced42017-04-03 12:36:22 +0200550 int maxactive = 0;
Masami Hiramatsuda34634f2010-08-27 20:39:12 +0900551 char *arg;
Masami Hiramatsuc5d343b2018-03-17 21:38:10 +0900552 long offset = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400553 void *addr = NULL;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200554 char buf[MAX_EVENT_NAME_LEN];
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900555 unsigned int flags = TPARG_FL_KERNEL;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400556
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500557 /* argc must be >= 1 */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400558 if (argv[0][0] == 'p')
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530559 is_return = false;
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900560 else if (argv[0][0] == 'r') {
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530561 is_return = true;
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900562 flags |= TPARG_FL_RETURN;
563 } else if (argv[0][0] == '-')
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530564 is_delete = true;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400565 else {
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500566 pr_info("Probe definition must be started with 'p', 'r' or"
567 " '-'.\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400568 return -EINVAL;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400569 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400570
Alban Crequy696ced42017-04-03 12:36:22 +0200571 event = strchr(&argv[0][1], ':');
572 if (event) {
573 event[0] = '\0';
574 event++;
575 }
576 if (is_return && isdigit(argv[0][1])) {
577 ret = kstrtouint(&argv[0][1], 0, &maxactive);
578 if (ret) {
579 pr_info("Failed to parse maxactive.\n");
580 return ret;
581 }
582 /* kretprobes instances are iterated over via a list. The
583 * maximum should stay reasonable.
584 */
585 if (maxactive > KRETPROBE_MAXACTIVE_MAX) {
586 pr_info("Maxactive is too big (%d > %d).\n",
587 maxactive, KRETPROBE_MAXACTIVE_MAX);
588 return -E2BIG;
589 }
590 }
591
592 if (event) {
Steven Rostedt (VMware)d6b183e2018-08-24 16:20:28 -0400593 char *slash;
594
595 slash = strchr(event, '/');
596 if (slash) {
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400597 group = event;
Steven Rostedt (VMware)d6b183e2018-08-24 16:20:28 -0400598 event = slash + 1;
599 slash[0] = '\0';
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400600 if (strlen(group) == 0) {
Wenji Huanga5efd922010-02-24 15:40:23 +0800601 pr_info("Group name is not specified\n");
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400602 return -EINVAL;
603 }
604 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400605 if (strlen(event) == 0) {
Wenji Huanga5efd922010-02-24 15:40:23 +0800606 pr_info("Event name is not specified\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400607 return -EINVAL;
608 }
609 }
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500610 if (!group)
611 group = KPROBE_EVENT_SYSTEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400612
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500613 if (is_delete) {
614 if (!event) {
615 pr_info("Delete command needs an event name.\n");
616 return -EINVAL;
617 }
Srikar Dronamraju9da79ab2010-06-30 14:15:48 +0530618 mutex_lock(&probe_lock);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900619 tk = find_trace_kprobe(event, group);
620 if (!tk) {
Srikar Dronamraju9da79ab2010-06-30 14:15:48 +0530621 mutex_unlock(&probe_lock);
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500622 pr_info("Event %s/%s doesn't exist.\n", group, event);
623 return -ENOENT;
624 }
625 /* delete an event */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900626 ret = unregister_trace_kprobe(tk);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900627 if (ret == 0)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900628 free_trace_kprobe(tk);
Srikar Dronamraju9da79ab2010-06-30 14:15:48 +0530629 mutex_unlock(&probe_lock);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900630 return ret;
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500631 }
632
633 if (argc < 2) {
634 pr_info("Probe point is not specified.\n");
635 return -EINVAL;
636 }
Sabrina Dubroca9e52b322017-06-22 11:24:42 +0200637
638 /* try to parse an address. if that fails, try to read the
639 * input as a symbol. */
640 if (kstrtoul(argv[1], 0, (unsigned long *)&addr)) {
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400641 /* a symbol specified */
642 symbol = argv[1];
643 /* TODO: support .init module functions */
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +0530644 ret = traceprobe_split_symbol_offset(symbol, &offset);
Masami Hiramatsuc5d343b2018-03-17 21:38:10 +0900645 if (ret || offset < 0 || offset > UINT_MAX) {
Sabrina Dubroca9e52b322017-06-22 11:24:42 +0200646 pr_info("Failed to parse either an address or a symbol.\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400647 return ret;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400648 }
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900649 if (kprobe_on_func_entry(NULL, symbol, offset))
650 flags |= TPARG_FL_FENTRY;
651 if (offset && is_return && !(flags & TPARG_FL_FENTRY)) {
Steven Rostedt (VMware)d0e02572017-02-27 11:52:04 -0500652 pr_info("Given offset is not valid for return probe.\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400653 return -EINVAL;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400654 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400655 }
Masami Hiramatsua82378d2009-08-13 16:35:18 -0400656 argc -= 2; argv += 2;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400657
658 /* setup a probe */
Masami Hiramatsu42635652009-08-13 16:35:26 -0400659 if (!event) {
660 /* Make a new event name */
Masami Hiramatsu42635652009-08-13 16:35:26 -0400661 if (symbol)
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500662 snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_%ld",
Masami Hiramatsu42635652009-08-13 16:35:26 -0400663 is_return ? 'r' : 'p', symbol, offset);
664 else
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500665 snprintf(buf, MAX_EVENT_NAME_LEN, "%c_0x%p",
Masami Hiramatsu42635652009-08-13 16:35:26 -0400666 is_return ? 'r' : 'p', addr);
Naveen N. Raofca18a42017-07-08 00:27:30 +0530667 sanitize_event_name(buf);
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200668 event = buf;
669 }
Alban Crequy696ced42017-04-03 12:36:22 +0200670 tk = alloc_trace_kprobe(group, event, addr, symbol, offset, maxactive,
671 argc, is_return);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900672 if (IS_ERR(tk)) {
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400673 pr_info("Failed to allocate trace_probe.(%d)\n",
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900674 (int)PTR_ERR(tk));
675 return PTR_ERR(tk);
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400676 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400677
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400678 /* parse arguments */
Masami Hiramatsua82378d2009-08-13 16:35:18 -0400679 ret = 0;
680 for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900681 struct probe_arg *parg = &tk->tp.args[i];
682
Masami Hiramatsu61a52732010-08-27 20:38:46 +0900683 /* Increment count for freeing args in error case */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900684 tk->tp.nr_args++;
Masami Hiramatsu61a52732010-08-27 20:38:46 +0900685
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400686 /* Parse argument name */
687 arg = strchr(argv[i], '=');
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900688 if (arg) {
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400689 *arg++ = '\0';
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900690 parg->name = kstrdup(argv[i], GFP_KERNEL);
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900691 } else {
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400692 arg = argv[i];
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900693 /* If argument name is omitted, set "argN" */
694 snprintf(buf, MAX_EVENT_NAME_LEN, "arg%d", i + 1);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900695 parg->name = kstrdup(buf, GFP_KERNEL);
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900696 }
Masami Hiramatsua703d942009-10-07 18:28:07 -0400697
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900698 if (!parg->name) {
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900699 pr_info("Failed to allocate argument[%d] name.\n", i);
Masami Hiramatsuba8665d2009-11-30 19:19:20 -0500700 ret = -ENOMEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400701 goto error;
702 }
Masami Hiramatsuda34634f2010-08-27 20:39:12 +0900703
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900704 if (!is_good_name(parg->name)) {
Masami Hiramatsuda34634f2010-08-27 20:39:12 +0900705 pr_info("Invalid argument[%d] name: %s\n",
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900706 i, parg->name);
Masami Hiramatsuda34634f2010-08-27 20:39:12 +0900707 ret = -EINVAL;
708 goto error;
709 }
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400710
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900711 if (traceprobe_conflict_field_name(parg->name,
712 tk->tp.args, i)) {
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900713 pr_info("Argument[%d] name '%s' conflicts with "
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400714 "another field.\n", i, argv[i]);
715 ret = -EINVAL;
716 goto error;
717 }
Masami Hiramatsuba8665d2009-11-30 19:19:20 -0500718
719 /* Parse fetch argument */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900720 ret = traceprobe_parse_probe_arg(arg, &tk->tp.size, parg,
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900721 flags);
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400722 if (ret) {
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900723 pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400724 goto error;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400725 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400726 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400727
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900728 ret = register_trace_kprobe(tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400729 if (ret)
730 goto error;
731 return 0;
732
733error:
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900734 free_trace_kprobe(tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400735 return ret;
736}
737
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900738static int release_all_trace_kprobes(void)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400739{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900740 struct trace_kprobe *tk;
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900741 int ret = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400742
743 mutex_lock(&probe_lock);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900744 /* Ensure no probe is in use. */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900745 list_for_each_entry(tk, &probe_list, list)
746 if (trace_probe_is_enabled(&tk->tp)) {
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900747 ret = -EBUSY;
748 goto end;
749 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400750 /* TODO: Use batch unregistration */
751 while (!list_empty(&probe_list)) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900752 tk = list_entry(probe_list.next, struct trace_kprobe, list);
753 ret = unregister_trace_kprobe(tk);
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -0400754 if (ret)
755 goto end;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900756 free_trace_kprobe(tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400757 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900758
759end:
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400760 mutex_unlock(&probe_lock);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900761
762 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400763}
764
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400765/* Probes listing interfaces */
766static void *probes_seq_start(struct seq_file *m, loff_t *pos)
767{
768 mutex_lock(&probe_lock);
769 return seq_list_start(&probe_list, *pos);
770}
771
772static void *probes_seq_next(struct seq_file *m, void *v, loff_t *pos)
773{
774 return seq_list_next(v, &probe_list, pos);
775}
776
777static void probes_seq_stop(struct seq_file *m, void *v)
778{
779 mutex_unlock(&probe_lock);
780}
781
782static int probes_seq_show(struct seq_file *m, void *v)
783{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900784 struct trace_kprobe *tk = v;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400785 int i;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400786
Rasmus Villemoesfa6f0cc2014-11-08 21:42:10 +0100787 seq_putc(m, trace_kprobe_is_return(tk) ? 'r' : 'p');
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -0400788 seq_printf(m, ":%s/%s", tk->tp.call.class->system,
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -0400789 trace_event_name(&tk->tp.call));
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400790
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900791 if (!tk->symbol)
792 seq_printf(m, " 0x%p", tk->rp.kp.addr);
793 else if (tk->rp.kp.offset)
794 seq_printf(m, " %s+%u", trace_kprobe_symbol(tk),
795 tk->rp.kp.offset);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400796 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900797 seq_printf(m, " %s", trace_kprobe_symbol(tk));
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400798
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900799 for (i = 0; i < tk->tp.nr_args; i++)
800 seq_printf(m, " %s=%s", tk->tp.args[i].name, tk->tp.args[i].comm);
Rasmus Villemoesfa6f0cc2014-11-08 21:42:10 +0100801 seq_putc(m, '\n');
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400802
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400803 return 0;
804}
805
806static const struct seq_operations probes_seq_op = {
807 .start = probes_seq_start,
808 .next = probes_seq_next,
809 .stop = probes_seq_stop,
810 .show = probes_seq_show
811};
812
813static int probes_open(struct inode *inode, struct file *file)
814{
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900815 int ret;
816
817 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900818 ret = release_all_trace_kprobes();
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900819 if (ret < 0)
820 return ret;
821 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400822
823 return seq_open(file, &probes_seq_op);
824}
825
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400826static ssize_t probes_write(struct file *file, const char __user *buffer,
827 size_t count, loff_t *ppos)
828{
Tom Zanussi7e465ba2017-09-22 14:58:20 -0500829 return trace_parse_run_command(file, buffer, count, ppos,
830 create_trace_kprobe);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400831}
832
833static const struct file_operations kprobe_events_ops = {
834 .owner = THIS_MODULE,
835 .open = probes_open,
836 .read = seq_read,
837 .llseek = seq_lseek,
838 .release = seq_release,
839 .write = probes_write,
840};
841
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400842/* Probes profiling interfaces */
843static int probes_profile_seq_show(struct seq_file *m, void *v)
844{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900845 struct trace_kprobe *tk = v;
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400846
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -0400847 seq_printf(m, " %-44s %15lu %15lu\n",
Marcin Nowakowskif18f97a2016-12-09 15:19:37 +0100848 trace_event_name(&tk->tp.call),
849 trace_kprobe_nhit(tk),
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900850 tk->rp.kp.nmissed);
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -0400851
852 return 0;
853}
854
855static const struct seq_operations profile_seq_op = {
856 .start = probes_seq_start,
857 .next = probes_seq_next,
858 .stop = probes_seq_stop,
859 .show = probes_profile_seq_show
860};
861
862static int profile_open(struct inode *inode, struct file *file)
863{
864 return seq_open(file, &profile_seq_op);
865}
866
867static const struct file_operations kprobe_profile_ops = {
868 .owner = THIS_MODULE,
869 .open = profile_open,
870 .read = seq_read,
871 .llseek = seq_lseek,
872 .release = seq_release,
873};
874
Masami Hiramatsu53305922018-04-25 21:18:03 +0900875/* Kprobe specific fetch functions */
876
877/* Return the length of string -- including null terminal byte */
Masami Hiramatsu91784122018-04-25 21:19:01 +0900878static nokprobe_inline int
879fetch_store_strlen(unsigned long addr)
Masami Hiramatsu53305922018-04-25 21:18:03 +0900880{
881 mm_segment_t old_fs;
882 int ret, len = 0;
883 u8 c;
884
885 old_fs = get_fs();
886 set_fs(KERNEL_DS);
887 pagefault_disable();
888
889 do {
890 ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
891 len++;
892 } while (c && ret == 0 && len < MAX_STRING_SIZE);
893
894 pagefault_enable();
895 set_fs(old_fs);
896
Masami Hiramatsu91784122018-04-25 21:19:01 +0900897 return (ret < 0) ? ret : len;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900898}
899
900/*
901 * Fetch a null-terminated string. Caller MUST set *(u32 *)buf with max
902 * length and relative data location.
903 */
Masami Hiramatsu91784122018-04-25 21:19:01 +0900904static nokprobe_inline int
905fetch_store_string(unsigned long addr, void *dest, void *base)
Masami Hiramatsu53305922018-04-25 21:18:03 +0900906{
Masami Hiramatsu91784122018-04-25 21:19:01 +0900907 int maxlen = get_loc_len(*(u32 *)dest);
908 u8 *dst = get_loc_data(dest, base);
Masami Hiramatsu53305922018-04-25 21:18:03 +0900909 long ret;
910
Masami Hiramatsu91784122018-04-25 21:19:01 +0900911 if (unlikely(!maxlen))
912 return -ENOMEM;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900913 /*
914 * Try to get string again, since the string can be changed while
915 * probing.
916 */
917 ret = strncpy_from_unsafe(dst, (void *)addr, maxlen);
918
Masami Hiramatsu91784122018-04-25 21:19:01 +0900919 if (ret >= 0)
920 *(u32 *)dest = make_data_loc(ret, (void *)dst - base);
921 return ret;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900922}
923
Masami Hiramatsu9b960a32018-04-25 21:19:59 +0900924static nokprobe_inline int
925probe_mem_read(void *dest, void *src, size_t size)
926{
927 return probe_kernel_read(dest, src, size);
928}
929
Masami Hiramatsu53305922018-04-25 21:18:03 +0900930/* Note that we don't verify it, since the code does not come from user space */
931static int
932process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
Masami Hiramatsu91784122018-04-25 21:19:01 +0900933 void *base)
Masami Hiramatsu53305922018-04-25 21:18:03 +0900934{
935 unsigned long val;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900936
Masami Hiramatsua6682812018-08-29 01:18:43 +0900937retry:
Masami Hiramatsu53305922018-04-25 21:18:03 +0900938 /* 1st stage: get value from context */
939 switch (code->op) {
940 case FETCH_OP_REG:
941 val = regs_get_register(regs, code->param);
942 break;
943 case FETCH_OP_STACK:
944 val = regs_get_kernel_stack_nth(regs, code->param);
945 break;
946 case FETCH_OP_STACKP:
947 val = kernel_stack_pointer(regs);
948 break;
949 case FETCH_OP_RETVAL:
950 val = regs_return_value(regs);
951 break;
952 case FETCH_OP_IMM:
953 val = code->immediate;
954 break;
955 case FETCH_OP_COMM:
956 val = (unsigned long)current->comm;
957 break;
Masami Hiramatsua1303af2018-04-25 21:21:26 +0900958#ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
959 case FETCH_OP_ARG:
960 val = regs_get_kernel_argument(regs, code->param);
961 break;
962#endif
Masami Hiramatsua6682812018-08-29 01:18:43 +0900963 case FETCH_NOP_SYMBOL: /* Ignore a place holder */
964 code++;
965 goto retry;
Masami Hiramatsu53305922018-04-25 21:18:03 +0900966 default:
967 return -EILSEQ;
968 }
969 code++;
970
Masami Hiramatsu9b960a32018-04-25 21:19:59 +0900971 return process_fetch_insn_bottom(code, val, dest, base);
Masami Hiramatsu53305922018-04-25 21:18:03 +0900972}
973NOKPROBE_SYMBOL(process_fetch_insn)
974
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400975/* Kprobe handler */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900976static nokprobe_inline void
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900977__kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs,
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400978 struct trace_event_file *trace_file)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400979{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400980 struct kprobe_trace_entry_head *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400981 struct ring_buffer_event *event;
Frederic Weisbecker8f8ffe22009-09-11 01:09:23 +0200982 struct ring_buffer *buffer;
Masami Hiramatsue09c8612010-07-05 15:54:45 -0300983 int size, dsize, pc;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400984 unsigned long irq_flags;
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -0400985 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400986
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400987 WARN_ON(call != trace_file->event_call);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900988
Steven Rostedt (Red Hat)09a50592015-05-13 15:21:25 -0400989 if (trace_trigger_soft_disabled(trace_file))
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -0500990 return;
Masami Hiramatsub8820082013-05-09 14:44:54 +0900991
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400992 local_save_flags(irq_flags);
993 pc = preempt_count();
994
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900995 dsize = __get_data_size(&tk->tp, regs);
996 size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400997
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400998 event = trace_event_buffer_lock_reserve(&buffer, trace_file,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900999 call->event.type,
1000 size, irq_flags, pc);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001001 if (!event)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001002 return;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001003
1004 entry = ring_buffer_event_data(event);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001005 entry->ip = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsu91784122018-04-25 21:19:01 +09001006 store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001007
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001008 event_trigger_unlock_commit_regs(trace_file, buffer, event,
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -05001009 entry, irq_flags, pc, regs);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001010}
1011
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001012static void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001013kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001014{
Oleg Nesterovb04d52e2013-06-20 19:38:14 +02001015 struct event_file_link *link;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001016
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001017 list_for_each_entry_rcu(link, &tk->tp.files, list)
1018 __kprobe_trace_func(tk, regs, link->file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001019}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001020NOKPROBE_SYMBOL(kprobe_trace_func);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001021
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001022/* Kretprobe handler */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001023static nokprobe_inline void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001024__kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001025 struct pt_regs *regs,
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001026 struct trace_event_file *trace_file)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001027{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001028 struct kretprobe_trace_entry_head *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001029 struct ring_buffer_event *event;
Frederic Weisbecker8f8ffe22009-09-11 01:09:23 +02001030 struct ring_buffer *buffer;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001031 int size, pc, dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001032 unsigned long irq_flags;
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001033 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001034
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001035 WARN_ON(call != trace_file->event_call);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001036
Steven Rostedt (Red Hat)09a50592015-05-13 15:21:25 -04001037 if (trace_trigger_soft_disabled(trace_file))
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -05001038 return;
Masami Hiramatsub8820082013-05-09 14:44:54 +09001039
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001040 local_save_flags(irq_flags);
1041 pc = preempt_count();
1042
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001043 dsize = __get_data_size(&tk->tp, regs);
1044 size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001045
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001046 event = trace_event_buffer_lock_reserve(&buffer, trace_file,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001047 call->event.type,
1048 size, irq_flags, pc);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001049 if (!event)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001050 return;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001051
1052 entry = ring_buffer_event_data(event);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001053 entry->func = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001054 entry->ret_ip = (unsigned long)ri->ret_addr;
Masami Hiramatsu91784122018-04-25 21:19:01 +09001055 store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001056
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001057 event_trigger_unlock_commit_regs(trace_file, buffer, event,
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -05001058 entry, irq_flags, pc, regs);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001059}
1060
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001061static void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001062kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001063 struct pt_regs *regs)
1064{
Oleg Nesterovb04d52e2013-06-20 19:38:14 +02001065 struct event_file_link *link;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001066
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001067 list_for_each_entry_rcu(link, &tk->tp.files, list)
1068 __kretprobe_trace_func(tk, ri, regs, link->file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001069}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001070NOKPROBE_SYMBOL(kretprobe_trace_func);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001071
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001072/* Event entry printers */
Masami Hiramatsub62fdd92013-05-13 20:58:39 +09001073static enum print_line_t
Steven Rostedta9a57762010-04-22 18:46:14 -04001074print_kprobe_event(struct trace_iterator *iter, int flags,
1075 struct trace_event *event)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001076{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001077 struct kprobe_trace_entry_head *field;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001078 struct trace_seq *s = &iter->seq;
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001079 struct trace_probe *tp;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001080
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001081 field = (struct kprobe_trace_entry_head *)iter->ent;
Steven Rostedt80decc72010-04-23 10:00:22 -04001082 tp = container_of(event, struct trace_probe, call.event);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001083
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -04001084 trace_seq_printf(s, "%s: (", trace_event_name(&tp->call));
Masami Hiramatsu6e9f23d2009-09-10 19:53:45 -04001085
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001086 if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001087 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001088
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001089 trace_seq_putc(s, ')');
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001090
Masami Hiramatsu56de7632018-04-25 21:16:36 +09001091 if (print_probe_args(s, tp->args, tp->nr_args,
1092 (u8 *)&field[1], field) < 0)
1093 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001094
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001095 trace_seq_putc(s, '\n');
1096 out:
1097 return trace_handle_return(s);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001098}
1099
Masami Hiramatsub62fdd92013-05-13 20:58:39 +09001100static enum print_line_t
Steven Rostedta9a57762010-04-22 18:46:14 -04001101print_kretprobe_event(struct trace_iterator *iter, int flags,
1102 struct trace_event *event)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001103{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001104 struct kretprobe_trace_entry_head *field;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001105 struct trace_seq *s = &iter->seq;
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001106 struct trace_probe *tp;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001107
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001108 field = (struct kretprobe_trace_entry_head *)iter->ent;
Steven Rostedt80decc72010-04-23 10:00:22 -04001109 tp = container_of(event, struct trace_probe, call.event);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001110
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -04001111 trace_seq_printf(s, "%s: (", trace_event_name(&tp->call));
Masami Hiramatsu6e9f23d2009-09-10 19:53:45 -04001112
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001113 if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001114 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001115
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001116 trace_seq_puts(s, " <- ");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001117
1118 if (!seq_print_ip_sym(s, field->func, flags & ~TRACE_ITER_SYM_OFFSET))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001119 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001120
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001121 trace_seq_putc(s, ')');
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001122
Masami Hiramatsu56de7632018-04-25 21:16:36 +09001123 if (print_probe_args(s, tp->args, tp->nr_args,
1124 (u8 *)&field[1], field) < 0)
1125 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001126
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001127 trace_seq_putc(s, '\n');
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001128
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001129 out:
1130 return trace_handle_return(s);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001131}
1132
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001133
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001134static int kprobe_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 kprobe_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, ip, FIELD_STRING_IP, 0);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001141
Masami Hiramatsueeb07b02018-04-25 21:17:05 +09001142 return traceprobe_define_arg_fields(event_call, sizeof(field), &tk->tp);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001143}
1144
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001145static int kretprobe_event_define_fields(struct trace_event_call *event_call)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001146{
Masami Hiramatsueeb07b02018-04-25 21:17:05 +09001147 int ret;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001148 struct kretprobe_trace_entry_head field;
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001149 struct trace_kprobe *tk = (struct trace_kprobe *)event_call->data;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001150
Masami Hiramatsua703d942009-10-07 18:28:07 -04001151 DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0);
1152 DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001153
Masami Hiramatsueeb07b02018-04-25 21:17:05 +09001154 return traceprobe_define_arg_fields(event_call, sizeof(field), &tk->tp);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001155}
1156
Li Zefan07b139c2009-12-21 14:27:35 +08001157#ifdef CONFIG_PERF_EVENTS
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001158
1159/* Kprobe profile handler */
Josef Bacik9802d862017-12-11 11:36:48 -05001160static int
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001161kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs)
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001162{
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001163 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001164 struct kprobe_trace_entry_head *entry;
Peter Zijlstra1c024eca2010-05-19 14:02:22 +02001165 struct hlist_head *head;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001166 int size, __size, dsize;
Peter Zijlstra4ed7c922009-11-23 11:37:29 +01001167 int rctx;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001168
Josef Bacik9802d862017-12-11 11:36:48 -05001169 if (bpf_prog_array_valid(call)) {
Masami Hiramatsu66665ad2018-01-13 02:54:33 +09001170 unsigned long orig_ip = instruction_pointer(regs);
Josef Bacik9802d862017-12-11 11:36:48 -05001171 int ret;
1172
1173 ret = trace_call_bpf(call, regs);
1174
1175 /*
1176 * We need to check and see if we modified the pc of the
Masami Hiramatsucce188b2018-06-20 01:15:45 +09001177 * pt_regs, and if so return 1 so that we don't do the
1178 * single stepping.
Josef Bacik9802d862017-12-11 11:36:48 -05001179 */
Masami Hiramatsucce188b2018-06-20 01:15:45 +09001180 if (orig_ip != instruction_pointer(regs))
Josef Bacik9802d862017-12-11 11:36:48 -05001181 return 1;
Josef Bacik9802d862017-12-11 11:36:48 -05001182 if (!ret)
1183 return 0;
1184 }
Alexei Starovoitov25415172015-03-25 12:49:20 -07001185
Oleg Nesterov288e9842013-06-20 19:38:06 +02001186 head = this_cpu_ptr(call->perf_events);
1187 if (hlist_empty(head))
Josef Bacik9802d862017-12-11 11:36:48 -05001188 return 0;
Oleg Nesterov288e9842013-06-20 19:38:06 +02001189
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001190 dsize = __get_data_size(&tk->tp, regs);
1191 __size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu74ebb632009-09-14 16:49:28 -04001192 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1193 size -= sizeof(u32);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001194
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001195 entry = perf_trace_buf_alloc(size, NULL, &rctx);
Xiao Guangrong430ad5a2010-01-28 09:32:29 +08001196 if (!entry)
Josef Bacik9802d862017-12-11 11:36:48 -05001197 return 0;
Frederic Weisbeckerce71b9d2009-11-22 05:26:55 +01001198
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001199 entry->ip = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001200 memset(&entry[1], 0, dsize);
Masami Hiramatsu91784122018-04-25 21:19:01 +09001201 store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001202 perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs,
Peter Zijlstra8fd0fbb2017-10-11 09:45:29 +02001203 head, NULL);
Josef Bacik9802d862017-12-11 11:36:48 -05001204 return 0;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001205}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001206NOKPROBE_SYMBOL(kprobe_perf_func);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001207
1208/* Kretprobe profile handler */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001209static void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001210kretprobe_perf_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001211 struct pt_regs *regs)
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001212{
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001213 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001214 struct kretprobe_trace_entry_head *entry;
Peter Zijlstra1c024eca2010-05-19 14:02:22 +02001215 struct hlist_head *head;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001216 int size, __size, dsize;
Peter Zijlstra4ed7c922009-11-23 11:37:29 +01001217 int rctx;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001218
Yonghong Songe87c6bc382017-10-23 23:53:08 -07001219 if (bpf_prog_array_valid(call) && !trace_call_bpf(call, regs))
Alexei Starovoitov25415172015-03-25 12:49:20 -07001220 return;
1221
Oleg Nesterov288e9842013-06-20 19:38:06 +02001222 head = this_cpu_ptr(call->perf_events);
1223 if (hlist_empty(head))
1224 return;
1225
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001226 dsize = __get_data_size(&tk->tp, regs);
1227 __size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu74ebb632009-09-14 16:49:28 -04001228 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1229 size -= sizeof(u32);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001230
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001231 entry = perf_trace_buf_alloc(size, NULL, &rctx);
Xiao Guangrong430ad5a2010-01-28 09:32:29 +08001232 if (!entry)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001233 return;
Frederic Weisbeckerce71b9d2009-11-22 05:26:55 +01001234
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001235 entry->func = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsua1a138d2009-09-25 11:20:12 -07001236 entry->ret_ip = (unsigned long)ri->ret_addr;
Masami Hiramatsu91784122018-04-25 21:19:01 +09001237 store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001238 perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs,
Peter Zijlstra8fd0fbb2017-10-11 09:45:29 +02001239 head, NULL);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001240}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001241NOKPROBE_SYMBOL(kretprobe_perf_func);
Yonghong Song41bdc4b2018-05-24 11:21:09 -07001242
1243int bpf_get_kprobe_info(const struct perf_event *event, u32 *fd_type,
1244 const char **symbol, u64 *probe_offset,
1245 u64 *probe_addr, bool perf_type_tracepoint)
1246{
1247 const char *pevent = trace_event_name(event->tp_event);
1248 const char *group = event->tp_event->class->system;
1249 struct trace_kprobe *tk;
1250
1251 if (perf_type_tracepoint)
1252 tk = find_trace_kprobe(pevent, group);
1253 else
1254 tk = event->tp_event->data;
1255 if (!tk)
1256 return -EINVAL;
1257
1258 *fd_type = trace_kprobe_is_return(tk) ? BPF_FD_TYPE_KRETPROBE
1259 : BPF_FD_TYPE_KPROBE;
1260 if (tk->symbol) {
1261 *symbol = tk->symbol;
1262 *probe_offset = tk->rp.kp.offset;
1263 *probe_addr = 0;
1264 } else {
1265 *symbol = NULL;
1266 *probe_offset = 0;
1267 *probe_addr = (unsigned long)tk->rp.kp.addr;
1268 }
1269 return 0;
1270}
Li Zefan07b139c2009-12-21 14:27:35 +08001271#endif /* CONFIG_PERF_EVENTS */
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001272
Oleg Nesterov3fe3d612013-06-20 19:38:09 +02001273/*
1274 * called by perf_trace_init() or __ftrace_set_clr_event() under event_mutex.
1275 *
1276 * kprobe_trace_self_tests_init() does enable_trace_probe/disable_trace_probe
1277 * lockless, but we can't race with this __init function.
1278 */
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001279static int kprobe_register(struct trace_event_call *event,
Masami Hiramatsufbc19632014-04-17 17:18:00 +09001280 enum trace_reg type, void *data)
Steven Rostedt22392912010-04-21 12:27:06 -04001281{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001282 struct trace_kprobe *tk = (struct trace_kprobe *)event->data;
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001283 struct trace_event_file *file = data;
Masami Hiramatsu1538f882011-06-27 16:26:44 +09001284
Steven Rostedt22392912010-04-21 12:27:06 -04001285 switch (type) {
1286 case TRACE_REG_REGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001287 return enable_trace_kprobe(tk, file);
Steven Rostedt22392912010-04-21 12:27:06 -04001288 case TRACE_REG_UNREGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001289 return disable_trace_kprobe(tk, file);
Steven Rostedt22392912010-04-21 12:27:06 -04001290
1291#ifdef CONFIG_PERF_EVENTS
1292 case TRACE_REG_PERF_REGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001293 return enable_trace_kprobe(tk, NULL);
Steven Rostedt22392912010-04-21 12:27:06 -04001294 case TRACE_REG_PERF_UNREGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001295 return disable_trace_kprobe(tk, NULL);
Jiri Olsaceec0b62012-02-15 15:51:49 +01001296 case TRACE_REG_PERF_OPEN:
1297 case TRACE_REG_PERF_CLOSE:
Jiri Olsa489c75c2012-02-15 15:51:50 +01001298 case TRACE_REG_PERF_ADD:
1299 case TRACE_REG_PERF_DEL:
Jiri Olsaceec0b62012-02-15 15:51:49 +01001300 return 0;
Steven Rostedt22392912010-04-21 12:27:06 -04001301#endif
1302 }
1303 return 0;
1304}
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001305
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001306static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs)
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001307{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001308 struct trace_kprobe *tk = container_of(kp, struct trace_kprobe, rp.kp);
Josef Bacik9802d862017-12-11 11:36:48 -05001309 int ret = 0;
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001310
Martin KaFai Laua7636d92016-02-03 12:28:28 -08001311 raw_cpu_inc(*tk->nhit);
Masami Hiramatsu48182bd2013-05-09 14:44:36 +09001312
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001313 if (tk->tp.flags & TP_FLAG_TRACE)
1314 kprobe_trace_func(tk, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001315#ifdef CONFIG_PERF_EVENTS
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001316 if (tk->tp.flags & TP_FLAG_PROFILE)
Josef Bacik9802d862017-12-11 11:36:48 -05001317 ret = kprobe_perf_func(tk, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001318#endif
Josef Bacik9802d862017-12-11 11:36:48 -05001319 return ret;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001320}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001321NOKPROBE_SYMBOL(kprobe_dispatcher);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001322
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001323static int
1324kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs)
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001325{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001326 struct trace_kprobe *tk = container_of(ri->rp, struct trace_kprobe, rp);
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001327
Martin KaFai Laua7636d92016-02-03 12:28:28 -08001328 raw_cpu_inc(*tk->nhit);
Masami Hiramatsu48182bd2013-05-09 14:44:36 +09001329
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001330 if (tk->tp.flags & TP_FLAG_TRACE)
1331 kretprobe_trace_func(tk, ri, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001332#ifdef CONFIG_PERF_EVENTS
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001333 if (tk->tp.flags & TP_FLAG_PROFILE)
1334 kretprobe_perf_func(tk, ri, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001335#endif
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001336 return 0; /* We don't tweek kernel, so just return 0 */
1337}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001338NOKPROBE_SYMBOL(kretprobe_dispatcher);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001339
Steven Rostedta9a57762010-04-22 18:46:14 -04001340static struct trace_event_functions kretprobe_funcs = {
1341 .trace = print_kretprobe_event
1342};
1343
1344static struct trace_event_functions kprobe_funcs = {
1345 .trace = print_kprobe_event
1346};
1347
Song Liue12f03d2017-12-06 14:45:15 -08001348static inline void init_trace_event_call(struct trace_kprobe *tk,
1349 struct trace_event_call *call)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001350{
Li Zefanffb9f992010-05-24 16:24:52 +08001351 INIT_LIST_HEAD(&call->class->fields);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001352 if (trace_kprobe_is_return(tk)) {
Steven Rostedt80decc72010-04-23 10:00:22 -04001353 call->event.funcs = &kretprobe_funcs;
Steven Rostedt2e33af02010-04-22 10:35:55 -04001354 call->class->define_fields = kretprobe_event_define_fields;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001355 } else {
Steven Rostedt80decc72010-04-23 10:00:22 -04001356 call->event.funcs = &kprobe_funcs;
Steven Rostedt2e33af02010-04-22 10:35:55 -04001357 call->class->define_fields = kprobe_event_define_fields;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001358 }
Song Liue12f03d2017-12-06 14:45:15 -08001359
1360 call->flags = TRACE_EVENT_FL_KPROBE;
1361 call->class->reg = kprobe_register;
1362 call->data = tk;
1363}
1364
1365static int register_kprobe_event(struct trace_kprobe *tk)
1366{
1367 struct trace_event_call *call = &tk->tp.call;
1368 int ret = 0;
1369
1370 init_trace_event_call(tk, call);
1371
Masami Hiramatsu0a46c852018-04-25 21:19:30 +09001372 if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0)
Lai Jiangshana342a0282009-12-15 15:39:49 +08001373 return -ENOMEM;
Steven Rostedt (Red Hat)9023c932015-05-05 09:39:12 -04001374 ret = register_trace_event(&call->event);
Steven Rostedt32c0eda2010-04-23 10:38:03 -04001375 if (!ret) {
Lai Jiangshana342a0282009-12-15 15:39:49 +08001376 kfree(call->print_fmt);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001377 return -ENODEV;
Lai Jiangshana342a0282009-12-15 15:39:49 +08001378 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001379 ret = trace_add_event_call(call);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001380 if (ret) {
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -04001381 pr_info("Failed to register kprobe event: %s\n",
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -04001382 trace_event_name(call));
Lai Jiangshana342a0282009-12-15 15:39:49 +08001383 kfree(call->print_fmt);
Steven Rostedt (Red Hat)9023c932015-05-05 09:39:12 -04001384 unregister_trace_event(&call->event);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001385 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001386 return ret;
1387}
1388
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001389static int unregister_kprobe_event(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001390{
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -04001391 int ret;
1392
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001393 /* tp->event is unregistered in trace_remove_event_call() */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001394 ret = trace_remove_event_call(&tk->tp.call);
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -04001395 if (!ret)
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001396 kfree(tk->tp.call.print_fmt);
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -04001397 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001398}
1399
Song Liue12f03d2017-12-06 14:45:15 -08001400#ifdef CONFIG_PERF_EVENTS
1401/* create a trace_kprobe, but don't add it to global lists */
1402struct trace_event_call *
1403create_local_trace_kprobe(char *func, void *addr, unsigned long offs,
1404 bool is_return)
1405{
1406 struct trace_kprobe *tk;
1407 int ret;
1408 char *event;
1409
1410 /*
1411 * local trace_kprobes are not added to probe_list, so they are never
1412 * searched in find_trace_kprobe(). Therefore, there is no concern of
1413 * duplicated name here.
1414 */
1415 event = func ? func : "DUMMY_EVENT";
1416
1417 tk = alloc_trace_kprobe(KPROBE_EVENT_SYSTEM, event, (void *)addr, func,
1418 offs, 0 /* maxactive */, 0 /* nargs */,
1419 is_return);
1420
1421 if (IS_ERR(tk)) {
1422 pr_info("Failed to allocate trace_probe.(%d)\n",
1423 (int)PTR_ERR(tk));
1424 return ERR_CAST(tk);
1425 }
1426
1427 init_trace_event_call(tk, &tk->tp.call);
1428
Masami Hiramatsu0a46c852018-04-25 21:19:30 +09001429 if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) {
Song Liue12f03d2017-12-06 14:45:15 -08001430 ret = -ENOMEM;
1431 goto error;
1432 }
1433
1434 ret = __register_trace_kprobe(tk);
Jiri Olsa0fc8c352018-07-09 16:19:06 +02001435 if (ret < 0) {
1436 kfree(tk->tp.call.print_fmt);
Song Liue12f03d2017-12-06 14:45:15 -08001437 goto error;
Jiri Olsa0fc8c352018-07-09 16:19:06 +02001438 }
Song Liue12f03d2017-12-06 14:45:15 -08001439
1440 return &tk->tp.call;
1441error:
1442 free_trace_kprobe(tk);
1443 return ERR_PTR(ret);
1444}
1445
1446void destroy_local_trace_kprobe(struct trace_event_call *event_call)
1447{
1448 struct trace_kprobe *tk;
1449
1450 tk = container_of(event_call, struct trace_kprobe, tp.call);
1451
1452 if (trace_probe_is_enabled(&tk->tp)) {
1453 WARN_ON(1);
1454 return;
1455 }
1456
1457 __unregister_trace_kprobe(tk);
Jiri Olsa0fc8c352018-07-09 16:19:06 +02001458
1459 kfree(tk->tp.call.print_fmt);
Song Liue12f03d2017-12-06 14:45:15 -08001460 free_trace_kprobe(tk);
1461}
1462#endif /* CONFIG_PERF_EVENTS */
1463
Steven Rostedt (Red Hat)8434dc92015-01-20 12:13:40 -05001464/* Make a tracefs interface for controlling probe points */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001465static __init int init_kprobe_trace(void)
1466{
1467 struct dentry *d_tracer;
1468 struct dentry *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001469
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001470 if (register_module_notifier(&trace_kprobe_module_nb))
Masami Hiramatsu61424312011-06-27 16:26:56 +09001471 return -EINVAL;
1472
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001473 d_tracer = tracing_init_dentry();
Steven Rostedt (Red Hat)14a5ae42015-01-20 11:14:16 -05001474 if (IS_ERR(d_tracer))
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001475 return 0;
1476
Steven Rostedt (Red Hat)8434dc92015-01-20 12:13:40 -05001477 entry = tracefs_create_file("kprobe_events", 0644, d_tracer,
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001478 NULL, &kprobe_events_ops);
1479
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001480 /* Event list interface */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001481 if (!entry)
Joe Perchesa395d6a2016-03-22 14:28:09 -07001482 pr_warn("Could not create tracefs 'kprobe_events' entry\n");
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001483
1484 /* Profile interface */
Steven Rostedt (Red Hat)8434dc92015-01-20 12:13:40 -05001485 entry = tracefs_create_file("kprobe_profile", 0444, d_tracer,
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001486 NULL, &kprobe_profile_ops);
1487
1488 if (!entry)
Joe Perchesa395d6a2016-03-22 14:28:09 -07001489 pr_warn("Could not create tracefs 'kprobe_profile' entry\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001490 return 0;
1491}
1492fs_initcall(init_kprobe_trace);
1493
1494
1495#ifdef CONFIG_FTRACE_STARTUP_TEST
Arnd Bergmann26a346f2017-02-01 17:57:56 +01001496static __init struct trace_event_file *
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001497find_trace_probe_file(struct trace_kprobe *tk, struct trace_array *tr)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001498{
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001499 struct trace_event_file *file;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001500
1501 list_for_each_entry(file, &tr->events, list)
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001502 if (file->event_call == &tk->tp.call)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001503 return file;
1504
1505 return NULL;
1506}
1507
Oleg Nesterov3fe3d612013-06-20 19:38:09 +02001508/*
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001509 * Nobody but us can call enable_trace_kprobe/disable_trace_kprobe at this
Oleg Nesterov3fe3d612013-06-20 19:38:09 +02001510 * stage, we can do this lockless.
1511 */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001512static __init int kprobe_trace_self_tests_init(void)
1513{
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001514 int ret, warn = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001515 int (*target)(int, int, int, int, int, int);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001516 struct trace_kprobe *tk;
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001517 struct trace_event_file *file;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001518
Yoshihiro YUNOMAE748ec3a2014-06-06 07:35:20 +09001519 if (tracing_is_disabled())
1520 return -ENODEV;
1521
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001522 target = kprobe_trace_selftest_target;
1523
1524 pr_info("Testing kprobe tracing: ");
1525
Tom Zanussi7e465ba2017-09-22 14:58:20 -05001526 ret = trace_run_command("p:testprobe kprobe_trace_selftest_target "
1527 "$stack $stack0 +0($stack)",
1528 create_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 entry.\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("testprobe", KPROBE_EVENT_SYSTEM);
1535 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001536 pr_warn("error on getting 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 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001547
Tom Zanussi7e465ba2017-09-22 14:58:20 -05001548 ret = trace_run_command("r:testprobe2 kprobe_trace_selftest_target "
1549 "$retval", create_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001550 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001551 pr_warn("error on probing function return.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001552 warn++;
1553 } else {
1554 /* Enable trace point */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001555 tk = find_trace_kprobe("testprobe2", KPROBE_EVENT_SYSTEM);
1556 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001557 pr_warn("error on getting 2nd new probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001558 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001559 } else {
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001560 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001561 if (WARN_ON_ONCE(file == NULL)) {
1562 pr_warn("error on getting probe file.\n");
1563 warn++;
1564 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001565 enable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001566 }
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001567 }
1568
1569 if (warn)
1570 goto end;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001571
1572 ret = target(1, 2, 3, 4, 5, 6);
1573
Marcin Nowakowskid4d7ccc2016-12-09 15:19:38 +01001574 /*
1575 * Not expecting an error here, the check is only to prevent the
1576 * optimizer from removing the call to target() as otherwise there
1577 * are no side-effects and the call is never performed.
1578 */
1579 if (ret != 21)
1580 warn++;
1581
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001582 /* Disable trace points before removing it */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001583 tk = find_trace_kprobe("testprobe", KPROBE_EVENT_SYSTEM);
1584 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001585 pr_warn("error on getting test probe.\n");
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001586 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001587 } else {
Marcin Nowakowskid4d7ccc2016-12-09 15:19:38 +01001588 if (trace_kprobe_nhit(tk) != 1) {
1589 pr_warn("incorrect number of testprobe hits\n");
1590 warn++;
1591 }
1592
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001593 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001594 if (WARN_ON_ONCE(file == NULL)) {
1595 pr_warn("error on getting probe file.\n");
1596 warn++;
1597 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001598 disable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001599 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001600
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001601 tk = find_trace_kprobe("testprobe2", KPROBE_EVENT_SYSTEM);
1602 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001603 pr_warn("error on getting 2nd test probe.\n");
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001604 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001605 } else {
Marcin Nowakowskid4d7ccc2016-12-09 15:19:38 +01001606 if (trace_kprobe_nhit(tk) != 1) {
1607 pr_warn("incorrect number of testprobe2 hits\n");
1608 warn++;
1609 }
1610
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001611 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001612 if (WARN_ON_ONCE(file == NULL)) {
1613 pr_warn("error on getting probe file.\n");
1614 warn++;
1615 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001616 disable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001617 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001618
Tom Zanussi7e465ba2017-09-22 14:58:20 -05001619 ret = trace_run_command("-:testprobe", create_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001620 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001621 pr_warn("error on deleting a probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001622 warn++;
1623 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001624
Tom Zanussi7e465ba2017-09-22 14:58:20 -05001625 ret = trace_run_command("-:testprobe2", create_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001626 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001627 pr_warn("error on deleting a probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001628 warn++;
1629 }
1630
1631end:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001632 release_all_trace_kprobes();
Thomas Gleixner30e7d8942017-05-17 10:19:49 +02001633 /*
1634 * Wait for the optimizer work to finish. Otherwise it might fiddle
1635 * with probes in already freed __init text.
1636 */
1637 wait_for_kprobe_optimizer();
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001638 if (warn)
1639 pr_cont("NG: Some tests are failed. Please check them.\n");
1640 else
1641 pr_cont("OK\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001642 return 0;
1643}
1644
1645late_initcall(kprobe_trace_self_tests_init);
1646
1647#endif