Commit 562e14f7 authored by Steven Rostedt (VMware)'s avatar Steven Rostedt (VMware)
Browse files

ftrace/x86: Remove mcount support



There's two methods of enabling function tracing in Linux on x86. One is
with just "gcc -pg" and the other is "gcc -pg -mfentry". The former will use
calls to a special function "mcount" after the frame is set up in all C
functions. The latter will add calls to a special function called "fentry"
as the very first instruction of all C functions.

At compile time, there is a check to see if gcc supports, -mfentry, and if
it does, it will use that, because it is more versatile and less error prone
for function tracing.

Starting with v4.19, the minimum gcc supported to build the Linux kernel,
was raised to version 4.6. That also happens to be the first gcc version to
support -mfentry. Since on x86, using gcc versions from 4.6 and beyond will
unconditionally enable the -mfentry, it will no longer use mcount as the
method for inserting calls into the C functions of the kernel. This means
that there is no point in continuing to maintain mcount in x86.

Remove support for using mcount. This makes the code less complex, and will
also allow it to be simplified in the future.

Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: default avatarJiri Kosina <jkosina@suse.cz>
Acked-by: default avatarJosh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
parent 518049d9
Loading
Loading
Loading
Loading
+3 −5
Original line number Original line Diff line number Diff line
@@ -3,12 +3,10 @@
#define _ASM_X86_FTRACE_H
#define _ASM_X86_FTRACE_H


#ifdef CONFIG_FUNCTION_TRACER
#ifdef CONFIG_FUNCTION_TRACER
#ifdef CC_USING_FENTRY
#ifndef CC_USING_FENTRY
# define MCOUNT_ADDR		((unsigned long)(__fentry__))
# error Compiler does not support fentry?
#else
# define MCOUNT_ADDR		((unsigned long)(mcount))
# define HAVE_FUNCTION_GRAPH_FP_TEST
#endif
#endif
# define MCOUNT_ADDR		((unsigned long)(__fentry__))
#define MCOUNT_INSN_SIZE	5 /* sizeof mcount call */
#define MCOUNT_INSN_SIZE	5 /* sizeof mcount call */


#ifdef CONFIG_DYNAMIC_FTRACE
#ifdef CONFIG_DYNAMIC_FTRACE
+0 −3
Original line number Original line Diff line number Diff line
@@ -26,9 +26,6 @@


static inline int klp_check_compiler_support(void)
static inline int klp_check_compiler_support(void)
{
{
#ifndef CC_USING_FENTRY
	return 1;
#endif
	return 0;
	return 0;
}
}


+5 −31
Original line number Original line Diff line number Diff line
@@ -10,20 +10,10 @@
#include <asm/ftrace.h>
#include <asm/ftrace.h>
#include <asm/nospec-branch.h>
#include <asm/nospec-branch.h>


#ifdef CC_USING_FENTRY
# define function_hook	__fentry__
# define function_hook	__fentry__
EXPORT_SYMBOL(__fentry__)
EXPORT_SYMBOL(__fentry__)
#else
# define function_hook	mcount
EXPORT_SYMBOL(mcount)
#endif

/* 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
#endif


#ifdef USING_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
# define MCOUNT_FRAME			1	/* using frame = true  */
# define MCOUNT_FRAME			1	/* using frame = true  */
#else
#else
# define MCOUNT_FRAME			0	/* using frame = false */
# define MCOUNT_FRAME			0	/* using frame = false */
@@ -35,8 +25,7 @@ END(function_hook)


ENTRY(ftrace_caller)
ENTRY(ftrace_caller)


#ifdef USING_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
# ifdef CC_USING_FENTRY
	/*
	/*
	 * Frame pointers are of ip followed by bp.
	 * Frame pointers are of ip followed by bp.
	 * Since fentry is an immediate jump, we are left with
	 * Since fentry is an immediate jump, we are left with
@@ -47,7 +36,7 @@ ENTRY(ftrace_caller)
	pushl	%ebp
	pushl	%ebp
	movl	%esp, %ebp
	movl	%esp, %ebp
	pushl	2*4(%esp)			/* function ip */
	pushl	2*4(%esp)			/* function ip */
# endif

	/* For mcount, the function ip is directly above */
	/* For mcount, the function ip is directly above */
	pushl	%ebp
	pushl	%ebp
	movl	%esp, %ebp
	movl	%esp, %ebp
@@ -57,7 +46,7 @@ ENTRY(ftrace_caller)
	pushl	%edx
	pushl	%edx
	pushl	$0				/* Pass NULL as regs pointer */
	pushl	$0				/* Pass NULL as regs pointer */


#ifdef USING_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
	/* Load parent ebp into edx */
	/* Load parent ebp into edx */
	movl	4*4(%esp), %edx
	movl	4*4(%esp), %edx
#else
#else
@@ -80,14 +69,12 @@ ftrace_call:
	popl	%edx
	popl	%edx
	popl	%ecx
	popl	%ecx
	popl	%eax
	popl	%eax
#ifdef USING_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
	popl	%ebp
	popl	%ebp
# ifdef CC_USING_FENTRY
	addl	$4,%esp				/* skip function ip */
	addl	$4,%esp				/* skip function ip */
	popl	%ebp				/* this is the orig bp */
	popl	%ebp				/* this is the orig bp */
	addl	$4, %esp			/* skip parent ip */
	addl	$4, %esp			/* skip parent ip */
#endif
#endif
#endif
.Lftrace_ret:
.Lftrace_ret:
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
#ifdef CONFIG_FUNCTION_GRAPH_TRACER
.globl ftrace_graph_call
.globl ftrace_graph_call
@@ -131,11 +118,7 @@ ENTRY(ftrace_regs_caller)


	movl	12*4(%esp), %eax		/* Load ip (1st parameter) */
	movl	12*4(%esp), %eax		/* Load ip (1st parameter) */
	subl	$MCOUNT_INSN_SIZE, %eax		/* Adjust ip */
	subl	$MCOUNT_INSN_SIZE, %eax		/* Adjust ip */
#ifdef CC_USING_FENTRY
	movl	15*4(%esp), %edx		/* Load parent ip (2nd parameter) */
	movl	15*4(%esp), %edx		/* Load parent ip (2nd parameter) */
#else
	movl	0x4(%ebp), %edx			/* Load parent ip (2nd parameter) */
#endif
	movl	function_trace_op, %ecx		/* Save ftrace_pos in 3rd parameter */
	movl	function_trace_op, %ecx		/* Save ftrace_pos in 3rd parameter */
	pushl	%esp				/* Save pt_regs as 4th parameter */
	pushl	%esp				/* Save pt_regs as 4th parameter */


@@ -176,13 +159,8 @@ ENTRY(ftrace_graph_caller)
	pushl	%edx
	pushl	%edx
	movl	3*4(%esp), %eax
	movl	3*4(%esp), %eax
	/* Even with frame pointers, fentry doesn't have one here */
	/* Even with frame pointers, fentry doesn't have one here */
#ifdef CC_USING_FENTRY
	lea	4*4(%esp), %edx
	lea	4*4(%esp), %edx
	movl	$0, %ecx
	movl	$0, %ecx
#else
	lea	0x4(%ebp), %edx
	movl	(%ebp), %ecx
#endif
	subl	$MCOUNT_INSN_SIZE, %eax
	subl	$MCOUNT_INSN_SIZE, %eax
	call	prepare_ftrace_return
	call	prepare_ftrace_return
	popl	%edx
	popl	%edx
@@ -195,11 +173,7 @@ END(ftrace_graph_caller)
return_to_handler:
return_to_handler:
	pushl	%eax
	pushl	%eax
	pushl	%edx
	pushl	%edx
#ifdef CC_USING_FENTRY
	movl	$0, %eax
	movl	$0, %eax
#else
	movl	%ebp, %eax
#endif
	call	ftrace_return_to_handler
	call	ftrace_return_to_handler
	movl	%eax, %ecx
	movl	%eax, %ecx
	popl	%edx
	popl	%edx
+1 −27
Original line number Original line Diff line number Diff line
@@ -13,23 +13,13 @@
	.code64
	.code64
	.section .entry.text, "ax"
	.section .entry.text, "ax"


#ifdef CC_USING_FENTRY
# define function_hook	__fentry__
# define function_hook	__fentry__
EXPORT_SYMBOL(__fentry__)
EXPORT_SYMBOL(__fentry__)
#else
# define function_hook	mcount
EXPORT_SYMBOL(mcount)
#endif


#ifdef CONFIG_FRAME_POINTER
#ifdef CONFIG_FRAME_POINTER
# ifdef CC_USING_FENTRY
/* Save parent and function stack frames (rip and rbp) */
/* Save parent and function stack frames (rip and rbp) */
#  define MCOUNT_FRAME_SIZE	(8+16*2)
#  define MCOUNT_FRAME_SIZE	(8+16*2)
#else
#else
/* Save just function stack frame (rip and rbp) */
#  define MCOUNT_FRAME_SIZE	(8+16)
# endif
#else
/* No need to save a stack frame */
/* No need to save a stack frame */
# define MCOUNT_FRAME_SIZE	0
# define MCOUNT_FRAME_SIZE	0
#endif /* CONFIG_FRAME_POINTER */
#endif /* CONFIG_FRAME_POINTER */
@@ -75,17 +65,13 @@ EXPORT_SYMBOL(mcount)
	 * fentry is called before the stack frame is set up, where as mcount
	 * fentry is called before the stack frame is set up, where as mcount
	 * is called afterward.
	 * is called afterward.
	 */
	 */
#ifdef CC_USING_FENTRY

	/* Save the parent pointer (skip orig rbp and our return address) */
	/* Save the parent pointer (skip orig rbp and our return address) */
	pushq \added+8*2(%rsp)
	pushq \added+8*2(%rsp)
	pushq %rbp
	pushq %rbp
	movq %rsp, %rbp
	movq %rsp, %rbp
	/* Save the return address (now skip orig rbp, rbp and parent) */
	/* Save the return address (now skip orig rbp, rbp and parent) */
	pushq \added+8*3(%rsp)
	pushq \added+8*3(%rsp)
#else
	/* Can't assume that rip is before this (unless added was zero) */
	pushq \added+8(%rsp)
#endif
	pushq %rbp
	pushq %rbp
	movq %rsp, %rbp
	movq %rsp, %rbp
#endif /* CONFIG_FRAME_POINTER */
#endif /* CONFIG_FRAME_POINTER */
@@ -113,12 +99,7 @@ EXPORT_SYMBOL(mcount)
	movq %rdx, RBP(%rsp)
	movq %rdx, RBP(%rsp)


	/* Copy the parent address into %rsi (second parameter) */
	/* Copy the parent address into %rsi (second parameter) */
#ifdef CC_USING_FENTRY
	movq MCOUNT_REG_SIZE+8+\added(%rsp), %rsi
	movq MCOUNT_REG_SIZE+8+\added(%rsp), %rsi
#else
	/* %rdx contains original %rbp */
	movq 8(%rdx), %rsi
#endif


	 /* Move RIP to its proper location */
	 /* Move RIP to its proper location */
	movq MCOUNT_REG_SIZE+\added(%rsp), %rdi
	movq MCOUNT_REG_SIZE+\added(%rsp), %rdi
@@ -303,15 +284,8 @@ ENTRY(ftrace_graph_caller)
	/* Saves rbp into %rdx and fills first parameter  */
	/* Saves rbp into %rdx and fills first parameter  */
	save_mcount_regs
	save_mcount_regs


#ifdef CC_USING_FENTRY
	leaq MCOUNT_REG_SIZE+8(%rsp), %rsi
	leaq MCOUNT_REG_SIZE+8(%rsp), %rsi
	movq $0, %rdx	/* No framepointers needed */
	movq $0, %rdx	/* No framepointers needed */
#else
	/* Save address of the return address of traced function */
	leaq 8(%rdx), %rsi
	/* ftrace does sanity checks against frame pointers */
	movq (%rdx), %rdx
#endif
	call	prepare_ftrace_return
	call	prepare_ftrace_return


	restore_mcount_regs
	restore_mcount_regs