diff options
Diffstat (limited to 'arch/arm64/kernel/perf_regs.c')
-rw-r--r-- | arch/arm64/kernel/perf_regs.c | 44 |
1 files changed, 44 insertions, 0 deletions
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 | } | ||