mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02: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
					
				
					 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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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 a new issue