aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@redhat.com>2018-01-22 23:07:46 -0500
committerSteven Rostedt (VMware) <rostedt@goodmis.org>2018-01-23 13:24:19 -0500
commite2ac83d74a4d753cea88407e65136c84a0cb60b2 (patch)
tree2ccc7c642996b201c6f4f6e908a05879f695ac82
parent0c5b9b5d9adbad4b60491f9ba0d2af38904bb4b9 (diff)
x86/ftrace: Fix ORC unwinding from ftrace handlers
Steven Rostedt discovered that the ftrace stack tracer is broken when it's used with the ORC unwinder. The problem is that objtool is instructed by the Makefile to ignore the ftrace_64.S code, so it doesn't generate any ORC data for it. Fix it by making the asm code objtool-friendly: - Objtool doesn't like the fact that save_mcount_regs pushes RBP at the beginning, but it's never restored (directly, at least). So just skip the original RBP push, which is only needed for frame pointers anyway. - Annotate some functions as normal callable functions with ENTRY/ENDPROC. - Add an empty unwind hint to return_to_handler(). The return address isn't on the stack, so there's nothing ORC can do there. It will just punt in the unlikely case it tries to unwind from that code. With all that fixed, remove the OBJECT_FILES_NON_STANDARD Makefile annotation so objtool can read the file. Link: http://lkml.kernel.org/r/20180123040746.ih4ep3tk4pbjvg7c@treble Reported-by: Steven Rostedt <rostedt@goodmis.org> Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
-rw-r--r--arch/x86/kernel/Makefile5
-rw-r--r--arch/x86/kernel/ftrace_64.S24
2 files changed, 19 insertions, 10 deletions
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 81bb565f4497..7e2baf7304ae 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -29,10 +29,13 @@ KASAN_SANITIZE_stacktrace.o := n
29KASAN_SANITIZE_paravirt.o := n 29KASAN_SANITIZE_paravirt.o := n
30 30
31OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y 31OBJECT_FILES_NON_STANDARD_relocate_kernel_$(BITS).o := y
32OBJECT_FILES_NON_STANDARD_ftrace_$(BITS).o := y
33OBJECT_FILES_NON_STANDARD_test_nx.o := y 32OBJECT_FILES_NON_STANDARD_test_nx.o := y
34OBJECT_FILES_NON_STANDARD_paravirt_patch_$(BITS).o := y 33OBJECT_FILES_NON_STANDARD_paravirt_patch_$(BITS).o := y
35 34
35ifdef CONFIG_FRAME_POINTER
36OBJECT_FILES_NON_STANDARD_ftrace_$(BITS).o := y
37endif
38
36# If instrumentation of this dir is enabled, boot hangs during first second. 39# If instrumentation of this dir is enabled, boot hangs during first second.
37# Probably could be more selective here, but note that files related to irqs, 40# Probably could be more selective here, but note that files related to irqs,
38# boot, dumpstack/stacktrace, etc are either non-interesting or can lead to 41# boot, dumpstack/stacktrace, etc are either non-interesting or can lead to
diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S
index 7cb8ba08beb9..ef61f540cf0a 100644
--- a/arch/x86/kernel/ftrace_64.S
+++ b/arch/x86/kernel/ftrace_64.S
@@ -8,6 +8,7 @@
8#include <asm/ftrace.h> 8#include <asm/ftrace.h>
9#include <asm/export.h> 9#include <asm/export.h>
10#include <asm/nospec-branch.h> 10#include <asm/nospec-branch.h>
11#include <asm/unwind_hints.h>
11 12
12 .code64 13 .code64
13 .section .entry.text, "ax" 14 .section .entry.text, "ax"
@@ -20,7 +21,6 @@ EXPORT_SYMBOL(__fentry__)
20EXPORT_SYMBOL(mcount) 21EXPORT_SYMBOL(mcount)
21#endif 22#endif
22 23
23/* All cases save the original rbp (8 bytes) */
24#ifdef CONFIG_FRAME_POINTER 24#ifdef CONFIG_FRAME_POINTER
25# ifdef CC_USING_FENTRY 25# ifdef CC_USING_FENTRY
26/* Save parent and function stack frames (rip and rbp) */ 26/* Save parent and function stack frames (rip and rbp) */
@@ -31,7 +31,7 @@ EXPORT_SYMBOL(mcount)
31# endif 31# endif
32#else 32#else
33/* No need to save a stack frame */ 33/* No need to save a stack frame */
34# define MCOUNT_FRAME_SIZE 8 34# define MCOUNT_FRAME_SIZE 0
35#endif /* CONFIG_FRAME_POINTER */ 35#endif /* CONFIG_FRAME_POINTER */
36 36
37/* Size of stack used to save mcount regs in save_mcount_regs */ 37/* Size of stack used to save mcount regs in save_mcount_regs */
@@ -64,10 +64,10 @@ EXPORT_SYMBOL(mcount)
64 */ 64 */
65.macro save_mcount_regs added=0 65.macro save_mcount_regs added=0
66 66
67 /* Always save the original rbp */ 67#ifdef CONFIG_FRAME_POINTER
68 /* Save the original rbp */
68 pushq %rbp 69 pushq %rbp
69 70
70#ifdef CONFIG_FRAME_POINTER
71 /* 71 /*
72 * Stack traces will stop at the ftrace trampoline if the frame pointer 72 * Stack traces will stop at the ftrace trampoline if the frame pointer
73 * is not set up properly. If fentry is used, we need to save a frame 73 * is not set up properly. If fentry is used, we need to save a frame
@@ -105,7 +105,11 @@ EXPORT_SYMBOL(mcount)
105 * Save the original RBP. Even though the mcount ABI does not 105 * Save the original RBP. Even though the mcount ABI does not
106 * require this, it helps out callers. 106 * require this, it helps out callers.
107 */ 107 */
108#ifdef CONFIG_FRAME_POINTER
108 movq MCOUNT_REG_SIZE-8(%rsp), %rdx 109 movq MCOUNT_REG_SIZE-8(%rsp), %rdx
110#else
111 movq %rbp, %rdx
112#endif
109 movq %rdx, RBP(%rsp) 113 movq %rdx, RBP(%rsp)
110 114
111 /* Copy the parent address into %rsi (second parameter) */ 115 /* Copy the parent address into %rsi (second parameter) */
@@ -148,7 +152,7 @@ EXPORT_SYMBOL(mcount)
148 152
149ENTRY(function_hook) 153ENTRY(function_hook)
150 retq 154 retq
151END(function_hook) 155ENDPROC(function_hook)
152 156
153ENTRY(ftrace_caller) 157ENTRY(ftrace_caller)
154 /* save_mcount_regs fills in first two parameters */ 158 /* save_mcount_regs fills in first two parameters */
@@ -184,7 +188,7 @@ GLOBAL(ftrace_graph_call)
184/* This is weak to keep gas from relaxing the jumps */ 188/* This is weak to keep gas from relaxing the jumps */
185WEAK(ftrace_stub) 189WEAK(ftrace_stub)
186 retq 190 retq
187END(ftrace_caller) 191ENDPROC(ftrace_caller)
188 192
189ENTRY(ftrace_regs_caller) 193ENTRY(ftrace_regs_caller)
190 /* Save the current flags before any operations that can change them */ 194 /* Save the current flags before any operations that can change them */
@@ -255,7 +259,7 @@ GLOBAL(ftrace_regs_caller_end)
255 259
256 jmp ftrace_epilogue 260 jmp ftrace_epilogue
257 261
258END(ftrace_regs_caller) 262ENDPROC(ftrace_regs_caller)
259 263
260 264
261#else /* ! CONFIG_DYNAMIC_FTRACE */ 265#else /* ! CONFIG_DYNAMIC_FTRACE */
@@ -313,9 +317,10 @@ ENTRY(ftrace_graph_caller)
313 restore_mcount_regs 317 restore_mcount_regs
314 318
315 retq 319 retq
316END(ftrace_graph_caller) 320ENDPROC(ftrace_graph_caller)
317 321
318GLOBAL(return_to_handler) 322ENTRY(return_to_handler)
323 UNWIND_HINT_EMPTY
319 subq $24, %rsp 324 subq $24, %rsp
320 325
321 /* Save the return values */ 326 /* Save the return values */
@@ -330,4 +335,5 @@ GLOBAL(return_to_handler)
330 movq (%rsp), %rax 335 movq (%rsp), %rax
331 addq $24, %rsp 336 addq $24, %rsp
332 JMP_NOSPEC %rdi 337 JMP_NOSPEC %rdi
338END(return_to_handler)
333#endif 339#endif