aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-02-09 13:32:18 -0500
committerSteven Rostedt <rostedt@goodmis.org>2012-08-23 11:26:36 -0400
commitd57c5d51a30152f3175d2344cb6395f08bf8ee0c (patch)
tree50b33f8eeb945d759ef79992b73428da14f2f1ec
parent781d06248234e221edb560a18461d65808a8a942 (diff)
ftrace/x86: Add support for -mfentry to x86_64
If the kernel is compiled with gcc 4.6.0 which supports -mfentry, then use that instead of mcount. With mcount, frame pointers are forced with the -pg option and we get something like: <can_vma_merge_before>: 55 push %rbp 48 89 e5 mov %rsp,%rbp 53 push %rbx 41 51 push %r9 e8 fe 6a 39 00 callq ffffffff81483d00 <mcount> 31 c0 xor %eax,%eax 48 89 fb mov %rdi,%rbx 48 89 d7 mov %rdx,%rdi 48 33 73 30 xor 0x30(%rbx),%rsi 48 f7 c6 ff ff ff f7 test $0xfffffffff7ffffff,%rsi With -mfentry, frame pointers are no longer forced and the call looks like this: <can_vma_merge_before>: e8 33 af 37 00 callq ffffffff81461b40 <__fentry__> 53 push %rbx 48 89 fb mov %rdi,%rbx 31 c0 xor %eax,%eax 48 89 d7 mov %rdx,%rdi 41 51 push %r9 48 33 73 30 xor 0x30(%rbx),%rsi 48 f7 c6 ff ff ff f7 test $0xfffffffff7ffffff,%rsi This adds the ftrace hook at the beginning of the function before a frame is set up, and allows the function callbacks to be able to access parameters. As kprobes now can use function tracing (at least on x86) this speeds up the kprobe hooks that are at the beginning of the function. Link: http://lkml.kernel.org/r/20120807194100.130477900@goodmis.org Acked-by: Ingo Molnar <mingo@kernel.org> Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Andi Kleen <andi@firstfloor.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--arch/x86/Kconfig1
-rw-r--r--arch/x86/include/asm/ftrace.h7
-rw-r--r--arch/x86/kernel/entry_64.S32
-rw-r--r--arch/x86/kernel/x8664_ksyms_64.c6
4 files changed, 39 insertions, 7 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index a2d19ee750ca..28dd891a0a16 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -36,6 +36,7 @@ config X86
36 select HAVE_KRETPROBES 36 select HAVE_KRETPROBES
37 select HAVE_OPTPROBES 37 select HAVE_OPTPROBES
38 select HAVE_FTRACE_MCOUNT_RECORD 38 select HAVE_FTRACE_MCOUNT_RECORD
39 select HAVE_FENTRY if X86_64
39 select HAVE_C_RECORDMCOUNT 40 select HAVE_C_RECORDMCOUNT
40 select HAVE_DYNAMIC_FTRACE 41 select HAVE_DYNAMIC_FTRACE
41 select HAVE_FUNCTION_TRACER 42 select HAVE_FUNCTION_TRACER
diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h
index a6cae0c1720c..9a25b522d377 100644
--- a/arch/x86/include/asm/ftrace.h
+++ b/arch/x86/include/asm/ftrace.h
@@ -35,7 +35,11 @@
35#endif 35#endif
36 36
37#ifdef CONFIG_FUNCTION_TRACER 37#ifdef CONFIG_FUNCTION_TRACER
38#define MCOUNT_ADDR ((long)(mcount)) 38#ifdef CC_USING_FENTRY
39# define MCOUNT_ADDR ((long)(__fentry__))
40#else
41# define MCOUNT_ADDR ((long)(mcount))
42#endif
39#define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */ 43#define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */
40 44
41#ifdef CONFIG_DYNAMIC_FTRACE 45#ifdef CONFIG_DYNAMIC_FTRACE
@@ -46,6 +50,7 @@
46#ifndef __ASSEMBLY__ 50#ifndef __ASSEMBLY__
47extern void mcount(void); 51extern void mcount(void);
48extern atomic_t modifying_ftrace_code; 52extern atomic_t modifying_ftrace_code;
53extern void __fentry__(void);
49 54
50static inline unsigned long ftrace_call_adjust(unsigned long addr) 55static inline unsigned long ftrace_call_adjust(unsigned long addr)
51{ 56{
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index b7a81dcb7366..ed767b747fe5 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -68,10 +68,18 @@
68 .section .entry.text, "ax" 68 .section .entry.text, "ax"
69 69
70#ifdef CONFIG_FUNCTION_TRACER 70#ifdef CONFIG_FUNCTION_TRACER
71
72#ifdef CC_USING_FENTRY
73# define function_hook __fentry__
74#else
75# define function_hook mcount
76#endif
77
71#ifdef CONFIG_DYNAMIC_FTRACE 78#ifdef CONFIG_DYNAMIC_FTRACE
72ENTRY(mcount) 79
80ENTRY(function_hook)
73 retq 81 retq
74END(mcount) 82END(function_hook)
75 83
76/* skip is set if stack has been adjusted */ 84/* skip is set if stack has been adjusted */
77.macro ftrace_caller_setup skip=0 85.macro ftrace_caller_setup skip=0
@@ -84,7 +92,11 @@ END(mcount)
84 movq RIP(%rsp), %rdi 92 movq RIP(%rsp), %rdi
85 subq $MCOUNT_INSN_SIZE, %rdi 93 subq $MCOUNT_INSN_SIZE, %rdi
86 /* Load the parent_ip into the second parameter */ 94 /* Load the parent_ip into the second parameter */
95#ifdef CC_USING_FENTRY
96 movq SS+16(%rsp), %rsi
97#else
87 movq 8(%rbp), %rsi 98 movq 8(%rbp), %rsi
99#endif
88.endm 100.endm
89 101
90ENTRY(ftrace_caller) 102ENTRY(ftrace_caller)
@@ -177,7 +189,8 @@ END(ftrace_regs_caller)
177 189
178 190
179#else /* ! CONFIG_DYNAMIC_FTRACE */ 191#else /* ! CONFIG_DYNAMIC_FTRACE */
180ENTRY(mcount) 192
193ENTRY(function_hook)
181 cmpl $0, function_trace_stop 194 cmpl $0, function_trace_stop
182 jne ftrace_stub 195 jne ftrace_stub
183 196
@@ -199,7 +212,11 @@ trace:
199 MCOUNT_SAVE_FRAME 212 MCOUNT_SAVE_FRAME
200 213
201 movq RIP(%rsp), %rdi 214 movq RIP(%rsp), %rdi
215#ifdef CC_USING_FENTRY
216 movq SS+16(%rsp), %rsi
217#else
202 movq 8(%rbp), %rsi 218 movq 8(%rbp), %rsi
219#endif
203 subq $MCOUNT_INSN_SIZE, %rdi 220 subq $MCOUNT_INSN_SIZE, %rdi
204 221
205 call *ftrace_trace_function 222 call *ftrace_trace_function
@@ -207,7 +224,7 @@ trace:
207 MCOUNT_RESTORE_FRAME 224 MCOUNT_RESTORE_FRAME
208 225
209 jmp ftrace_stub 226 jmp ftrace_stub
210END(mcount) 227END(function_hook)
211#endif /* CONFIG_DYNAMIC_FTRACE */ 228#endif /* CONFIG_DYNAMIC_FTRACE */
212#endif /* CONFIG_FUNCTION_TRACER */ 229#endif /* CONFIG_FUNCTION_TRACER */
213 230
@@ -215,9 +232,14 @@ END(mcount)
215ENTRY(ftrace_graph_caller) 232ENTRY(ftrace_graph_caller)
216 MCOUNT_SAVE_FRAME 233 MCOUNT_SAVE_FRAME
217 234
235#ifdef CC_USING_FENTRY
236 leaq SS+16(%rsp), %rdi
237 movq $0, %rdx /* No framepointers needed */
238#else
218 leaq 8(%rbp), %rdi 239 leaq 8(%rbp), %rdi
219 movq RIP(%rsp), %rsi
220 movq (%rbp), %rdx 240 movq (%rbp), %rdx
241#endif
242 movq RIP(%rsp), %rsi
221 subq $MCOUNT_INSN_SIZE, %rsi 243 subq $MCOUNT_INSN_SIZE, %rsi
222 244
223 call prepare_ftrace_return 245 call prepare_ftrace_return
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
index 6020f6f5927c..1330dd102950 100644
--- a/arch/x86/kernel/x8664_ksyms_64.c
+++ b/arch/x86/kernel/x8664_ksyms_64.c
@@ -13,9 +13,13 @@
13#include <asm/ftrace.h> 13#include <asm/ftrace.h>
14 14
15#ifdef CONFIG_FUNCTION_TRACER 15#ifdef CONFIG_FUNCTION_TRACER
16/* mcount is defined in assembly */ 16/* mcount and __fentry__ are defined in assembly */
17#ifdef CC_USING_FENTRY
18EXPORT_SYMBOL(__fentry__);
19#else
17EXPORT_SYMBOL(mcount); 20EXPORT_SYMBOL(mcount);
18#endif 21#endif
22#endif
19 23
20EXPORT_SYMBOL(__get_user_1); 24EXPORT_SYMBOL(__get_user_1);
21EXPORT_SYMBOL(__get_user_2); 25EXPORT_SYMBOL(__get_user_2);