blob: 2e13f77b9a37a073743edefaf54c7af2713cd58d [file] [log] [blame]
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001/*
Masami Hiramatsu77b44d12009-11-03 19:12:47 -05002 * Kprobes-based tracing events
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04003 *
4 * Created by Masami Hiramatsu <mhiramat@redhat.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
Masami Hiramatsu72576342017-02-07 20:21:28 +090019#define pr_fmt(fmt) "trace_kprobe: " fmt
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040020
21#include <linux/module.h>
22#include <linux/uaccess.h>
Ingo Molnarb2d09102017-02-04 01:27:20 +010023#include <linux/rculist.h>
Masami Hiramatsu540adea2018-01-13 02:55:03 +090024#include <linux/error-injection.h>
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040025
Francis Deslauriersd8999262018-07-30 19:20:42 +090026#include "trace_kprobe_selftest.h"
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +053027#include "trace_probe.h"
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040028
Masami Hiramatsuf52487e2009-09-10 19:53:53 -040029#define KPROBE_EVENT_SYSTEM "kprobes"
Alban Crequy696ced42017-04-03 12:36:22 +020030#define KRETPROBE_MAXACTIVE_MAX 4096
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040031
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040032/**
Masami Hiramatsu77b44d12009-11-03 19:12:47 -050033 * Kprobe event core functions
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040034 */
Namhyung Kimc31ffb32013-07-03 13:50:51 +090035struct trace_kprobe {
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040036 struct list_head list;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +020037 struct kretprobe rp; /* Use rp.kp for kprobe use */
Martin KaFai Laua7636d92016-02-03 12:28:28 -080038 unsigned long __percpu *nhit;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040039 const char *symbol; /* symbol name */
Namhyung Kimc31ffb32013-07-03 13:50:51 +090040 struct trace_probe tp;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040041};
42
Namhyung Kimc31ffb32013-07-03 13:50:51 +090043#define SIZEOF_TRACE_KPROBE(n) \
44 (offsetof(struct trace_kprobe, tp.args) + \
Masami Hiramatsueca0d912009-09-10 19:53:38 -040045 (sizeof(struct probe_arg) * (n)))
Masami Hiramatsua82378d2009-08-13 16:35:18 -040046
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090047static nokprobe_inline bool trace_kprobe_is_return(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040048{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090049 return tk->rp.handler != NULL;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040050}
51
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090052static nokprobe_inline const char *trace_kprobe_symbol(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040053{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090054 return tk->symbol ? tk->symbol : "unknown";
Masami Hiramatsu413d37d2009-08-13 16:35:11 -040055}
56
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090057static nokprobe_inline unsigned long trace_kprobe_offset(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +090058{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090059 return tk->rp.kp.offset;
Masami Hiramatsu61424312011-06-27 16:26:56 +090060}
61
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090062static nokprobe_inline bool trace_kprobe_has_gone(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +090063{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090064 return !!(kprobe_gone(&tk->rp.kp));
Masami Hiramatsu61424312011-06-27 16:26:56 +090065}
66
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090067static nokprobe_inline bool trace_kprobe_within_module(struct trace_kprobe *tk,
Namhyung Kimc31ffb32013-07-03 13:50:51 +090068 struct module *mod)
Masami Hiramatsu61424312011-06-27 16:26:56 +090069{
70 int len = strlen(mod->name);
Namhyung Kimc31ffb32013-07-03 13:50:51 +090071 const char *name = trace_kprobe_symbol(tk);
Masami Hiramatsu61424312011-06-27 16:26:56 +090072 return strncmp(mod->name, name, len) == 0 && name[len] == ':';
73}
74
Masami Hiramatsu3da0f182014-04-17 17:18:28 +090075static nokprobe_inline bool trace_kprobe_is_on_module(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +090076{
Namhyung Kimc31ffb32013-07-03 13:50:51 +090077 return !!strchr(trace_kprobe_symbol(tk), ':');
Masami Hiramatsu61424312011-06-27 16:26:56 +090078}
79
Marcin Nowakowskif18f97a2016-12-09 15:19:37 +010080static nokprobe_inline unsigned long trace_kprobe_nhit(struct trace_kprobe *tk)
81{
82 unsigned long nhit = 0;
83 int cpu;
84
85 for_each_possible_cpu(cpu)
86 nhit += *per_cpu_ptr(tk->nhit, cpu);
87
88 return nhit;
89}
90
Masami Hiramatsu6bc6c772018-08-02 16:50:48 +090091/* Return 0 if it fails to find the symbol address */
Masami Hiramatsu45408c42018-07-30 19:20:14 +090092static nokprobe_inline
93unsigned long trace_kprobe_address(struct trace_kprobe *tk)
94{
95 unsigned long addr;
96
97 if (tk->symbol) {
98 addr = (unsigned long)
99 kallsyms_lookup_name(trace_kprobe_symbol(tk));
Masami Hiramatsu6bc6c772018-08-02 16:50:48 +0900100 if (addr)
101 addr += tk->rp.kp.offset;
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900102 } else {
103 addr = (unsigned long)tk->rp.kp.addr;
104 }
105 return addr;
106}
107
Masami Hiramatsub4da3342018-01-13 02:54:04 +0900108bool trace_kprobe_on_func_entry(struct trace_event_call *call)
Josef Bacik9802d862017-12-11 11:36:48 -0500109{
110 struct trace_kprobe *tk = (struct trace_kprobe *)call->data;
Masami Hiramatsub4da3342018-01-13 02:54:04 +0900111
112 return kprobe_on_func_entry(tk->rp.kp.addr,
113 tk->rp.kp.addr ? NULL : tk->rp.kp.symbol_name,
114 tk->rp.kp.addr ? 0 : tk->rp.kp.offset);
Josef Bacik9802d862017-12-11 11:36:48 -0500115}
116
Masami Hiramatsub4da3342018-01-13 02:54:04 +0900117bool trace_kprobe_error_injectable(struct trace_event_call *call)
Josef Bacik9802d862017-12-11 11:36:48 -0500118{
119 struct trace_kprobe *tk = (struct trace_kprobe *)call->data;
Josef Bacik9802d862017-12-11 11:36:48 -0500120
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900121 return within_error_injection_list(trace_kprobe_address(tk));
Josef Bacik9802d862017-12-11 11:36:48 -0500122}
123
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900124static int register_kprobe_event(struct trace_kprobe *tk);
125static int unregister_kprobe_event(struct trace_kprobe *tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400126
127static DEFINE_MUTEX(probe_lock);
128static LIST_HEAD(probe_list);
129
Masami Hiramatsu50d78052009-09-14 16:49:20 -0400130static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs);
131static int kretprobe_dispatcher(struct kretprobe_instance *ri,
132 struct pt_regs *regs);
133
Namhyung Kim1301a442013-11-26 15:21:04 +0900134/* Memory fetching by symbol */
135struct symbol_cache {
136 char *symbol;
137 long offset;
138 unsigned long addr;
139};
140
141unsigned long update_symbol_cache(struct symbol_cache *sc)
142{
143 sc->addr = (unsigned long)kallsyms_lookup_name(sc->symbol);
144
145 if (sc->addr)
146 sc->addr += sc->offset;
147
148 return sc->addr;
149}
150
151void free_symbol_cache(struct symbol_cache *sc)
152{
153 kfree(sc->symbol);
154 kfree(sc);
155}
156
157struct symbol_cache *alloc_symbol_cache(const char *sym, long offset)
158{
159 struct symbol_cache *sc;
160
161 if (!sym || strlen(sym) == 0)
162 return NULL;
163
164 sc = kzalloc(sizeof(struct symbol_cache), GFP_KERNEL);
165 if (!sc)
166 return NULL;
167
168 sc->symbol = kstrdup(sym, GFP_KERNEL);
169 if (!sc->symbol) {
170 kfree(sc);
171 return NULL;
172 }
173 sc->offset = offset;
174 update_symbol_cache(sc);
175
176 return sc;
177}
178
Namhyung Kim3fd996a2013-11-26 15:21:04 +0900179/*
180 * Kprobes-specific fetch functions
181 */
182#define DEFINE_FETCH_stack(type) \
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900183static void FETCH_FUNC_NAME(stack, type)(struct pt_regs *regs, \
Namhyung Kim3fd996a2013-11-26 15:21:04 +0900184 void *offset, void *dest) \
185{ \
186 *(type *)dest = (type)regs_get_kernel_stack_nth(regs, \
187 (unsigned int)((unsigned long)offset)); \
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900188} \
189NOKPROBE_SYMBOL(FETCH_FUNC_NAME(stack, type));
190
Namhyung Kim3fd996a2013-11-26 15:21:04 +0900191DEFINE_BASIC_FETCH_FUNCS(stack)
192/* No string on the stack entry */
193#define fetch_stack_string NULL
194#define fetch_stack_string_size NULL
195
Namhyung Kim5baaa592013-11-26 15:21:04 +0900196#define DEFINE_FETCH_memory(type) \
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900197static void FETCH_FUNC_NAME(memory, type)(struct pt_regs *regs, \
Namhyung Kim5baaa592013-11-26 15:21:04 +0900198 void *addr, void *dest) \
199{ \
200 type retval; \
201 if (probe_kernel_address(addr, retval)) \
202 *(type *)dest = 0; \
203 else \
204 *(type *)dest = retval; \
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900205} \
206NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, type));
207
Namhyung Kim5baaa592013-11-26 15:21:04 +0900208DEFINE_BASIC_FETCH_FUNCS(memory)
209/*
210 * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
211 * length and relative data location.
212 */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900213static void FETCH_FUNC_NAME(memory, string)(struct pt_regs *regs,
214 void *addr, void *dest)
Namhyung Kim5baaa592013-11-26 15:21:04 +0900215{
Namhyung Kim5baaa592013-11-26 15:21:04 +0900216 int maxlen = get_rloc_len(*(u32 *)dest);
217 u8 *dst = get_rloc_data(dest);
Alexei Starovoitov1a6877b2015-08-28 15:56:22 -0700218 long ret;
Namhyung Kim5baaa592013-11-26 15:21:04 +0900219
220 if (!maxlen)
221 return;
222
223 /*
224 * Try to get string again, since the string can be changed while
225 * probing.
226 */
Alexei Starovoitov1a6877b2015-08-28 15:56:22 -0700227 ret = strncpy_from_unsafe(dst, addr, maxlen);
Namhyung Kim5baaa592013-11-26 15:21:04 +0900228
229 if (ret < 0) { /* Failed to fetch string */
Alexei Starovoitov1a6877b2015-08-28 15:56:22 -0700230 dst[0] = '\0';
Namhyung Kim5baaa592013-11-26 15:21:04 +0900231 *(u32 *)dest = make_data_rloc(0, get_rloc_offs(*(u32 *)dest));
232 } else {
Alexei Starovoitov1a6877b2015-08-28 15:56:22 -0700233 *(u32 *)dest = make_data_rloc(ret, get_rloc_offs(*(u32 *)dest));
Namhyung Kim5baaa592013-11-26 15:21:04 +0900234 }
235}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900236NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, string));
Namhyung Kim5baaa592013-11-26 15:21:04 +0900237
238/* Return the length of string -- including null terminal byte */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900239static void FETCH_FUNC_NAME(memory, string_size)(struct pt_regs *regs,
240 void *addr, void *dest)
Namhyung Kim5baaa592013-11-26 15:21:04 +0900241{
242 mm_segment_t old_fs;
243 int ret, len = 0;
244 u8 c;
245
246 old_fs = get_fs();
247 set_fs(KERNEL_DS);
248 pagefault_disable();
249
250 do {
251 ret = __copy_from_user_inatomic(&c, (u8 *)addr + len, 1);
252 len++;
253 } while (c && ret == 0 && len < MAX_STRING_SIZE);
254
255 pagefault_enable();
256 set_fs(old_fs);
257
258 if (ret < 0) /* Failed to check the length */
259 *(u32 *)dest = 0;
260 else
261 *(u32 *)dest = len;
262}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900263NOKPROBE_SYMBOL(FETCH_FUNC_NAME(memory, string_size));
Namhyung Kim5baaa592013-11-26 15:21:04 +0900264
Namhyung Kim1301a442013-11-26 15:21:04 +0900265#define DEFINE_FETCH_symbol(type) \
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900266void FETCH_FUNC_NAME(symbol, type)(struct pt_regs *regs, void *data, void *dest)\
Namhyung Kim1301a442013-11-26 15:21:04 +0900267{ \
268 struct symbol_cache *sc = data; \
269 if (sc->addr) \
270 fetch_memory_##type(regs, (void *)sc->addr, dest); \
271 else \
272 *(type *)dest = 0; \
Masami Hiramatsu3da0f182014-04-17 17:18:28 +0900273} \
274NOKPROBE_SYMBOL(FETCH_FUNC_NAME(symbol, type));
275
Namhyung Kim1301a442013-11-26 15:21:04 +0900276DEFINE_BASIC_FETCH_FUNCS(symbol)
277DEFINE_FETCH_symbol(string)
278DEFINE_FETCH_symbol(string_size)
279
Namhyung Kimb7e0bf32013-11-25 13:42:47 +0900280/* kprobes don't support file_offset fetch methods */
281#define fetch_file_offset_u8 NULL
282#define fetch_file_offset_u16 NULL
283#define fetch_file_offset_u32 NULL
284#define fetch_file_offset_u64 NULL
285#define fetch_file_offset_string NULL
286#define fetch_file_offset_string_size NULL
287
Namhyung Kim34fee3a2013-11-26 14:56:28 +0900288/* Fetch type information table */
Stephen Rothwelld9a16d32015-03-12 16:58:34 +1100289static const struct fetch_type kprobes_fetch_type_table[] = {
Namhyung Kim34fee3a2013-11-26 14:56:28 +0900290 /* Special types */
291 [FETCH_TYPE_STRING] = __ASSIGN_FETCH_TYPE("string", string, string,
292 sizeof(u32), 1, "__data_loc char[]"),
293 [FETCH_TYPE_STRSIZE] = __ASSIGN_FETCH_TYPE("string_size", u32,
294 string_size, sizeof(u32), 0, "u32"),
295 /* Basic types */
296 ASSIGN_FETCH_TYPE(u8, u8, 0),
297 ASSIGN_FETCH_TYPE(u16, u16, 0),
298 ASSIGN_FETCH_TYPE(u32, u32, 0),
299 ASSIGN_FETCH_TYPE(u64, u64, 0),
300 ASSIGN_FETCH_TYPE(s8, u8, 1),
301 ASSIGN_FETCH_TYPE(s16, u16, 1),
302 ASSIGN_FETCH_TYPE(s32, u32, 1),
303 ASSIGN_FETCH_TYPE(s64, u64, 1),
Masami Hiramatsu17ce3dc2016-08-18 17:57:50 +0900304 ASSIGN_FETCH_TYPE_ALIAS(x8, u8, u8, 0),
305 ASSIGN_FETCH_TYPE_ALIAS(x16, u16, u16, 0),
306 ASSIGN_FETCH_TYPE_ALIAS(x32, u32, u32, 0),
307 ASSIGN_FETCH_TYPE_ALIAS(x64, u64, u64, 0),
Namhyung Kim34fee3a2013-11-26 14:56:28 +0900308
309 ASSIGN_FETCH_TYPE_END
310};
311
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200312/*
313 * Allocate new trace_probe and initialize it (including kprobes).
314 */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900315static struct trace_kprobe *alloc_trace_kprobe(const char *group,
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400316 const char *event,
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200317 void *addr,
318 const char *symbol,
319 unsigned long offs,
Alban Crequy696ced42017-04-03 12:36:22 +0200320 int maxactive,
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530321 int nargs, bool is_return)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400322{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900323 struct trace_kprobe *tk;
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500324 int ret = -ENOMEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400325
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900326 tk = kzalloc(SIZEOF_TRACE_KPROBE(nargs), GFP_KERNEL);
327 if (!tk)
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500328 return ERR_PTR(ret);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400329
Martin KaFai Laua7636d92016-02-03 12:28:28 -0800330 tk->nhit = alloc_percpu(unsigned long);
331 if (!tk->nhit)
332 goto error;
333
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400334 if (symbol) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900335 tk->symbol = kstrdup(symbol, GFP_KERNEL);
336 if (!tk->symbol)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400337 goto error;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900338 tk->rp.kp.symbol_name = tk->symbol;
339 tk->rp.kp.offset = offs;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200340 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900341 tk->rp.kp.addr = addr;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200342
343 if (is_return)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900344 tk->rp.handler = kretprobe_dispatcher;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200345 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900346 tk->rp.kp.pre_handler = kprobe_dispatcher;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200347
Alban Crequy696ced42017-04-03 12:36:22 +0200348 tk->rp.maxactive = maxactive;
349
Masami Hiramatsuda346342010-08-27 20:39:12 +0900350 if (!event || !is_good_name(event)) {
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500351 ret = -EINVAL;
Masami Hiramatsu42635652009-08-13 16:35:26 -0400352 goto error;
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500353 }
354
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900355 tk->tp.call.class = &tk->tp.class;
356 tk->tp.call.name = kstrdup(event, GFP_KERNEL);
357 if (!tk->tp.call.name)
Masami Hiramatsu42635652009-08-13 16:35:26 -0400358 goto error;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400359
Masami Hiramatsuda346342010-08-27 20:39:12 +0900360 if (!group || !is_good_name(group)) {
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500361 ret = -EINVAL;
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400362 goto error;
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500363 }
364
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900365 tk->tp.class.system = kstrdup(group, GFP_KERNEL);
366 if (!tk->tp.class.system)
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400367 goto error;
368
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900369 INIT_LIST_HEAD(&tk->list);
370 INIT_LIST_HEAD(&tk->tp.files);
371 return tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400372error:
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900373 kfree(tk->tp.call.name);
374 kfree(tk->symbol);
Martin KaFai Laua7636d92016-02-03 12:28:28 -0800375 free_percpu(tk->nhit);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900376 kfree(tk);
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500377 return ERR_PTR(ret);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400378}
379
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900380static void free_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400381{
382 int i;
383
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900384 for (i = 0; i < tk->tp.nr_args; i++)
385 traceprobe_free_probe_arg(&tk->tp.args[i]);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400386
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900387 kfree(tk->tp.call.class->system);
388 kfree(tk->tp.call.name);
389 kfree(tk->symbol);
Martin KaFai Laua7636d92016-02-03 12:28:28 -0800390 free_percpu(tk->nhit);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900391 kfree(tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400392}
393
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900394static struct trace_kprobe *find_trace_kprobe(const char *event,
395 const char *group)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400396{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900397 struct trace_kprobe *tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400398
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900399 list_for_each_entry(tk, &probe_list, list)
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -0400400 if (strcmp(trace_event_name(&tk->tp.call), event) == 0 &&
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900401 strcmp(tk->tp.call.class->system, group) == 0)
402 return tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400403 return NULL;
404}
405
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400406static inline int __enable_trace_kprobe(struct trace_kprobe *tk)
407{
408 int ret = 0;
409
410 if (trace_probe_is_registered(&tk->tp) && !trace_kprobe_has_gone(tk)) {
411 if (trace_kprobe_is_return(tk))
412 ret = enable_kretprobe(&tk->rp);
413 else
414 ret = enable_kprobe(&tk->rp.kp);
415 }
416
417 return ret;
418}
419
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200420/*
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900421 * Enable trace_probe
422 * if the file is NULL, enable "perf" handler, or enable "trace" handler.
423 */
424static int
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400425enable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900426{
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400427 struct event_file_link *link;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900428 int ret = 0;
429
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900430 if (file) {
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200431 link = kmalloc(sizeof(*link), GFP_KERNEL);
432 if (!link) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900433 ret = -ENOMEM;
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200434 goto out;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900435 }
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900436
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200437 link->file = file;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900438 list_add_tail_rcu(&link->list, &tk->tp.files);
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200439
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900440 tk->tp.flags |= TP_FLAG_TRACE;
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400441 ret = __enable_trace_kprobe(tk);
442 if (ret) {
443 list_del_rcu(&link->list);
Artem Savkov57ea2a32018-07-25 16:20:38 +0200444 kfree(link);
445 tk->tp.flags &= ~TP_FLAG_TRACE;
Artem Savkov57ea2a32018-07-25 16:20:38 +0200446 }
Steven Rostedt (VMware)87107a22018-07-26 12:07:32 -0400447
448 } else {
449 tk->tp.flags |= TP_FLAG_PROFILE;
450 ret = __enable_trace_kprobe(tk);
451 if (ret)
452 tk->tp.flags &= ~TP_FLAG_PROFILE;
Artem Savkov57ea2a32018-07-25 16:20:38 +0200453 }
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200454 out:
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900455 return ret;
456}
457
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900458/*
459 * Disable trace_probe
460 * if the file is NULL, disable "perf" handler, or disable "trace" handler.
461 */
462static int
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -0400463disable_trace_kprobe(struct trace_kprobe *tk, struct trace_event_file *file)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900464{
Masami Hiramatsua232e272013-07-09 18:35:26 +0900465 struct event_file_link *link = NULL;
466 int wait = 0;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900467 int ret = 0;
468
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900469 if (file) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900470 link = find_event_file_link(&tk->tp, file);
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200471 if (!link) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900472 ret = -EINVAL;
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200473 goto out;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900474 }
475
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200476 list_del_rcu(&link->list);
Masami Hiramatsua232e272013-07-09 18:35:26 +0900477 wait = 1;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900478 if (!list_empty(&tk->tp.files))
Oleg Nesterovb04d52e2013-06-20 19:38:14 +0200479 goto out;
480
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900481 tk->tp.flags &= ~TP_FLAG_TRACE;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900482 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900483 tk->tp.flags &= ~TP_FLAG_PROFILE;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900484
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900485 if (!trace_probe_is_enabled(&tk->tp) && trace_probe_is_registered(&tk->tp)) {
486 if (trace_kprobe_is_return(tk))
487 disable_kretprobe(&tk->rp);
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900488 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900489 disable_kprobe(&tk->rp.kp);
Masami Hiramatsua232e272013-07-09 18:35:26 +0900490 wait = 1;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900491 }
Song Liue12f03d2017-12-06 14:45:15 -0800492
493 /*
494 * if tk is not added to any list, it must be a local trace_kprobe
495 * created with perf_event_open. We don't need to wait for these
496 * trace_kprobes
497 */
498 if (list_empty(&tk->list))
499 wait = 0;
Oleg Nesterov3fe3d612013-06-20 19:38:09 +0200500 out:
Masami Hiramatsua232e272013-07-09 18:35:26 +0900501 if (wait) {
502 /*
503 * Synchronize with kprobe_trace_func/kretprobe_trace_func
504 * to ensure disabled (all running handlers are finished).
505 * This is not only for kfree(), but also the caller,
506 * trace_remove_event_call() supposes it for releasing
507 * event_call related objects, which will be accessed in
508 * the kprobe_trace_func/kretprobe_trace_func.
509 */
510 synchronize_sched();
511 kfree(link); /* Ignored if link == NULL */
512 }
513
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +0900514 return ret;
Masami Hiramatsu1538f882011-06-27 16:26:44 +0900515}
516
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900517#if defined(CONFIG_KPROBES_ON_FTRACE) && \
518 !defined(CONFIG_KPROBE_EVENTS_ON_NOTRACE)
519static bool within_notrace_func(struct trace_kprobe *tk)
520{
521 unsigned long offset, size, addr;
522
523 addr = trace_kprobe_address(tk);
Masami Hiramatsu6bc6c772018-08-02 16:50:48 +0900524 if (!addr || !kallsyms_lookup_size_offset(addr, &size, &offset))
525 return false;
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900526
527 return !ftrace_location_range(addr - offset, addr - offset + size);
528}
529#else
530#define within_notrace_func(tk) (false)
531#endif
532
Masami Hiramatsu61424312011-06-27 16:26:56 +0900533/* Internal register function - just handle k*probes and flags */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900534static int __register_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +0900535{
Masami Hiramatsu7f6878a2011-06-27 16:27:03 +0900536 int i, ret;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900537
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900538 if (trace_probe_is_registered(&tk->tp))
Masami Hiramatsu61424312011-06-27 16:26:56 +0900539 return -EINVAL;
540
Masami Hiramatsu45408c42018-07-30 19:20:14 +0900541 if (within_notrace_func(tk)) {
542 pr_warn("Could not probe notrace function %s\n",
543 trace_kprobe_symbol(tk));
544 return -EINVAL;
545 }
546
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900547 for (i = 0; i < tk->tp.nr_args; i++)
548 traceprobe_update_arg(&tk->tp.args[i]);
Masami Hiramatsu7f6878a2011-06-27 16:27:03 +0900549
Masami Hiramatsu61424312011-06-27 16:26:56 +0900550 /* Set/clear disabled flag according to tp->flag */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900551 if (trace_probe_is_enabled(&tk->tp))
552 tk->rp.kp.flags &= ~KPROBE_FLAG_DISABLED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900553 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900554 tk->rp.kp.flags |= KPROBE_FLAG_DISABLED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900555
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900556 if (trace_kprobe_is_return(tk))
557 ret = register_kretprobe(&tk->rp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900558 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900559 ret = register_kprobe(&tk->rp.kp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900560
561 if (ret == 0)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900562 tk->tp.flags |= TP_FLAG_REGISTERED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900563 else {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900564 if (ret == -ENOENT && trace_kprobe_is_on_module(tk)) {
Joe Perchesa395d6a2016-03-22 14:28:09 -0700565 pr_warn("This probe might be able to register after target module is loaded. Continue.\n");
Masami Hiramatsu61424312011-06-27 16:26:56 +0900566 ret = 0;
567 } else if (ret == -EILSEQ) {
Joe Perchesa395d6a2016-03-22 14:28:09 -0700568 pr_warn("Probing address(0x%p) is not an instruction boundary.\n",
569 tk->rp.kp.addr);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900570 ret = -EINVAL;
571 }
572 }
573
574 return ret;
575}
576
577/* Internal unregister function - just handle k*probes and flags */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900578static void __unregister_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu61424312011-06-27 16:26:56 +0900579{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900580 if (trace_probe_is_registered(&tk->tp)) {
581 if (trace_kprobe_is_return(tk))
582 unregister_kretprobe(&tk->rp);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900583 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900584 unregister_kprobe(&tk->rp.kp);
585 tk->tp.flags &= ~TP_FLAG_REGISTERED;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900586 /* Cleanup kprobe for reuse */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900587 if (tk->rp.kp.symbol_name)
588 tk->rp.kp.addr = NULL;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900589 }
590}
591
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400592/* Unregister a trace_probe and probe_event: call with locking probe_lock */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900593static int unregister_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400594{
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900595 /* Enabled event can not be unregistered */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900596 if (trace_probe_is_enabled(&tk->tp))
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900597 return -EBUSY;
598
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -0400599 /* Will fail if probe is being used by ftrace or perf */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900600 if (unregister_kprobe_event(tk))
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -0400601 return -EBUSY;
602
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900603 __unregister_trace_kprobe(tk);
604 list_del(&tk->list);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900605
606 return 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400607}
608
609/* Register a trace_probe and probe_event */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900610static int register_trace_kprobe(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400611{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900612 struct trace_kprobe *old_tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400613 int ret;
614
615 mutex_lock(&probe_lock);
616
Masami Hiramatsu61424312011-06-27 16:26:56 +0900617 /* Delete old (same name) event if exist */
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -0400618 old_tk = find_trace_kprobe(trace_event_name(&tk->tp.call),
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -0400619 tk->tp.call.class->system);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900620 if (old_tk) {
621 ret = unregister_trace_kprobe(old_tk);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900622 if (ret < 0)
623 goto end;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900624 free_trace_kprobe(old_tk);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400625 }
Masami Hiramatsu61424312011-06-27 16:26:56 +0900626
627 /* Register new event */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900628 ret = register_kprobe_event(tk);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400629 if (ret) {
Joe Perchesa395d6a2016-03-22 14:28:09 -0700630 pr_warn("Failed to register probe event(%d)\n", ret);
Masami Hiramatsu2d5e0672009-09-14 16:48:56 -0400631 goto end;
632 }
633
Masami Hiramatsu61424312011-06-27 16:26:56 +0900634 /* Register k*probe */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900635 ret = __register_trace_kprobe(tk);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900636 if (ret < 0)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900637 unregister_kprobe_event(tk);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900638 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900639 list_add_tail(&tk->list, &probe_list);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900640
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400641end:
642 mutex_unlock(&probe_lock);
643 return ret;
644}
645
Masami Hiramatsu61424312011-06-27 16:26:56 +0900646/* Module notifier call back, checking event on the module */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900647static int trace_kprobe_module_callback(struct notifier_block *nb,
Masami Hiramatsu61424312011-06-27 16:26:56 +0900648 unsigned long val, void *data)
649{
650 struct module *mod = data;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900651 struct trace_kprobe *tk;
Masami Hiramatsu61424312011-06-27 16:26:56 +0900652 int ret;
653
654 if (val != MODULE_STATE_COMING)
655 return NOTIFY_DONE;
656
657 /* Update probes on coming module */
658 mutex_lock(&probe_lock);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900659 list_for_each_entry(tk, &probe_list, list) {
660 if (trace_kprobe_within_module(tk, mod)) {
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900661 /* Don't need to check busy - this should have gone. */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900662 __unregister_trace_kprobe(tk);
663 ret = __register_trace_kprobe(tk);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900664 if (ret)
Joe Perchesa395d6a2016-03-22 14:28:09 -0700665 pr_warn("Failed to re-register probe %s on %s: %d\n",
666 trace_event_name(&tk->tp.call),
667 mod->name, ret);
Masami Hiramatsu61424312011-06-27 16:26:56 +0900668 }
669 }
670 mutex_unlock(&probe_lock);
671
672 return NOTIFY_DONE;
673}
674
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900675static struct notifier_block trace_kprobe_module_nb = {
676 .notifier_call = trace_kprobe_module_callback,
Masami Hiramatsu61424312011-06-27 16:26:56 +0900677 .priority = 1 /* Invoked after kprobe module callback */
678};
679
Naveen N. Raofca18a42017-07-08 00:27:30 +0530680/* Convert certain expected symbols into '_' when generating event names */
681static inline void sanitize_event_name(char *name)
682{
683 while (*name++ != '\0')
684 if (*name == ':' || *name == '.')
685 *name = '_';
686}
687
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900688static int create_trace_kprobe(int argc, char **argv)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400689{
690 /*
691 * Argument syntax:
Alban Crequy696ced42017-04-03 12:36:22 +0200692 * - Add kprobe:
693 * p[:[GRP/]EVENT] [MOD:]KSYM[+OFFS]|KADDR [FETCHARGS]
694 * - Add kretprobe:
695 * r[MAXACTIVE][:[GRP/]EVENT] [MOD:]KSYM[+0] [FETCHARGS]
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400696 * Fetch args:
Masami Hiramatsu2e06ff62009-10-07 18:27:59 -0400697 * $retval : fetch return value
698 * $stack : fetch stack address
699 * $stackN : fetch Nth of stack (N:0-)
Omar Sandoval35abb672016-06-08 18:38:02 -0700700 * $comm : fetch current task comm
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400701 * @ADDR : fetch memory at ADDR (ADDR should be in kernel)
702 * @SYM[+|-offs] : fetch memory at SYM +|- offs (SYM is a data symbol)
703 * %REG : fetch register REG
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400704 * Dereferencing memory fetch:
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400705 * +|-offs(ARG) : fetch memory at ARG +|- offs address.
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400706 * Alias name of args:
707 * NAME=FETCHARG : set NAME as alias of FETCHARG.
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400708 * Type of args:
709 * FETCHARG:TYPE : use TYPE instead of unsigned long.
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400710 */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900711 struct trace_kprobe *tk;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400712 int i, ret = 0;
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530713 bool is_return = false, is_delete = false;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400714 char *symbol = NULL, *event = NULL, *group = NULL;
Alban Crequy696ced42017-04-03 12:36:22 +0200715 int maxactive = 0;
Masami Hiramatsuda346342010-08-27 20:39:12 +0900716 char *arg;
Masami Hiramatsuc5d343b2018-03-17 21:38:10 +0900717 long offset = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400718 void *addr = NULL;
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200719 char buf[MAX_EVENT_NAME_LEN];
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400720
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500721 /* argc must be >= 1 */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400722 if (argv[0][0] == 'p')
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530723 is_return = false;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400724 else if (argv[0][0] == 'r')
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530725 is_return = true;
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500726 else if (argv[0][0] == '-')
Srikar Dronamraju3a6b7662012-04-09 14:41:33 +0530727 is_delete = true;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400728 else {
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500729 pr_info("Probe definition must be started with 'p', 'r' or"
730 " '-'.\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400731 return -EINVAL;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400732 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400733
Alban Crequy696ced42017-04-03 12:36:22 +0200734 event = strchr(&argv[0][1], ':');
735 if (event) {
736 event[0] = '\0';
737 event++;
738 }
739 if (is_return && isdigit(argv[0][1])) {
740 ret = kstrtouint(&argv[0][1], 0, &maxactive);
741 if (ret) {
742 pr_info("Failed to parse maxactive.\n");
743 return ret;
744 }
745 /* kretprobes instances are iterated over via a list. The
746 * maximum should stay reasonable.
747 */
748 if (maxactive > KRETPROBE_MAXACTIVE_MAX) {
749 pr_info("Maxactive is too big (%d > %d).\n",
750 maxactive, KRETPROBE_MAXACTIVE_MAX);
751 return -E2BIG;
752 }
753 }
754
755 if (event) {
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400756 if (strchr(event, '/')) {
757 group = event;
758 event = strchr(group, '/') + 1;
759 event[-1] = '\0';
760 if (strlen(group) == 0) {
Wenji Huanga5efd922010-02-24 15:40:23 +0800761 pr_info("Group name is not specified\n");
Masami Hiramatsuf52487e2009-09-10 19:53:53 -0400762 return -EINVAL;
763 }
764 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400765 if (strlen(event) == 0) {
Wenji Huanga5efd922010-02-24 15:40:23 +0800766 pr_info("Event name is not specified\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400767 return -EINVAL;
768 }
769 }
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500770 if (!group)
771 group = KPROBE_EVENT_SYSTEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400772
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500773 if (is_delete) {
774 if (!event) {
775 pr_info("Delete command needs an event name.\n");
776 return -EINVAL;
777 }
Srikar Dronamraju9da79ab2010-06-30 14:15:48 +0530778 mutex_lock(&probe_lock);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900779 tk = find_trace_kprobe(event, group);
780 if (!tk) {
Srikar Dronamraju9da79ab2010-06-30 14:15:48 +0530781 mutex_unlock(&probe_lock);
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500782 pr_info("Event %s/%s doesn't exist.\n", group, event);
783 return -ENOENT;
784 }
785 /* delete an event */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900786 ret = unregister_trace_kprobe(tk);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900787 if (ret == 0)
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900788 free_trace_kprobe(tk);
Srikar Dronamraju9da79ab2010-06-30 14:15:48 +0530789 mutex_unlock(&probe_lock);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900790 return ret;
Masami Hiramatsua7c312b2009-12-08 17:03:16 -0500791 }
792
793 if (argc < 2) {
794 pr_info("Probe point is not specified.\n");
795 return -EINVAL;
796 }
Sabrina Dubroca9e52b322017-06-22 11:24:42 +0200797
798 /* try to parse an address. if that fails, try to read the
799 * input as a symbol. */
800 if (kstrtoul(argv[1], 0, (unsigned long *)&addr)) {
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400801 /* a symbol specified */
802 symbol = argv[1];
803 /* TODO: support .init module functions */
Srikar Dronamraju8ab83f52012-04-09 14:41:44 +0530804 ret = traceprobe_split_symbol_offset(symbol, &offset);
Masami Hiramatsuc5d343b2018-03-17 21:38:10 +0900805 if (ret || offset < 0 || offset > UINT_MAX) {
Sabrina Dubroca9e52b322017-06-22 11:24:42 +0200806 pr_info("Failed to parse either an address or a symbol.\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400807 return ret;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400808 }
Steven Rostedt (VMware)d0e02572017-02-27 11:52:04 -0500809 if (offset && is_return &&
Naveen N. Rao659b9572017-07-07 22:37:24 +0530810 !kprobe_on_func_entry(NULL, symbol, offset)) {
Steven Rostedt (VMware)d0e02572017-02-27 11:52:04 -0500811 pr_info("Given offset is not valid for return probe.\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400812 return -EINVAL;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400813 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400814 }
Masami Hiramatsua82378d2009-08-13 16:35:18 -0400815 argc -= 2; argv += 2;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400816
817 /* setup a probe */
Masami Hiramatsu42635652009-08-13 16:35:26 -0400818 if (!event) {
819 /* Make a new event name */
Masami Hiramatsu42635652009-08-13 16:35:26 -0400820 if (symbol)
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500821 snprintf(buf, MAX_EVENT_NAME_LEN, "%c_%s_%ld",
Masami Hiramatsu42635652009-08-13 16:35:26 -0400822 is_return ? 'r' : 'p', symbol, offset);
823 else
Masami Hiramatsu6f3cf442009-12-16 17:24:08 -0500824 snprintf(buf, MAX_EVENT_NAME_LEN, "%c_0x%p",
Masami Hiramatsu42635652009-08-13 16:35:26 -0400825 is_return ? 'r' : 'p', addr);
Naveen N. Raofca18a42017-07-08 00:27:30 +0530826 sanitize_event_name(buf);
Masami Hiramatsu4a846b42009-09-11 05:31:21 +0200827 event = buf;
828 }
Alban Crequy696ced42017-04-03 12:36:22 +0200829 tk = alloc_trace_kprobe(group, event, addr, symbol, offset, maxactive,
830 argc, is_return);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900831 if (IS_ERR(tk)) {
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400832 pr_info("Failed to allocate trace_probe.(%d)\n",
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900833 (int)PTR_ERR(tk));
834 return PTR_ERR(tk);
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400835 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400836
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400837 /* parse arguments */
Masami Hiramatsua82378d2009-08-13 16:35:18 -0400838 ret = 0;
839 for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900840 struct probe_arg *parg = &tk->tp.args[i];
841
Masami Hiramatsu61a52732010-08-27 20:38:46 +0900842 /* Increment count for freeing args in error case */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900843 tk->tp.nr_args++;
Masami Hiramatsu61a52732010-08-27 20:38:46 +0900844
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400845 /* Parse argument name */
846 arg = strchr(argv[i], '=');
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900847 if (arg) {
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400848 *arg++ = '\0';
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900849 parg->name = kstrdup(argv[i], GFP_KERNEL);
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900850 } else {
Masami Hiramatsueca0d912009-09-10 19:53:38 -0400851 arg = argv[i];
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900852 /* If argument name is omitted, set "argN" */
853 snprintf(buf, MAX_EVENT_NAME_LEN, "arg%d", i + 1);
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900854 parg->name = kstrdup(buf, GFP_KERNEL);
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900855 }
Masami Hiramatsua703d942009-10-07 18:28:07 -0400856
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900857 if (!parg->name) {
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900858 pr_info("Failed to allocate argument[%d] name.\n", i);
Masami Hiramatsuba8665d2009-11-30 19:19:20 -0500859 ret = -ENOMEM;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400860 goto error;
861 }
Masami Hiramatsuda346342010-08-27 20:39:12 +0900862
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900863 if (!is_good_name(parg->name)) {
Masami Hiramatsuda346342010-08-27 20:39:12 +0900864 pr_info("Invalid argument[%d] name: %s\n",
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900865 i, parg->name);
Masami Hiramatsuda346342010-08-27 20:39:12 +0900866 ret = -EINVAL;
867 goto error;
868 }
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400869
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900870 if (traceprobe_conflict_field_name(parg->name,
871 tk->tp.args, i)) {
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900872 pr_info("Argument[%d] name '%s' conflicts with "
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400873 "another field.\n", i, argv[i]);
874 ret = -EINVAL;
875 goto error;
876 }
Masami Hiramatsuba8665d2009-11-30 19:19:20 -0500877
878 /* Parse fetch argument */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900879 ret = traceprobe_parse_probe_arg(arg, &tk->tp.size, parg,
Stephen Rothwelld9a16d32015-03-12 16:58:34 +1100880 is_return, true,
881 kprobes_fetch_type_table);
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400882 if (ret) {
Masami Hiramatsuaba91592010-08-27 20:39:06 +0900883 pr_info("Parse error at argument[%d]. (%d)\n", i, ret);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400884 goto error;
Masami Hiramatsue63cc232009-10-16 20:07:28 -0400885 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400886 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400887
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900888 ret = register_trace_kprobe(tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400889 if (ret)
890 goto error;
891 return 0;
892
893error:
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900894 free_trace_kprobe(tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400895 return ret;
896}
897
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900898static int release_all_trace_kprobes(void)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400899{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900900 struct trace_kprobe *tk;
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900901 int ret = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400902
903 mutex_lock(&probe_lock);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900904 /* Ensure no probe is in use. */
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900905 list_for_each_entry(tk, &probe_list, list)
906 if (trace_probe_is_enabled(&tk->tp)) {
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900907 ret = -EBUSY;
908 goto end;
909 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400910 /* TODO: Use batch unregistration */
911 while (!list_empty(&probe_list)) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900912 tk = list_entry(probe_list.next, struct trace_kprobe, list);
913 ret = unregister_trace_kprobe(tk);
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -0400914 if (ret)
915 goto end;
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900916 free_trace_kprobe(tk);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400917 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900918
919end:
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400920 mutex_unlock(&probe_lock);
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900921
922 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400923}
924
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400925/* Probes listing interfaces */
926static void *probes_seq_start(struct seq_file *m, loff_t *pos)
927{
928 mutex_lock(&probe_lock);
929 return seq_list_start(&probe_list, *pos);
930}
931
932static void *probes_seq_next(struct seq_file *m, void *v, loff_t *pos)
933{
934 return seq_list_next(v, &probe_list, pos);
935}
936
937static void probes_seq_stop(struct seq_file *m, void *v)
938{
939 mutex_unlock(&probe_lock);
940}
941
942static int probes_seq_show(struct seq_file *m, void *v)
943{
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900944 struct trace_kprobe *tk = v;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400945 int i;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400946
Rasmus Villemoesfa6f0cc2014-11-08 21:42:10 +0100947 seq_putc(m, trace_kprobe_is_return(tk) ? 'r' : 'p');
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -0400948 seq_printf(m, ":%s/%s", tk->tp.call.class->system,
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -0400949 trace_event_name(&tk->tp.call));
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400950
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900951 if (!tk->symbol)
952 seq_printf(m, " 0x%p", tk->rp.kp.addr);
953 else if (tk->rp.kp.offset)
954 seq_printf(m, " %s+%u", trace_kprobe_symbol(tk),
955 tk->rp.kp.offset);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400956 else
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900957 seq_printf(m, " %s", trace_kprobe_symbol(tk));
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400958
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900959 for (i = 0; i < tk->tp.nr_args; i++)
960 seq_printf(m, " %s=%s", tk->tp.args[i].name, tk->tp.args[i].comm);
Rasmus Villemoesfa6f0cc2014-11-08 21:42:10 +0100961 seq_putc(m, '\n');
Masami Hiramatsu93ccae72010-04-12 13:17:08 -0400962
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400963 return 0;
964}
965
966static const struct seq_operations probes_seq_op = {
967 .start = probes_seq_start,
968 .next = probes_seq_next,
969 .stop = probes_seq_stop,
970 .show = probes_seq_show
971};
972
973static int probes_open(struct inode *inode, struct file *file)
974{
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900975 int ret;
976
977 if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
Namhyung Kimc31ffb32013-07-03 13:50:51 +0900978 ret = release_all_trace_kprobes();
Masami Hiramatsu02ca1522011-10-04 19:44:38 +0900979 if (ret < 0)
980 return ret;
981 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400982
983 return seq_open(file, &probes_seq_op);
984}
985
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400986static ssize_t probes_write(struct file *file, const char __user *buffer,
987 size_t count, loff_t *ppos)
988{
Tom Zanussi7e465ba2017-09-22 14:58:20 -0500989 return trace_parse_run_command(file, buffer, count, ppos,
990 create_trace_kprobe);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -0400991}
992
993static const struct file_operations kprobe_events_ops = {
994 .owner = THIS_MODULE,
995 .open = probes_open,
996 .read = seq_read,
997 .llseek = seq_lseek,
998 .release = seq_release,
999 .write = probes_write,
1000};
1001
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001002/* Probes profiling interfaces */
1003static int probes_profile_seq_show(struct seq_file *m, void *v)
1004{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001005 struct trace_kprobe *tk = v;
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001006
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -04001007 seq_printf(m, " %-44s %15lu %15lu\n",
Marcin Nowakowskif18f97a2016-12-09 15:19:37 +01001008 trace_event_name(&tk->tp.call),
1009 trace_kprobe_nhit(tk),
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001010 tk->rp.kp.nmissed);
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001011
1012 return 0;
1013}
1014
1015static const struct seq_operations profile_seq_op = {
1016 .start = probes_seq_start,
1017 .next = probes_seq_next,
1018 .stop = probes_seq_stop,
1019 .show = probes_profile_seq_show
1020};
1021
1022static int profile_open(struct inode *inode, struct file *file)
1023{
1024 return seq_open(file, &profile_seq_op);
1025}
1026
1027static const struct file_operations kprobe_profile_ops = {
1028 .owner = THIS_MODULE,
1029 .open = profile_open,
1030 .read = seq_read,
1031 .llseek = seq_lseek,
1032 .release = seq_release,
1033};
1034
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001035/* Kprobe handler */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001036static nokprobe_inline void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001037__kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs,
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001038 struct trace_event_file *trace_file)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001039{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001040 struct kprobe_trace_entry_head *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001041 struct ring_buffer_event *event;
Frederic Weisbecker8f8ffe22009-09-11 01:09:23 +02001042 struct ring_buffer *buffer;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001043 int size, dsize, pc;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001044 unsigned long irq_flags;
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001045 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001046
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001047 WARN_ON(call != trace_file->event_call);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001048
Steven Rostedt (Red Hat)09a50592015-05-13 15:21:25 -04001049 if (trace_trigger_soft_disabled(trace_file))
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -05001050 return;
Masami Hiramatsub8820082013-05-09 14:44:54 +09001051
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001052 local_save_flags(irq_flags);
1053 pc = preempt_count();
1054
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001055 dsize = __get_data_size(&tk->tp, regs);
1056 size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001057
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001058 event = trace_event_buffer_lock_reserve(&buffer, trace_file,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001059 call->event.type,
1060 size, irq_flags, pc);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001061 if (!event)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001062 return;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001063
1064 entry = ring_buffer_event_data(event);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001065 entry->ip = (unsigned long)tk->rp.kp.addr;
1066 store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001067
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001068 event_trigger_unlock_commit_regs(trace_file, buffer, event,
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -05001069 entry, irq_flags, pc, regs);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001070}
1071
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001072static void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001073kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001074{
Oleg Nesterovb04d52e2013-06-20 19:38:14 +02001075 struct event_file_link *link;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001076
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001077 list_for_each_entry_rcu(link, &tk->tp.files, list)
1078 __kprobe_trace_func(tk, regs, link->file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001079}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001080NOKPROBE_SYMBOL(kprobe_trace_func);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001081
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001082/* Kretprobe handler */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001083static nokprobe_inline void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001084__kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001085 struct pt_regs *regs,
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001086 struct trace_event_file *trace_file)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001087{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001088 struct kretprobe_trace_entry_head *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001089 struct ring_buffer_event *event;
Frederic Weisbecker8f8ffe22009-09-11 01:09:23 +02001090 struct ring_buffer *buffer;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001091 int size, pc, dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001092 unsigned long irq_flags;
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001093 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001094
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001095 WARN_ON(call != trace_file->event_call);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001096
Steven Rostedt (Red Hat)09a50592015-05-13 15:21:25 -04001097 if (trace_trigger_soft_disabled(trace_file))
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -05001098 return;
Masami Hiramatsub8820082013-05-09 14:44:54 +09001099
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001100 local_save_flags(irq_flags);
1101 pc = preempt_count();
1102
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001103 dsize = __get_data_size(&tk->tp, regs);
1104 size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001105
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001106 event = trace_event_buffer_lock_reserve(&buffer, trace_file,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001107 call->event.type,
1108 size, irq_flags, pc);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001109 if (!event)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001110 return;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001111
1112 entry = ring_buffer_event_data(event);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001113 entry->func = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001114 entry->ret_ip = (unsigned long)ri->ret_addr;
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001115 store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001116
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001117 event_trigger_unlock_commit_regs(trace_file, buffer, event,
Steven Rostedt (Red Hat)13a1e4a2014-01-06 21:32:10 -05001118 entry, irq_flags, pc, regs);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001119}
1120
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001121static void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001122kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001123 struct pt_regs *regs)
1124{
Oleg Nesterovb04d52e2013-06-20 19:38:14 +02001125 struct event_file_link *link;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001126
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001127 list_for_each_entry_rcu(link, &tk->tp.files, list)
1128 __kretprobe_trace_func(tk, ri, regs, link->file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001129}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001130NOKPROBE_SYMBOL(kretprobe_trace_func);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001131
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001132/* Event entry printers */
Masami Hiramatsub62fdd92013-05-13 20:58:39 +09001133static enum print_line_t
Steven Rostedta9a57762010-04-22 18:46:14 -04001134print_kprobe_event(struct trace_iterator *iter, int flags,
1135 struct trace_event *event)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001136{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001137 struct kprobe_trace_entry_head *field;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001138 struct trace_seq *s = &iter->seq;
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001139 struct trace_probe *tp;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001140 u8 *data;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001141 int i;
1142
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001143 field = (struct kprobe_trace_entry_head *)iter->ent;
Steven Rostedt80decc72010-04-23 10:00:22 -04001144 tp = container_of(event, struct trace_probe, call.event);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001145
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -04001146 trace_seq_printf(s, "%s: (", trace_event_name(&tp->call));
Masami Hiramatsu6e9f23d2009-09-10 19:53:45 -04001147
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001148 if (!seq_print_ip_sym(s, field->ip, flags | TRACE_ITER_SYM_OFFSET))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001149 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001150
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001151 trace_seq_putc(s, ')');
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001152
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001153 data = (u8 *)&field[1];
1154 for (i = 0; i < tp->nr_args; i++)
1155 if (!tp->args[i].type->print(s, tp->args[i].name,
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001156 data + tp->args[i].offset, field))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001157 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001158
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001159 trace_seq_putc(s, '\n');
1160 out:
1161 return trace_handle_return(s);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001162}
1163
Masami Hiramatsub62fdd92013-05-13 20:58:39 +09001164static enum print_line_t
Steven Rostedta9a57762010-04-22 18:46:14 -04001165print_kretprobe_event(struct trace_iterator *iter, int flags,
1166 struct trace_event *event)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001167{
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001168 struct kretprobe_trace_entry_head *field;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001169 struct trace_seq *s = &iter->seq;
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001170 struct trace_probe *tp;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001171 u8 *data;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001172 int i;
1173
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001174 field = (struct kretprobe_trace_entry_head *)iter->ent;
Steven Rostedt80decc72010-04-23 10:00:22 -04001175 tp = container_of(event, struct trace_probe, call.event);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001176
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -04001177 trace_seq_printf(s, "%s: (", trace_event_name(&tp->call));
Masami Hiramatsu6e9f23d2009-09-10 19:53:45 -04001178
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001179 if (!seq_print_ip_sym(s, field->ret_ip, flags | TRACE_ITER_SYM_OFFSET))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001180 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001181
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001182 trace_seq_puts(s, " <- ");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001183
1184 if (!seq_print_ip_sym(s, field->func, flags & ~TRACE_ITER_SYM_OFFSET))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001185 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001186
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001187 trace_seq_putc(s, ')');
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001188
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001189 data = (u8 *)&field[1];
1190 for (i = 0; i < tp->nr_args; i++)
1191 if (!tp->args[i].type->print(s, tp->args[i].name,
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001192 data + tp->args[i].offset, field))
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001193 goto out;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001194
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001195 trace_seq_putc(s, '\n');
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001196
Steven Rostedt (Red Hat)85224da2014-11-12 15:18:16 -05001197 out:
1198 return trace_handle_return(s);
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001199}
1200
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001201
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001202static int kprobe_event_define_fields(struct trace_event_call *event_call)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001203{
1204 int ret, i;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001205 struct kprobe_trace_entry_head field;
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001206 struct trace_kprobe *tk = (struct trace_kprobe *)event_call->data;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001207
Masami Hiramatsua703d942009-10-07 18:28:07 -04001208 DEFINE_FIELD(unsigned long, ip, FIELD_STRING_IP, 0);
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001209 /* Set argument names as fields */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001210 for (i = 0; i < tk->tp.nr_args; i++) {
1211 struct probe_arg *parg = &tk->tp.args[i];
1212
1213 ret = trace_define_field(event_call, parg->type->fmttype,
1214 parg->name,
1215 sizeof(field) + parg->offset,
1216 parg->type->size,
1217 parg->type->is_signed,
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001218 FILTER_OTHER);
1219 if (ret)
1220 return ret;
1221 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001222 return 0;
1223}
1224
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001225static int kretprobe_event_define_fields(struct trace_event_call *event_call)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001226{
1227 int ret, i;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001228 struct kretprobe_trace_entry_head field;
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001229 struct trace_kprobe *tk = (struct trace_kprobe *)event_call->data;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001230
Masami Hiramatsua703d942009-10-07 18:28:07 -04001231 DEFINE_FIELD(unsigned long, func, FIELD_STRING_FUNC, 0);
1232 DEFINE_FIELD(unsigned long, ret_ip, FIELD_STRING_RETIP, 0);
Masami Hiramatsueca0d912009-09-10 19:53:38 -04001233 /* Set argument names as fields */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001234 for (i = 0; i < tk->tp.nr_args; i++) {
1235 struct probe_arg *parg = &tk->tp.args[i];
1236
1237 ret = trace_define_field(event_call, parg->type->fmttype,
1238 parg->name,
1239 sizeof(field) + parg->offset,
1240 parg->type->size,
1241 parg->type->is_signed,
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001242 FILTER_OTHER);
1243 if (ret)
1244 return ret;
1245 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001246 return 0;
1247}
1248
Li Zefan07b139c2009-12-21 14:27:35 +08001249#ifdef CONFIG_PERF_EVENTS
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001250
1251/* Kprobe profile handler */
Josef Bacik9802d862017-12-11 11:36:48 -05001252static int
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001253kprobe_perf_func(struct trace_kprobe *tk, struct pt_regs *regs)
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001254{
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001255 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001256 struct kprobe_trace_entry_head *entry;
Peter Zijlstra1c024eca2010-05-19 14:02:22 +02001257 struct hlist_head *head;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001258 int size, __size, dsize;
Peter Zijlstra4ed7c922009-11-23 11:37:29 +01001259 int rctx;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001260
Josef Bacik9802d862017-12-11 11:36:48 -05001261 if (bpf_prog_array_valid(call)) {
Masami Hiramatsu66665ad2018-01-13 02:54:33 +09001262 unsigned long orig_ip = instruction_pointer(regs);
Josef Bacik9802d862017-12-11 11:36:48 -05001263 int ret;
1264
1265 ret = trace_call_bpf(call, regs);
1266
1267 /*
1268 * We need to check and see if we modified the pc of the
1269 * pt_regs, and if so clear the kprobe and return 1 so that we
Masami Hiramatsu66665ad2018-01-13 02:54:33 +09001270 * don't do the single stepping.
1271 * The ftrace kprobe handler leaves it up to us to re-enable
1272 * preemption here before returning if we've modified the ip.
Josef Bacik9802d862017-12-11 11:36:48 -05001273 */
Masami Hiramatsu66665ad2018-01-13 02:54:33 +09001274 if (orig_ip != instruction_pointer(regs)) {
Josef Bacik9802d862017-12-11 11:36:48 -05001275 reset_current_kprobe();
Masami Hiramatsu66665ad2018-01-13 02:54:33 +09001276 preempt_enable_no_resched();
Josef Bacik9802d862017-12-11 11:36:48 -05001277 return 1;
1278 }
1279 if (!ret)
1280 return 0;
1281 }
Alexei Starovoitov25415172015-03-25 12:49:20 -07001282
Oleg Nesterov288e9842013-06-20 19:38:06 +02001283 head = this_cpu_ptr(call->perf_events);
1284 if (hlist_empty(head))
Josef Bacik9802d862017-12-11 11:36:48 -05001285 return 0;
Oleg Nesterov288e9842013-06-20 19:38:06 +02001286
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001287 dsize = __get_data_size(&tk->tp, regs);
1288 __size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu74ebb632009-09-14 16:49:28 -04001289 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1290 size -= sizeof(u32);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001291
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001292 entry = perf_trace_buf_alloc(size, NULL, &rctx);
Xiao Guangrong430ad5a2010-01-28 09:32:29 +08001293 if (!entry)
Josef Bacik9802d862017-12-11 11:36:48 -05001294 return 0;
Frederic Weisbeckerce71b9d2009-11-22 05:26:55 +01001295
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001296 entry->ip = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001297 memset(&entry[1], 0, dsize);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001298 store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize);
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001299 perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs,
Peter Zijlstra8fd0fbb2017-10-11 09:45:29 +02001300 head, NULL);
Josef Bacik9802d862017-12-11 11:36:48 -05001301 return 0;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001302}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001303NOKPROBE_SYMBOL(kprobe_perf_func);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001304
1305/* Kretprobe profile handler */
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001306static void
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001307kretprobe_perf_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
Masami Hiramatsu2b106aa2013-05-09 14:44:41 +09001308 struct pt_regs *regs)
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001309{
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001310 struct trace_event_call *call = &tk->tp.call;
Masami Hiramatsu93ccae72010-04-12 13:17:08 -04001311 struct kretprobe_trace_entry_head *entry;
Peter Zijlstra1c024eca2010-05-19 14:02:22 +02001312 struct hlist_head *head;
Masami Hiramatsue09c8612010-07-05 15:54:45 -03001313 int size, __size, dsize;
Peter Zijlstra4ed7c922009-11-23 11:37:29 +01001314 int rctx;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001315
Yonghong Songe87c6bc2017-10-23 23:53:08 -07001316 if (bpf_prog_array_valid(call) && !trace_call_bpf(call, regs))
Alexei Starovoitov25415172015-03-25 12:49:20 -07001317 return;
1318
Oleg Nesterov288e9842013-06-20 19:38:06 +02001319 head = this_cpu_ptr(call->perf_events);
1320 if (hlist_empty(head))
1321 return;
1322
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001323 dsize = __get_data_size(&tk->tp, regs);
1324 __size = sizeof(*entry) + tk->tp.size + dsize;
Masami Hiramatsu74ebb632009-09-14 16:49:28 -04001325 size = ALIGN(__size + sizeof(u32), sizeof(u64));
1326 size -= sizeof(u32);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001327
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001328 entry = perf_trace_buf_alloc(size, NULL, &rctx);
Xiao Guangrong430ad5a2010-01-28 09:32:29 +08001329 if (!entry)
Xiao Guangrong1e12a4a2010-01-28 09:34:27 +08001330 return;
Frederic Weisbeckerce71b9d2009-11-22 05:26:55 +01001331
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001332 entry->func = (unsigned long)tk->rp.kp.addr;
Masami Hiramatsua1a138d2009-09-25 11:20:12 -07001333 entry->ret_ip = (unsigned long)ri->ret_addr;
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001334 store_trace_args(sizeof(*entry), &tk->tp, regs, (u8 *)&entry[1], dsize);
Alexei Starovoitov1e1dcd92016-04-06 18:43:24 -07001335 perf_trace_buf_submit(entry, size, rctx, call->event.type, 1, regs,
Peter Zijlstra8fd0fbb2017-10-11 09:45:29 +02001336 head, NULL);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001337}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001338NOKPROBE_SYMBOL(kretprobe_perf_func);
Yonghong Song41bdc4b2018-05-24 11:21:09 -07001339
1340int bpf_get_kprobe_info(const struct perf_event *event, u32 *fd_type,
1341 const char **symbol, u64 *probe_offset,
1342 u64 *probe_addr, bool perf_type_tracepoint)
1343{
1344 const char *pevent = trace_event_name(event->tp_event);
1345 const char *group = event->tp_event->class->system;
1346 struct trace_kprobe *tk;
1347
1348 if (perf_type_tracepoint)
1349 tk = find_trace_kprobe(pevent, group);
1350 else
1351 tk = event->tp_event->data;
1352 if (!tk)
1353 return -EINVAL;
1354
1355 *fd_type = trace_kprobe_is_return(tk) ? BPF_FD_TYPE_KRETPROBE
1356 : BPF_FD_TYPE_KPROBE;
1357 if (tk->symbol) {
1358 *symbol = tk->symbol;
1359 *probe_offset = tk->rp.kp.offset;
1360 *probe_addr = 0;
1361 } else {
1362 *symbol = NULL;
1363 *probe_offset = 0;
1364 *probe_addr = (unsigned long)tk->rp.kp.addr;
1365 }
1366 return 0;
1367}
Li Zefan07b139c2009-12-21 14:27:35 +08001368#endif /* CONFIG_PERF_EVENTS */
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001369
Oleg Nesterov3fe3d612013-06-20 19:38:09 +02001370/*
1371 * called by perf_trace_init() or __ftrace_set_clr_event() under event_mutex.
1372 *
1373 * kprobe_trace_self_tests_init() does enable_trace_probe/disable_trace_probe
1374 * lockless, but we can't race with this __init function.
1375 */
Steven Rostedt (Red Hat)2425bcb2015-05-05 11:45:27 -04001376static int kprobe_register(struct trace_event_call *event,
Masami Hiramatsufbc19632014-04-17 17:18:00 +09001377 enum trace_reg type, void *data)
Steven Rostedt22392912010-04-21 12:27:06 -04001378{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001379 struct trace_kprobe *tk = (struct trace_kprobe *)event->data;
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001380 struct trace_event_file *file = data;
Masami Hiramatsu1538f882011-06-27 16:26:44 +09001381
Steven Rostedt22392912010-04-21 12:27:06 -04001382 switch (type) {
1383 case TRACE_REG_REGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001384 return enable_trace_kprobe(tk, file);
Steven Rostedt22392912010-04-21 12:27:06 -04001385 case TRACE_REG_UNREGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001386 return disable_trace_kprobe(tk, file);
Steven Rostedt22392912010-04-21 12:27:06 -04001387
1388#ifdef CONFIG_PERF_EVENTS
1389 case TRACE_REG_PERF_REGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001390 return enable_trace_kprobe(tk, NULL);
Steven Rostedt22392912010-04-21 12:27:06 -04001391 case TRACE_REG_PERF_UNREGISTER:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001392 return disable_trace_kprobe(tk, NULL);
Jiri Olsaceec0b62012-02-15 15:51:49 +01001393 case TRACE_REG_PERF_OPEN:
1394 case TRACE_REG_PERF_CLOSE:
Jiri Olsa489c75c2012-02-15 15:51:50 +01001395 case TRACE_REG_PERF_ADD:
1396 case TRACE_REG_PERF_DEL:
Jiri Olsaceec0b62012-02-15 15:51:49 +01001397 return 0;
Steven Rostedt22392912010-04-21 12:27:06 -04001398#endif
1399 }
1400 return 0;
1401}
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001402
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001403static int kprobe_dispatcher(struct kprobe *kp, struct pt_regs *regs)
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001404{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001405 struct trace_kprobe *tk = container_of(kp, struct trace_kprobe, rp.kp);
Josef Bacik9802d862017-12-11 11:36:48 -05001406 int ret = 0;
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001407
Martin KaFai Laua7636d92016-02-03 12:28:28 -08001408 raw_cpu_inc(*tk->nhit);
Masami Hiramatsu48182bd2013-05-09 14:44:36 +09001409
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001410 if (tk->tp.flags & TP_FLAG_TRACE)
1411 kprobe_trace_func(tk, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001412#ifdef CONFIG_PERF_EVENTS
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001413 if (tk->tp.flags & TP_FLAG_PROFILE)
Josef Bacik9802d862017-12-11 11:36:48 -05001414 ret = kprobe_perf_func(tk, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001415#endif
Josef Bacik9802d862017-12-11 11:36:48 -05001416 return ret;
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001417}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001418NOKPROBE_SYMBOL(kprobe_dispatcher);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001419
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001420static int
1421kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs)
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001422{
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001423 struct trace_kprobe *tk = container_of(ri->rp, struct trace_kprobe, rp);
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001424
Martin KaFai Laua7636d92016-02-03 12:28:28 -08001425 raw_cpu_inc(*tk->nhit);
Masami Hiramatsu48182bd2013-05-09 14:44:36 +09001426
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001427 if (tk->tp.flags & TP_FLAG_TRACE)
1428 kretprobe_trace_func(tk, ri, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001429#ifdef CONFIG_PERF_EVENTS
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001430 if (tk->tp.flags & TP_FLAG_PROFILE)
1431 kretprobe_perf_func(tk, ri, regs);
Li Zefan07b139c2009-12-21 14:27:35 +08001432#endif
Masami Hiramatsu50d78052009-09-14 16:49:20 -04001433 return 0; /* We don't tweek kernel, so just return 0 */
1434}
Masami Hiramatsu3da0f182014-04-17 17:18:28 +09001435NOKPROBE_SYMBOL(kretprobe_dispatcher);
Masami Hiramatsue08d1c62009-09-10 19:53:30 -04001436
Steven Rostedta9a57762010-04-22 18:46:14 -04001437static struct trace_event_functions kretprobe_funcs = {
1438 .trace = print_kretprobe_event
1439};
1440
1441static struct trace_event_functions kprobe_funcs = {
1442 .trace = print_kprobe_event
1443};
1444
Song Liue12f03d2017-12-06 14:45:15 -08001445static inline void init_trace_event_call(struct trace_kprobe *tk,
1446 struct trace_event_call *call)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001447{
Li Zefanffb9f992010-05-24 16:24:52 +08001448 INIT_LIST_HEAD(&call->class->fields);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001449 if (trace_kprobe_is_return(tk)) {
Steven Rostedt80decc72010-04-23 10:00:22 -04001450 call->event.funcs = &kretprobe_funcs;
Steven Rostedt2e33af02010-04-22 10:35:55 -04001451 call->class->define_fields = kretprobe_event_define_fields;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001452 } else {
Steven Rostedt80decc72010-04-23 10:00:22 -04001453 call->event.funcs = &kprobe_funcs;
Steven Rostedt2e33af02010-04-22 10:35:55 -04001454 call->class->define_fields = kprobe_event_define_fields;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001455 }
Song Liue12f03d2017-12-06 14:45:15 -08001456
1457 call->flags = TRACE_EVENT_FL_KPROBE;
1458 call->class->reg = kprobe_register;
1459 call->data = tk;
1460}
1461
1462static int register_kprobe_event(struct trace_kprobe *tk)
1463{
1464 struct trace_event_call *call = &tk->tp.call;
1465 int ret = 0;
1466
1467 init_trace_event_call(tk, call);
1468
Namhyung Kim5bf652a2013-07-03 16:09:02 +09001469 if (set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0)
Lai Jiangshana342a0282009-12-15 15:39:49 +08001470 return -ENOMEM;
Steven Rostedt (Red Hat)9023c932015-05-05 09:39:12 -04001471 ret = register_trace_event(&call->event);
Steven Rostedt32c0eda2010-04-23 10:38:03 -04001472 if (!ret) {
Lai Jiangshana342a0282009-12-15 15:39:49 +08001473 kfree(call->print_fmt);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001474 return -ENODEV;
Lai Jiangshana342a0282009-12-15 15:39:49 +08001475 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001476 ret = trace_add_event_call(call);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001477 if (ret) {
Mathieu Desnoyersde7b2972014-04-08 17:26:21 -04001478 pr_info("Failed to register kprobe event: %s\n",
Steven Rostedt (Red Hat)687fcc42015-05-13 14:20:14 -04001479 trace_event_name(call));
Lai Jiangshana342a0282009-12-15 15:39:49 +08001480 kfree(call->print_fmt);
Steven Rostedt (Red Hat)9023c932015-05-05 09:39:12 -04001481 unregister_trace_event(&call->event);
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001482 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001483 return ret;
1484}
1485
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001486static int unregister_kprobe_event(struct trace_kprobe *tk)
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001487{
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -04001488 int ret;
1489
Masami Hiramatsuff50d992009-08-13 16:35:34 -04001490 /* tp->event is unregistered in trace_remove_event_call() */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001491 ret = trace_remove_event_call(&tk->tp.call);
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -04001492 if (!ret)
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001493 kfree(tk->tp.call.print_fmt);
Steven Rostedt (Red Hat)40c32592013-07-03 23:33:50 -04001494 return ret;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001495}
1496
Song Liue12f03d2017-12-06 14:45:15 -08001497#ifdef CONFIG_PERF_EVENTS
1498/* create a trace_kprobe, but don't add it to global lists */
1499struct trace_event_call *
1500create_local_trace_kprobe(char *func, void *addr, unsigned long offs,
1501 bool is_return)
1502{
1503 struct trace_kprobe *tk;
1504 int ret;
1505 char *event;
1506
1507 /*
1508 * local trace_kprobes are not added to probe_list, so they are never
1509 * searched in find_trace_kprobe(). Therefore, there is no concern of
1510 * duplicated name here.
1511 */
1512 event = func ? func : "DUMMY_EVENT";
1513
1514 tk = alloc_trace_kprobe(KPROBE_EVENT_SYSTEM, event, (void *)addr, func,
1515 offs, 0 /* maxactive */, 0 /* nargs */,
1516 is_return);
1517
1518 if (IS_ERR(tk)) {
1519 pr_info("Failed to allocate trace_probe.(%d)\n",
1520 (int)PTR_ERR(tk));
1521 return ERR_CAST(tk);
1522 }
1523
1524 init_trace_event_call(tk, &tk->tp.call);
1525
1526 if (set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) {
1527 ret = -ENOMEM;
1528 goto error;
1529 }
1530
1531 ret = __register_trace_kprobe(tk);
Jiri Olsa0fc8c352018-07-09 16:19:06 +02001532 if (ret < 0) {
1533 kfree(tk->tp.call.print_fmt);
Song Liue12f03d2017-12-06 14:45:15 -08001534 goto error;
Jiri Olsa0fc8c352018-07-09 16:19:06 +02001535 }
Song Liue12f03d2017-12-06 14:45:15 -08001536
1537 return &tk->tp.call;
1538error:
1539 free_trace_kprobe(tk);
1540 return ERR_PTR(ret);
1541}
1542
1543void destroy_local_trace_kprobe(struct trace_event_call *event_call)
1544{
1545 struct trace_kprobe *tk;
1546
1547 tk = container_of(event_call, struct trace_kprobe, tp.call);
1548
1549 if (trace_probe_is_enabled(&tk->tp)) {
1550 WARN_ON(1);
1551 return;
1552 }
1553
1554 __unregister_trace_kprobe(tk);
Jiri Olsa0fc8c352018-07-09 16:19:06 +02001555
1556 kfree(tk->tp.call.print_fmt);
Song Liue12f03d2017-12-06 14:45:15 -08001557 free_trace_kprobe(tk);
1558}
1559#endif /* CONFIG_PERF_EVENTS */
1560
Steven Rostedt (Red Hat)8434dc92015-01-20 12:13:40 -05001561/* Make a tracefs interface for controlling probe points */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001562static __init int init_kprobe_trace(void)
1563{
1564 struct dentry *d_tracer;
1565 struct dentry *entry;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001566
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001567 if (register_module_notifier(&trace_kprobe_module_nb))
Masami Hiramatsu61424312011-06-27 16:26:56 +09001568 return -EINVAL;
1569
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001570 d_tracer = tracing_init_dentry();
Steven Rostedt (Red Hat)14a5ae42015-01-20 11:14:16 -05001571 if (IS_ERR(d_tracer))
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001572 return 0;
1573
Steven Rostedt (Red Hat)8434dc92015-01-20 12:13:40 -05001574 entry = tracefs_create_file("kprobe_events", 0644, d_tracer,
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001575 NULL, &kprobe_events_ops);
1576
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001577 /* Event list interface */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001578 if (!entry)
Joe Perchesa395d6a2016-03-22 14:28:09 -07001579 pr_warn("Could not create tracefs 'kprobe_events' entry\n");
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001580
1581 /* Profile interface */
Steven Rostedt (Red Hat)8434dc92015-01-20 12:13:40 -05001582 entry = tracefs_create_file("kprobe_profile", 0444, d_tracer,
Masami Hiramatsucd7e7bd2009-08-13 16:35:42 -04001583 NULL, &kprobe_profile_ops);
1584
1585 if (!entry)
Joe Perchesa395d6a2016-03-22 14:28:09 -07001586 pr_warn("Could not create tracefs 'kprobe_profile' entry\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001587 return 0;
1588}
1589fs_initcall(init_kprobe_trace);
1590
1591
1592#ifdef CONFIG_FTRACE_STARTUP_TEST
Arnd Bergmann26a346f2017-02-01 17:57:56 +01001593static __init struct trace_event_file *
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001594find_trace_probe_file(struct trace_kprobe *tk, struct trace_array *tr)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001595{
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001596 struct trace_event_file *file;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001597
1598 list_for_each_entry(file, &tr->events, list)
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001599 if (file->event_call == &tk->tp.call)
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001600 return file;
1601
1602 return NULL;
1603}
1604
Oleg Nesterov3fe3d612013-06-20 19:38:09 +02001605/*
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001606 * Nobody but us can call enable_trace_kprobe/disable_trace_kprobe at this
Oleg Nesterov3fe3d612013-06-20 19:38:09 +02001607 * stage, we can do this lockless.
1608 */
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001609static __init int kprobe_trace_self_tests_init(void)
1610{
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001611 int ret, warn = 0;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001612 int (*target)(int, int, int, int, int, int);
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001613 struct trace_kprobe *tk;
Steven Rostedt (Red Hat)7f1d2f82015-05-05 10:09:53 -04001614 struct trace_event_file *file;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001615
Yoshihiro YUNOMAE748ec3a2014-06-06 07:35:20 +09001616 if (tracing_is_disabled())
1617 return -ENODEV;
1618
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001619 target = kprobe_trace_selftest_target;
1620
1621 pr_info("Testing kprobe tracing: ");
1622
Tom Zanussi7e465ba2017-09-22 14:58:20 -05001623 ret = trace_run_command("p:testprobe kprobe_trace_selftest_target "
1624 "$stack $stack0 +0($stack)",
1625 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 probing function entry.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001628 warn++;
1629 } else {
1630 /* Enable trace point */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001631 tk = find_trace_kprobe("testprobe", KPROBE_EVENT_SYSTEM);
1632 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001633 pr_warn("error on getting new probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001634 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001635 } else {
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001636 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001637 if (WARN_ON_ONCE(file == NULL)) {
1638 pr_warn("error on getting probe file.\n");
1639 warn++;
1640 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001641 enable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001642 }
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001643 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001644
Tom Zanussi7e465ba2017-09-22 14:58:20 -05001645 ret = trace_run_command("r:testprobe2 kprobe_trace_selftest_target "
1646 "$retval", create_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001647 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001648 pr_warn("error on probing function return.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001649 warn++;
1650 } else {
1651 /* Enable trace point */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001652 tk = find_trace_kprobe("testprobe2", KPROBE_EVENT_SYSTEM);
1653 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001654 pr_warn("error on getting 2nd new probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001655 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001656 } else {
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001657 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001658 if (WARN_ON_ONCE(file == NULL)) {
1659 pr_warn("error on getting probe file.\n");
1660 warn++;
1661 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001662 enable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001663 }
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001664 }
1665
1666 if (warn)
1667 goto end;
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001668
1669 ret = target(1, 2, 3, 4, 5, 6);
1670
Marcin Nowakowskid4d7ccc2016-12-09 15:19:38 +01001671 /*
1672 * Not expecting an error here, the check is only to prevent the
1673 * optimizer from removing the call to target() as otherwise there
1674 * are no side-effects and the call is never performed.
1675 */
1676 if (ret != 21)
1677 warn++;
1678
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001679 /* Disable trace points before removing it */
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001680 tk = find_trace_kprobe("testprobe", KPROBE_EVENT_SYSTEM);
1681 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001682 pr_warn("error on getting test probe.\n");
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001683 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001684 } else {
Marcin Nowakowskid4d7ccc2016-12-09 15:19:38 +01001685 if (trace_kprobe_nhit(tk) != 1) {
1686 pr_warn("incorrect number of testprobe hits\n");
1687 warn++;
1688 }
1689
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001690 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001691 if (WARN_ON_ONCE(file == NULL)) {
1692 pr_warn("error on getting probe file.\n");
1693 warn++;
1694 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001695 disable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001696 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001697
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001698 tk = find_trace_kprobe("testprobe2", KPROBE_EVENT_SYSTEM);
1699 if (WARN_ON_ONCE(tk == NULL)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001700 pr_warn("error on getting 2nd test probe.\n");
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001701 warn++;
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001702 } else {
Marcin Nowakowskid4d7ccc2016-12-09 15:19:38 +01001703 if (trace_kprobe_nhit(tk) != 1) {
1704 pr_warn("incorrect number of testprobe2 hits\n");
1705 warn++;
1706 }
1707
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001708 file = find_trace_probe_file(tk, top_trace_array());
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001709 if (WARN_ON_ONCE(file == NULL)) {
1710 pr_warn("error on getting probe file.\n");
1711 warn++;
1712 } else
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001713 disable_trace_kprobe(tk, file);
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001714 }
Masami Hiramatsu02ca1522011-10-04 19:44:38 +09001715
Tom Zanussi7e465ba2017-09-22 14:58:20 -05001716 ret = trace_run_command("-:testprobe", create_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001717 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001718 pr_warn("error on deleting a probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001719 warn++;
1720 }
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001721
Tom Zanussi7e465ba2017-09-22 14:58:20 -05001722 ret = trace_run_command("-:testprobe2", create_trace_kprobe);
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001723 if (WARN_ON_ONCE(ret)) {
Masami Hiramatsu41a7dd42013-05-09 14:44:49 +09001724 pr_warn("error on deleting a probe.\n");
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001725 warn++;
1726 }
1727
1728end:
Namhyung Kimc31ffb32013-07-03 13:50:51 +09001729 release_all_trace_kprobes();
Thomas Gleixner30e7d8942017-05-17 10:19:49 +02001730 /*
1731 * Wait for the optimizer work to finish. Otherwise it might fiddle
1732 * with probes in already freed __init text.
1733 */
1734 wait_for_kprobe_optimizer();
Masami Hiramatsu231e36f2010-01-14 00:12:12 -05001735 if (warn)
1736 pr_cont("NG: Some tests are failed. Please check them.\n");
1737 else
1738 pr_cont("OK\n");
Masami Hiramatsu413d37d2009-08-13 16:35:11 -04001739 return 0;
1740}
1741
1742late_initcall(kprobe_trace_self_tests_init);
1743
1744#endif