Loading arch/x86/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ config X86 select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_RET_TRACER if X86_32 select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) select HAVE_ARCH_KGDB if !X86_VOYAGER Loading arch/x86/include/asm/ftrace.h +26 −0 Original line number Diff line number Diff line Loading @@ -20,4 +20,30 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_FUNCTION_RET_TRACER #define FTRACE_RET_STACK_SIZE 20 #ifndef __ASSEMBLY__ /* * Stack of return addresses for functions * of a thread. * Used in struct thread_info */ struct ftrace_ret_stack { unsigned long ret; unsigned long func; unsigned long long calltime; }; /* * Primary handler of a function return. * It relays on ftrace_return_to_handler. * Defined in entry32.S */ extern void return_to_handler(void); #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_RET_TRACER */ #endif /* _ASM_X86_FTRACE_H */ arch/x86/include/asm/thread_info.h +24 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ struct task_struct; struct exec_domain; #include <asm/processor.h> #include <asm/ftrace.h> struct thread_info { struct task_struct *task; /* main task structure */ Loading @@ -38,8 +39,30 @@ struct thread_info { */ __u8 supervisor_stack[0]; #endif #ifdef CONFIG_FUNCTION_RET_TRACER /* Index of current stored adress in ret_stack */ int curr_ret_stack; /* Stack of return addresses for return function tracing */ struct ftrace_ret_stack ret_stack[FTRACE_RET_STACK_SIZE]; #endif }; #ifdef CONFIG_FUNCTION_RET_TRACER #define INIT_THREAD_INFO(tsk) \ { \ .task = &tsk, \ .exec_domain = &default_exec_domain, \ .flags = 0, \ .cpu = 0, \ .preempt_count = 1, \ .addr_limit = KERNEL_DS, \ .restart_block = { \ .fn = do_no_restart_syscall, \ }, \ .curr_ret_stack = -1,\ } #else #define INIT_THREAD_INFO(tsk) \ { \ .task = &tsk, \ Loading @@ -52,6 +75,7 @@ struct thread_info { .fn = do_no_restart_syscall, \ }, \ } #endif #define init_thread_info (init_thread_union.thread_info) #define init_stack (init_thread_union.stack) Loading arch/x86/kernel/Makefile +6 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,11 @@ CFLAGS_REMOVE_paravirt-spinlocks.o = -pg CFLAGS_REMOVE_ftrace.o = -pg endif ifdef CONFIG_FUNCTION_RET_TRACER # Don't trace __switch_to() but let it for function tracer CFLAGS_REMOVE_process_32.o = -pg endif # # vsyscalls (which work on the user stack) should have # no stack-protector checks: Loading Loading @@ -65,6 +70,7 @@ obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_FUNCTION_RET_TRACER) += ftrace.o obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o Loading arch/x86/kernel/entry_32.S +33 −0 Original line number Diff line number Diff line Loading @@ -1188,6 +1188,10 @@ ENTRY(mcount) cmpl $ftrace_stub, ftrace_trace_function jnz trace #ifdef CONFIG_FUNCTION_RET_TRACER cmpl $ftrace_stub, ftrace_function_return jnz trace_return #endif .globl ftrace_stub ftrace_stub: ret Loading @@ -1206,8 +1210,37 @@ trace: popl %edx popl %ecx popl %eax jmp ftrace_stub #ifdef CONFIG_FUNCTION_RET_TRACER trace_return: pushl %eax pushl %ecx pushl %edx movl 0xc(%esp), %eax pushl %eax lea 0x4(%ebp), %eax pushl %eax call prepare_ftrace_return addl $8, %esp popl %edx popl %ecx popl %eax jmp ftrace_stub .globl return_to_handler return_to_handler: pushl $0 pushl %eax pushl %ecx pushl %edx call ftrace_return_to_handler movl %eax, 0xc(%esp) popl %edx popl %ecx popl %eax ret #endif /* CONFIG_FUNCTION_RET_TRACER */ END(mcount) #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_FUNCTION_TRACER */ Loading Loading
arch/x86/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ config X86 select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_RET_TRACER if X86_32 select HAVE_FUNCTION_TRACE_MCOUNT_TEST select HAVE_KVM if ((X86_32 && !X86_VOYAGER && !X86_VISWS && !X86_NUMAQ) || X86_64) select HAVE_ARCH_KGDB if !X86_VOYAGER Loading
arch/x86/include/asm/ftrace.h +26 −0 Original line number Diff line number Diff line Loading @@ -20,4 +20,30 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_TRACER */ #ifdef CONFIG_FUNCTION_RET_TRACER #define FTRACE_RET_STACK_SIZE 20 #ifndef __ASSEMBLY__ /* * Stack of return addresses for functions * of a thread. * Used in struct thread_info */ struct ftrace_ret_stack { unsigned long ret; unsigned long func; unsigned long long calltime; }; /* * Primary handler of a function return. * It relays on ftrace_return_to_handler. * Defined in entry32.S */ extern void return_to_handler(void); #endif /* __ASSEMBLY__ */ #endif /* CONFIG_FUNCTION_RET_TRACER */ #endif /* _ASM_X86_FTRACE_H */
arch/x86/include/asm/thread_info.h +24 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ struct task_struct; struct exec_domain; #include <asm/processor.h> #include <asm/ftrace.h> struct thread_info { struct task_struct *task; /* main task structure */ Loading @@ -38,8 +39,30 @@ struct thread_info { */ __u8 supervisor_stack[0]; #endif #ifdef CONFIG_FUNCTION_RET_TRACER /* Index of current stored adress in ret_stack */ int curr_ret_stack; /* Stack of return addresses for return function tracing */ struct ftrace_ret_stack ret_stack[FTRACE_RET_STACK_SIZE]; #endif }; #ifdef CONFIG_FUNCTION_RET_TRACER #define INIT_THREAD_INFO(tsk) \ { \ .task = &tsk, \ .exec_domain = &default_exec_domain, \ .flags = 0, \ .cpu = 0, \ .preempt_count = 1, \ .addr_limit = KERNEL_DS, \ .restart_block = { \ .fn = do_no_restart_syscall, \ }, \ .curr_ret_stack = -1,\ } #else #define INIT_THREAD_INFO(tsk) \ { \ .task = &tsk, \ Loading @@ -52,6 +75,7 @@ struct thread_info { .fn = do_no_restart_syscall, \ }, \ } #endif #define init_thread_info (init_thread_union.thread_info) #define init_stack (init_thread_union.stack) Loading
arch/x86/kernel/Makefile +6 −0 Original line number Diff line number Diff line Loading @@ -14,6 +14,11 @@ CFLAGS_REMOVE_paravirt-spinlocks.o = -pg CFLAGS_REMOVE_ftrace.o = -pg endif ifdef CONFIG_FUNCTION_RET_TRACER # Don't trace __switch_to() but let it for function tracer CFLAGS_REMOVE_process_32.o = -pg endif # # vsyscalls (which work on the user stack) should have # no stack-protector checks: Loading Loading @@ -65,6 +70,7 @@ obj-$(CONFIG_X86_LOCAL_APIC) += apic.o nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o obj-$(CONFIG_X86_REBOOTFIXUPS) += reboot_fixups_32.o obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o obj-$(CONFIG_FUNCTION_RET_TRACER) += ftrace.o obj-$(CONFIG_KEXEC) += machine_kexec_$(BITS).o obj-$(CONFIG_KEXEC) += relocate_kernel_$(BITS).o crash.o obj-$(CONFIG_CRASH_DUMP) += crash_dump_$(BITS).o Loading
arch/x86/kernel/entry_32.S +33 −0 Original line number Diff line number Diff line Loading @@ -1188,6 +1188,10 @@ ENTRY(mcount) cmpl $ftrace_stub, ftrace_trace_function jnz trace #ifdef CONFIG_FUNCTION_RET_TRACER cmpl $ftrace_stub, ftrace_function_return jnz trace_return #endif .globl ftrace_stub ftrace_stub: ret Loading @@ -1206,8 +1210,37 @@ trace: popl %edx popl %ecx popl %eax jmp ftrace_stub #ifdef CONFIG_FUNCTION_RET_TRACER trace_return: pushl %eax pushl %ecx pushl %edx movl 0xc(%esp), %eax pushl %eax lea 0x4(%ebp), %eax pushl %eax call prepare_ftrace_return addl $8, %esp popl %edx popl %ecx popl %eax jmp ftrace_stub .globl return_to_handler return_to_handler: pushl $0 pushl %eax pushl %ecx pushl %edx call ftrace_return_to_handler movl %eax, 0xc(%esp) popl %edx popl %ecx popl %eax ret #endif /* CONFIG_FUNCTION_RET_TRACER */ END(mcount) #endif /* CONFIG_DYNAMIC_FTRACE */ #endif /* CONFIG_FUNCTION_TRACER */ Loading