Skip to content

Commit b9b55c8

Browse files
mhiramatrostedt
authored andcommitted
tracing: Add ftrace_partial_regs() for converting ftrace_regs to pt_regs
Add ftrace_partial_regs() which converts the ftrace_regs to pt_regs. This is for the eBPF which needs this to keep the same pt_regs interface to access registers. Thus when replacing the pt_regs with ftrace_regs in fprobes (which is used by kprobe_multi eBPF event), this will be used. If the architecture defines its own ftrace_regs, this copies partial registers to pt_regs and returns it. If not, ftrace_regs is the same as pt_regs and ftrace_partial_regs() will return ftrace_regs::regs. Signed-off-by: Masami Hiramatsu (Google) <[email protected]> Acked-by: Florent Revest <[email protected]> Cc: Alexei Starovoitov <[email protected]> Cc: Martin KaFai Lau <[email protected]> Cc: bpf <[email protected]> Cc: Alexei Starovoitov <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Alan Maguire <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Will Deacon <[email protected]> Cc: Paul Walmsley <[email protected]> Cc: Palmer Dabbelt <[email protected]> Cc: Albert Ou <[email protected]> Link: https://lore.kernel.org/173518996761.391279.4987911298206448122.stgit@devnote2 Signed-off-by: Steven Rostedt (Google) <[email protected]>
1 parent 762abbc commit b9b55c8

File tree

3 files changed

+44
-0
lines changed

3 files changed

+44
-0
lines changed

arch/arm64/include/asm/ftrace.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,19 @@ ftrace_regs_get_frame_pointer(const struct ftrace_regs *fregs)
135135
return arch_ftrace_regs(fregs)->fp;
136136
}
137137

138+
static __always_inline struct pt_regs *
139+
ftrace_partial_regs(const struct ftrace_regs *fregs, struct pt_regs *regs)
140+
{
141+
struct __arch_ftrace_regs *afregs = arch_ftrace_regs(fregs);
142+
143+
memcpy(regs->regs, afregs->regs, sizeof(afregs->regs));
144+
regs->sp = afregs->sp;
145+
regs->pc = afregs->pc;
146+
regs->regs[29] = afregs->fp;
147+
regs->regs[30] = afregs->lr;
148+
return regs;
149+
}
150+
138151
int ftrace_regs_query_register_offset(const char *name);
139152

140153
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);

arch/riscv/include/asm/ftrace.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,20 @@ static __always_inline void ftrace_override_function_with_return(struct ftrace_r
197197
arch_ftrace_regs(fregs)->epc = arch_ftrace_regs(fregs)->ra;
198198
}
199199

200+
static __always_inline struct pt_regs *
201+
ftrace_partial_regs(const struct ftrace_regs *fregs, struct pt_regs *regs)
202+
{
203+
struct __arch_ftrace_regs *afregs = arch_ftrace_regs(fregs);
204+
205+
memcpy(&regs->a0, afregs->args, sizeof(afregs->args));
206+
regs->epc = afregs->epc;
207+
regs->ra = afregs->ra;
208+
regs->sp = afregs->sp;
209+
regs->s0 = afregs->s0;
210+
regs->t1 = afregs->t1;
211+
return regs;
212+
}
213+
200214
int ftrace_regs_query_register_offset(const char *name);
201215

202216
void ftrace_graph_func(unsigned long ip, unsigned long parent_ip,

include/linux/ftrace.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,23 @@ static __always_inline struct pt_regs *ftrace_get_regs(struct ftrace_regs *fregs
190190
return arch_ftrace_get_regs(fregs);
191191
}
192192

193+
#if !defined(CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS) || \
194+
defined(CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS)
195+
196+
static __always_inline struct pt_regs *
197+
ftrace_partial_regs(struct ftrace_regs *fregs, struct pt_regs *regs)
198+
{
199+
/*
200+
* If CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS=y, ftrace_regs memory
201+
* layout is including pt_regs. So always returns that address.
202+
* Since arch_ftrace_get_regs() will check some members and may return
203+
* NULL, we can not use it.
204+
*/
205+
return &arch_ftrace_regs(fregs)->regs;
206+
}
207+
208+
#endif /* !CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS || CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS */
209+
193210
/*
194211
* When true, the ftrace_regs_{get,set}_*() functions may be used on fregs.
195212
* Note: this can be true even when ftrace_get_regs() cannot provide a pt_regs.

0 commit comments

Comments
 (0)