diff options
author | Mao Han <han_mao@c-sky.com> | 2019-04-15 05:17:29 -0400 |
---|---|---|
committer | Guo Ren <ren_guo@c-sky.com> | 2019-04-22 01:44:57 -0400 |
commit | daac95e70f482e7add3305ee5e38f00dca505268 (patch) | |
tree | 9b33464b7770ef5a5ca52617abca314ee01fb390 /arch | |
parent | 0eaf50deec8d550164b3cf6a5d68ec1072916f0e (diff) |
csky: Add support for perf registers sampling
This patch implements the perf registers sampling and validation API
for csky arch. The valid registers and their register ID are defined in
perf_regs.h. Perf tool can backtrace in userspace with unwind library
and the registers/user stack dump support.
Signed-off-by: Mao Han <han_mao@c-sky.com>
Signed-off-by: Guo Ren <ren_guo@c-sky.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/csky/Kconfig | 2 | ||||
-rw-r--r-- | arch/csky/include/uapi/asm/perf_regs.h | 51 | ||||
-rw-r--r-- | arch/csky/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/csky/kernel/perf_regs.c | 40 |
4 files changed, 94 insertions, 0 deletions
diff --git a/arch/csky/Kconfig b/arch/csky/Kconfig index c4974cf6a222..8e45c7ac8e24 100644 --- a/arch/csky/Kconfig +++ b/arch/csky/Kconfig | |||
@@ -38,6 +38,8 @@ config CSKY | |||
38 | select HAVE_KERNEL_LZO | 38 | select HAVE_KERNEL_LZO |
39 | select HAVE_KERNEL_LZMA | 39 | select HAVE_KERNEL_LZMA |
40 | select HAVE_PERF_EVENTS | 40 | select HAVE_PERF_EVENTS |
41 | select HAVE_PERF_REGS | ||
42 | select HAVE_PERF_USER_STACK_DUMP | ||
41 | select HAVE_DMA_API_DEBUG | 43 | select HAVE_DMA_API_DEBUG |
42 | select HAVE_DMA_CONTIGUOUS | 44 | select HAVE_DMA_CONTIGUOUS |
43 | select HAVE_SYSCALL_TRACEPOINTS | 45 | select HAVE_SYSCALL_TRACEPOINTS |
diff --git a/arch/csky/include/uapi/asm/perf_regs.h b/arch/csky/include/uapi/asm/perf_regs.h new file mode 100644 index 000000000000..ee323d818592 --- /dev/null +++ b/arch/csky/include/uapi/asm/perf_regs.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | // Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. | ||
3 | |||
4 | #ifndef _ASM_CSKY_PERF_REGS_H | ||
5 | #define _ASM_CSKY_PERF_REGS_H | ||
6 | |||
7 | /* Index of struct pt_regs */ | ||
8 | enum perf_event_csky_regs { | ||
9 | PERF_REG_CSKY_TLS, | ||
10 | PERF_REG_CSKY_LR, | ||
11 | PERF_REG_CSKY_PC, | ||
12 | PERF_REG_CSKY_SR, | ||
13 | PERF_REG_CSKY_SP, | ||
14 | PERF_REG_CSKY_ORIG_A0, | ||
15 | PERF_REG_CSKY_A0, | ||
16 | PERF_REG_CSKY_A1, | ||
17 | PERF_REG_CSKY_A2, | ||
18 | PERF_REG_CSKY_A3, | ||
19 | PERF_REG_CSKY_REGS0, | ||
20 | PERF_REG_CSKY_REGS1, | ||
21 | PERF_REG_CSKY_REGS2, | ||
22 | PERF_REG_CSKY_REGS3, | ||
23 | PERF_REG_CSKY_REGS4, | ||
24 | PERF_REG_CSKY_REGS5, | ||
25 | PERF_REG_CSKY_REGS6, | ||
26 | PERF_REG_CSKY_REGS7, | ||
27 | PERF_REG_CSKY_REGS8, | ||
28 | PERF_REG_CSKY_REGS9, | ||
29 | #if defined(__CSKYABIV2__) | ||
30 | PERF_REG_CSKY_EXREGS0, | ||
31 | PERF_REG_CSKY_EXREGS1, | ||
32 | PERF_REG_CSKY_EXREGS2, | ||
33 | PERF_REG_CSKY_EXREGS3, | ||
34 | PERF_REG_CSKY_EXREGS4, | ||
35 | PERF_REG_CSKY_EXREGS5, | ||
36 | PERF_REG_CSKY_EXREGS6, | ||
37 | PERF_REG_CSKY_EXREGS7, | ||
38 | PERF_REG_CSKY_EXREGS8, | ||
39 | PERF_REG_CSKY_EXREGS9, | ||
40 | PERF_REG_CSKY_EXREGS10, | ||
41 | PERF_REG_CSKY_EXREGS11, | ||
42 | PERF_REG_CSKY_EXREGS12, | ||
43 | PERF_REG_CSKY_EXREGS13, | ||
44 | PERF_REG_CSKY_EXREGS14, | ||
45 | PERF_REG_CSKY_HI, | ||
46 | PERF_REG_CSKY_LO, | ||
47 | PERF_REG_CSKY_DCSR, | ||
48 | #endif | ||
49 | PERF_REG_CSKY_MAX, | ||
50 | }; | ||
51 | #endif /* _ASM_CSKY_PERF_REGS_H */ | ||
diff --git a/arch/csky/kernel/Makefile b/arch/csky/kernel/Makefile index 4c462f584dd1..1624b04bffb5 100644 --- a/arch/csky/kernel/Makefile +++ b/arch/csky/kernel/Makefile | |||
@@ -10,6 +10,7 @@ obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o | |||
10 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 10 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
11 | obj-$(CONFIG_CSKY_PMU_V1) += perf_event.o | 11 | obj-$(CONFIG_CSKY_PMU_V1) += perf_event.o |
12 | obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o | 12 | obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o |
13 | obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o | ||
13 | 14 | ||
14 | ifdef CONFIG_FUNCTION_TRACER | 15 | ifdef CONFIG_FUNCTION_TRACER |
15 | CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) | 16 | CFLAGS_REMOVE_ftrace.o = $(CC_FLAGS_FTRACE) |
diff --git a/arch/csky/kernel/perf_regs.c b/arch/csky/kernel/perf_regs.c new file mode 100644 index 000000000000..eb32838b8210 --- /dev/null +++ b/arch/csky/kernel/perf_regs.c | |||
@@ -0,0 +1,40 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | // Copyright (C) 2019 Hangzhou C-SKY Microsystems co.,ltd. | ||
3 | |||
4 | #include <linux/errno.h> | ||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/perf_event.h> | ||
7 | #include <linux/bug.h> | ||
8 | #include <asm/perf_regs.h> | ||
9 | #include <asm/ptrace.h> | ||
10 | |||
11 | u64 perf_reg_value(struct pt_regs *regs, int idx) | ||
12 | { | ||
13 | if (WARN_ON_ONCE((u32)idx >= PERF_REG_CSKY_MAX)) | ||
14 | return 0; | ||
15 | |||
16 | return (u64)*((u32 *)regs + idx); | ||
17 | } | ||
18 | |||
19 | #define REG_RESERVED (~((1ULL << PERF_REG_CSKY_MAX) - 1)) | ||
20 | |||
21 | int perf_reg_validate(u64 mask) | ||
22 | { | ||
23 | if (!mask || mask & REG_RESERVED) | ||
24 | return -EINVAL; | ||
25 | |||
26 | return 0; | ||
27 | } | ||
28 | |||
29 | u64 perf_reg_abi(struct task_struct *task) | ||
30 | { | ||
31 | return PERF_SAMPLE_REGS_ABI_32; | ||
32 | } | ||
33 | |||
34 | void perf_get_regs_user(struct perf_regs *regs_user, | ||
35 | struct pt_regs *regs, | ||
36 | struct pt_regs *regs_user_copy) | ||
37 | { | ||
38 | regs_user->regs = task_pt_regs(current); | ||
39 | regs_user->abi = perf_reg_abi(current); | ||
40 | } | ||