ftrace: Updates for 6.13
Steven Rostedt
maintainercover ftrace: Updates for 6.13
git://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace.git
ftrace/for-next
Head SHA1: 3e7814207b41eafafd49e6d8010c07f2d5831891
Masami Hiramatsu (Google) (1):
fgraph: Simplify return address printing in function graph tracer
Steven Rostedt (3):
fgragh: No need to invoke the function call_filter_check_discard()
ftrace: Make ftrace_regs abstract from direct use
ftrace: Consolidate ftrace_regs accessor functions for archs using pt_regs
----
arch/arm64/include/asm/ftrace.h | 21 ++++++------ arch/arm64/kernel/asm-offsets.c | 22 ++++++------- arch/arm64/kernel/ftrace.c | 10 +++--- arch/loongarch/include/asm/ftrace.h | 29 +++-------------- arch/loongarch/kernel/ftrace_dyn.c | 2 +- arch/powerpc/include/asm/ftrace.h | 27 ++-------------- arch/powerpc/kernel/trace/ftrace.c | 4 +-- arch/powerpc/kernel/trace/ftrace_64_pg.c | 2 +- arch/riscv/include/asm/ftrace.h | 22 +++++++------ arch/riscv/kernel/asm-offsets.c | 28 ++++++++-------- arch/riscv/kernel/ftrace.c | 2 +- arch/s390/include/asm/ftrace.h | 29 +++-------------- arch/s390/kernel/asm-offsets.c | 4 +-- arch/s390/kernel/ftrace.c | 2 +- arch/s390/lib/test_unwind.c | 4 +-- arch/x86/include/asm/ftrace.h | 30 ++++------------- arch/x86/kernel/ftrace.c | 2 +- include/linux/ftrace.h | 55 ++++++++++++-------------------- include/linux/ftrace_regs.h | 36 +++++++++++++++++++++ kernel/trace/fgraph.c | 45 ++++++++++++++++---------- kernel/trace/ftrace.c | 5 ++- kernel/trace/trace.h | 3 +- kernel/trace/trace_functions_graph.c | 22 ++++++------- kernel/trace/trace_irqsoff.c | 3 +- kernel/trace/trace_sched_wakeup.c | 3 +- kernel/trace/trace_selftest.c | 8 ++--- 26 files changed, 188 insertions(+), 232 deletions(-) create mode 100644 include/linux/ftrace_regs.h
Steven Rostedt
maintainerPATCH 1/4 fgraph: Simplify return address printing in function graph tracer
From: "Masami Hiramatsu (Google)" <[email protected]>
Simplify return address printing in the function graph tracer by removing fgraph_extras. Since this feature is only used by the function graph tracer and the feature flags can directly accessible from the function graph tracer, fgraph_extras can be removed from the fgraph callback.
--- include/linux/ftrace.h | 16 ++-------- kernel/trace/fgraph.c | 45 ++++++++++++++++++---------- kernel/trace/ftrace.c | 3 +- kernel/trace/trace.h | 3 +- kernel/trace/trace_functions_graph.c | 18 +++++------ kernel/trace/trace_irqsoff.c | 3 +- kernel/trace/trace_sched_wakeup.c | 3 +- kernel/trace/trace_selftest.c | 8 ++--- 8 files changed, 48 insertions(+), 51 deletions(-)
include/linux/ftrace.h +3 -13
@@ -1068,29 +1068,20 @@ struct ftrace_graph_ret {unsigned long long rettime; } __packed; -struct fgraph_extras ;struct fgraph_ops ;/* Type of the callback handlers for tracing function graph*/ typedef void (*trace_func_graph_ret_t )(struct ftrace_graph_ret *,struct fgraph_ops *);/* return */ typedef int (*trace_func_graph_ent_t )(struct ftrace_graph_ent *, -struct fgraph_ops *, -struct fgraph_extras *);/* entry */ +struct fgraph_ops *);/* entry */ extern int ftrace_graph_entry_stub (struct ftrace_graph_ent *trace, -struct fgraph_ops *gops, -struct fgraph_extras *extras); +struct fgraph_ops *gops);bool ftrace_pids_enabled (struct ftrace_ops *ops); #ifdef CONFIG_FUNCTION_GRAPH_TRACER -/* Used to convey some extra datas when creating a graph entry */ -struct fgraph_extras { - u32 flags; - unsigned long retaddr; -}; - struct fgraph_ops { trace_func_graph_ent_t entryfunc; trace_func_graph_ret_t retfunc;
@@ -1131,13 +1122,12 @@ function_graph_enter(unsigned long ret, unsigned long func,struct ftrace_ret_stack *ftrace_graph_get_ret_stack (struct task_struct *task,int skip); +unsigned long ftrace_graph_top_ret_addr (struct task_struct *task);unsigned long ftrace_graph_ret_addr (struct task_struct *task,int *idx,unsigned long ret,unsigned long *retp);unsigned long *fgraph_get_task_var (struct fgraph_ops *gops); -u32 graph_tracer_flags_get (u32 flags); -/* * Sometimes we don't want to trace a function with the function * graph tracer but we want them to keep traced by the usual function
kernel/trace/fgraph.c +29 -16
100 lines not on this page · raw message
kernel/trace/ftrace.c +1 -2
@@ -827,8 +827,7 @@ struct profile_fgraph_data { };static int profile_graph_entry (struct ftrace_graph_ent *trace, -struct fgraph_ops *gops, -struct fgraph_extras *extras) +struct fgraph_ops *gops) {struct profile_fgraph_data *profile_data;
kernel/trace/trace.h +1 -2
@@ -695,8 +695,7 @@ void trace_default_header(struct seq_file *m);void print_trace_header (struct seq_file *m,struct trace_iterator *iter);void trace_graph_return (struct ftrace_graph_ret *trace,struct fgraph_ops *gops); -int trace_graph_entry (struct ftrace_graph_ent *trace,struct fgraph_ops *gops, -struct fgraph_extras *extras); +int trace_graph_entry (struct ftrace_graph_ent *trace,struct fgraph_ops *gops);void tracing_start_cmdline_record (void );void tracing_stop_cmdline_record (void );
kernel/trace/trace_functions_graph.c +9 -9
@@ -90,9 +90,9 @@ static struct tracer_flags tracer_flags = { .opts = trace_opts }; -u32 graph_tracer_flags_get (u32 flags) +static bool tracer_flags_is_set (u32 flags) { -return tracer_flags.val & flags; +return (tracer_flags.val & flags) == flags; }/*
@@ -179,8 +179,7 @@ struct fgraph_times { };int trace_graph_entry (struct ftrace_graph_ent *trace, -struct fgraph_ops *gops, -struct fgraph_extras *extras) +struct fgraph_ops *gops) {unsigned long *task_var =fgraph_get_task_var (gops);struct trace_array *tr = gops->private;
@@ -246,11 +245,12 @@ int trace_graph_entry(struct ftrace_graph_ent *trace, disabled =atomic_inc_return (&data->disabled);if (likely (disabled ==1 )) { trace_ctx =tracing_gen_ctx_flags (flags); -if (unlikely (IS_ENABLED (CONFIG_FUNCTION_GRAPH_RETADDR ) && extras - && (extras->flags &TRACE_GRAPH_PRINT_RETADDR ))) - ret =__trace_graph_retaddr_entry (tr, trace, trace_ctx, - extras->retaddr); -else +if (unlikely (IS_ENABLED (CONFIG_FUNCTION_GRAPH_RETADDR ) && +tracer_flags_is_set (TRACE_GRAPH_PRINT_RETADDR ))) { +unsigned long retaddr =ftrace_graph_top_ret_addr (current); + + ret =__trace_graph_retaddr_entry (tr, trace, trace_ctx, retaddr); + }else ret =__trace_graph_entry (tr, trace, trace_ctx); }else { ret =0 ;
kernel/trace/trace_irqsoff.c +1 -2
@@ -176,8 +176,7 @@ static int irqsoff_display_graph(struct trace_array *tr, int set) }static int irqsoff_graph_entry (struct ftrace_graph_ent *trace, -struct fgraph_ops *gops, -struct fgraph_extras *extras) +struct fgraph_ops *gops) {struct trace_array *tr = irqsoff_trace;struct trace_array_cpu *data;
kernel/trace/trace_sched_wakeup.c +1 -2
@@ -113,8 +113,7 @@ static int wakeup_display_graph(struct trace_array *tr, int set) }static int wakeup_graph_entry (struct ftrace_graph_ent *trace, -struct fgraph_ops *gops, -struct fgraph_extras *extras) +struct fgraph_ops *gops) {struct trace_array *tr = wakeup_trace;struct trace_array_cpu *data;
kernel/trace/trace_selftest.c +3 -5
@@ -774,8 +774,7 @@ struct fgraph_fixture { };static __init int store_entry (struct ftrace_graph_ent *trace, -struct fgraph_ops *gops, -struct fgraph_extras *extras) +struct fgraph_ops *gops) { struct fgraph_fixture *fixture = container_of(gops, struct fgraph_fixture, gops);const char *type = fixture->store_type_name;
@@ -1026,8 +1025,7 @@ static unsigned int graph_hang_thresh;/* Wrap the real function entry probe to avoid possible hanging */ static int trace_graph_entry_watchdog (struct ftrace_graph_ent *trace, -struct fgraph_ops *gops, -struct fgraph_extras *extras) +struct fgraph_ops *gops) {/* This is harmlessly racy, we want to approximately detect a hang */ if (unlikely (++graph_hang_thresh >GRAPH_MAX_FUNC_TEST )) {
@@ -1041,7 +1039,7 @@ static int trace_graph_entry_watchdog(struct ftrace_graph_ent *trace,return 0 ; } -return trace_graph_entry (trace, gops,NULL ); +return trace_graph_entry (trace, gops); }static struct fgraph_ops fgraph_ops__initdata = {
Signature · 1 line
2.45.2
Steven Rostedt
maintainerPATCH 2/4 fgragh: No need to invoke the function call_filter_check_discard()
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
The function call_filter_check_discard() has been removed in the commit 49e4154f4b16 ("tracing: Remove TRACE_EVENT_FL_FILTERED logic"), from another topic branch. But when merged together with commit 21e92806d39c6 ("function_graph: Support recording and printing the function return address") which added another call to call_filter_check_discard(), it caused the build to fail. Since the function call_filter_check_discard() is useless, it can simply be removed regardless of being merged with commit 49e4154f4b16 or not.
--- kernel/trace/trace_functions_graph.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
kernel/trace/trace_functions_graph.c +1 -3
@@ -137,7 +137,6 @@ int __trace_graph_retaddr_entry(struct trace_array *tr, unsigned int trace_ctx, unsigned long retaddr) { -struct trace_event_call *call = &event_fgraph_retaddr_entry;struct ring_buffer_event *event;struct trace_buffer *buffer = tr->array_buffer.buffer;struct fgraph_retaddr_ent_entry *entry;
@@ -150,8 +149,7 @@ int __trace_graph_retaddr_entry(struct trace_array *tr, entry->graph_ent.func = trace->func; entry->graph_ent.depth = trace->depth; entry->graph_ent.retaddr = retaddr; -if (!call_filter_check_discard (call, entry, buffer, event)) -trace_buffer_unlock_commit_nostack (buffer, event); +trace_buffer_unlock_commit_nostack (buffer, event);return 1 ; }
Signature · 1 line
2.45.2
Steven Rostedt
maintainerPATCH 3/4 ftrace: Make ftrace_regs abstract from direct use
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
ftrace_regs was created to hold registers that store information to save function parameters, return value and stack. Since it is a subset of pt_regs, it should only be used by its accessor functions. But because pt_regs can easily be taken from ftrace_regs (on most archs), it is tempting to use it directly. But when running on other architectures, it may fail to build or worse, build but crash the kernel!
Instead, make struct ftrace_regs an empty structure and have the architectures define __arch_ftrace_regs and all the accessor functions will typecast to it to get to the actual fields. This will help avoid usage of ftrace_regs directly.
--- arch/arm64/include/asm/ftrace.h | 20 +++++++++-------- arch/arm64/kernel/asm-offsets.c | 22 +++++++++---------- arch/arm64/kernel/ftrace.c | 10 ++++----- arch/loongarch/include/asm/ftrace.h | 22 ++++++++++--------- arch/loongarch/kernel/ftrace_dyn.c | 2 +- arch/powerpc/include/asm/ftrace.h | 21 ++++++++++-------- arch/powerpc/kernel/trace/ftrace.c | 4 ++-- arch/powerpc/kernel/trace/ftrace_64_pg.c | 2 +- arch/riscv/include/asm/ftrace.h | 21 ++++++++++-------- arch/riscv/kernel/asm-offsets.c | 28 ++++++++++++------------ arch/riscv/kernel/ftrace.c | 2 +- arch/s390/include/asm/ftrace.h | 23 ++++++++++--------- arch/s390/kernel/asm-offsets.c | 4 ++-- arch/s390/kernel/ftrace.c | 2 +- arch/s390/lib/test_unwind.c | 4 ++-- arch/x86/include/asm/ftrace.h | 25 +++++++++++---------- arch/x86/kernel/ftrace.c | 2 +- include/linux/ftrace.h | 21 +++++++++++++++--- kernel/trace/ftrace.c | 2 +- 19 files changed, 134 insertions(+), 103 deletions(-)
arch/arm64/include/asm/ftrace.h +11 -9
@@ -56,6 +56,8 @@ unsigned long ftrace_call_adjust(unsigned long addr);#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS struct dyn_ftrace ;struct ftrace_ops ; +struct ftrace_regs ; +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs))#define arch_ftrace_get_regs (regs) NULL
@@ -63,7 +65,7 @@ struct ftrace_ops;* Note: sizeof(struct ftrace_regs) must be a multiple of 16 to ensure correct * stack alignment */ -struct ftrace_regs { +struct __arch_ftrace_regs {/* x0 - x8 */ unsigned long regs[9 ];
@@ -83,47 +85,47 @@ struct ftrace_regs {static __always_inline unsigned long ftrace_regs_get_instruction_pointer (const struct ftrace_regs *fregs) { -return fregs->pc; +return arch_ftrace_regs (fregs)->pc; } static __always_inline voidftrace_regs_set_instruction_pointer (struct ftrace_regs *fregs,unsigned long pc) { - fregs->pc = pc; +arch_ftrace_regs (fregs)->pc = pc; }static __always_inline unsigned long ftrace_regs_get_stack_pointer (const struct ftrace_regs *fregs) { -return fregs->sp; +return arch_ftrace_regs (fregs)->sp; }static __always_inline unsigned long ftrace_regs_get_argument (struct ftrace_regs *fregs,unsigned int n) {if (n <8 ) -return fregs->regs[n]; +return arch_ftrace_regs (fregs)->regs[n];return 0 ; }static __always_inline unsigned long ftrace_regs_get_return_value (const struct ftrace_regs *fregs) { -return fregs->regs[0 ]; +return arch_ftrace_regs (fregs)->regs[0 ]; } static __always_inline voidftrace_regs_set_return_value (struct ftrace_regs *fregs,unsigned long ret) { - fregs->regs[0 ] = ret; +arch_ftrace_regs (fregs)->regs[0 ] = ret; } static __always_inline voidftrace_override_function_with_return (struct ftrace_regs *fregs) { - fregs->pc = fregs->lr; +arch_ftrace_regs (fregs)->pc =arch_ftrace_regs (fregs)->lr; }int ftrace_regs_query_register_offset (const char *name);
@@ -143,7 +145,7 @@ static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs,* The ftrace trampoline will return to this address instead of the * instrumented function. */ - fregs->direct_tramp = addr; + arch_ftrace_regs(fregs)->direct_tramp = addr; }#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
arch/arm64/kernel/asm-offsets.c +11 -11
@@ -84,19 +84,19 @@ int main(void)DEFINE (PT_REGS_SIZE ,sizeof (struct pt_regs ));BLANK ();#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS - DEFINE(FREGS_X0, offsetof(struct ftrace_regs, regs[0])); - DEFINE(FREGS_X2, offsetof(struct ftrace_regs, regs[2])); - DEFINE(FREGS_X4, offsetof(struct ftrace_regs, regs[4])); - DEFINE(FREGS_X6, offsetof(struct ftrace_regs, regs[6])); - DEFINE(FREGS_X8, offsetof(struct ftrace_regs, regs[8])); -DEFINE (FREGS_FP , offsetof(struct ftrace_regs , fp)); -DEFINE (FREGS_LR , offsetof(struct ftrace_regs , lr)); -DEFINE (FREGS_SP , offsetof(struct ftrace_regs , sp)); -DEFINE (FREGS_PC , offsetof(struct ftrace_regs , pc)); + DEFINE(FREGS_X0, offsetof(struct __arch_ftrace_regs, regs[0])); + DEFINE(FREGS_X2, offsetof(struct __arch_ftrace_regs, regs[2])); + DEFINE(FREGS_X4, offsetof(struct __arch_ftrace_regs, regs[4])); + DEFINE(FREGS_X6, offsetof(struct __arch_ftrace_regs, regs[6])); + DEFINE(FREGS_X8, offsetof(struct __arch_ftrace_regs, regs[8])); +DEFINE (FREGS_FP , offsetof(struct __arch_ftrace_regs , fp)); +DEFINE (FREGS_LR , offsetof(struct __arch_ftrace_regs , lr)); +DEFINE (FREGS_SP , offsetof(struct __arch_ftrace_regs , sp)); +DEFINE (FREGS_PC , offsetof(struct __arch_ftrace_regs , pc));#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS -DEFINE (FREGS_DIRECT_TRAMP , offsetof(struct ftrace_regs , direct_tramp)); +DEFINE (FREGS_DIRECT_TRAMP , offsetof(struct __arch_ftrace_regs , direct_tramp));#endif -DEFINE (FREGS_SIZE ,sizeof (struct ftrace_regs )); +DEFINE (FREGS_SIZE ,sizeof (struct __arch_ftrace_regs ));BLANK ();#endif #ifdef CONFIG_COMPAT
arch/arm64/kernel/ftrace.c +5 -5
@@ -23,10 +23,10 @@ struct fregs_offset {int offset; }; -#define FREGS_OFFSET (n, field) \ -{ \ - .name = n, \ - .offset = offsetof(struct ftrace_regs, field), \ +#define FREGS_OFFSET (n, field) \ +{ \ + .name = n, \ + .offset = offsetof(struct __arch_ftrace_regs, field), \ }static const struct fregs_offset fregs_offsets[] = {
@@ -481,7 +481,7 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,void ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { -prepare_ftrace_return (ip, &fregs->lr, fregs->fp); +prepare_ftrace_return (ip, &arch_ftrace_regs (fregs)->lr,arch_ftrace_regs (fregs)->fp); }#else /*
arch/loongarch/include/asm/ftrace.h +12 -10
@@ -43,38 +43,40 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent);#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS struct ftrace_ops ; +struct ftrace_regs ; +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) -struct ftrace_regs { +struct __arch_ftrace_regs {struct pt_regs regs; }; static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs) { -return &fregs->regs; +return &arch_ftrace_regs (fregs)->regs; }static __always_inline unsigned long ftrace_regs_get_instruction_pointer (struct ftrace_regs *fregs) { -return instruction_pointer (&fregs->regs); +return instruction_pointer (&arch_ftrace_regs (fregs)->regs); } static __always_inline voidftrace_regs_set_instruction_pointer (struct ftrace_regs *fregs,unsigned long ip) { -instruction_pointer_set (&fregs->regs, ip); +instruction_pointer_set (&arch_ftrace_regs (fregs)->regs, ip); }#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(&(fregs)->regs, n) + regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n)#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(&(fregs)->regs) + kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_return_value (fregs) \ - regs_return_value(&(fregs)->regs) + regs_return_value(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(&(fregs)->regs, ret) + regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret)#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(&(fregs)->regs) + override_function_with_return(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_query_register_offset (name) \ regs_query_register_offset(name)
@@ -90,7 +92,7 @@ __arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr) }#define arch_ftrace_set_direct_caller (fregs, addr) \ - __arch_ftrace_set_direct_caller(&(fregs)->regs, addr) + __arch_ftrace_set_direct_caller(&arch_ftrace_regs(fregs)->regs, addr)#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ #endif
arch/loongarch/kernel/ftrace_dyn.c +1 -1
@@ -241,7 +241,7 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent)void ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { -struct pt_regs *regs = &fregs->regs; +struct pt_regs *regs = &arch_ftrace_regs (fregs)->regs;unsigned long *parent = (unsigned long *)®s->regs[1 ];prepare_ftrace_return (ip, (unsigned long *)parent);
arch/powerpc/include/asm/ftrace.h +12 -9
@@ -32,39 +32,42 @@ struct dyn_arch_ftrace {int ftrace_init_nop (struct module *mod,struct dyn_ftrace *rec);#define ftrace_init_nop ftrace_init_nop -struct ftrace_regs { +struct ftrace_regs ; +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) + +struct __arch_ftrace_regs {struct pt_regs regs; }; static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs) {/* We clear regs.msr in ftrace_call */ -return fregs->regs.msr ? &fregs->regs :NULL ; +return arch_ftrace_regs (fregs)->regs.msr ? &arch_ftrace_regs (fregs)->regs :NULL ; } static __always_inline voidftrace_regs_set_instruction_pointer (struct ftrace_regs *fregs,unsigned long ip) { -regs_set_return_ip (&fregs->regs, ip); +regs_set_return_ip (&arch_ftrace_regs (fregs)->regs, ip); }static __always_inline unsigned long ftrace_regs_get_instruction_pointer (struct ftrace_regs *fregs) { -return instruction_pointer (&fregs->regs); +return instruction_pointer (&arch_ftrace_regs (fregs)->regs); }#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(&(fregs)->regs, n) + regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n)#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(&(fregs)->regs) + kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_return_value (fregs) \ - regs_return_value(&(fregs)->regs) + regs_return_value(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(&(fregs)->regs, ret) + regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret)#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(&(fregs)->regs) + override_function_with_return(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_query_register_offset (name) \ regs_query_register_offset(name)
arch/powerpc/kernel/trace/ftrace.c +2 -2
@@ -421,7 +421,7 @@ int __init ftrace_dyn_arch_init(void)void ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { -unsigned long sp = fregs->regs.gpr[1 ]; +unsigned long sp =arch_ftrace_regs (fregs)->regs.gpr[1 ];int bit;if (unlikely (ftrace_graph_is_dead ()))
@@ -439,6 +439,6 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,ftrace_test_recursion_unlock (bit); out: - fregs->regs.link = parent_ip; + arch_ftrace_regs(fregs)->regs.link = parent_ip; }#endif /* CONFIG_FUNCTION_GRAPH_TRACER */
arch/powerpc/kernel/trace/ftrace_64_pg.c +1 -1
@@ -829,7 +829,7 @@ __prepare_ftrace_return(unsigned long parent, unsigned long ip, unsigned long spvoid ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { - fregs->regs.link =__prepare_ftrace_return (parent_ip, ip, fregs->regs.gpr[1 ]); +arch_ftrace_regs (fregs)->regs.link =__prepare_ftrace_return (parent_ip, ip,arch_ftrace_regs (fregs)->regs.gpr[1 ]); }#else unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip,
arch/riscv/include/asm/ftrace.h +12 -9
@@ -126,7 +126,10 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec); #ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS #define arch_ftrace_get_regs(regs) NULL struct ftrace_ops; -struct ftrace_regs { +struct ftrace_regs; +#define arch_ftrace_regs(fregs) ((struct __arch_ftrace_regs *)(fregs)) + +struct __arch_ftrace_regs { unsigned long epc; unsigned long ra; unsigned long sp;
@@ -150,42 +153,42 @@ struct ftrace_regs {static __always_inline unsigned long ftrace_regs_get_instruction_pointer (const struct ftrace_regs *fregs) { -return fregs->epc; +return arch_ftrace_regs (fregs)->epc; } static __always_inline void ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,unsigned long pc) { - fregs->epc = pc; +arch_ftrace_regs (fregs)->epc = pc; }static __always_inline unsigned long ftrace_regs_get_stack_pointer (const struct ftrace_regs *fregs) { -return fregs->sp; +return arch_ftrace_regs (fregs)->sp; }static __always_inline unsigned long ftrace_regs_get_argument (struct ftrace_regs *fregs,unsigned int n) {if (n <8 ) -return fregs->args[n]; +return arch_ftrace_regs (fregs)->args[n];return 0 ; }static __always_inline unsigned long ftrace_regs_get_return_value (const struct ftrace_regs *fregs) { -return fregs->a0; +return arch_ftrace_regs (fregs)->a0; } static __always_inline void ftrace_regs_set_return_value(struct ftrace_regs *fregs,unsigned long ret) { - fregs->a0 = ret; +arch_ftrace_regs (fregs)->a0 = ret; } static __always_inline void ftrace_override_function_with_return(struct ftrace_regs *fregs) { - fregs->epc = fregs->ra; +arch_ftrace_regs (fregs)->epc =arch_ftrace_regs (fregs)->ra; }int ftrace_regs_query_register_offset (const char *name);
@@ -196,7 +199,7 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,static inline void arch_ftrace_set_direct_caller (struct ftrace_regs *fregs,unsigned long addr) { - fregs->t1 = addr; +arch_ftrace_regs (fregs)->t1 = addr; }#endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */
arch/riscv/kernel/asm-offsets.c +14 -14
@@ -498,19 +498,19 @@ void asm_offsets(void)OFFSET (STACKFRAME_RA , stackframe, ra);#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS -DEFINE (FREGS_SIZE_ON_STACK ,ALIGN (sizeof (struct ftrace_regs ),STACK_ALIGN )); -DEFINE (FREGS_EPC , offsetof(struct ftrace_regs , epc)); -DEFINE (FREGS_RA , offsetof(struct ftrace_regs , ra)); -DEFINE (FREGS_SP , offsetof(struct ftrace_regs , sp)); -DEFINE (FREGS_S0 , offsetof(struct ftrace_regs , s0)); -DEFINE (FREGS_T1 , offsetof(struct ftrace_regs , t1)); -DEFINE (FREGS_A0 , offsetof(struct ftrace_regs , a0)); -DEFINE (FREGS_A1 , offsetof(struct ftrace_regs , a1)); -DEFINE (FREGS_A2 , offsetof(struct ftrace_regs , a2)); -DEFINE (FREGS_A3 , offsetof(struct ftrace_regs , a3)); -DEFINE (FREGS_A4 , offsetof(struct ftrace_regs , a4)); -DEFINE (FREGS_A5 , offsetof(struct ftrace_regs , a5)); -DEFINE (FREGS_A6 , offsetof(struct ftrace_regs , a6)); -DEFINE (FREGS_A7 , offsetof(struct ftrace_regs , a7)); +DEFINE (FREGS_SIZE_ON_STACK ,ALIGN (sizeof (struct __arch_ftrace_regs ),STACK_ALIGN )); +DEFINE (FREGS_EPC , offsetof(struct __arch_ftrace_regs , epc)); +DEFINE (FREGS_RA , offsetof(struct __arch_ftrace_regs , ra)); +DEFINE (FREGS_SP , offsetof(struct __arch_ftrace_regs , sp)); +DEFINE (FREGS_S0 , offsetof(struct __arch_ftrace_regs , s0)); +DEFINE (FREGS_T1 , offsetof(struct __arch_ftrace_regs , t1)); +DEFINE (FREGS_A0 , offsetof(struct __arch_ftrace_regs , a0)); +DEFINE (FREGS_A1 , offsetof(struct __arch_ftrace_regs , a1)); +DEFINE (FREGS_A2 , offsetof(struct __arch_ftrace_regs , a2)); +DEFINE (FREGS_A3 , offsetof(struct __arch_ftrace_regs , a3)); +DEFINE (FREGS_A4 , offsetof(struct __arch_ftrace_regs , a4)); +DEFINE (FREGS_A5 , offsetof(struct __arch_ftrace_regs , a5)); +DEFINE (FREGS_A6 , offsetof(struct __arch_ftrace_regs , a6)); +DEFINE (FREGS_A7 , offsetof(struct __arch_ftrace_regs , a7));#endif }
arch/riscv/kernel/ftrace.c +1 -1
@@ -214,7 +214,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,void ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { -prepare_ftrace_return (&fregs->ra, ip, fregs->s0); +prepare_ftrace_return (&arch_ftrace_regs (fregs)->ra, ip,arch_ftrace_regs (fregs)->s0); }#else /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */ extern void ftrace_graph_call (void );
arch/s390/include/asm/ftrace.h +13 -10
@@ -51,13 +51,16 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)return addr; } -struct ftrace_regs { +struct ftrace_regs ; +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) + +struct __arch_ftrace_regs {struct pt_regs regs; }; static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs) { -struct pt_regs *regs = &fregs->regs; +struct pt_regs *regs = &arch_ftrace_regs (fregs)->regs;if (test_pt_regs_flag (regs,PIF_FTRACE_FULL_REGS ))return regs;
@@ -84,26 +87,26 @@ static __always_inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraphstatic __always_inline unsigned long ftrace_regs_get_instruction_pointer (const struct ftrace_regs *fregs) { -return fregs->regs.psw.addr; +return arch_ftrace_regs (fregs)->regs.psw.addr; } static __always_inline voidftrace_regs_set_instruction_pointer (struct ftrace_regs *fregs,unsigned long ip) { - fregs->regs.psw.addr = ip; +arch_ftrace_regs (fregs)->regs.psw.addr = ip; }#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(&(fregs)->regs, n) + regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n)#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(&(fregs)->regs) + kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_return_value (fregs) \ - regs_return_value(&(fregs)->regs) + regs_return_value(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(&(fregs)->regs, ret) + regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret)#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(&(fregs)->regs) + override_function_with_return(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_query_register_offset (name) \ regs_query_register_offset(name)
@@ -117,7 +120,7 @@ ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,*/ static inline void arch_ftrace_set_direct_caller (struct ftrace_regs *fregs,unsigned long addr) { -struct pt_regs *regs = &fregs->regs; +struct pt_regs *regs = &arch_ftrace_regs (fregs)->regs; regs->orig_gpr2 = addr; }#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */
arch/s390/kernel/asm-offsets.c +2 -2
@@ -184,8 +184,8 @@ int main(void)OFFSET (__FGRAPH_RET_FP, fgraph_ret_regs, fp);DEFINE (__FGRAPH_RET_SIZE,sizeof (struct fgraph_ret_regs ));#endif -OFFSET (__FTRACE_REGS_PT_REGS, ftrace_regs, regs); -DEFINE (__FTRACE_REGS_SIZE,sizeof (struct ftrace_regs )); +OFFSET (__FTRACE_REGS_PT_REGS, __arch_ftrace_regs, regs); +DEFINE (__FTRACE_REGS_SIZE,sizeof (struct __arch_ftrace_regs ));OFFSET (__PCPU_FLAGS, pcpu, flags);return 0 ;
arch/s390/kernel/ftrace.c +1 -1
@@ -318,7 +318,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,if (bit <0 )return ; -kmsan_unpoison_memory (fregs,sizeof (*fregs)); +kmsan_unpoison_memory (fregs,ftrace_regs_size ()); regs =ftrace_get_regs (fregs); p =get_kprobe ((kprobe_opcode_t *)ip);if (!regs ||unlikely (!p) ||kprobe_disabled (p))
arch/s390/lib/test_unwind.c +2 -2
@@ -270,9 +270,9 @@ static void notrace __used test_unwind_ftrace_handler(unsigned long ip,struct ftrace_ops *fops, struct ftrace_regs *fregs) { - struct unwindme *u = (struct unwindme *)fregs->regs.gprs[2]; + struct unwindme *u = (struct unwindme *)arch_ftrace_regs(fregs)->regs.gprs[2]; - u->ret =test_unwind (NULL , (u->flags &UWM_REGS ) ? &fregs->regs :NULL , + u->ret =test_unwind (NULL , (u->flags &UWM_REGS ) ? &arch_ftrace_regs (fregs)->regs :NULL , (u->flags &UWM_SP ) ? u->sp :0 ); }
arch/x86/include/asm/ftrace.h +14 -11
@@ -33,7 +33,10 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) }#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS -struct ftrace_regs { +struct ftrace_regs ; +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) + +struct __arch_ftrace_regs {struct pt_regs regs; };
@@ -41,27 +44,27 @@ static __always_inline struct pt_regs * arch_ftrace_get_regs(struct ftrace_regs *fregs) {/* Only when FL_SAVE_REGS is set, cs will be non zero */ -if (!fregs->regs.cs) +if (!arch_ftrace_regs (fregs)->regs.cs)return NULL ; -return &fregs->regs; +return &arch_ftrace_regs (fregs)->regs; }#define ftrace_regs_set_instruction_pointer (fregs, _ip) \ - do { (fregs)->regs.ip = (_ip); } while (0) + do { arch_ftrace_regs(fregs)->regs.ip = (_ip); } while (0)#define ftrace_regs_get_instruction_pointer (fregs) \ - ((fregs)->regs.ip) + arch_ftrace_regs(fregs)->regs.ip)#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(&(fregs)->regs, n) + regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n)#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(&(fregs)->regs) + kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_return_value (fregs) \ - regs_return_value(&(fregs)->regs) + regs_return_value(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(&(fregs)->regs, ret) + regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret)#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(&(fregs)->regs) + override_function_with_return(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_query_register_offset (name) \ regs_query_register_offset(name)
@@ -88,7 +91,7 @@ __arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr) regs->orig_ax = addr; }#define arch_ftrace_set_direct_caller (fregs, addr) \ - __arch_ftrace_set_direct_caller(&(fregs)->regs, addr) + __arch_ftrace_set_direct_caller(&arch_ftrace_regs(fregs)->regs, addr)#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ #ifdef CONFIG_DYNAMIC_FTRACE
arch/x86/kernel/ftrace.c +1 -1
@@ -647,7 +647,7 @@ void prepare_ftrace_return(unsigned long ip, unsigned long *parent,void ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { -struct pt_regs *regs = &fregs->regs; +struct pt_regs *regs = &arch_ftrace_regs (fregs)->regs;unsigned long *stack = (unsigned long *)kernel_stack_pointer (regs);prepare_ftrace_return (ip, (unsigned long *)stack,0 );
include/linux/ftrace.h +18 -3
@@ -115,8 +115,6 @@ static inline int ftrace_mod_get_kallsym(unsigned int symnum, unsigned long *valextern int ftrace_enabled; -#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS -/** * ftrace_regs - ftrace partial/optimal register set *
@@ -142,11 +140,28 @@ extern int ftrace_enabled;* * NOTE: user *must not* access regs directly, only do it via APIs, because * the member can be changed according to the architecture. +* This is why the structure is empty here, so that nothing accesses +* the ftrace_regs directly. */ struct ftrace_regs { +/* Nothing to see here, use the accessor functions! */ +}; + +#define ftrace_regs_size () sizeof(struct __arch_ftrace_regs) + +#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS + +struct __arch_ftrace_regs {struct pt_regs regs; }; -#define arch_ftrace_get_regs (fregs) (&(fregs)->regs) + +struct ftrace_regs ; +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) + +static inline struct pt_regs *arch_ftrace_get_regs (struct ftrace_regs *fregs) +{ +return &arch_ftrace_regs (fregs)->regs; +}/* * ftrace_regs_set_instruction_pointer() is to be defined by the architecture
kernel/trace/ftrace.c +1 -1
@@ -7943,7 +7943,7 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip,void arch_ftrace_ops_list_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { -kmsan_unpoison_memory (fregs,sizeof (*fregs)); +kmsan_unpoison_memory (fregs,ftrace_regs_size ());__ftrace_ops_list_func (ip, parent_ip,NULL , fregs); }#else
Signature · 1 line
2.45.2
Madhavan Srinivasan
maintainerRe: [for-next][PATCH 3/4] ftrace: Make ftrace_regs abstract from direct use
Quoted 9 lines · Steven Rostedt
From: Steven Rostedt <[email protected]>
ftrace_regswas created to hold registers that store information to save function parameters, return value and stack. Since it is a subset ofpt_regs, it should only be used by its accessor functions. But becausept_regscan easily be taken fromftrace_regs(on most archs), it is tempting to use it directly. But when running on other architectures, it may fail to build or worse, build but crash the kernel!
Quoted 7 lines
Instead, make struct
ftrace_regsan empty structure and have the architectures define__arch_ftrace_regsand all the accessor functions will typecast to it to get to the actual fields. This will help avoid usage offtrace_regsdirectly.
I could build your for-next branch both ppc[64/32] fine with config_bcachefs_fs=n.
Quoted 734 lines
Cc Mathieu Desnoyers <[email protected]>Cc Mark Rutland <[email protected]>Cc Will Deacon <[email protected]>Cc Huacai Chen <[email protected]>Cc WANG Xuerui <[email protected]>Cc Michael Ellerman <[email protected]>Cc Nicholas Piggin <[email protected]>Cc Christophe Leroy <[email protected]>Cc Naveen N Rao <[email protected]>Cc Madhavan Srinivasan <[email protected]>Cc Paul Walmsley <[email protected]>Cc Palmer Dabbelt <[email protected]>Cc Albert Ou <[email protected]>Cc Heiko Carstens <[email protected]>Cc Vasily Gorbik <[email protected]>Cc Alexander Gordeev <[email protected]>Cc Christian Borntraeger <[email protected]>Cc Sven Schnelle <[email protected]>Cc Thomas Gleixner <[email protected]>Cc Ingo Molnar <[email protected]>Cc Borislav Petkov <[email protected]>Cc Dave Hansen <[email protected]>Acked-by Catalin Marinas <[email protected]>Signed-off-by Steven Rostedt (Google) <[email protected]>Signed-off-by Steven Rostedt (Google) <[email protected]>--- arch/arm64/include/asm/ftrace.h | 20 +++++++++-------- arch/arm64/kernel/asm-offsets.c | 22 +++++++++---------- arch/arm64/kernel/ftrace.c | 10 ++++----- arch/loongarch/include/asm/ftrace.h | 22 ++++++++++--------- arch/loongarch/kernel/ftrace_dyn.c | 2 +- arch/powerpc/include/asm/ftrace.h | 21 ++++++++++-------- arch/powerpc/kernel/trace/ftrace.c | 4 ++-- arch/powerpc/kernel/trace/ftrace_64_pg.c | 2 +- arch/riscv/include/asm/ftrace.h | 21 ++++++++++-------- arch/riscv/kernel/asm-offsets.c | 28 ++++++++++++------------ arch/riscv/kernel/ftrace.c | 2 +- arch/s390/include/asm/ftrace.h | 23 ++++++++++--------- arch/s390/kernel/asm-offsets.c | 4 ++-- arch/s390/kernel/ftrace.c | 2 +- arch/s390/lib/test_unwind.c | 4 ++-- arch/x86/include/asm/ftrace.h | 25 +++++++++++---------- arch/x86/kernel/ftrace.c | 2 +- include/linux/ftrace.h | 21 +++++++++++++++--- kernel/trace/ftrace.c | 2 +- 19 files changed, 134 insertions(+), 103 deletions(-)arch/arm64/include/asm/ftrace.h +11
-9@@ -56,6 +56,8 @@ unsigned long ftrace_call_adjust(unsigned long addr);#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS struct dyn_ftrace ;struct ftrace_ops ; +struct ftrace_regs ; +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs))#define arch_ftrace_get_regs (regs) NULL@@ -63,7 +65,7 @@ struct ftrace_ops;* Note: sizeof(struct ftrace_regs) must be a multiple of 16 to ensure correct * stack alignment */ -struct ftrace_regs { +struct __arch_ftrace_regs {/* x0 - x8 */ unsigned long regs[9 ];@@ -83,47 +85,47 @@ struct ftrace_regs {static __always_inline unsigned long ftrace_regs_get_instruction_pointer (const struct ftrace_regs *fregs) { -return fregs->pc; +return arch_ftrace_regs (fregs)->pc; } static __always_inline voidftrace_regs_set_instruction_pointer (struct ftrace_regs *fregs,unsigned long pc) { - fregs->pc = pc; +arch_ftrace_regs (fregs)->pc = pc; }static __always_inline unsigned long ftrace_regs_get_stack_pointer (const struct ftrace_regs *fregs) { -return fregs->sp; +return arch_ftrace_regs (fregs)->sp; }static __always_inline unsigned long ftrace_regs_get_argument (struct ftrace_regs *fregs,unsigned int n) {if (n <8 ) -return fregs->regs[n]; +return arch_ftrace_regs (fregs)->regs[n];return 0 ; }static __always_inline unsigned long ftrace_regs_get_return_value (const struct ftrace_regs *fregs) { -return fregs->regs[0 ]; +return arch_ftrace_regs (fregs)->regs[0 ]; } static __always_inline voidftrace_regs_set_return_value (struct ftrace_regs *fregs,unsigned long ret) { - fregs->regs[0 ] = ret; +arch_ftrace_regs (fregs)->regs[0 ] = ret; } static __always_inline voidftrace_override_function_with_return (struct ftrace_regs *fregs) { - fregs->pc = fregs->lr; +arch_ftrace_regs (fregs)->pc =arch_ftrace_regs (fregs)->lr; }int ftrace_regs_query_register_offset (const char *name);@@ -143,7 +145,7 @@ static inline void arch_ftrace_set_direct_caller(struct ftrace_regs *fregs,* The ftrace trampoline will return to this address instead of the * instrumented function. */ - fregs->direct_tramp = addr; + arch_ftrace_regs(fregs)->direct_tramp = addr; }#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ arch/arm64/kernel/asm-offsets.c +11
-11@@ -84,19 +84,19 @@ int main(void)DEFINE (PT_REGS_SIZE ,sizeof (struct pt_regs ));BLANK ();#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS - DEFINE(FREGS_X0, offsetof(struct ftrace_regs, regs[0])); - DEFINE(FREGS_X2, offsetof(struct ftrace_regs, regs[2])); - DEFINE(FREGS_X4, offsetof(struct ftrace_regs, regs[4])); - DEFINE(FREGS_X6, offsetof(struct ftrace_regs, regs[6])); - DEFINE(FREGS_X8, offsetof(struct ftrace_regs, regs[8])); -DEFINE (FREGS_FP , offsetof(struct ftrace_regs , fp)); -DEFINE (FREGS_LR , offsetof(struct ftrace_regs , lr)); -DEFINE (FREGS_SP , offsetof(struct ftrace_regs , sp)); -DEFINE (FREGS_PC , offsetof(struct ftrace_regs , pc)); + DEFINE(FREGS_X0, offsetof(struct __arch_ftrace_regs, regs[0])); + DEFINE(FREGS_X2, offsetof(struct __arch_ftrace_regs, regs[2])); + DEFINE(FREGS_X4, offsetof(struct __arch_ftrace_regs, regs[4])); + DEFINE(FREGS_X6, offsetof(struct __arch_ftrace_regs, regs[6])); + DEFINE(FREGS_X8, offsetof(struct __arch_ftrace_regs, regs[8])); +DEFINE (FREGS_FP , offsetof(struct __arch_ftrace_regs , fp)); +DEFINE (FREGS_LR , offsetof(struct __arch_ftrace_regs , lr)); +DEFINE (FREGS_SP , offsetof(struct __arch_ftrace_regs , sp)); +DEFINE (FREGS_PC , offsetof(struct __arch_ftrace_regs , pc));#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS -DEFINE (FREGS_DIRECT_TRAMP , offsetof(struct ftrace_regs , direct_tramp)); +DEFINE (FREGS_DIRECT_TRAMP , offsetof(struct __arch_ftrace_regs , direct_tramp));#endif -DEFINE (FREGS_SIZE ,sizeof (struct ftrace_regs )); +DEFINE (FREGS_SIZE ,sizeof (struct __arch_ftrace_regs ));BLANK ();#endif #ifdef CONFIG_COMPAT arch/arm64/kernel/ftrace.c +5
-5@@ -23,10 +23,10 @@ struct fregs_offset {int offset; }; -#define FREGS_OFFSET (n, field) \ -{ \ - .name = n, \ - .offset = offsetof(struct ftrace_regs, field), \ +#define FREGS_OFFSET (n, field) \ +{ \ + .name = n, \ + .offset = offsetof(struct __arch_ftrace_regs, field), \ }static const struct fregs_offset fregs_offsets[] = {@@ -481,7 +481,7 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent,void ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { -prepare_ftrace_return (ip, &fregs->lr, fregs->fp); +prepare_ftrace_return (ip, &arch_ftrace_regs (fregs)->lr,arch_ftrace_regs (fregs)->fp); }#else /* arch/loongarch/include/asm/ftrace.h +12
-10@@ -43,38 +43,40 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent);#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS struct ftrace_ops ; +struct ftrace_regs ; +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) -struct ftrace_regs { +struct __arch_ftrace_regs {struct pt_regs regs; }; static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs) { -return &fregs->regs; +return &arch_ftrace_regs (fregs)->regs; }static __always_inline unsigned long ftrace_regs_get_instruction_pointer (struct ftrace_regs *fregs) { -return instruction_pointer (&fregs->regs); +return instruction_pointer (&arch_ftrace_regs (fregs)->regs); } static __always_inline voidftrace_regs_set_instruction_pointer (struct ftrace_regs *fregs,unsigned long ip) { -instruction_pointer_set (&fregs->regs, ip); +instruction_pointer_set (&arch_ftrace_regs (fregs)->regs, ip); }#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(&(fregs)->regs, n) + regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n)#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(&(fregs)->regs) + kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_return_value (fregs) \ - regs_return_value(&(fregs)->regs) + regs_return_value(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(&(fregs)->regs, ret) + regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret)#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(&(fregs)->regs) + override_function_with_return(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_query_register_offset (name) \ regs_query_register_offset(name)@@ -90,7 +92,7 @@ __arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr) }#define arch_ftrace_set_direct_caller (fregs, addr) \ - __arch_ftrace_set_direct_caller(&(fregs)->regs, addr) + __arch_ftrace_set_direct_caller(&arch_ftrace_regs(fregs)->regs, addr)#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ #endif arch/loongarch/kernel/ftrace_dyn.c +1
-1@@ -241,7 +241,7 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent)void ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { -struct pt_regs *regs = &fregs->regs; +struct pt_regs *regs = &arch_ftrace_regs (fregs)->regs;unsigned long *parent = (unsigned long *)®s->regs[1 ];prepare_ftrace_return (ip, (unsigned long *)parent);arch/powerpc/include/asm/ftrace.h +12
-9@@ -32,39 +32,42 @@ struct dyn_arch_ftrace {int ftrace_init_nop (struct module *mod,struct dyn_ftrace *rec);#define ftrace_init_nop ftrace_init_nop -struct ftrace_regs { +struct ftrace_regs ; +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) + +struct __arch_ftrace_regs {struct pt_regs regs; }; static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs) {/* We clear regs.msr in ftrace_call */ -return fregs->regs.msr ? &fregs->regs :NULL ; +return arch_ftrace_regs (fregs)->regs.msr ? &arch_ftrace_regs (fregs)->regs :NULL ; } static __always_inline voidftrace_regs_set_instruction_pointer (struct ftrace_regs *fregs,unsigned long ip) { -regs_set_return_ip (&fregs->regs, ip); +regs_set_return_ip (&arch_ftrace_regs (fregs)->regs, ip); }static __always_inline unsigned long ftrace_regs_get_instruction_pointer (struct ftrace_regs *fregs) { -return instruction_pointer (&fregs->regs); +return instruction_pointer (&arch_ftrace_regs (fregs)->regs); }#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(&(fregs)->regs, n) + regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n)#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(&(fregs)->regs) + kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_return_value (fregs) \ - regs_return_value(&(fregs)->regs) + regs_return_value(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(&(fregs)->regs, ret) + regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret)#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(&(fregs)->regs) + override_function_with_return(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_query_register_offset (name) \ regs_query_register_offset(name)arch/powerpc/kernel/trace/ftrace.c +2
-2@@ -421,7 +421,7 @@ int __init ftrace_dyn_arch_init(void)void ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { -unsigned long sp = fregs->regs.gpr[1 ]; +unsigned long sp =arch_ftrace_regs (fregs)->regs.gpr[1 ];int bit;if (unlikely (ftrace_graph_is_dead ()))@@ -439,6 +439,6 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,ftrace_test_recursion_unlock (bit); out: - fregs->regs.link = parent_ip; + arch_ftrace_regs(fregs)->regs.link = parent_ip; }#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ arch/powerpc/kernel/trace/ftrace_64_pg.c +1
-1@@ -829,7 +829,7 @@ __prepare_ftrace_return(unsigned long parent, unsigned long ip, unsigned long spvoid ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { - fregs->regs.link =__prepare_ftrace_return (parent_ip, ip, fregs->regs.gpr[1 ]); +arch_ftrace_regs (fregs)->regs.link =__prepare_ftrace_return (parent_ip, ip,arch_ftrace_regs (fregs)->regs.gpr[1 ]); }#else unsigned long prepare_ftrace_return(unsigned long parent, unsigned long ip,arch/riscv/include/asm/ftrace.h +12
-9@@ -126,7 +126,10 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec); #ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS #define arch_ftrace_get_regs(regs) NULL struct ftrace_ops; -struct ftrace_regs { +struct ftrace_regs; +#define arch_ftrace_regs(fregs) ((struct __arch_ftrace_regs *)(fregs)) + +struct __arch_ftrace_regs { unsigned long epc; unsigned long ra; unsigned long sp;@@ -150,42 +153,42 @@ struct ftrace_regs {static __always_inline unsigned long ftrace_regs_get_instruction_pointer (const struct ftrace_regs *fregs) { -return fregs->epc; +return arch_ftrace_regs (fregs)->epc; } static __always_inline void ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,unsigned long pc) { - fregs->epc = pc; +arch_ftrace_regs (fregs)->epc = pc; }static __always_inline unsigned long ftrace_regs_get_stack_pointer (const struct ftrace_regs *fregs) { -return fregs->sp; +return arch_ftrace_regs (fregs)->sp; }static __always_inline unsigned long ftrace_regs_get_argument (struct ftrace_regs *fregs,unsigned int n) {if (n <8 ) -return fregs->args[n]; +return arch_ftrace_regs (fregs)->args[n];return 0 ; }static __always_inline unsigned long ftrace_regs_get_return_value (const struct ftrace_regs *fregs) { -return fregs->a0; +return arch_ftrace_regs (fregs)->a0; } static __always_inline void ftrace_regs_set_return_value(struct ftrace_regs *fregs,unsigned long ret) { - fregs->a0 = ret; +arch_ftrace_regs (fregs)->a0 = ret; } static __always_inline void ftrace_override_function_with_return(struct ftrace_regs *fregs) { - fregs->epc = fregs->ra; +arch_ftrace_regs (fregs)->epc =arch_ftrace_regs (fregs)->ra; }int ftrace_regs_query_register_offset (const char *name);@@ -196,7 +199,7 @@ void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,static inline void arch_ftrace_set_direct_caller (struct ftrace_regs *fregs,unsigned long addr) { - fregs->t1 = addr; +arch_ftrace_regs (fregs)->t1 = addr; }#endif /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */ arch/riscv/kernel/asm-offsets.c +14
-14@@ -498,19 +498,19 @@ void asm_offsets(void)OFFSET (STACKFRAME_RA , stackframe, ra);#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS -DEFINE (FREGS_SIZE_ON_STACK ,ALIGN (sizeof (struct ftrace_regs ),STACK_ALIGN )); -DEFINE (FREGS_EPC , offsetof(struct ftrace_regs , epc)); -DEFINE (FREGS_RA , offsetof(struct ftrace_regs , ra)); -DEFINE (FREGS_SP , offsetof(struct ftrace_regs , sp)); -DEFINE (FREGS_S0 , offsetof(struct ftrace_regs , s0)); -DEFINE (FREGS_T1 , offsetof(struct ftrace_regs , t1)); -DEFINE (FREGS_A0 , offsetof(struct ftrace_regs , a0)); -DEFINE (FREGS_A1 , offsetof(struct ftrace_regs , a1)); -DEFINE (FREGS_A2 , offsetof(struct ftrace_regs , a2)); -DEFINE (FREGS_A3 , offsetof(struct ftrace_regs , a3)); -DEFINE (FREGS_A4 , offsetof(struct ftrace_regs , a4)); -DEFINE (FREGS_A5 , offsetof(struct ftrace_regs , a5)); -DEFINE (FREGS_A6 , offsetof(struct ftrace_regs , a6)); -DEFINE (FREGS_A7 , offsetof(struct ftrace_regs , a7)); +DEFINE (FREGS_SIZE_ON_STACK ,ALIGN (sizeof (struct __arch_ftrace_regs ),STACK_ALIGN )); +DEFINE (FREGS_EPC , offsetof(struct __arch_ftrace_regs , epc)); +DEFINE (FREGS_RA , offsetof(struct __arch_ftrace_regs , ra)); +DEFINE (FREGS_SP , offsetof(struct __arch_ftrace_regs , sp)); +DEFINE (FREGS_S0 , offsetof(struct __arch_ftrace_regs , s0)); +DEFINE (FREGS_T1 , offsetof(struct __arch_ftrace_regs , t1)); +DEFINE (FREGS_A0 , offsetof(struct __arch_ftrace_regs , a0)); +DEFINE (FREGS_A1 , offsetof(struct __arch_ftrace_regs , a1)); +DEFINE (FREGS_A2 , offsetof(struct __arch_ftrace_regs , a2)); +DEFINE (FREGS_A3 , offsetof(struct __arch_ftrace_regs , a3)); +DEFINE (FREGS_A4 , offsetof(struct __arch_ftrace_regs , a4)); +DEFINE (FREGS_A5 , offsetof(struct __arch_ftrace_regs , a5)); +DEFINE (FREGS_A6 , offsetof(struct __arch_ftrace_regs , a6)); +DEFINE (FREGS_A7 , offsetof(struct __arch_ftrace_regs , a7));#endif }arch/riscv/kernel/ftrace.c +1
-1@@ -214,7 +214,7 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,void ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { -prepare_ftrace_return (&fregs->ra, ip, fregs->s0); +prepare_ftrace_return (&arch_ftrace_regs (fregs)->ra, ip,arch_ftrace_regs (fregs)->s0); }#else /* CONFIG_DYNAMIC_FTRACE_WITH_ARGS */ extern void ftrace_graph_call (void );arch/s390/include/asm/ftrace.h +13
-10@@ -51,13 +51,16 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)return addr; } -struct ftrace_regs { +struct ftrace_regs ; +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) + +struct __arch_ftrace_regs {struct pt_regs regs; }; static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs) { -struct pt_regs *regs = &fregs->regs; +struct pt_regs *regs = &arch_ftrace_regs (fregs)->regs;if (test_pt_regs_flag (regs,PIF_FTRACE_FULL_REGS ))return regs;@@ -84,26 +87,26 @@ static __always_inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraphstatic __always_inline unsigned long ftrace_regs_get_instruction_pointer (const struct ftrace_regs *fregs) { -return fregs->regs.psw.addr; +return arch_ftrace_regs (fregs)->regs.psw.addr; } static __always_inline voidftrace_regs_set_instruction_pointer (struct ftrace_regs *fregs,unsigned long ip) { - fregs->regs.psw.addr = ip; +arch_ftrace_regs (fregs)->regs.psw.addr = ip; }#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(&(fregs)->regs, n) + regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n)#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(&(fregs)->regs) + kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_return_value (fregs) \ - regs_return_value(&(fregs)->regs) + regs_return_value(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(&(fregs)->regs, ret) + regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret)#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(&(fregs)->regs) + override_function_with_return(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_query_register_offset (name) \ regs_query_register_offset(name)@@ -117,7 +120,7 @@ ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,*/ static inline void arch_ftrace_set_direct_caller (struct ftrace_regs *fregs,unsigned long addr) { -struct pt_regs *regs = &fregs->regs; +struct pt_regs *regs = &arch_ftrace_regs (fregs)->regs; regs->orig_gpr2 = addr; }#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ arch/s390/kernel/asm-offsets.c +2
-2@@ -184,8 +184,8 @@ int main(void)OFFSET (__FGRAPH_RET_FP, fgraph_ret_regs, fp);DEFINE (__FGRAPH_RET_SIZE,sizeof (struct fgraph_ret_regs ));#endif -OFFSET (__FTRACE_REGS_PT_REGS, ftrace_regs, regs); -DEFINE (__FTRACE_REGS_SIZE,sizeof (struct ftrace_regs )); +OFFSET (__FTRACE_REGS_PT_REGS, __arch_ftrace_regs, regs); +DEFINE (__FTRACE_REGS_SIZE,sizeof (struct __arch_ftrace_regs ));OFFSET (__PCPU_FLAGS, pcpu, flags);return 0 ;arch/s390/kernel/ftrace.c +1
-1@@ -318,7 +318,7 @@ void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,if (bit <0 )return ; -kmsan_unpoison_memory (fregs,sizeof (*fregs)); +kmsan_unpoison_memory (fregs,ftrace_regs_size ()); regs =ftrace_get_regs (fregs); p =get_kprobe ((kprobe_opcode_t *)ip);if (!regs ||unlikely (!p) ||kprobe_disabled (p))arch/s390/lib/test_unwind.c +2
-2@@ -270,9 +270,9 @@ static void notrace __used test_unwind_ftrace_handler(unsigned long ip,struct ftrace_ops *fops, struct ftrace_regs *fregs) { - struct unwindme *u = (struct unwindme *)fregs->regs.gprs[2]; + struct unwindme *u = (struct unwindme *)arch_ftrace_regs(fregs)->regs.gprs[2]; - u->ret =test_unwind (NULL , (u->flags &UWM_REGS ) ? &fregs->regs :NULL , + u->ret =test_unwind (NULL , (u->flags &UWM_REGS ) ? &arch_ftrace_regs (fregs)->regs :NULL , (u->flags &UWM_SP ) ? u->sp :0 ); }arch/x86/include/asm/ftrace.h +14
-11@@ -33,7 +33,10 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) }#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS -struct ftrace_regs { +struct ftrace_regs ; +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) + +struct __arch_ftrace_regs {struct pt_regs regs; };@@ -41,27 +44,27 @@ static __always_inline struct pt_regs * arch_ftrace_get_regs(struct ftrace_regs *fregs) {/* Only when FL_SAVE_REGS is set, cs will be non zero */ -if (!fregs->regs.cs) +if (!arch_ftrace_regs (fregs)->regs.cs)return NULL ; -return &fregs->regs; +return &arch_ftrace_regs (fregs)->regs; }#define ftrace_regs_set_instruction_pointer (fregs, _ip) \ - do { (fregs)->regs.ip = (_ip); } while (0) + do { arch_ftrace_regs(fregs)->regs.ip = (_ip); } while (0)#define ftrace_regs_get_instruction_pointer (fregs) \ - ((fregs)->regs.ip) + arch_ftrace_regs(fregs)->regs.ip)#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(&(fregs)->regs, n) + regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n)#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(&(fregs)->regs) + kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_return_value (fregs) \ - regs_return_value(&(fregs)->regs) + regs_return_value(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(&(fregs)->regs, ret) + regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret)#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(&(fregs)->regs) + override_function_with_return(&arch_ftrace_regs(fregs)->regs)#define ftrace_regs_query_register_offset (name) \ regs_query_register_offset(name)@@ -88,7 +91,7 @@ __arch_ftrace_set_direct_caller(struct pt_regs *regs, unsigned long addr) regs->orig_ax = addr; }#define arch_ftrace_set_direct_caller (fregs, addr) \ - __arch_ftrace_set_direct_caller(&(fregs)->regs, addr) + __arch_ftrace_set_direct_caller(&arch_ftrace_regs(fregs)->regs, addr)#endif /* CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS */ #ifdef CONFIG_DYNAMIC_FTRACE arch/x86/kernel/ftrace.c +1
-1@@ -647,7 +647,7 @@ void prepare_ftrace_return(unsigned long ip, unsigned long *parent,void ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { -struct pt_regs *regs = &fregs->regs; +struct pt_regs *regs = &arch_ftrace_regs (fregs)->regs;unsigned long *stack = (unsigned long *)kernel_stack_pointer (regs);prepare_ftrace_return (ip, (unsigned long *)stack,0 );include/linux/ftrace.h +18
-3@@ -115,8 +115,6 @@ static inline int ftrace_mod_get_kallsym(unsigned int symnum, unsigned long *valextern int ftrace_enabled; -#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS -/** * ftrace_regs - ftrace partial/optimal register set * @@ -142,11 +140,28 @@ extern int ftrace_enabled;* * NOTE: user *must not* access regs directly, only do it via APIs, because * the member can be changed according to the architecture. +* This is why the structure is empty here, so that nothing accesses +* the ftrace_regs directly. */ struct ftrace_regs { +/* Nothing to see here, use the accessor functions! */ +}; + +#define ftrace_regs_size () sizeof(struct __arch_ftrace_regs) + +#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS + +struct __arch_ftrace_regs {struct pt_regs regs; }; -#define arch_ftrace_get_regs (fregs) (&(fregs)->regs) + +struct ftrace_regs ; +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) + +static inline struct pt_regs *arch_ftrace_get_regs (struct ftrace_regs *fregs) +{ +return &arch_ftrace_regs (fregs)->regs; +}/* * ftrace_regs_set_instruction_pointer() is to be defined by the architecture kernel/trace/ftrace.c +1
-1@@ -7943,7 +7943,7 @@ __ftrace_ops_list_func(unsigned long ip, unsigned long parent_ip,void arch_ftrace_ops_list_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs) { -kmsan_unpoison_memory (fregs,sizeof (*fregs)); +kmsan_unpoison_memory (fregs,ftrace_regs_size ());__ftrace_ops_list_func (ip, parent_ip,NULL , fregs); }#else
Steven Rostedt
maintainerPATCH 4/4 ftrace: Consolidate ftrace_regs accessor functions for archs using pt_regs
In reply to Steven RostedtFrom: Steven Rostedt <[email protected]>
Most architectures use pt_regs within ftrace_regs making a lot of the accessor functions just calls to the pt_regs internally. Instead of duplication this effort, use a HAVE_ARCH_FTRACE_REGS for architectures that have their own ftrace_regs that is not based on pt_regs and will define all the accessor functions, and for the architectures that just use pt_regs, it will leave it undefined, and the default accessor functions will be used.
Note, this will also make it easier to add new accessor functions to ftrace_regs as it will mean having to touch less architectures.
--- arch/arm64/include/asm/ftrace.h | 1 + arch/loongarch/include/asm/ftrace.h | 25 +------------------- arch/powerpc/include/asm/ftrace.h | 26 +-------------------- arch/riscv/include/asm/ftrace.h | 1 + arch/s390/include/asm/ftrace.h | 26 +-------------------- arch/x86/include/asm/ftrace.h | 21 +---------------- include/linux/ftrace.h | 32 ++++++------------------- include/linux/ftrace_regs.h | 36 +++++++++++++++++++++++++++++ 8 files changed, 49 insertions(+), 119 deletions(-) create mode 100644 include/linux/ftrace_regs.h
arch/arm64/include/asm/ftrace.h +1 -0
@@ -54,6 +54,7 @@ extern void return_to_handler(void);unsigned long ftrace_call_adjust (unsigned long addr);#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS +#define HAVE_ARCH_FTRACE_REGS struct dyn_ftrace ;struct ftrace_ops ;struct ftrace_regs ;
arch/loongarch/include/asm/ftrace.h +1 -24
@@ -43,43 +43,20 @@ void prepare_ftrace_return(unsigned long self_addr, unsigned long *parent);#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS struct ftrace_ops ; -struct ftrace_regs ; -#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) -struct __arch_ftrace_regs { -struct pt_regs regs; -}; +#include <linux/ftrace_regs.h> static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs) {return &arch_ftrace_regs (fregs)->regs; } -static __always_inline unsigned long -ftrace_regs_get_instruction_pointer (struct ftrace_regs *fregs) -{ -return instruction_pointer (&arch_ftrace_regs (fregs)->regs); -} - static __always_inline voidftrace_regs_set_instruction_pointer (struct ftrace_regs *fregs,unsigned long ip) {instruction_pointer_set (&arch_ftrace_regs (fregs)->regs, ip); } -#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n) -#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs) -#define ftrace_regs_return_value (fregs) \ - regs_return_value(&arch_ftrace_regs(fregs)->regs) -#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret) -#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(&arch_ftrace_regs(fregs)->regs) -#define ftrace_regs_query_register_offset (name) \ - regs_query_register_offset(name) -#define ftrace_graph_func ftrace_graph_funcvoid ftrace_graph_func (unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs);
arch/powerpc/include/asm/ftrace.h +1 -25
@@ -32,12 +32,7 @@ struct dyn_arch_ftrace {int ftrace_init_nop (struct module *mod,struct dyn_ftrace *rec);#define ftrace_init_nop ftrace_init_nop -struct ftrace_regs ; -#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) - -struct __arch_ftrace_regs { -struct pt_regs regs; -}; +#include <linux/ftrace_regs.h> static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs) {
@@ -52,25 +47,6 @@ ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,regs_set_return_ip (&arch_ftrace_regs (fregs)->regs, ip); } -static __always_inline unsigned long -ftrace_regs_get_instruction_pointer (struct ftrace_regs *fregs) -{ -return instruction_pointer (&arch_ftrace_regs (fregs)->regs); -} - -#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n) -#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs) -#define ftrace_regs_return_value (fregs) \ - regs_return_value(&arch_ftrace_regs(fregs)->regs) -#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret) -#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(&arch_ftrace_regs(fregs)->regs) -#define ftrace_regs_query_register_offset (name) \ - regs_query_register_offset(name) -struct ftrace_ops ;#define ftrace_graph_func ftrace_graph_func
arch/riscv/include/asm/ftrace.h +1 -0
@@ -125,6 +125,7 @@ int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);#ifdef CONFIG_DYNAMIC_FTRACE_WITH_ARGS #define arch_ftrace_get_regs (regs) NULL +#define HAVE_ARCH_FTRACE_REGS struct ftrace_ops ;struct ftrace_regs ;#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs))
arch/s390/include/asm/ftrace.h +1 -25
@@ -51,12 +51,7 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr)return addr; } -struct ftrace_regs ; -#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) - -struct __arch_ftrace_regs { -struct pt_regs regs; -}; +#include <linux/ftrace_regs.h> static __always_inline struct pt_regs *arch_ftrace_get_regs(struct ftrace_regs *fregs) {
@@ -84,12 +79,6 @@ static __always_inline unsigned long fgraph_ret_regs_frame_pointer(struct fgraph }#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -static __always_inline unsigned long -ftrace_regs_get_instruction_pointer (const struct ftrace_regs *fregs) -{ -return arch_ftrace_regs (fregs)->regs.psw.addr; -} - static __always_inline voidftrace_regs_set_instruction_pointer (struct ftrace_regs *fregs,unsigned long ip)
@@ -97,19 +86,6 @@ ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs,arch_ftrace_regs (fregs)->regs.psw.addr = ip; } -#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n) -#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs) -#define ftrace_regs_return_value (fregs) \ - regs_return_value(&arch_ftrace_regs(fregs)->regs) -#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret) -#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(&arch_ftrace_regs(fregs)->regs) -#define ftrace_regs_query_register_offset (name) \ - regs_query_register_offset(name) -#ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS /* * When an ftrace registered caller is tracing a function that is
arch/x86/include/asm/ftrace.h +1 -20
@@ -33,12 +33,8 @@ static inline unsigned long ftrace_call_adjust(unsigned long addr) }#ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS -struct ftrace_regs ; -#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) -struct __arch_ftrace_regs { -struct pt_regs regs; -}; +#include <linux/ftrace_regs.h> static __always_inline struct pt_regs *arch_ftrace_get_regs (struct ftrace_regs *fregs)
@@ -52,21 +48,6 @@ arch_ftrace_get_regs(struct ftrace_regs *fregs)#define ftrace_regs_set_instruction_pointer (fregs, _ip) \ do { arch_ftrace_regs(fregs)->regs.ip = (_ip); } while (0) -#define ftrace_regs_get_instruction_pointer (fregs) \ - arch_ftrace_regs(fregs)->regs.ip) - -#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n) -#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(&arch_ftrace_regs(fregs)->regs) -#define ftrace_regs_return_value (fregs) \ - regs_return_value(&arch_ftrace_regs(fregs)->regs) -#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(&arch_ftrace_regs(fregs)->regs, ret) -#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(&arch_ftrace_regs(fregs)->regs) -#define ftrace_regs_query_register_offset (name) \ - regs_query_register_offset(name)struct ftrace_ops ;#define ftrace_graph_func ftrace_graph_func
include/linux/ftrace.h +7 -25
@@ -113,6 +113,8 @@ static inline int ftrace_mod_get_kallsym(unsigned int symnum, unsigned long *val#ifdef CONFIG_FUNCTION_TRACER +#include <linux/ftrace_regs.h> +extern int ftrace_enabled;/**
@@ -150,14 +152,11 @@ struct ftrace_regs {#define ftrace_regs_size () sizeof(struct __arch_ftrace_regs)#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS - -struct __arch_ftrace_regs { -struct pt_regs regs; -}; - -struct ftrace_regs ; -#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) - +/* +* Architectures that define HAVE_DYNAMIC_FTRACE_WITH_ARGS must define their own +* arch_ftrace_get_regs() where it only returns pt_regs *if* it is fully +* populated. It should return NULL otherwise. +*/ static inline struct pt_regs *arch_ftrace_get_regs (struct ftrace_regs *fregs) {return &arch_ftrace_regs (fregs)->regs;
@@ -191,23 +190,6 @@ static __always_inline bool ftrace_regs_has_args(struct ftrace_regs *fregs)return ftrace_get_regs (fregs) !=NULL ; } -#ifndef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS -#define ftrace_regs_get_instruction_pointer (fregs) \ - instruction_pointer(ftrace_get_regs(fregs)) -#define ftrace_regs_get_argument (fregs, n) \ - regs_get_kernel_argument(ftrace_get_regs(fregs), n) -#define ftrace_regs_get_stack_pointer (fregs) \ - kernel_stack_pointer(ftrace_get_regs(fregs)) -#define ftrace_regs_return_value (fregs) \ - regs_return_value(ftrace_get_regs(fregs)) -#define ftrace_regs_set_return_value (fregs, ret) \ - regs_set_return_value(ftrace_get_regs(fregs), ret) -#define ftrace_override_function_with_return (fregs) \ - override_function_with_return(ftrace_get_regs(fregs)) -#define ftrace_regs_query_register_offset (name) \ - regs_query_register_offset(name) -#endif -typedef void (*ftrace_func_t )(unsigned long ip,unsigned long parent_ip,struct ftrace_ops *op,struct ftrace_regs *fregs);
include/linux/ftrace_regs.h new file +36 -0
@@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _LINUX_FTRACE_REGS_H +#define _LINUX_FTRACE_REGS_H + +/* +* For archs that just copy pt_regs in ftrace regs, it can use this default. +* If an architecture does not use pt_regs, it must define all the below +* accessor functions. +*/ +#ifndef HAVE_ARCH_FTRACE_REGS +struct __arch_ftrace_regs { +struct pt_regs regs; +}; + +#define arch_ftrace_regs (fregs) ((struct __arch_ftrace_regs *)(fregs)) + +struct ftrace_regs ; + +#define ftrace_regs_get_instruction_pointer (fregs) \ + instruction_pointer(arch_ftrace_get_regs(fregs)) +#define ftrace_regs_get_argument (fregs, n) \ + regs_get_kernel_argument(arch_ftrace_get_regs(fregs), n) +#define ftrace_regs_get_stack_pointer (fregs) \ + kernel_stack_pointer(arch_ftrace_get_regs(fregs)) +#define ftrace_regs_return_value (fregs) \ + regs_return_value(arch_ftrace_get_regs(fregs)) +#define ftrace_regs_set_return_value (fregs, ret) \ + regs_set_return_value(arch_ftrace_get_regs(fregs), ret) +#define ftrace_override_function_with_return (fregs) \ + override_function_with_return(arch_ftrace_get_regs(fregs)) +#define ftrace_regs_query_register_offset (name) \ + regs_query_register_offset(name) + +#endif /* HAVE_ARCH_FTRACE_REGS */ + +#endif /* _LINUX_FTRACE_REGS_H */
Signature · 1 line
2.45.2
Re: [for-next][PATCH 4/4] ftrace: Consolidate ftrace_regs accessor functions for archs using pt_regs
Quoted 43 lines · Steven Rostedt
From: Steven Rostedt <[email protected]>
Most architectures use
pt_regswithinftrace_regsmaking a lot of the accessor functions just calls to thept_regsinternally. Instead of duplication this effort, use aHAVE_ARCH_FTRACE_REGSfor architectures that have their ownftrace_regsthat is not based onpt_regsand will define all the accessor functions, and for the architectures that just usept_regs, it will leave it undefined, and the default accessor functions will be used.Note, this will also make it easier to add new accessor functions to
ftrace_regsas it will mean having to touch less architectures.Cc <[email protected]>Cc Mathieu Desnoyers <[email protected]>Cc Mark Rutland <[email protected]>Cc Will Deacon <[email protected]>Cc Huacai Chen <[email protected]>Cc WANG Xuerui <[email protected]>Cc Michael Ellerman <[email protected]>Cc Nicholas Piggin <[email protected]>Cc Christophe Leroy <[email protected]>Cc Naveen N Rao <[email protected]>Cc Madhavan Srinivasan <[email protected]>Cc Paul Walmsley <[email protected]>Cc Palmer Dabbelt <[email protected]>Cc Albert Ou <[email protected]>Cc Heiko Carstens <[email protected]>Cc Vasily Gorbik <[email protected]>Cc Alexander Gordeev <[email protected]>Cc Christian Borntraeger <[email protected]>Cc Sven Schnelle <[email protected]>Cc Thomas Gleixner <[email protected]>Cc Ingo Molnar <[email protected]>Cc Borislav Petkov <[email protected]>Cc Dave Hansen <[email protected]>Acked-by Catalin Marinas <[email protected]>Suggested-by Masami Hiramatsu (Google) <[email protected]>Signed-off-by Steven Rostedt (Google) <[email protected]>
Quoted 4 lines
--- arch/arm64/include/asm/ftrace.h | 1 + arch/loongarch/include/asm/ftrace.h | 25 +------------------- arch/powerpc/include/asm/ftrace.h | 26 +--------------------
cheers
Quoted 7 lines
arch/riscv/include/asm/ftrace.h | 1 + arch/s390/include/asm/ftrace.h | 26 +-------------------- arch/x86/include/asm/ftrace.h | 21 +---------------- include/linux/ftrace.h | 32 ++++++------------------- include/linux/ftrace_regs.h | 36 +++++++++++++++++++++++++++++ 8 files changed, 49 insertions(+), 119 deletions(-) create mode 100644 include/linux/ftrace_regs.h
Masami Hiramatsu (Google)
maintainerRe: [for-next][PATCH 4/4] ftrace: Consolidate ftrace_regs accessor functions for archs using pt_regs
In reply to Steven RostedtHi Steve,
I found one problem on this patch while debugging my series;
Review
Quoted 2 lines · On Fri, 11 Oct 2024 09:29:45 -0400 Steven Rostedt <[email protected]> wrote:
(quoted diff) +0
-2-#define ftrace_regs_get_argument(fregs, n) \ - regs_get_kernel_argument(&arch_ftrace_regs(fregs)->regs, n)
As you can seem most arch uses "arch_ftrace_regs()" macro for ftrace_regs_*() macros. This is because we are sure this ftrace_regs is not fully compatible with pt_regs.
include/linux/ftrace_regs.h line 20
Quoted 2 lines
include/linux/ftrace_regs.h new file +2
-0+#define ftrace_regs_get_instruction_pointer (fregs) \ + instruction_pointer(arch_ftrace_get_regs(fregs))
However, these consolidated macros in ftrace_regs.h are using "arch_ftrace_get_regs()" macro, which can return NULL if FL_SAVE_REGS is not set.
So, those should use arch_ftrace_regs() as original code does.
Thank you,
Signature · 1 line
Masami Hiramatsu (Google) <[email protected]>