forked from mirrors/linux
		
	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
	
	 Mark Rutland
						Mark Rutland