Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1603863 > unrolled thread

[PATCH 4/6 v3] ftrace/x86_32: Clean up ftrace_regs_caller

Started bySteven Rostedt <rostedt@goodmis.org>
First post2017-03-18 22:20 +0100
Last post2017-03-20 15:30 +0100
Articles 2 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH 4/6 v3] ftrace/x86_32: Clean up ftrace_regs_caller Steven Rostedt <rostedt@goodmis.org> - 2017-03-18 22:20 +0100
    Re: [PATCH 4/6 v3] ftrace/x86_32: Clean up ftrace_regs_caller Josh Poimboeuf <jpoimboe@redhat.com> - 2017-03-20 15:30 +0100

#1603863 — [PATCH 4/6 v3] ftrace/x86_32: Clean up ftrace_regs_caller

FromSteven Rostedt <rostedt@goodmis.org>
Date2017-03-18 22:20 +0100
Subject[PATCH 4/6 v3] ftrace/x86_32: Clean up ftrace_regs_caller
Message-ID<tmtVv-3Pb-5@gated-at.bofh.it>
From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

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.

Link: http://lkml.kernel.org/r/20170316135328.36123c3e@gandalf.local.home
[ simpler logic to save flags ]
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 arch/x86/kernel/ftrace_32.S | 40 +++++++++++++++++++++-------------------
 1 file changed, 21 insertions(+), 19 deletions(-)

diff --git a/arch/x86/kernel/ftrace_32.S b/arch/x86/kernel/ftrace_32.S
index f991e723c3e4..7cd27cf56578 100644
--- a/arch/x86/kernel/ftrace_32.S
+++ b/arch/x86/kernel/ftrace_32.S
@@ -56,23 +56,27 @@ WEAK(ftrace_stub)
 END(ftrace_caller)
 
 ENTRY(ftrace_regs_caller)
-	pushf	/* push flags before compare (in cs location) */
-
 	/*
 	 * i386 does not save SS and ESP when coming from kernel.
 	 * Instead, to get sp, &regs->sp is used (see ptrace.h).
 	 * Unfortunately, that means eflags must be at the same location
 	 * as the current return ip is. We move the return ip into the
-	 * ip location, and move flags into the return ip location.
+	 * regs->ip location, and move flags into the return ip location.
 	 */
-	pushl	4(%esp)				/* save return ip into ip slot */
-
+	pushl	$__KERNEL_CS
+	pushl	4(%esp)				/* Save the return ip */
 	pushl	$0				/* Load 0 into orig_ax */
 	pushl	%gs
 	pushl	%fs
 	pushl	%es
 	pushl	%ds
 	pushl	%eax
+
+	/* Get flags and place them into the return ip slot */
+	pushf
+	popl	%eax
+	movl	%eax, 8*4(%esp)
+
 	pushl	%ebp
 	pushl	%edi
 	pushl	%esi
@@ -80,11 +84,6 @@ ENTRY(ftrace_regs_caller)
 	pushl	%ecx
 	pushl	%ebx
 
-	movl	13*4(%esp), %eax		/* Get the saved flags */
-	movl	%eax, 14*4(%esp)		/* Move saved flags into regs->flags location */
-						/* clobbering return ip */
-	movl	$__KERNEL_CS, 13*4(%esp)
-
 	movl	12*4(%esp), %eax		/* Load ip (1st parameter) */
 	subl	$MCOUNT_INSN_SIZE, %eax		/* Adjust ip */
 	movl	0x4(%ebp), %edx			/* Load parent ip (2nd parameter) */
@@ -95,10 +94,14 @@ GLOBAL(ftrace_regs_call)
 	call	ftrace_stub
 
 	addl	$4, %esp			/* Skip pt_regs */
-	movl	14*4(%esp), %eax		/* Move flags back into cs */
-	movl	%eax, 13*4(%esp)		/* Needed to keep addl	from modifying flags */
-	movl	12*4(%esp), %eax		/* Get return ip from regs->ip */
-	movl	%eax, 14*4(%esp)		/* Put return ip back for ret */
+
+	/* restore flags */
+	push	14*4(%esp)
+	popf
+
+	/* Move return ip back to its original location */
+	movl	12*4(%esp), %eax
+	movl	%eax, 14*4(%esp)
 
 	popl	%ebx
 	popl	%ecx
@@ -111,12 +114,11 @@ GLOBAL(ftrace_regs_call)
 	popl	%es
 	popl	%fs
 	popl	%gs
-	addl	$8, %esp			/* Skip orig_ax and ip */
-	popf					/* Pop flags at end (no addl to corrupt flags) */
-	jmp	.Lftrace_ret
 
-	popf
-	jmp	ftrace_stub
+	/* use lea to not affect flags */
+	lea	3*4(%esp), %esp			/* Skip orig_ax, ip and flags */
+
+	jmp	.Lftrace_ret
 #else /* ! CONFIG_DYNAMIC_FTRACE */
 
 ENTRY(mcount)
-- 
2.10.2

[toc] | [next] | [standalone]


#1604641

FromJosh Poimboeuf <jpoimboe@redhat.com>
Date2017-03-20 15:30 +0100
Message-ID<tn6tR-5Wi-47@gated-at.bofh.it>
In reply to#1603863
On Sat, Mar 18, 2017 at 05:09:27PM -0400, Steven Rostedt wrote:
> @@ -111,12 +114,11 @@ GLOBAL(ftrace_regs_call)
>  	popl	%es
>  	popl	%fs
>  	popl	%gs
> -	addl	$8, %esp			/* Skip orig_ax and ip */
> -	popf					/* Pop flags at end (no addl to corrupt flags) */
> -	jmp	.Lftrace_ret
>  
> -	popf
> -	jmp	ftrace_stub
> +	/* use lea to not affect flags */
> +	lea	3*4(%esp), %esp			/* Skip orig_ax, ip and flags */
> +
> +	jmp	.Lftrace_ret
>  #else /* ! CONFIG_DYNAMIC_FTRACE */
>  
>  ENTRY(mcount)

That last comment should be

  /* Skip orig_ax, ip and cs */

Otherwise:

  Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com>

-- 
Josh

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web