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
4 changed files with 27 additions and 21 deletions
|
@ -60,6 +60,7 @@ static __always_inline void ftrace_instruction_pointer_set(struct ftrace_regs *f
|
||||||
fregs->regs.psw.addr = ip;
|
fregs->regs.psw.addr = ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
|
||||||
/*
|
/*
|
||||||
* When an ftrace registered caller is tracing a function that is
|
* When an ftrace registered caller is tracing a function that is
|
||||||
* also set by a register_ftrace_direct() call, it needs to be
|
* 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
|
* place the direct caller in the ORIG_GPR2 part of pt_regs. This
|
||||||
* tells the ftrace_caller that there's a direct caller.
|
* 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;
|
regs->orig_gpr2 = addr;
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Even though the system call numbers are identical for s390/s390x a
|
* 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;
|
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
|
#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS
|
||||||
struct ftrace_regs {
|
struct ftrace_regs {
|
||||||
struct pt_regs 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
|
#define FTRACE_GRAPH_TRAMP_ADDR FTRACE_GRAPH_ADDR
|
||||||
#endif
|
#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
|
#ifdef CONFIG_DYNAMIC_FTRACE
|
||||||
|
|
||||||
struct dyn_arch_ftrace {
|
struct dyn_arch_ftrace {
|
||||||
|
|
|
@ -37,9 +37,10 @@ extern void ftrace_boot_snapshot(void);
|
||||||
static inline void ftrace_boot_snapshot(void) { }
|
static inline void ftrace_boot_snapshot(void) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_FUNCTION_TRACER
|
|
||||||
struct ftrace_ops;
|
struct ftrace_ops;
|
||||||
struct ftrace_regs;
|
struct ftrace_regs;
|
||||||
|
|
||||||
|
#ifdef CONFIG_FUNCTION_TRACER
|
||||||
/*
|
/*
|
||||||
* If the arch's mcount caller does not support all of ftrace's
|
* If the arch's mcount caller does not support all of ftrace's
|
||||||
* features, then it must call an indirect function that
|
* 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;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
|
|
||||||
|
|
||||||
#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
|
|
||||||
/*
|
/*
|
||||||
* This must be implemented by the architecture.
|
* This must be implemented by the architecture.
|
||||||
* It is the way the ftrace direct_ops helper, when called
|
* 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
|
* the return from the trampoline jump to the direct caller
|
||||||
* instead of going back to the function it just traced.
|
* 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) { }
|
unsigned long addr) { }
|
||||||
#endif /* CONFIG_HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
|
#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
|
||||||
|
|
||||||
#ifdef CONFIG_STACK_TRACER
|
#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,
|
static void call_direct_funcs(unsigned long ip, unsigned long pip,
|
||||||
struct ftrace_ops *ops, struct ftrace_regs *fregs)
|
struct ftrace_ops *ops, struct ftrace_regs *fregs)
|
||||||
{
|
{
|
||||||
struct pt_regs *regs = ftrace_get_regs(fregs);
|
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
|
|
||||||
addr = ftrace_find_rec_direct(ip);
|
addr = ftrace_find_rec_direct(ip);
|
||||||
if (!addr)
|
if (!addr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
arch_ftrace_set_direct_caller(regs, addr);
|
arch_ftrace_set_direct_caller(fregs, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ftrace_ops direct_ops = {
|
struct ftrace_ops direct_ops = {
|
||||||
|
|
Loading…
Add table
Reference in a new issue