Skip to content

Commit ff04b44

Browse files
rostedtKAGA-KOKO
authored andcommitted
x86/ftrace: Clean up ftrace_regs_caller
When ftrace_regs_caller was created, it was designed to preserve flags as much as possible as it needed to act just like a breakpoint triggered on the same location. But the design is over complicated as it treated all operations as modifying flags. But push, mov and lea do not modify flags. This means the code can become more simplified by allowing flags to be stored further down. Making ftrace_regs_caller simpler will also be useful in implementing fentry logic. Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org> Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com> Reviewed-by: Ingo Molnar <mingo@kernel.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Andrew Morton <akpm@linux-foundation.org> Link: http://lkml.kernel.org/r/20170316135328.36123c3e@gandalf.local.home Link: http://lkml.kernel.org/r/20170323143445.917292592@goodmis.org Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
1 parent e6928e5 commit ff04b44

File tree

1 file changed

+21
-19
lines changed

1 file changed

+21
-19
lines changed

arch/x86/kernel/ftrace_32.S

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -54,35 +54,34 @@ WEAK(ftrace_stub)
5454
END(ftrace_caller)
5555

5656
ENTRY(ftrace_regs_caller)
57-
pushf /* push flags before compare (in cs location) */
58-
5957
/*
6058
* i386 does not save SS and ESP when coming from kernel.
6159
* Instead, to get sp, &regs->sp is used (see ptrace.h).
6260
* Unfortunately, that means eflags must be at the same location
6361
* as the current return ip is. We move the return ip into the
64-
* ip location, and move flags into the return ip location.
62+
* regs->ip location, and move flags into the return ip location.
6563
*/
66-
pushl 4(%esp) /* save return ip into ip slot */
67-
64+
pushl $__KERNEL_CS
65+
pushl 4(%esp) /* Save the return ip */
6866
pushl $0 /* Load 0 into orig_ax */
6967
pushl %gs
7068
pushl %fs
7169
pushl %es
7270
pushl %ds
7371
pushl %eax
72+
73+
/* Get flags and place them into the return ip slot */
74+
pushf
75+
popl %eax
76+
movl %eax, 8*4(%esp)
77+
7478
pushl %ebp
7579
pushl %edi
7680
pushl %esi
7781
pushl %edx
7882
pushl %ecx
7983
pushl %ebx
8084

81-
movl 13*4(%esp), %eax /* Get the saved flags */
82-
movl %eax, 14*4(%esp) /* Move saved flags into regs->flags location */
83-
/* clobbering return ip */
84-
movl $__KERNEL_CS, 13*4(%esp)
85-
8685
movl 12*4(%esp), %eax /* Load ip (1st parameter) */
8786
subl $MCOUNT_INSN_SIZE, %eax /* Adjust ip */
8887
movl 0x4(%ebp), %edx /* Load parent ip (2nd parameter) */
@@ -93,10 +92,14 @@ GLOBAL(ftrace_regs_call)
9392
call ftrace_stub
9493

9594
addl $4, %esp /* Skip pt_regs */
96-
movl 14*4(%esp), %eax /* Move flags back into cs */
97-
movl %eax, 13*4(%esp) /* Needed to keep addl from modifying flags */
98-
movl 12*4(%esp), %eax /* Get return ip from regs->ip */
99-
movl %eax, 14*4(%esp) /* Put return ip back for ret */
95+
96+
/* restore flags */
97+
push 14*4(%esp)
98+
popf
99+
100+
/* Move return ip back to its original location */
101+
movl 12*4(%esp), %eax
102+
movl %eax, 14*4(%esp)
100103

101104
popl %ebx
102105
popl %ecx
@@ -109,12 +112,11 @@ GLOBAL(ftrace_regs_call)
109112
popl %es
110113
popl %fs
111114
popl %gs
112-
addl $8, %esp /* Skip orig_ax and ip */
113-
popf /* Pop flags at end (no addl to corrupt flags) */
114-
jmp .Lftrace_ret
115115

116-
popf
117-
jmp ftrace_stub
116+
/* use lea to not affect flags */
117+
lea 3*4(%esp), %esp /* Skip orig_ax, ip and cs */
118+
119+
jmp .Lftrace_ret
118120
#else /* ! CONFIG_DYNAMIC_FTRACE */
119121

120122
ENTRY(mcount)

0 commit comments

Comments
 (0)