[
 Ingo, Thomas or Peter,

 I believe this is all set to go now. I updated those patches that Linus
 commented on and I don't believe there are any more issues. I ran this
 through several tests (although some of my tests are failing due to
 bugs introduced by others in 4.11-rc2). You can take this as a patch
 series, or you can pull from my tree defined below. It's based on 4.11-rc2
 as I noticed that tip/x86/core is rather outdated, and Linus is fine with
 basing off of his tagged releases.
]

With the issues of gcc screwing around with the mcount stack frame causing
function graph tracer to panic on x86_32, and with Linus saying that we
should start deprecating mcount (at least on x86), I figured that x86_32
needs to support fentry.

First, I renamed mcount_64.S to ftrace_64.S. As we want to get away from
mcount, having the ftrace code in a file called mcount seems rather backwards.

Next I moved the ftrace code out of entry_32.S. It's not in entry_64.S
and it does not belong in entry_32.S.

I noticed that the x86_32 code has the same issue as the x86_64 did
in the past with respect to a stack frame. I fixed that just for the main
ftrace_caller. The ftrace_regs_caller is rather special, and so is
function graph tracing.

I realized the ftrace_regs_caller code was complex due to me aggressively
saving flags, even though I could still do push, lea and mov without
changing them. That made the logic a little nicer.

Finally I added the fentry code.

I tested this with an older compiler (for mcount) with and without
FRAME_POINTER set. I also did it with a new compiler (with fentry), with and
without FRAME_POINTER. I tested function tracing, stack tracing, function_graph
tracing, and kprobes (as that uses the ftrace_regs_caller).

Please pull (or take the patch series) from:

  git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
tip/x86/ftrace

Head SHA1: 7506fa66bcd267c587b43d39f9fc9acb48925b5a


Steven Rostedt (VMware) (6):
      ftrace/x86_64: Rename mcount_64.S to ftrace_64.S
      ftrace/x86_32: Move the ftrace specific code out of entry_32.S
      ftrace/x86_32: Add stack frame pointer to ftrace_caller
      ftrace/x86_32: Clean up ftrace_regs_caller
      ftrace/x86_32: Add -mfentry support to x86_32 with DYNAMIC_FTRACE set
      ftrace/x86: Use Makefile logic instead of #ifdef of compling ftrace_*.o

----
Changes from v2:

 * removed accidental committing of asm goto code from someone else

 * Better code for ftrace_regs_caller (Linus Torvalds)

 * Added patch to only compile ftrace_*.o if FUNCTION_TRACER is defined
    (Josh Poimboeuf)

 * Fixed comment whitespace issue (Peter Zijlstra)


 arch/x86/Kconfig                             |   2 +-
 arch/x86/entry/entry_32.S                    | 169 ------------------
 arch/x86/kernel/Makefile                     |   5 +-
 arch/x86/kernel/ftrace_32.S                  | 246 +++++++++++++++++++++++++++
 arch/x86/kernel/{mcount_64.S => ftrace_64.S} |   4 -
 5 files changed, 250 insertions(+), 176 deletions(-)
 create mode 100644 arch/x86/kernel/ftrace_32.S
 rename arch/x86/kernel/{mcount_64.S => ftrace_64.S} (99%)

Diff against v2:

diff --git a/Makefile b/Makefile
index 7df3247..b841fb3 100644
--- a/Makefile
+++ b/Makefile
@@ -653,12 +653,6 @@ KBUILD_CFLAGS += $(call cc-ifversion, -lt, 0409, \
 # Tell gcc to never replace conditional load with a non-conditional one
 KBUILD_CFLAGS  += $(call cc-option,--param=allow-store-data-races=0)
 
-# check for 'asm goto'
-ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC) 
$(KBUILD_CFLAGS)), y)
-       KBUILD_CFLAGS += -DCC_HAVE_ASM_GOTO
-       KBUILD_AFLAGS += -DCC_HAVE_ASM_GOTO
-endif
-
 include scripts/Makefile.gcc-plugins
 
 ifdef CONFIG_READABLE_ASM
@@ -804,6 +798,12 @@ KBUILD_CFLAGS   += $(call 
cc-option,-Werror=incompatible-pointer-types)
 # use the deterministic mode of AR if available
 KBUILD_ARFLAGS := $(call ar-option,D)
 
+# check for 'asm goto'
+ifeq ($(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-goto.sh $(CC) 
$(KBUILD_CFLAGS)), y)
+       KBUILD_CFLAGS += -DCC_HAVE_ASM_GOTO
+       KBUILD_AFLAGS += -DCC_HAVE_ASM_GOTO
+endif
+
 include scripts/Makefile.kasan
 include scripts/Makefile.extrawarn
 include scripts/Makefile.ubsan
diff --git a/arch/x86/entry/entry_32.S b/arch/x86/entry/entry_32.S
index c576352..169b3b0 100644
--- a/arch/x86/entry/entry_32.S
+++ b/arch/x86/entry/entry_32.S
@@ -35,7 +35,6 @@
 #include <asm/errno.h>
 #include <asm/segment.h>
 #include <asm/smp.h>
-#include <asm/page_types.h>
 #include <asm/percpu.h>
 #include <asm/processor-flags.h>
 #include <asm/irq_vectors.h>
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
index 55e8902..4b99423 100644
--- a/arch/x86/kernel/Makefile
+++ b/arch/x86/kernel/Makefile
@@ -46,8 +46,7 @@ obj-$(CONFIG_MODIFY_LDT_SYSCALL)      += ldt.o
 obj-y                  += setup.o x86_init.o i8259.o irqinit.o jump_label.o
 obj-$(CONFIG_IRQ_WORK)  += irq_work.o
 obj-y                  += probe_roms.o
-obj-$(CONFIG_X86_64)   += sys_x86_64.o ftrace_64.o
-obj-$(CONFIG_X86_32)   += ftrace_32.o
+obj-$(CONFIG_X86_64)   += sys_x86_64.o
 obj-$(CONFIG_X86_ESPFIX64)     += espfix_64.o
 obj-$(CONFIG_SYSFS)    += ksysfs.o
 obj-y                  += bootflag.o e820.o
@@ -83,6 +82,7 @@ obj-y                         += apic/
 obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o
 obj-$(CONFIG_DYNAMIC_FTRACE)   += ftrace.o
 obj-$(CONFIG_LIVEPATCH)        += livepatch.o
+obj-$(CONFIG_FUNCTION_TRACER)  += ftrace_$(BITS).o
 obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
 obj-$(CONFIG_FTRACE_SYSCALLS)  += ftrace.o
 obj-$(CONFIG_X86_TSC)          += trace_clock.o
diff --git a/arch/x86/kernel/ftrace_32.S b/arch/x86/kernel/ftrace_32.S
index 7ed4137..4d52e0d 100644
--- a/arch/x86/kernel/ftrace_32.S
+++ b/arch/x86/kernel/ftrace_32.S
@@ -5,6 +5,7 @@
  */
 
 #include <linux/linkage.h>
+#include <asm/page_types.h>
 #include <asm/segment.h>
 #include <asm/export.h>
 #include <asm/ftrace.h>
@@ -17,6 +18,8 @@ EXPORT_SYMBOL(__fentry__)
 EXPORT_SYMBOL(mcount)
 #endif
 
+#ifdef CONFIG_DYNAMIC_FTRACE
+
 /* mcount uses a frame pointer even if CONFIG_FRAME_POINTER is not set */
 #if !defined(CC_USING_FENTRY) || defined(CONFIG_FRAME_POINTER)
 # define USING_FRAME_POINTER
@@ -28,9 +31,6 @@ EXPORT_SYMBOL(mcount)
 # define MCOUNT_FRAME                  0       /* using frame = false */
 #endif
 
-#ifdef CONFIG_FUNCTION_TRACER
-#ifdef CONFIG_DYNAMIC_FTRACE
-
 ENTRY(function_hook)
        ret
 END(function_hook)
@@ -109,23 +109,20 @@ ENTRY(ftrace_regs_caller)
         * Unfortunately, that means eflags must be at the same location
         * as the current return ip is. We move the return ip into the
         * regs->ip location, and move flags into the return ip location.
-         */
+        */
        pushl   $__KERNEL_CS
        pushl   4(%esp)                         /* Save the return ip */
-
-       /* temporarily save flags in the orig_ax location */
-       pushf
-
+       pushl   $0                              /* Load 0 into orig_ax */
        pushl   %gs
        pushl   %fs
        pushl   %es
        pushl   %ds
        pushl   %eax
 
-       /* move flags into the location of where the return ip was */
-       movl    5*4(%esp), %eax
-       movl    $0, 5*4(%esp)                   /* Load 0 into orig_ax */
-       movl    %eax, 8*4(%esp)                 /* Load flags in return ip */
+       /* Get flags and place them into the return ip slot */
+       pushf
+       popl    %eax
+       movl    %eax, 8*4(%esp)
 
        pushl   %ebp
        pushl   %edi
@@ -149,9 +146,9 @@ GLOBAL(ftrace_regs_call)
 
        addl    $4, %esp                        /* Skip pt_regs */
 
-       /* Since we don't care about cs, move flags there to simplify return */
-       movl    14*4(%esp), %eax
-       movl    %eax, 13*4(%esp)
+       /* restore flags */
+       push    14*4(%esp)
+       popf
 
        /* Move return ip back to its original location */
        movl    12*4(%esp), %eax
@@ -168,9 +165,9 @@ GLOBAL(ftrace_regs_call)
        popl    %es
        popl    %fs
        popl    %gs
-       addl    $8, %esp                        /* Skip orig_ax and old ip */
 
-       popf                                    /* flags is in the cs location 
*/
+       /* use lea to not affect flags */
+       lea     3*4(%esp), %esp                 /* Skip orig_ax, ip and flags */
 
        jmp     .Lftrace_ret
 #else /* ! CONFIG_DYNAMIC_FTRACE */
@@ -209,7 +206,6 @@ ftrace_stub:
        jmp     ftrace_stub
 END(function_hook)
 #endif /* CONFIG_DYNAMIC_FTRACE */
-#endif /* CONFIG_FUNCTION_TRACER */
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 ENTRY(ftrace_graph_caller)
diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S
index 7b0d3da..b9c4691 100644
--- a/arch/x86/kernel/ftrace_64.S
+++ b/arch/x86/kernel/ftrace_64.S
@@ -13,9 +13,6 @@
        .code64
        .section .entry.text, "ax"
 
-
-#ifdef CONFIG_FUNCTION_TRACER
-
 #ifdef CC_USING_FENTRY
 # define function_hook __fentry__
 EXPORT_SYMBOL(__fentry__)
@@ -297,7 +294,6 @@ trace:
        jmp fgraph_trace
 END(function_hook)
 #endif /* CONFIG_DYNAMIC_FTRACE */
-#endif /* CONFIG_FUNCTION_TRACER */
 
 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
 ENTRY(ftrace_graph_caller)

Reply via email to