Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

tracing: Add ftrace_fill_perf_regs() for perf event

Add ftrace_fill_perf_regs() which should be compatible with the
perf_fetch_caller_regs(). In other words, the pt_regs returned from the
ftrace_fill_perf_regs() must satisfy 'user_mode(regs) == false' and can be
used for stack tracing.

Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Acked-by: Will Deacon <will@kernel.org>
Acked-by: Heiko Carstens <hca@linux.ibm.com> # s390
Cc: Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: Florent Revest <revest@chromium.org>
Cc: Martin KaFai Lau <martin.lau@linux.dev>
Cc: bpf <bpf@vger.kernel.org>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Alan Maguire <alan.maguire@oracle.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Naveen N Rao <naveen@kernel.org>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Sven Schnelle <svens@linux.ibm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: x86@kernel.org
Cc: "H. Peter Anvin" <hpa@zytor.com>
Link: https://lore.kernel.org/173518997908.391279.15910334347345106424.stgit@devnote2
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

authored by

Masami Hiramatsu (Google) and committed by
Steven Rostedt (Google)
d5d01b71 b9b55c89

+58
+7
arch/arm64/include/asm/ftrace.h
··· 148 148 return regs; 149 149 } 150 150 151 + #define arch_ftrace_fill_perf_regs(fregs, _regs) do { \ 152 + (_regs)->pc = arch_ftrace_regs(fregs)->pc; \ 153 + (_regs)->regs[29] = arch_ftrace_regs(fregs)->fp; \ 154 + (_regs)->sp = arch_ftrace_regs(fregs)->sp; \ 155 + (_regs)->pstate = PSR_MODE_EL1h; \ 156 + } while (0) 157 + 151 158 int ftrace_regs_query_register_offset(const char *name); 152 159 153 160 int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
+7
arch/powerpc/include/asm/ftrace.h
··· 43 43 return arch_ftrace_regs(fregs)->regs.msr ? &arch_ftrace_regs(fregs)->regs : NULL; 44 44 } 45 45 46 + #define arch_ftrace_fill_perf_regs(fregs, _regs) do { \ 47 + (_regs)->result = 0; \ 48 + (_regs)->nip = arch_ftrace_regs(fregs)->regs.nip; \ 49 + (_regs)->gpr[1] = arch_ftrace_regs(fregs)->regs.gpr[1]; \ 50 + asm volatile("mfmsr %0" : "=r" ((_regs)->msr)); \ 51 + } while (0) 52 + 46 53 static __always_inline void 47 54 ftrace_regs_set_instruction_pointer(struct ftrace_regs *fregs, 48 55 unsigned long ip)
+6
arch/s390/include/asm/ftrace.h
··· 76 76 return ftrace_regs_get_stack_pointer(fregs); 77 77 } 78 78 79 + #define arch_ftrace_fill_perf_regs(fregs, _regs) do { \ 80 + (_regs)->psw.mask = 0; \ 81 + (_regs)->psw.addr = arch_ftrace_regs(fregs)->regs.psw.addr; \ 82 + (_regs)->gprs[15] = arch_ftrace_regs(fregs)->regs.gprs[15]; \ 83 + } while (0) 84 + 79 85 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS 80 86 /* 81 87 * When an ftrace registered caller is tracing a function that is
+7
arch/x86/include/asm/ftrace.h
··· 47 47 return &arch_ftrace_regs(fregs)->regs; 48 48 } 49 49 50 + #define arch_ftrace_fill_perf_regs(fregs, _regs) do { \ 51 + (_regs)->ip = arch_ftrace_regs(fregs)->regs.ip; \ 52 + (_regs)->sp = arch_ftrace_regs(fregs)->regs.sp; \ 53 + (_regs)->cs = __KERNEL_CS; \ 54 + (_regs)->flags = 0; \ 55 + } while (0) 56 + 50 57 #define ftrace_regs_set_instruction_pointer(fregs, _ip) \ 51 58 do { arch_ftrace_regs(fregs)->regs.ip = (_ip); } while (0) 52 59
+31
include/linux/ftrace.h
··· 207 207 208 208 #endif /* !CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS || CONFIG_HAVE_FTRACE_REGS_HAVING_PT_REGS */ 209 209 210 + #ifdef CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS 211 + 212 + /* 213 + * Please define arch dependent pt_regs which compatible to the 214 + * perf_arch_fetch_caller_regs() but based on ftrace_regs. 215 + * This requires 216 + * - user_mode(_regs) returns false (always kernel mode). 217 + * - able to use the _regs for stack trace. 218 + */ 219 + #ifndef arch_ftrace_fill_perf_regs 220 + /* As same as perf_arch_fetch_caller_regs(), do nothing by default */ 221 + #define arch_ftrace_fill_perf_regs(fregs, _regs) do {} while (0) 222 + #endif 223 + 224 + static __always_inline struct pt_regs * 225 + ftrace_fill_perf_regs(struct ftrace_regs *fregs, struct pt_regs *regs) 226 + { 227 + arch_ftrace_fill_perf_regs(fregs, regs); 228 + return regs; 229 + } 230 + 231 + #else /* !CONFIG_HAVE_DYNAMIC_FTRACE_WITH_ARGS */ 232 + 233 + static __always_inline struct pt_regs * 234 + ftrace_fill_perf_regs(struct ftrace_regs *fregs, struct pt_regs *regs) 235 + { 236 + return &arch_ftrace_regs(fregs)->regs; 237 + } 238 + 239 + #endif 240 + 210 241 /* 211 242 * When true, the ftrace_regs_{get,set}_*() functions may be used on fregs. 212 243 * Note: this can be true even when ftrace_get_regs() cannot provide a pt_regs.