aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Rostedt (Red Hat) <rostedt@goodmis.org>2014-11-24 18:08:48 -0500
committerSteven Rostedt <rostedt@goodmis.org>2014-12-01 14:08:27 -0500
commit0687c36e456ca81feff5f3415e53c1cb8d8efd56 (patch)
tree347410628424a2c146e00932b6f8d0a3bbbcb823
parent85f6f0290c4d4667a5afb06e66815bcf5ce2c4f7 (diff)
ftrace/x86: Have save_mcount_regs macro also save stack frames if needed
The save_mcount_regs macro saves and restores the required mcount regs that need to be saved before calling C code. It is done for all the function hook utilities (static tracing, dynamic tracing, regs, function graph). When frame pointers are enabled, the ftrace trampolines need to set up frames and pointers such that a back trace (dump stack) can continue passed them. Currently, a separate macro is used (create_frame) to do this, but it's only done for the ftrace_caller and ftrace_reg_caller functions. It is not done for the static tracer or function graph tracing. Instead of having a separate macro doing the recording of the frames, have the save_mcount_regs perform this task. This also has all tracers saving the frame pointers when needed. Link: http://lkml.kernel.org/r/CA+55aFwF+qCGSKdGaEgW4p6N65GZ5_XTV=1NbtWDvxnd5yYLiw@mail.gmail.com Link: http://lkml.kernel.org/r/alpine.DEB.2.11.1411262304010.3961@nanos Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
-rw-r--r--arch/x86/kernel/mcount_64.S118
1 files changed, 67 insertions, 51 deletions
diff --git a/arch/x86/kernel/mcount_64.S b/arch/x86/kernel/mcount_64.S
index a0f6f942183a..003b22df1d87 100644
--- a/arch/x86/kernel/mcount_64.S
+++ b/arch/x86/kernel/mcount_64.S
@@ -21,8 +21,22 @@
21# define function_hook mcount 21# define function_hook mcount
22#endif 22#endif
23 23
24/* All cases save the original rbp (8 bytes) */
25#ifdef CONFIG_FRAME_POINTER
26# ifdef CC_USING_FENTRY
27/* Save parent and function stack frames (rip and rbp) */
28# define MCOUNT_FRAME_SIZE (8+16*2)
29# else
30/* Save just function stack frame (rip and rbp) */
31# define MCOUNT_FRAME_SIZE (8+16)
32# endif
33#else
34/* No need to save a stack frame */
35# define MCOUNT_FRAME_SIZE 8
36#endif /* CONFIG_FRAME_POINTER */
37
24/* Size of stack used to save mcount regs in save_mcount_regs */ 38/* Size of stack used to save mcount regs in save_mcount_regs */
25#define MCOUNT_REG_SIZE (SS+8) 39#define MCOUNT_REG_SIZE (SS+8 + MCOUNT_FRAME_SIZE)
26 40
27/* 41/*
28 * gcc -pg option adds a call to 'mcount' in most functions. 42 * gcc -pg option adds a call to 'mcount' in most functions.
@@ -42,10 +56,37 @@
42 56
43/* @added: the amount of stack added before calling this */ 57/* @added: the amount of stack added before calling this */
44.macro save_mcount_regs added=0 58.macro save_mcount_regs added=0
45 /* 59
46 * We add enough stack to save all regs. 60 /* Always save the original rbp */
47 */ 61 pushq %rbp
48 subq $MCOUNT_REG_SIZE, %rsp 62
63#ifdef CONFIG_FRAME_POINTER
64 /*
65 * Stack traces will stop at the ftrace trampoline if the frame pointer
66 * is not set up properly. If fentry is used, we need to save a frame
67 * pointer for the parent as well as the function traced, because the
68 * fentry is called before the stack frame is set up, where as mcount
69 * is called afterward.
70 */
71#ifdef CC_USING_FENTRY
72 /* Save the parent pointer (skip orig rbp and our return address) */
73 pushq \added+8*2(%rsp)
74 pushq %rbp
75 movq %rsp, %rbp
76 /* Save the return address (now skip orig rbp, rbp and parent) */
77 pushq \added+8*3(%rsp)
78#else
79 /* Can't assume that rip is before this (unless added was zero) */
80 pushq \added+8(%rsp)
81#endif
82 pushq %rbp
83 movq %rsp, %rbp
84#endif /* CONFIG_FRAME_POINTER */
85
86 /*
87 * We add enough stack to save all regs.
88 */
89 subq $(MCOUNT_REG_SIZE - MCOUNT_FRAME_SIZE), %rsp
49 movq %rax, RAX(%rsp) 90 movq %rax, RAX(%rsp)
50 movq %rcx, RCX(%rsp) 91 movq %rcx, RCX(%rsp)
51 movq %rdx, RDX(%rsp) 92 movq %rdx, RDX(%rsp)
@@ -53,6 +94,13 @@
53 movq %rdi, RDI(%rsp) 94 movq %rdi, RDI(%rsp)
54 movq %r8, R8(%rsp) 95 movq %r8, R8(%rsp)
55 movq %r9, R9(%rsp) 96 movq %r9, R9(%rsp)
97 /*
98 * Save the original RBP. Even though the mcount ABI does not
99 * require this, it helps out callers.
100 */
101 movq MCOUNT_REG_SIZE-8(%rsp), %rdx
102 movq %rdx, RBP(%rsp)
103
56 /* Move RIP to its proper location */ 104 /* Move RIP to its proper location */
57 movq MCOUNT_REG_SIZE+\added(%rsp), %rdi 105 movq MCOUNT_REG_SIZE+\added(%rsp), %rdi
58 movq %rdi, RIP(%rsp) 106 movq %rdi, RIP(%rsp)
@@ -66,7 +114,12 @@
66 movq RDX(%rsp), %rdx 114 movq RDX(%rsp), %rdx
67 movq RCX(%rsp), %rcx 115 movq RCX(%rsp), %rcx
68 movq RAX(%rsp), %rax 116 movq RAX(%rsp), %rax
117
118 /* ftrace_regs_caller can modify %rbp */
119 movq RBP(%rsp), %rbp
120
69 addq $MCOUNT_REG_SIZE, %rsp 121 addq $MCOUNT_REG_SIZE, %rsp
122
70 .endm 123 .endm
71 124
72/* skip is set if stack has been adjusted */ 125/* skip is set if stack has been adjusted */
@@ -84,7 +137,10 @@ GLOBAL(\trace_label)
84#ifdef CC_USING_FENTRY 137#ifdef CC_USING_FENTRY
85 movq MCOUNT_REG_SIZE+8+\added(%rsp), %rsi 138 movq MCOUNT_REG_SIZE+8+\added(%rsp), %rsi
86#else 139#else
87 movq 8+\added(%rbp), %rsi 140 /* Need to grab the original %rbp */
141 movq RBP(%rsp), %rsi
142 /* Now parent address is 8 above original %rbp */
143 movq 8(%rsi), %rsi
88#endif 144#endif
89.endm 145.endm
90 146
@@ -94,51 +150,14 @@ ENTRY(function_hook)
94 retq 150 retq
95END(function_hook) 151END(function_hook)
96 152
97#ifdef CONFIG_FRAME_POINTER
98/*
99 * Stack traces will stop at the ftrace trampoline if the frame pointer
100 * is not set up properly. If fentry is used, we need to save a frame
101 * pointer for the parent as well as the function traced, because the
102 * fentry is called before the stack frame is set up, where as mcount
103 * is called afterward.
104 */
105.macro create_frame parent rip
106#ifdef CC_USING_FENTRY
107 pushq \parent
108 pushq %rbp
109 movq %rsp, %rbp
110#endif
111 pushq \rip
112 pushq %rbp
113 movq %rsp, %rbp
114.endm
115
116.macro restore_frame
117#ifdef CC_USING_FENTRY
118 addq $16, %rsp
119#endif
120 popq %rbp
121 addq $8, %rsp
122.endm
123#else
124.macro create_frame parent rip
125.endm
126.macro restore_frame
127.endm
128#endif /* CONFIG_FRAME_POINTER */
129
130ENTRY(ftrace_caller) 153ENTRY(ftrace_caller)
131 ftrace_caller_setup ftrace_caller_op_ptr 154 ftrace_caller_setup ftrace_caller_op_ptr
132 /* regs go into 4th parameter (but make it NULL) */ 155 /* regs go into 4th parameter (but make it NULL) */
133 movq $0, %rcx 156 movq $0, %rcx
134 157
135 create_frame %rsi, %rdi
136
137GLOBAL(ftrace_call) 158GLOBAL(ftrace_call)
138 call ftrace_stub 159 call ftrace_stub
139 160
140 restore_frame
141
142 restore_mcount_regs 161 restore_mcount_regs
143 162
144 /* 163 /*
@@ -172,7 +191,6 @@ ENTRY(ftrace_regs_caller)
172 movq %r12, R12(%rsp) 191 movq %r12, R12(%rsp)
173 movq %r11, R11(%rsp) 192 movq %r11, R11(%rsp)
174 movq %r10, R10(%rsp) 193 movq %r10, R10(%rsp)
175 movq %rbp, RBP(%rsp)
176 movq %rbx, RBX(%rsp) 194 movq %rbx, RBX(%rsp)
177 /* Copy saved flags */ 195 /* Copy saved flags */
178 movq MCOUNT_REG_SIZE(%rsp), %rcx 196 movq MCOUNT_REG_SIZE(%rsp), %rcx
@@ -189,13 +207,9 @@ ENTRY(ftrace_regs_caller)
189 /* regs go into 4th parameter */ 207 /* regs go into 4th parameter */
190 leaq (%rsp), %rcx 208 leaq (%rsp), %rcx
191 209
192 create_frame %rsi, %rdi
193
194GLOBAL(ftrace_regs_call) 210GLOBAL(ftrace_regs_call)
195 call ftrace_stub 211 call ftrace_stub
196 212
197 restore_frame
198
199 /* Copy flags back to SS, to restore them */ 213 /* Copy flags back to SS, to restore them */
200 movq EFLAGS(%rsp), %rax 214 movq EFLAGS(%rsp), %rax
201 movq %rax, MCOUNT_REG_SIZE(%rsp) 215 movq %rax, MCOUNT_REG_SIZE(%rsp)
@@ -210,7 +224,6 @@ GLOBAL(ftrace_regs_call)
210 movq R13(%rsp), %r13 224 movq R13(%rsp), %r13
211 movq R12(%rsp), %r12 225 movq R12(%rsp), %r12
212 movq R10(%rsp), %r10 226 movq R10(%rsp), %r10
213 movq RBP(%rsp), %rbp
214 movq RBX(%rsp), %rbx 227 movq RBX(%rsp), %rbx
215 228
216 restore_mcount_regs 229 restore_mcount_regs
@@ -269,8 +282,11 @@ ENTRY(ftrace_graph_caller)
269 leaq MCOUNT_REG_SIZE+8(%rsp), %rdi 282 leaq MCOUNT_REG_SIZE+8(%rsp), %rdi
270 movq $0, %rdx /* No framepointers needed */ 283 movq $0, %rdx /* No framepointers needed */
271#else 284#else
272 leaq 8(%rbp), %rdi 285 /* Need to grab the original %rbp */
273 movq (%rbp), %rdx 286 movq RBP(%rsp), %rdx
287 /* Now parent address is 8 above original %rbp */
288 leaq 8(%rdx), %rdi
289 movq (%rdx), %rdx
274#endif 290#endif
275 movq RIP(%rsp), %rsi 291 movq RIP(%rsp), %rsi
276 subq $MCOUNT_INSN_SIZE, %rsi 292 subq $MCOUNT_INSN_SIZE, %rsi