summaryrefslogtreecommitdiffstats
path: root/include/linux/ftrace.h
diff options
context:
space:
mode:
authorMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>2014-11-21 05:25:16 -0500
committerSteven Rostedt <rostedt@goodmis.org>2014-11-21 14:42:10 -0500
commitf8b8be8a310a55856fd2c369dade08088d85df3b (patch)
tree4c427a2981e4b66392b5bf9d7f8988479040150c /include/linux/ftrace.h
parenta017784f1b236cbc42ce83b4345a667c21113481 (diff)
ftrace, kprobes: Support IPMODIFY flag to find IP modify conflict
Introduce FTRACE_OPS_FL_IPMODIFY to avoid conflict among ftrace users who may modify regs->ip to change the execution path. If two or more users modify the regs->ip on the same function entry, one of them will be broken. So they must add IPMODIFY flag and make sure that ftrace_set_filter_ip() succeeds. Note that ftrace doesn't allow ftrace_ops which has IPMODIFY flag to have notrace hash, and the ftrace_ops must have a filter hash (so that the ftrace_ops can hook only specific entries), because it strongly depends on the address and must be allowed for only few selected functions. Link: http://lkml.kernel.org/r/20141121102516.11844.27829.stgit@localhost.localdomain Cc: Jiri Kosina <jkosina@suse.cz> Cc: Seth Jennings <sjenning@redhat.com> Cc: Petr Mladek <pmladek@suse.cz> Cc: Vojtech Pavlik <vojtech@suse.cz> Cc: Miroslav Benes <mbenes@suse.cz> Cc: Ingo Molnar <mingo@kernel.org> Cc: Ananth N Mavinakayanahalli <ananth@in.ibm.com> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Namhyung Kim <namhyung@kernel.org> Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> [ fixed up some of the comments ] Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'include/linux/ftrace.h')
-rw-r--r--include/linux/ftrace.h16
1 files changed, 14 insertions, 2 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 7b2616fa2472..ed501953f0b2 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -61,6 +61,11 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops);
61/* 61/*
62 * FTRACE_OPS_FL_* bits denote the state of ftrace_ops struct and are 62 * FTRACE_OPS_FL_* bits denote the state of ftrace_ops struct and are
63 * set in the flags member. 63 * set in the flags member.
64 * CONTROL, SAVE_REGS, SAVE_REGS_IF_SUPPORTED, RECURSION_SAFE, STUB and
65 * IPMODIFY are a kind of attribute flags which can be set only before
66 * registering the ftrace_ops, and can not be modified while registered.
67 * Changing those attribute flags after regsitering ftrace_ops will
68 * cause unexpected results.
64 * 69 *
65 * ENABLED - set/unset when ftrace_ops is registered/unregistered 70 * ENABLED - set/unset when ftrace_ops is registered/unregistered
66 * DYNAMIC - set when ftrace_ops is registered to denote dynamically 71 * DYNAMIC - set when ftrace_ops is registered to denote dynamically
@@ -101,6 +106,10 @@ ftrace_func_t ftrace_ops_get_func(struct ftrace_ops *ops);
101 * The ftrace_ops trampoline can be set by the ftrace users, and 106 * The ftrace_ops trampoline can be set by the ftrace users, and
102 * in such cases the arch must not modify it. Only the arch ftrace 107 * in such cases the arch must not modify it. Only the arch ftrace
103 * core code should set this flag. 108 * core code should set this flag.
109 * IPMODIFY - The ops can modify the IP register. This can only be set with
110 * SAVE_REGS. If another ops with this flag set is already registered
111 * for any of the functions that this ops will be registered for, then
112 * this ops will fail to register or set_filter_ip.
104 */ 113 */
105enum { 114enum {
106 FTRACE_OPS_FL_ENABLED = 1 << 0, 115 FTRACE_OPS_FL_ENABLED = 1 << 0,
@@ -116,6 +125,7 @@ enum {
116 FTRACE_OPS_FL_REMOVING = 1 << 10, 125 FTRACE_OPS_FL_REMOVING = 1 << 10,
117 FTRACE_OPS_FL_MODIFYING = 1 << 11, 126 FTRACE_OPS_FL_MODIFYING = 1 << 11,
118 FTRACE_OPS_FL_ALLOC_TRAMP = 1 << 12, 127 FTRACE_OPS_FL_ALLOC_TRAMP = 1 << 12,
128 FTRACE_OPS_FL_IPMODIFY = 1 << 13,
119}; 129};
120 130
121#ifdef CONFIG_DYNAMIC_FTRACE 131#ifdef CONFIG_DYNAMIC_FTRACE
@@ -310,6 +320,7 @@ bool is_ftrace_trampoline(unsigned long addr);
310 * ENABLED - the function is being traced 320 * ENABLED - the function is being traced
311 * REGS - the record wants the function to save regs 321 * REGS - the record wants the function to save regs
312 * REGS_EN - the function is set up to save regs. 322 * REGS_EN - the function is set up to save regs.
323 * IPMODIFY - the record allows for the IP address to be changed.
313 * 324 *
314 * When a new ftrace_ops is registered and wants a function to save 325 * When a new ftrace_ops is registered and wants a function to save
315 * pt_regs, the rec->flag REGS is set. When the function has been 326 * pt_regs, the rec->flag REGS is set. When the function has been
@@ -323,10 +334,11 @@ enum {
323 FTRACE_FL_REGS_EN = (1UL << 29), 334 FTRACE_FL_REGS_EN = (1UL << 29),
324 FTRACE_FL_TRAMP = (1UL << 28), 335 FTRACE_FL_TRAMP = (1UL << 28),
325 FTRACE_FL_TRAMP_EN = (1UL << 27), 336 FTRACE_FL_TRAMP_EN = (1UL << 27),
337 FTRACE_FL_IPMODIFY = (1UL << 26),
326}; 338};
327 339
328#define FTRACE_REF_MAX_SHIFT 27 340#define FTRACE_REF_MAX_SHIFT 26
329#define FTRACE_FL_BITS 5 341#define FTRACE_FL_BITS 6
330#define FTRACE_FL_MASKED_BITS ((1UL << FTRACE_FL_BITS) - 1) 342#define FTRACE_FL_MASKED_BITS ((1UL << FTRACE_FL_BITS) - 1)
331#define FTRACE_FL_MASK (FTRACE_FL_MASKED_BITS << FTRACE_REF_MAX_SHIFT) 343#define FTRACE_FL_MASK (FTRACE_FL_MASKED_BITS << FTRACE_REF_MAX_SHIFT)
332#define FTRACE_REF_MAX ((1UL << FTRACE_REF_MAX_SHIFT) - 1) 344#define FTRACE_REF_MAX ((1UL << FTRACE_REF_MAX_SHIFT) - 1)