define FTRACE_BPF_FILTER if CONFIG_FTRACE_BPF_FILTER is enabled, create struct ftrace_regs, struct ftrace_regs is similar as pt_regs in kprobe, but ftrace doesn't save all context, only caller save registers, so use ftrace_regs to store these registers.
Signed-off-by: yupeng0...@gmail.com --- arch/x86/include/asm/ftrace.h | 22 ++++++++++++++++++++++ arch/x86/kernel/ftrace.c | 15 +++++++++++++++ arch/x86/kernel/ftrace_64.S | 1 + 3 files changed, 38 insertions(+) diff --git a/arch/x86/include/asm/ftrace.h b/arch/x86/include/asm/ftrace.h index 09ad885..9a5bffc 100644 --- a/arch/x86/include/asm/ftrace.h +++ b/arch/x86/include/asm/ftrace.h @@ -11,6 +11,28 @@ #endif #define MCOUNT_INSN_SIZE 5 /* sizeof mcount call */ +#ifndef __i386__ +#ifdef CONFIG_FTRACE_BPF_FILTER +#define FTRACE_BPF_FILTER +#ifndef __ASSEMBLY__ +/* + * The order is exactly same as + * arch/x86/entry/calling.h + */ +struct ftrace_regs { + unsigned long r9; + unsigned long r8; + unsigned long rax; + unsigned long rcx; + unsigned long rdx; + unsigned long rsi; + unsigned long rdi; +}; +#endif +#endif /* CONFIG_FTRACE_BPF_FILTER */ + +#endif + #ifdef CONFIG_DYNAMIC_FTRACE #define ARCH_SUPPORTS_FTRACE_OPS 1 #endif diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 01ebcb6..d190534 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -896,8 +896,14 @@ static void *addr_from_call(void *ptr) return ptr + MCOUNT_INSN_SIZE + calc.offset; } +#ifdef FTRACE_BPF_FILTER +void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, + unsigned long frame_pointer, + struct ftrace_regs *ctx); +#else void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, unsigned long frame_pointer); +#endif /* * If the ops->trampoline was not allocated, then it probably @@ -989,8 +995,14 @@ int ftrace_disable_ftrace_graph_caller(void) * Hook the return address and push it in the stack of return addrs * in current thread info. */ +#ifdef FTRACE_BPF_FILTER +void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, + unsigned long frame_pointer, + struct ftrace_regs *ctx) +#else void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, unsigned long frame_pointer) +#endif { unsigned long old; int faulted; @@ -1048,6 +1060,9 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent, trace.func = self_addr; trace.depth = current->curr_ret_stack + 1; +#ifdef FTRACE_BPF_FILTER + trace.ctx = ctx; +#endif /* Only trace if the calling function expects to */ if (!ftrace_graph_entry(&trace)) { diff --git a/arch/x86/kernel/ftrace_64.S b/arch/x86/kernel/ftrace_64.S index c832291..5e51b93 100644 --- a/arch/x86/kernel/ftrace_64.S +++ b/arch/x86/kernel/ftrace_64.S @@ -108,6 +108,7 @@ EXPORT_SYMBOL(mcount) movq MCOUNT_REG_SIZE-8(%rsp), %rdx movq %rdx, RBP(%rsp) + leaq R9(%rsp), %rcx /* Copy the parent address into %rsi (second parameter) */ #ifdef CC_USING_FENTRY movq MCOUNT_REG_SIZE+8+\added(%rsp), %rsi -- 2.7.4