aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/ftrace.h
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2008-11-14 19:21:19 -0500
committerIngo Molnar <mingo@elte.hu>2008-11-16 01:36:02 -0500
commit31e889098a80ceb3e9e3c555d522b2686a6663c6 (patch)
tree2acb73507de4191d4a9aa5ccf08fa24e7044c89e /include/linux/ftrace.h
parentd51ad7ac48f991c4a8834485727efa99a691cb87 (diff)
ftrace: pass module struct to arch dynamic ftrace functions
Impact: allow archs more flexibility on dynamic ftrace implementations Dynamic ftrace has largly been developed on x86. Since x86 does not have the same limitations as other architectures, the ftrace interaction between the generic code and the architecture specific code was not flexible enough to handle some of the issues that other architectures have. Most notably, module trampolines. Due to the limited branch distance that archs make in calling kernel core code from modules, the module load code must create a trampoline to jump to what will make the larger jump into core kernel code. The problem arises when this happens to a call to mcount. Ftrace checks all code before modifying it and makes sure the current code is what it expects. Right now, there is not enough information to handle modifying module trampolines. This patch changes the API between generic dynamic ftrace code and the arch dependent code. There is now two functions for modifying code: ftrace_make_nop(mod, rec, addr) - convert the code at rec->ip into a nop, where the original text is calling addr. (mod is the module struct if called by module init) ftrace_make_caller(rec, addr) - convert the code rec->ip that should be a nop into a caller to addr. The record "rec" now has a new field called "arch" where the architecture can add any special attributes to each call site record. Signed-off-by: Steven Rostedt <srostedt@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'include/linux/ftrace.h')
-rw-r--r--include/linux/ftrace.h53
1 files changed, 41 insertions, 12 deletions
diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 4fbc4a8b86a5..166a2070ef65 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -74,6 +74,9 @@ static inline void ftrace_start(void) { }
74#endif /* CONFIG_FUNCTION_TRACER */ 74#endif /* CONFIG_FUNCTION_TRACER */
75 75
76#ifdef CONFIG_DYNAMIC_FTRACE 76#ifdef CONFIG_DYNAMIC_FTRACE
77/* asm/ftrace.h must be defined for archs supporting dynamic ftrace */
78#include <asm/ftrace.h>
79
77enum { 80enum {
78 FTRACE_FL_FREE = (1 << 0), 81 FTRACE_FL_FREE = (1 << 0),
79 FTRACE_FL_FAILED = (1 << 1), 82 FTRACE_FL_FAILED = (1 << 1),
@@ -88,6 +91,7 @@ struct dyn_ftrace {
88 struct list_head list; 91 struct list_head list;
89 unsigned long ip; /* address of mcount call-site */ 92 unsigned long ip; /* address of mcount call-site */
90 unsigned long flags; 93 unsigned long flags;
94 struct dyn_arch_ftrace arch;
91}; 95};
92 96
93int ftrace_force_update(void); 97int ftrace_force_update(void);
@@ -95,22 +99,40 @@ void ftrace_set_filter(unsigned char *buf, int len, int reset);
95 99
96/* defined in arch */ 100/* defined in arch */
97extern int ftrace_ip_converted(unsigned long ip); 101extern int ftrace_ip_converted(unsigned long ip);
98extern unsigned char *ftrace_nop_replace(void);
99extern unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr);
100extern int ftrace_dyn_arch_init(void *data); 102extern int ftrace_dyn_arch_init(void *data);
101extern int ftrace_update_ftrace_func(ftrace_func_t func); 103extern int ftrace_update_ftrace_func(ftrace_func_t func);
102extern void ftrace_caller(void); 104extern void ftrace_caller(void);
103extern void ftrace_call(void); 105extern void ftrace_call(void);
104extern void mcount_call(void); 106extern void mcount_call(void);
105 107
106/* May be defined in arch */ 108/**
107extern int ftrace_arch_read_dyn_info(char *buf, int size); 109 * ftrace_make_nop - convert code into top
110 * @mod: module structure if called by module load initialization
111 * @rec: the mcount call site record
112 * @addr: the address that the call site should be calling
113 *
114 * This is a very sensitive operation and great care needs
115 * to be taken by the arch. The operation should carefully
116 * read the location, check to see if what is read is indeed
117 * what we expect it to be, and then on success of the compare,
118 * it should write to the location.
119 *
120 * The code segment at @rec->ip should be a caller to @addr
121 *
122 * Return must be:
123 * 0 on success
124 * -EFAULT on error reading the location
125 * -EINVAL on a failed compare of the contents
126 * -EPERM on error writing to the location
127 * Any other value will be considered a failure.
128 */
129extern int ftrace_make_nop(struct module *mod,
130 struct dyn_ftrace *rec, unsigned long addr);
108 131
109/** 132/**
110 * ftrace_modify_code - modify code segment 133 * ftrace_make_call - convert a nop call site into a call to addr
111 * @ip: the address of the code segment 134 * @rec: the mcount call site record
112 * @old_code: the contents of what is expected to be there 135 * @addr: the address that the call site should call
113 * @new_code: the code to patch in
114 * 136 *
115 * This is a very sensitive operation and great care needs 137 * This is a very sensitive operation and great care needs
116 * to be taken by the arch. The operation should carefully 138 * to be taken by the arch. The operation should carefully
@@ -118,6 +140,8 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size);
118 * what we expect it to be, and then on success of the compare, 140 * what we expect it to be, and then on success of the compare,
119 * it should write to the location. 141 * it should write to the location.
120 * 142 *
143 * The code segment at @rec->ip should be a nop
144 *
121 * Return must be: 145 * Return must be:
122 * 0 on success 146 * 0 on success
123 * -EFAULT on error reading the location 147 * -EFAULT on error reading the location
@@ -125,8 +149,11 @@ extern int ftrace_arch_read_dyn_info(char *buf, int size);
125 * -EPERM on error writing to the location 149 * -EPERM on error writing to the location
126 * Any other value will be considered a failure. 150 * Any other value will be considered a failure.
127 */ 151 */
128extern int ftrace_modify_code(unsigned long ip, unsigned char *old_code, 152extern int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr);
129 unsigned char *new_code); 153
154
155/* May be defined in arch */
156extern int ftrace_arch_read_dyn_info(char *buf, int size);
130 157
131extern int skip_trace(unsigned long ip); 158extern int skip_trace(unsigned long ip);
132 159
@@ -259,11 +286,13 @@ static inline void ftrace_dump(void) { }
259 286
260#ifdef CONFIG_FTRACE_MCOUNT_RECORD 287#ifdef CONFIG_FTRACE_MCOUNT_RECORD
261extern void ftrace_init(void); 288extern void ftrace_init(void);
262extern void ftrace_init_module(unsigned long *start, unsigned long *end); 289extern void ftrace_init_module(struct module *mod,
290 unsigned long *start, unsigned long *end);
263#else 291#else
264static inline void ftrace_init(void) { } 292static inline void ftrace_init(void) { }
265static inline void 293static inline void
266ftrace_init_module(unsigned long *start, unsigned long *end) { } 294ftrace_init_module(struct module *mod,
295 unsigned long *start, unsigned long *end) { }
267#endif 296#endif
268 297
269 298