aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ftrace.c
diff options
context:
space:
mode:
authorAbhishek Sagar <sagar.abhishek@gmail.com>2008-06-21 14:17:27 -0400
committerIngo Molnar <mingo@elte.hu>2008-06-23 16:10:56 -0400
commit395a59d0f8e86bb39cd700c3d185d30c670bb958 (patch)
tree1558e635efcede901c5dbe9acd625d475db5b369 /arch/x86/kernel/ftrace.c
parentf34bfb1beef8a17ba3d46b60f8fa19ffedc1ed8d (diff)
ftrace: store mcount address in rec->ip
Record the address of the mcount call-site. Currently all archs except sparc64 record the address of the instruction following the mcount call-site. Some general cleanups are entailed. Storing mcount addresses in rec->ip enables looking them up in the kprobe hash table later on to check if they're kprobe'd. Signed-off-by: Abhishek Sagar <sagar.abhishek@gmail.com> Cc: davem@davemloft.net Cc: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/ftrace.c')
-rw-r--r--arch/x86/kernel/ftrace.c26
1 files changed, 9 insertions, 17 deletions
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 55828149e01e..ab115cd15fdf 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -17,20 +17,21 @@
17#include <linux/list.h> 17#include <linux/list.h>
18 18
19#include <asm/alternative.h> 19#include <asm/alternative.h>
20#include <asm/ftrace.h>
20 21
21#define CALL_BACK 5
22 22
23/* Long is fine, even if it is only 4 bytes ;-) */ 23/* Long is fine, even if it is only 4 bytes ;-) */
24static long *ftrace_nop; 24static long *ftrace_nop;
25 25
26union ftrace_code_union { 26union ftrace_code_union {
27 char code[5]; 27 char code[MCOUNT_INSN_SIZE];
28 struct { 28 struct {
29 char e8; 29 char e8;
30 int offset; 30 int offset;
31 } __attribute__((packed)); 31 } __attribute__((packed));
32}; 32};
33 33
34
34static int notrace ftrace_calc_offset(long ip, long addr) 35static int notrace ftrace_calc_offset(long ip, long addr)
35{ 36{
36 return (int)(addr - ip); 37 return (int)(addr - ip);
@@ -46,7 +47,7 @@ notrace unsigned char *ftrace_call_replace(unsigned long ip, unsigned long addr)
46 static union ftrace_code_union calc; 47 static union ftrace_code_union calc;
47 48
48 calc.e8 = 0xe8; 49 calc.e8 = 0xe8;
49 calc.offset = ftrace_calc_offset(ip, addr); 50 calc.offset = ftrace_calc_offset(ip + MCOUNT_INSN_SIZE, addr);
50 51
51 /* 52 /*
52 * No locking needed, this must be called via kstop_machine 53 * No locking needed, this must be called via kstop_machine
@@ -65,9 +66,6 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
65 unsigned char newch = new_code[4]; 66 unsigned char newch = new_code[4];
66 int faulted = 0; 67 int faulted = 0;
67 68
68 /* move the IP back to the start of the call */
69 ip -= CALL_BACK;
70
71 /* 69 /*
72 * Note: Due to modules and __init, code can 70 * Note: Due to modules and __init, code can
73 * disappear and change, we need to protect against faulting 71 * disappear and change, we need to protect against faulting
@@ -102,12 +100,10 @@ ftrace_modify_code(unsigned long ip, unsigned char *old_code,
102notrace int ftrace_update_ftrace_func(ftrace_func_t func) 100notrace int ftrace_update_ftrace_func(ftrace_func_t func)
103{ 101{
104 unsigned long ip = (unsigned long)(&ftrace_call); 102 unsigned long ip = (unsigned long)(&ftrace_call);
105 unsigned char old[5], *new; 103 unsigned char old[MCOUNT_INSN_SIZE], *new;
106 int ret; 104 int ret;
107 105
108 ip += CALL_BACK; 106 memcpy(old, &ftrace_call, MCOUNT_INSN_SIZE);
109
110 memcpy(old, &ftrace_call, 5);
111 new = ftrace_call_replace(ip, (unsigned long)func); 107 new = ftrace_call_replace(ip, (unsigned long)func);
112 ret = ftrace_modify_code(ip, old, new); 108 ret = ftrace_modify_code(ip, old, new);
113 109
@@ -118,16 +114,13 @@ notrace int ftrace_mcount_set(unsigned long *data)
118{ 114{
119 unsigned long ip = (long)(&mcount_call); 115 unsigned long ip = (long)(&mcount_call);
120 unsigned long *addr = data; 116 unsigned long *addr = data;
121 unsigned char old[5], *new; 117 unsigned char old[MCOUNT_INSN_SIZE], *new;
122
123 /* ip is at the location, but modify code will subtact this */
124 ip += CALL_BACK;
125 118
126 /* 119 /*
127 * Replace the mcount stub with a pointer to the 120 * Replace the mcount stub with a pointer to the
128 * ip recorder function. 121 * ip recorder function.
129 */ 122 */
130 memcpy(old, &mcount_call, 5); 123 memcpy(old, &mcount_call, MCOUNT_INSN_SIZE);
131 new = ftrace_call_replace(ip, *addr); 124 new = ftrace_call_replace(ip, *addr);
132 *addr = ftrace_modify_code(ip, old, new); 125 *addr = ftrace_modify_code(ip, old, new);
133 126
@@ -142,8 +135,7 @@ int __init ftrace_dyn_arch_init(void *data)
142 135
143 ftrace_mcount_set(data); 136 ftrace_mcount_set(data);
144 137
145 ftrace_nop = (unsigned long *)noptable[CALL_BACK]; 138 ftrace_nop = (unsigned long *)noptable[MCOUNT_INSN_SIZE];
146 139
147 return 0; 140 return 0;
148} 141}
149