mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 20:48:49 +08:00
ftrace: pass fregs to arch_ftrace_set_direct_caller()
In subsequent patches we'll arrange for architectures to have an ftrace_regs which is entirely distinct from pt_regs. In preparation for this, we need to minimize the use of pt_regs to where strictly necessary in the core ftrace code. This patch changes the prototype of arch_ftrace_set_direct_caller() to take ftrace_regs rather than pt_regs, and moves the extraction of the pt_regs into arch_ftrace_set_direct_caller(). On x86, arch_ftrace_set_direct_caller() can be used even when CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=n, and <linux/ftrace.h> defines struct ftrace_regs. Due to this, it's necessary to define arch_ftrace_set_direct_caller() as a macro to avoid using an incomplete type. I've also moved the body of arch_ftrace_set_direct_caller() after the CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS=y defineidion of struct ftrace_regs. There should be no functional change as a result of this patch. Signed-off-by: Mark Rutland <mark.rutland@arm.com> Cc: Florent Revest <revest@chromium.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Steven Rostedt <rostedt@goodmis.org> Reviewed-by: Masami Hiramatsu (Google) <mhiramat@kernel.org> Reviewed-by: Steven Rostedt (Google) <rostedt@goodmis.org> Link: https://lore.kernel.org/r/20221103170520.931305-2-mark.rutland@arm.com Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
f0c4d9fc9c
commit
9705bc7096
@ -60,6 +60,7 @@ static __always_inline void ftrace_instruction_pointer_set(struct ftrace_regs *f
|
||||
fregs->regs.psw.addr = ip;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
|
||||
/*
|
||||
* When an ftrace registered caller is tracing a function that is
|
||||
* also set by a register_ftrace_direct() call, it needs to be
|
||||
@ -67,10 +68,12 @@ static __always_inline void ftrace_instruction_pointer_set(struct ftrace_regs *f
|
||||
* place the direct caller in the ORIG_GPR2 part of pt_regs. This
|
||||
* tells the ftrace_caller that there's a direct caller.
|
||||
*/
|
||||
static inline void arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr)
|
||||
static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs, unsigned long addr)
|
||||
{
|
||||
struct pt_regs *regs = &fregs->regs;
|
||||
regs->orig_gpr2 = addr;
|
||||
}
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
|
||||
|
||||
/*
|
||||
* Even though the system call numbers are identical for s390/s390x a
|
||||
|
@ -34,19 +34,6 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)
|
||||
return addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* When a ftrace registered caller is tracing a function that is
|
||||
* also set by a register_ftrace_direct() call, it needs to be
|
||||
* differentiated in the ftrace_caller trampoline. To do this, we
|
||||
* place the direct caller in the ORIG_AX part of pt_regs. This
|
||||
* tells the ftrace_caller that there's a direct caller.
|
||||
*/
|
||||
static inline void arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr)
|
||||
{
|
||||
/* Emulate a call */
|
||||
regs->orig_ax = addr;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
|
||||
struct ftrace_regs {
|
||||
struct pt_regs regs;
|
||||
@ -72,6 +59,24 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,
|
||||
#define FTRACE_GRAPH_TRAMP_ADDR FTRACE_GRAPH_ADDR
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
|
||||
/*
|
||||
* When a ftrace registered caller is tracing a function that is
|
||||
* also set by a register_ftrace_direct() call, it needs to be
|
||||
* differentiated in the ftrace_caller trampoline. To do this, we
|
||||
* place the direct caller in the ORIG_AX part of pt_regs. This
|
||||
* tells the ftrace_caller that there's a direct caller.
|
||||
*/
|
||||
static inline void
|
||||
__arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr)
|
||||
{
|
||||
/* Emulate a call */
|
||||
regs->orig_ax = addr;
|
||||
}
|
||||
#define arch_ftrace_set_direct_caller(fregs, addr) \
|
||||
__arch_ftrace_set_direct_caller(&(fregs)->regs, addr)
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
|
||||
|
||||
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||
|
||||
struct dyn_arch_ftrace {
|
||||
|
@ -37,9 +37,10 @@ extern void ftrace_boot_snapshot(void);
|
||||
static inline void ftrace_boot_snapshot(void) { }
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FUNCTION_TRACER
|
||||
struct ftrace_ops;
|
||||
struct ftrace_regs;
|
||||
|
||||
#ifdef CONFIG_FUNCTION_TRACER
|
||||
/*
|
||||
* If the arch's mcount caller does not support all of ftrace's
|
||||
* features, then it must call an indirect function that
|
||||
@ -427,9 +428,7 @@ static inline int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsi
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
|
||||
|
||||
#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
|
||||
/*
|
||||
* This must be implemented by the architecture.
|
||||
* It is the way the ftrace direct_ops helper, when called
|
||||
@ -443,9 +442,9 @@ static inline int modify_ftrace_direct_multi_nolock(struct ftrace_ops *ops, unsi
|
||||
* the return from the trampoline jump to the direct caller
|
||||
* instead of going back to the function it just traced.
|
||||
*/
|
||||
static inline void arch_ftrace_set_direct_caller(struct pt_regs *regs,
|
||||
static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs,
|
||||
unsigned long addr) { }
|
||||
#endif /* CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
|
||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
|
||||
|
||||
#ifdef CONFIG_STACK_TRACER
|
||||
|
||||
|
@ -2487,14 +2487,13 @@ ftrace_add_rec_direct(unsigned long ip, unsigned long addr,
|
||||
static void call_direct_funcs(unsigned long ip, unsigned long pip,
|
||||
struct ftrace_ops *ops, struct ftrace_regs *fregs)
|
||||
{
|
||||
struct pt_regs *regs = ftrace_get_regs(fregs);
|
||||
unsigned long addr;
|
||||
|
||||
addr = ftrace_find_rec_direct(ip);
|
||||
if (!addr)
|
||||
return;
|
||||
|
||||
arch_ftrace_set_direct_caller(regs, addr);
|
||||
arch_ftrace_set_direct_caller(fregs, addr);
|
||||
}
|
||||
|
||||
struct ftrace_ops direct_ops = {
|
||||
|
Loading…
Reference in New Issue
Block a user