diff options
-rw-r--r-- | arch/arm64/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm64/include/asm/ptrace.h | 1 | ||||
-rw-r--r-- | arch/arm64/include/uapi/asm/Kbuild | 1 | ||||
-rw-r--r-- | arch/arm64/include/uapi/asm/perf_regs.h | 40 | ||||
-rw-r--r-- | arch/arm64/kernel/Makefile | 3 | ||||
-rw-r--r-- | arch/arm64/kernel/perf_regs.c | 44 |
6 files changed, 90 insertions, 1 deletions
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 140cd1a9dc0c..507ab6e53522 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig | |||
@@ -39,6 +39,8 @@ config ARM64 | |||
39 | select HAVE_MEMBLOCK | 39 | select HAVE_MEMBLOCK |
40 | select HAVE_PATA_PLATFORM | 40 | select HAVE_PATA_PLATFORM |
41 | select HAVE_PERF_EVENTS | 41 | select HAVE_PERF_EVENTS |
42 | select HAVE_PERF_REGS | ||
43 | select HAVE_PERF_USER_STACK_DUMP | ||
42 | select IRQ_DOMAIN | 44 | select IRQ_DOMAIN |
43 | select MODULES_USE_ELF_RELA | 45 | select MODULES_USE_ELF_RELA |
44 | select NO_BOOTMEM | 46 | select NO_BOOTMEM |
diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 5233966fba3d..35ff2f9de072 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h | |||
@@ -68,6 +68,7 @@ | |||
68 | 68 | ||
69 | /* Architecturally defined mapping between AArch32 and AArch64 registers */ | 69 | /* Architecturally defined mapping between AArch32 and AArch64 registers */ |
70 | #define compat_usr(x) regs[(x)] | 70 | #define compat_usr(x) regs[(x)] |
71 | #define compat_fp regs[11] | ||
71 | #define compat_sp regs[13] | 72 | #define compat_sp regs[13] |
72 | #define compat_lr regs[14] | 73 | #define compat_lr regs[14] |
73 | #define compat_sp_hyp regs[15] | 74 | #define compat_sp_hyp regs[15] |
diff --git a/arch/arm64/include/uapi/asm/Kbuild b/arch/arm64/include/uapi/asm/Kbuild index e4b78bdca19e..942376d37d22 100644 --- a/arch/arm64/include/uapi/asm/Kbuild +++ b/arch/arm64/include/uapi/asm/Kbuild | |||
@@ -9,6 +9,7 @@ header-y += byteorder.h | |||
9 | header-y += fcntl.h | 9 | header-y += fcntl.h |
10 | header-y += hwcap.h | 10 | header-y += hwcap.h |
11 | header-y += kvm_para.h | 11 | header-y += kvm_para.h |
12 | header-y += perf_regs.h | ||
12 | header-y += param.h | 13 | header-y += param.h |
13 | header-y += ptrace.h | 14 | header-y += ptrace.h |
14 | header-y += setup.h | 15 | header-y += setup.h |
diff --git a/arch/arm64/include/uapi/asm/perf_regs.h b/arch/arm64/include/uapi/asm/perf_regs.h new file mode 100644 index 000000000000..172b8317ee49 --- /dev/null +++ b/arch/arm64/include/uapi/asm/perf_regs.h | |||
@@ -0,0 +1,40 @@ | |||
1 | #ifndef _ASM_ARM64_PERF_REGS_H | ||
2 | #define _ASM_ARM64_PERF_REGS_H | ||
3 | |||
4 | enum perf_event_arm_regs { | ||
5 | PERF_REG_ARM64_X0, | ||
6 | PERF_REG_ARM64_X1, | ||
7 | PERF_REG_ARM64_X2, | ||
8 | PERF_REG_ARM64_X3, | ||
9 | PERF_REG_ARM64_X4, | ||
10 | PERF_REG_ARM64_X5, | ||
11 | PERF_REG_ARM64_X6, | ||
12 | PERF_REG_ARM64_X7, | ||
13 | PERF_REG_ARM64_X8, | ||
14 | PERF_REG_ARM64_X9, | ||
15 | PERF_REG_ARM64_X10, | ||
16 | PERF_REG_ARM64_X11, | ||
17 | PERF_REG_ARM64_X12, | ||
18 | PERF_REG_ARM64_X13, | ||
19 | PERF_REG_ARM64_X14, | ||
20 | PERF_REG_ARM64_X15, | ||
21 | PERF_REG_ARM64_X16, | ||
22 | PERF_REG_ARM64_X17, | ||
23 | PERF_REG_ARM64_X18, | ||
24 | PERF_REG_ARM64_X19, | ||
25 | PERF_REG_ARM64_X20, | ||
26 | PERF_REG_ARM64_X21, | ||
27 | PERF_REG_ARM64_X22, | ||
28 | PERF_REG_ARM64_X23, | ||
29 | PERF_REG_ARM64_X24, | ||
30 | PERF_REG_ARM64_X25, | ||
31 | PERF_REG_ARM64_X26, | ||
32 | PERF_REG_ARM64_X27, | ||
33 | PERF_REG_ARM64_X28, | ||
34 | PERF_REG_ARM64_X29, | ||
35 | PERF_REG_ARM64_LR, | ||
36 | PERF_REG_ARM64_SP, | ||
37 | PERF_REG_ARM64_PC, | ||
38 | PERF_REG_ARM64_MAX, | ||
39 | }; | ||
40 | #endif /* _ASM_ARM64_PERF_REGS_H */ | ||
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index cfee8273fccb..7d811d9522bc 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile | |||
@@ -15,8 +15,9 @@ arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \ | |||
15 | sys_compat.o | 15 | sys_compat.o |
16 | arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o | 16 | arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o |
17 | arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o topology.o | 17 | arm64-obj-$(CONFIG_SMP) += smp.o smp_spin_table.o topology.o |
18 | arm64-obj-$(CONFIG_PERF_EVENTS) += perf_regs.o | ||
18 | arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o | 19 | arm64-obj-$(CONFIG_HW_PERF_EVENTS) += perf_event.o |
19 | arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT)+= hw_breakpoint.o | 20 | arm64-obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o |
20 | arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 21 | arm64-obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
21 | arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o | 22 | arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o |
22 | arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o | 23 | arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o |
diff --git a/arch/arm64/kernel/perf_regs.c b/arch/arm64/kernel/perf_regs.c new file mode 100644 index 000000000000..f2d6f0a36d63 --- /dev/null +++ b/arch/arm64/kernel/perf_regs.c | |||
@@ -0,0 +1,44 @@ | |||
1 | #include <linux/errno.h> | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/perf_event.h> | ||
4 | #include <linux/bug.h> | ||
5 | #include <asm/perf_regs.h> | ||
6 | #include <asm/ptrace.h> | ||
7 | |||
8 | u64 perf_reg_value(struct pt_regs *regs, int idx) | ||
9 | { | ||
10 | if (WARN_ON_ONCE((u32)idx >= PERF_REG_ARM64_MAX)) | ||
11 | return 0; | ||
12 | |||
13 | /* | ||
14 | * Compat (i.e. 32 bit) mode: | ||
15 | * - PC has been set in the pt_regs struct in kernel_entry, | ||
16 | * - Handle SP and LR here. | ||
17 | */ | ||
18 | if (compat_user_mode(regs)) { | ||
19 | if ((u32)idx == PERF_REG_ARM64_SP) | ||
20 | return regs->compat_sp; | ||
21 | if ((u32)idx == PERF_REG_ARM64_LR) | ||
22 | return regs->compat_lr; | ||
23 | } | ||
24 | |||
25 | return regs->regs[idx]; | ||
26 | } | ||
27 | |||
28 | #define REG_RESERVED (~((1ULL << PERF_REG_ARM64_MAX) - 1)) | ||
29 | |||
30 | int perf_reg_validate(u64 mask) | ||
31 | { | ||
32 | if (!mask || mask & REG_RESERVED) | ||
33 | return -EINVAL; | ||
34 | |||
35 | return 0; | ||
36 | } | ||
37 | |||
38 | u64 perf_reg_abi(struct task_struct *task) | ||
39 | { | ||
40 | if (is_compat_thread(task_thread_info(task))) | ||
41 | return PERF_SAMPLE_REGS_ABI_32; | ||
42 | else | ||
43 | return PERF_SAMPLE_REGS_ABI_64; | ||
44 | } | ||