]>
Commit | Line | Data |
---|---|---|
9fa1db4c | 1 | // SPDX-License-Identifier: GPL-2.0 |
c33eff60 HC |
2 | #include <linux/perf_event.h> |
3 | #include <linux/perf_regs.h> | |
4 | #include <linux/kernel.h> | |
5 | #include <linux/errno.h> | |
6 | #include <linux/bug.h> | |
7 | #include <asm/ptrace.h> | |
0da0017f HB |
8 | #include <asm/fpu/api.h> |
9 | #include <asm/fpu/types.h> | |
c33eff60 HC |
10 | |
11 | u64 perf_reg_value(struct pt_regs *regs, int idx) | |
12 | { | |
0da0017f HB |
13 | freg_t fp; |
14 | ||
c33eff60 HC |
15 | if (WARN_ON_ONCE((u32)idx >= PERF_REG_S390_MAX)) |
16 | return 0; | |
17 | ||
0da0017f HB |
18 | if (idx >= PERF_REG_S390_R0 && idx <= PERF_REG_S390_R15) |
19 | return regs->gprs[idx]; | |
20 | ||
21 | if (idx >= PERF_REG_S390_FP0 && idx <= PERF_REG_S390_FP15) { | |
22 | if (!user_mode(regs)) | |
23 | return 0; | |
24 | ||
25 | idx -= PERF_REG_S390_FP0; | |
26 | fp = MACHINE_HAS_VX ? *(freg_t *)(current->thread.fpu.vxrs + idx) | |
27 | : current->thread.fpu.fprs[idx]; | |
28 | return fp.ui; | |
29 | } | |
30 | ||
c33eff60 HC |
31 | if (idx == PERF_REG_S390_MASK) |
32 | return regs->psw.mask; | |
33 | if (idx == PERF_REG_S390_PC) | |
34 | return regs->psw.addr; | |
35 | ||
36 | return regs->gprs[idx]; | |
37 | } | |
38 | ||
39 | #define REG_RESERVED (~((1UL << PERF_REG_S390_MAX) - 1)) | |
40 | ||
41 | int perf_reg_validate(u64 mask) | |
42 | { | |
43 | if (!mask || mask & REG_RESERVED) | |
44 | return -EINVAL; | |
45 | ||
46 | return 0; | |
47 | } | |
48 | ||
49 | u64 perf_reg_abi(struct task_struct *task) | |
50 | { | |
51 | if (test_tsk_thread_flag(task, TIF_31BIT)) | |
52 | return PERF_SAMPLE_REGS_ABI_32; | |
53 | ||
54 | return PERF_SAMPLE_REGS_ABI_64; | |
55 | } | |
56 | ||
57 | void perf_get_regs_user(struct perf_regs *regs_user, | |
58 | struct pt_regs *regs, | |
59 | struct pt_regs *regs_user_copy) | |
60 | { | |
61 | /* | |
62 | * Use the regs from the first interruption and let | |
63 | * perf_sample_regs_intr() handle interrupts (regs == get_irq_regs()). | |
0da0017f HB |
64 | * |
65 | * Also save FPU registers for user-space tasks only. | |
c33eff60 HC |
66 | */ |
67 | regs_user->regs = task_pt_regs(current); | |
0da0017f HB |
68 | if (user_mode(regs_user->regs)) |
69 | save_fpu_regs(); | |
c33eff60 HC |
70 | regs_user->abi = perf_reg_abi(current); |
71 | } |