2 * Copyright (C) 2017 Steven Rostedt, VMware Inc.
5 #include <linux/linkage.h>
6 #include <asm/page_types.h>
7 #include <asm/segment.h>
8 #include <asm/export.h>
9 #include <asm/ftrace.h>
11 #ifdef CONFIG_FUNCTION_TRACER
12 #ifdef CONFIG_DYNAMIC_FTRACE
22 pushl $0 /* Pass NULL as regs pointer */
25 movl function_trace_op, %ecx
26 subl $MCOUNT_INSN_SIZE, %eax
32 addl $4, %esp /* skip NULL pointer */
37 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
38 .globl ftrace_graph_call
43 /* This is weak to keep gas from relaxing the jumps */
48 ENTRY(ftrace_regs_caller)
49 pushf /* push flags before compare (in cs location) */
52 * i386 does not save SS and ESP when coming from kernel.
53 * Instead, to get sp, ®s->sp is used (see ptrace.h).
54 * Unfortunately, that means eflags must be at the same location
55 * as the current return ip is. We move the return ip into the
56 * ip location, and move flags into the return ip location.
58 pushl 4(%esp) /* save return ip into ip slot */
60 pushl $0 /* Load 0 into orig_ax */
73 movl 13*4(%esp), %eax /* Get the saved flags */
74 movl %eax, 14*4(%esp) /* Move saved flags into regs->flags location */
75 /* clobbering return ip */
76 movl $__KERNEL_CS, 13*4(%esp)
78 movl 12*4(%esp), %eax /* Load ip (1st parameter) */
79 subl $MCOUNT_INSN_SIZE, %eax /* Adjust ip */
80 movl 0x4(%ebp), %edx /* Load parent ip (2nd parameter) */
81 movl function_trace_op, %ecx /* Save ftrace_pos in 3rd parameter */
82 pushl %esp /* Save pt_regs as 4th parameter */
84 GLOBAL(ftrace_regs_call)
87 addl $4, %esp /* Skip pt_regs */
88 movl 14*4(%esp), %eax /* Move flags back into cs */
89 movl %eax, 13*4(%esp) /* Needed to keep addl from modifying flags */
90 movl 12*4(%esp), %eax /* Get return ip from regs->ip */
91 movl %eax, 14*4(%esp) /* Put return ip back for ret */
104 addl $8, %esp /* Skip orig_ax and ip */
105 popf /* Pop flags at end (no addl to corrupt flags) */
110 #else /* ! CONFIG_DYNAMIC_FTRACE */
113 cmpl $__PAGE_OFFSET, %esp
114 jb ftrace_stub /* Paging not enabled yet? */
116 cmpl $ftrace_stub, ftrace_trace_function
118 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
119 cmpl $ftrace_stub, ftrace_graph_return
120 jnz ftrace_graph_caller
122 cmpl $ftrace_graph_entry_stub, ftrace_graph_entry
123 jnz ftrace_graph_caller
129 /* taken from glibc */
136 subl $MCOUNT_INSN_SIZE, %eax
138 call *ftrace_trace_function
145 #endif /* CONFIG_DYNAMIC_FTRACE */
146 EXPORT_SYMBOL(mcount)
147 #endif /* CONFIG_FUNCTION_TRACER */
149 #ifdef CONFIG_FUNCTION_GRAPH_TRACER
150 ENTRY(ftrace_graph_caller)
157 subl $MCOUNT_INSN_SIZE, %eax
158 call prepare_ftrace_return
163 END(ftrace_graph_caller)
165 .globl return_to_handler
170 call ftrace_return_to_handler