Commit 970988e1 authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Steven Rostedt (VMware)

tracing/kprobe: Add kprobe_event= boot parameter

Add kprobe_event= boot parameter to define kprobe events
at boot time.
The definition syntax is similar to tracefs/kprobe_events
interface, but use ',' and ';' instead of ' ' and '\n'
respectively. e.g.

  kprobe_event=p,vfs_read,$arg1,$arg2

This puts a probe on vfs_read with argument1 and 2, and
enable the new event.

Link: http://lkml.kernel.org/r/155851395498.15728.830529496248543583.stgit@devnote2Signed-off-by: default avatarMasami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent b5f8b32c
...@@ -2007,6 +2007,19 @@ ...@@ -2007,6 +2007,19 @@
Built with CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y, Built with CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y,
the default is off. the default is off.
kprobe_event=[probe-list]
[FTRACE] Add kprobe events and enable at boot time.
The probe-list is a semicolon delimited list of probe
definitions. Each definition is same as kprobe_events
interface, but the parameters are comma delimited.
For example, to add a kprobe event on vfs_read with
arg1 and arg2, add to the command line;
kprobe_event=p,vfs_read,$arg1,$arg2
See also Documentation/trace/kprobetrace.rst "Kernel
Boot Parameter" section.
kpti= [ARM64] Control page table isolation of user kpti= [ARM64] Control page table isolation of user
and kernel address spaces. and kernel address spaces.
Default: enabled on cores which need mitigation. Default: enabled on cores which need mitigation.
......
...@@ -146,6 +146,20 @@ You can check the total number of probe hits and probe miss-hits via ...@@ -146,6 +146,20 @@ You can check the total number of probe hits and probe miss-hits via
The first column is event name, the second is the number of probe hits, The first column is event name, the second is the number of probe hits,
the third is the number of probe miss-hits. the third is the number of probe miss-hits.
Kernel Boot Parameter
---------------------
You can add and enable new kprobe events when booting up the kernel by
"kprobe_event=" parameter. The parameter accepts a semicolon-delimited
kprobe events, which format is similar to the kprobe_events.
The difference is that the probe definition parameters are comma-delimited
instead of space. For example, adding myprobe event on do_sys_open like below
p:myprobe do_sys_open dfd=%ax filename=%dx flags=%cx mode=+4($stack)
should be below for kernel boot parameter (just replace spaces with comma)
p:myprobe,do_sys_open,dfd=%ax,filename=%dx,flags=%cx,mode=+4($stack)
Usage examples Usage examples
-------------- --------------
......
...@@ -12,6 +12,8 @@ ...@@ -12,6 +12,8 @@
#include <linux/rculist.h> #include <linux/rculist.h>
#include <linux/error-injection.h> #include <linux/error-injection.h>
#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
#include "trace_dynevent.h" #include "trace_dynevent.h"
#include "trace_kprobe_selftest.h" #include "trace_kprobe_selftest.h"
#include "trace_probe.h" #include "trace_probe.h"
...@@ -19,6 +21,17 @@ ...@@ -19,6 +21,17 @@
#define KPROBE_EVENT_SYSTEM "kprobes" #define KPROBE_EVENT_SYSTEM "kprobes"
#define KRETPROBE_MAXACTIVE_MAX 4096 #define KRETPROBE_MAXACTIVE_MAX 4096
#define MAX_KPROBE_CMDLINE_SIZE 1024
/* Kprobe early definition from command line */
static char kprobe_boot_events_buf[COMMAND_LINE_SIZE] __initdata;
static int __init set_kprobe_boot_events(char *str)
{
strlcpy(kprobe_boot_events_buf, str, COMMAND_LINE_SIZE);
return 0;
}
__setup("kprobe_event=", set_kprobe_boot_events);
static int trace_kprobe_create(int argc, const char **argv); static int trace_kprobe_create(int argc, const char **argv);
static int trace_kprobe_show(struct seq_file *m, struct dyn_event *ev); static int trace_kprobe_show(struct seq_file *m, struct dyn_event *ev);
...@@ -1494,6 +1507,44 @@ void destroy_local_trace_kprobe(struct trace_event_call *event_call) ...@@ -1494,6 +1507,44 @@ void destroy_local_trace_kprobe(struct trace_event_call *event_call)
} }
#endif /* CONFIG_PERF_EVENTS */ #endif /* CONFIG_PERF_EVENTS */
static __init void enable_boot_kprobe_events(void)
{
struct trace_array *tr = top_trace_array();
struct trace_event_file *file;
struct trace_kprobe *tk;
struct dyn_event *pos;
mutex_lock(&event_mutex);
for_each_trace_kprobe(tk, pos) {
list_for_each_entry(file, &tr->events, list)
if (file->event_call == &tk->tp.call)
trace_event_enable_disable(file, 1, 0);
}
mutex_unlock(&event_mutex);
}
static __init void setup_boot_kprobe_events(void)
{
char *p, *cmd = kprobe_boot_events_buf;
int ret;
strreplace(kprobe_boot_events_buf, ',', ' ');
while (cmd && *cmd != '\0') {
p = strchr(cmd, ';');
if (p)
*p++ = '\0';
ret = trace_run_command(cmd, create_or_delete_trace_kprobe);
if (ret)
pr_warn("Failed to add event(%d): %s\n", ret, cmd);
cmd = p;
}
enable_boot_kprobe_events();
}
/* Make a tracefs interface for controlling probe points */ /* Make a tracefs interface for controlling probe points */
static __init int init_kprobe_trace(void) static __init int init_kprobe_trace(void)
{ {
...@@ -1525,6 +1576,9 @@ static __init int init_kprobe_trace(void) ...@@ -1525,6 +1576,9 @@ static __init int init_kprobe_trace(void)
if (!entry) if (!entry)
pr_warn("Could not create tracefs 'kprobe_profile' entry\n"); pr_warn("Could not create tracefs 'kprobe_profile' entry\n");
setup_boot_kprobe_events();
return 0; return 0;
} }
fs_initcall(init_kprobe_trace); fs_initcall(init_kprobe_trace);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment