diff options
author | Abhishek Sagar <sagar.abhishek@gmail.com> | 2008-06-21 14:17:27 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-06-23 16:10:56 -0400 |
commit | 395a59d0f8e86bb39cd700c3d185d30c670bb958 (patch) | |
tree | 1558e635efcede901c5dbe9acd625d475db5b369 /arch/x86/kernel | |
parent | f34bfb1beef8a17ba3d46b60f8fa19ffedc1ed8d (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')
-rw-r--r-- | arch/x86/kernel/entry_32.S | 4 | ||||
-rw-r--r-- | arch/x86/kernel/entry_64.S | 4 | ||||
-rw-r--r-- | arch/x86/kernel/ftrace.c | 26 | ||||
-rw-r--r-- | arch/x86/kernel/i386_ksyms_32.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/x8664_ksyms_64.c | 2 |
5 files changed, 19 insertions, 19 deletions
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S index 04ea83ccb979..95e6bbe3665e 100644 --- a/arch/x86/kernel/entry_32.S +++ b/arch/x86/kernel/entry_32.S | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <asm/percpu.h> | 51 | #include <asm/percpu.h> |
52 | #include <asm/dwarf2.h> | 52 | #include <asm/dwarf2.h> |
53 | #include <asm/processor-flags.h> | 53 | #include <asm/processor-flags.h> |
54 | #include <asm/ftrace.h> | ||
54 | #include "irq_vectors.h" | 55 | #include "irq_vectors.h" |
55 | 56 | ||
56 | /* | 57 | /* |
@@ -1118,6 +1119,7 @@ ENTRY(mcount) | |||
1118 | pushl %ecx | 1119 | pushl %ecx |
1119 | pushl %edx | 1120 | pushl %edx |
1120 | movl 0xc(%esp), %eax | 1121 | movl 0xc(%esp), %eax |
1122 | subl $MCOUNT_INSN_SIZE, %eax | ||
1121 | 1123 | ||
1122 | .globl mcount_call | 1124 | .globl mcount_call |
1123 | mcount_call: | 1125 | mcount_call: |
@@ -1136,6 +1138,7 @@ ENTRY(ftrace_caller) | |||
1136 | pushl %edx | 1138 | pushl %edx |
1137 | movl 0xc(%esp), %eax | 1139 | movl 0xc(%esp), %eax |
1138 | movl 0x4(%ebp), %edx | 1140 | movl 0x4(%ebp), %edx |
1141 | subl $MCOUNT_INSN_SIZE, %eax | ||
1139 | 1142 | ||
1140 | .globl ftrace_call | 1143 | .globl ftrace_call |
1141 | ftrace_call: | 1144 | ftrace_call: |
@@ -1166,6 +1169,7 @@ trace: | |||
1166 | pushl %edx | 1169 | pushl %edx |
1167 | movl 0xc(%esp), %eax | 1170 | movl 0xc(%esp), %eax |
1168 | movl 0x4(%ebp), %edx | 1171 | movl 0x4(%ebp), %edx |
1172 | subl $MCOUNT_INSN_SIZE, %eax | ||
1169 | 1173 | ||
1170 | call *ftrace_trace_function | 1174 | call *ftrace_trace_function |
1171 | 1175 | ||
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index fe25e5febca3..b0f7308f78a6 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -51,6 +51,7 @@ | |||
51 | #include <asm/page.h> | 51 | #include <asm/page.h> |
52 | #include <asm/irqflags.h> | 52 | #include <asm/irqflags.h> |
53 | #include <asm/paravirt.h> | 53 | #include <asm/paravirt.h> |
54 | #include <asm/ftrace.h> | ||
54 | 55 | ||
55 | .code64 | 56 | .code64 |
56 | 57 | ||
@@ -68,6 +69,7 @@ ENTRY(mcount) | |||
68 | movq %r9, 48(%rsp) | 69 | movq %r9, 48(%rsp) |
69 | 70 | ||
70 | movq 0x38(%rsp), %rdi | 71 | movq 0x38(%rsp), %rdi |
72 | subq $MCOUNT_INSN_SIZE, %rdi | ||
71 | 73 | ||
72 | .globl mcount_call | 74 | .globl mcount_call |
73 | mcount_call: | 75 | mcount_call: |
@@ -99,6 +101,7 @@ ENTRY(ftrace_caller) | |||
99 | 101 | ||
100 | movq 0x38(%rsp), %rdi | 102 | movq 0x38(%rsp), %rdi |
101 | movq 8(%rbp), %rsi | 103 | movq 8(%rbp), %rsi |
104 | subq $MCOUNT_INSN_SIZE, %rdi | ||
102 | 105 | ||
103 | .globl ftrace_call | 106 | .globl ftrace_call |
104 | ftrace_call: | 107 | ftrace_call: |
@@ -139,6 +142,7 @@ trace: | |||
139 | 142 | ||
140 | movq 0x38(%rsp), %rdi | 143 | movq 0x38(%rsp), %rdi |
141 | movq 8(%rbp), %rsi | 144 | movq 8(%rbp), %rsi |
145 | subq $MCOUNT_INSN_SIZE, %rdi | ||
142 | 146 | ||
143 | call *ftrace_trace_function | 147 | call *ftrace_trace_function |
144 | 148 | ||
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 ;-) */ |
24 | static long *ftrace_nop; | 24 | static long *ftrace_nop; |
25 | 25 | ||
26 | union ftrace_code_union { | 26 | union 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 | |||
34 | static int notrace ftrace_calc_offset(long ip, long addr) | 35 | static 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, | |||
102 | notrace int ftrace_update_ftrace_func(ftrace_func_t func) | 100 | notrace 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 | |||
diff --git a/arch/x86/kernel/i386_ksyms_32.c b/arch/x86/kernel/i386_ksyms_32.c index 29999dbb754c..dd7ebee446af 100644 --- a/arch/x86/kernel/i386_ksyms_32.c +++ b/arch/x86/kernel/i386_ksyms_32.c | |||
@@ -1,9 +1,9 @@ | |||
1 | #include <linux/ftrace.h> | ||
2 | #include <linux/module.h> | 1 | #include <linux/module.h> |
3 | 2 | ||
4 | #include <asm/checksum.h> | 3 | #include <asm/checksum.h> |
5 | #include <asm/pgtable.h> | 4 | #include <asm/pgtable.h> |
6 | #include <asm/desc.h> | 5 | #include <asm/desc.h> |
6 | #include <asm/ftrace.h> | ||
7 | 7 | ||
8 | #ifdef CONFIG_FTRACE | 8 | #ifdef CONFIG_FTRACE |
9 | /* mcount is defined in assembly */ | 9 | /* mcount is defined in assembly */ |
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c index 122885bc5f3b..16ff4bf418d9 100644 --- a/arch/x86/kernel/x8664_ksyms_64.c +++ b/arch/x86/kernel/x8664_ksyms_64.c | |||
@@ -1,7 +1,6 @@ | |||
1 | /* Exports for assembly files. | 1 | /* Exports for assembly files. |
2 | All C exports should go in the respective C files. */ | 2 | All C exports should go in the respective C files. */ |
3 | 3 | ||
4 | #include <linux/ftrace.h> | ||
5 | #include <linux/module.h> | 4 | #include <linux/module.h> |
6 | #include <linux/smp.h> | 5 | #include <linux/smp.h> |
7 | 6 | ||
@@ -11,6 +10,7 @@ | |||
11 | #include <asm/pgtable.h> | 10 | #include <asm/pgtable.h> |
12 | #include <asm/uaccess.h> | 11 | #include <asm/uaccess.h> |
13 | #include <asm/desc.h> | 12 | #include <asm/desc.h> |
13 | #include <asm/ftrace.h> | ||
14 | 14 | ||
15 | #ifdef CONFIG_FTRACE | 15 | #ifdef CONFIG_FTRACE |
16 | /* mcount is defined in assembly */ | 16 | /* mcount is defined in assembly */ |