~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/riscv/kernel/perf_callchain.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0
  2 /* Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. */
  3 
  4 #include <linux/perf_event.h>
  5 #include <linux/uaccess.h>
  6 
  7 #include <asm/stacktrace.h>
  8 
  9 /*
 10  * Get the return address for a single stackframe and return a pointer to the
 11  * next frame tail.
 12  */
 13 static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry,
 14                                     unsigned long fp, unsigned long reg_ra)
 15 {
 16         struct stackframe buftail;
 17         unsigned long ra = 0;
 18         unsigned long __user *user_frame_tail =
 19                 (unsigned long __user *)(fp - sizeof(struct stackframe));
 20 
 21         /* Check accessibility of one struct frame_tail beyond */
 22         if (!access_ok(user_frame_tail, sizeof(buftail)))
 23                 return 0;
 24         if (__copy_from_user_inatomic(&buftail, user_frame_tail,
 25                                       sizeof(buftail)))
 26                 return 0;
 27 
 28         if (reg_ra != 0)
 29                 ra = reg_ra;
 30         else
 31                 ra = buftail.ra;
 32 
 33         fp = buftail.fp;
 34         if (ra != 0)
 35                 perf_callchain_store(entry, ra);
 36         else
 37                 return 0;
 38 
 39         return fp;
 40 }
 41 
 42 /*
 43  * This will be called when the target is in user mode
 44  * This function will only be called when we use
 45  * "PERF_SAMPLE_CALLCHAIN" in
 46  * kernel/events/core.c:perf_prepare_sample()
 47  *
 48  * How to trigger perf_callchain_[user/kernel] :
 49  * $ perf record -e cpu-clock --call-graph fp ./program
 50  * $ perf report --call-graph
 51  *
 52  * On RISC-V platform, the program being sampled and the C library
 53  * need to be compiled with -fno-omit-frame-pointer, otherwise
 54  * the user stack will not contain function frame.
 55  */
 56 void perf_callchain_user(struct perf_callchain_entry_ctx *entry,
 57                          struct pt_regs *regs)
 58 {
 59         unsigned long fp = 0;
 60 
 61         fp = regs->s0;
 62         perf_callchain_store(entry, regs->epc);
 63 
 64         fp = user_backtrace(entry, fp, regs->ra);
 65         while (fp && !(fp & 0x3) && entry->nr < entry->max_stack)
 66                 fp = user_backtrace(entry, fp, 0);
 67 }
 68 
 69 static bool fill_callchain(void *entry, unsigned long pc)
 70 {
 71         return perf_callchain_store(entry, pc) == 0;
 72 }
 73 
 74 void perf_callchain_kernel(struct perf_callchain_entry_ctx *entry,
 75                            struct pt_regs *regs)
 76 {
 77         walk_stackframe(NULL, regs, fill_callchain, entry);
 78 }
 79 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php