1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | |
3 | #include <linux/regset.h> |
4 | |
5 | #include <asm/switch_to.h> |
6 | |
7 | #include "ptrace-decl.h" |
8 | |
9 | /* |
10 | * For get_evrregs/set_evrregs functions 'data' has the following layout: |
11 | * |
12 | * struct { |
13 | * u32 evr[32]; |
14 | * u64 acc; |
15 | * u32 spefscr; |
16 | * } |
17 | */ |
18 | |
19 | int evr_active(struct task_struct *target, const struct user_regset *regset) |
20 | { |
21 | flush_spe_to_thread(target); |
22 | return target->thread.used_spe ? regset->n : 0; |
23 | } |
24 | |
25 | int evr_get(struct task_struct *target, const struct user_regset *regset, |
26 | struct membuf to) |
27 | { |
28 | flush_spe_to_thread(target); |
29 | |
30 | membuf_write(s: &to, v: &target->thread.evr, size: sizeof(target->thread.evr)); |
31 | |
32 | BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) != |
33 | offsetof(struct thread_struct, spefscr)); |
34 | |
35 | return membuf_write(s: &to, v: &target->thread.acc, |
36 | size: sizeof(u64) + sizeof(u32)); |
37 | } |
38 | |
39 | int evr_set(struct task_struct *target, const struct user_regset *regset, |
40 | unsigned int pos, unsigned int count, |
41 | const void *kbuf, const void __user *ubuf) |
42 | { |
43 | int ret; |
44 | |
45 | flush_spe_to_thread(target); |
46 | |
47 | ret = user_regset_copyin(pos: &pos, count: &count, kbuf: &kbuf, ubuf: &ubuf, |
48 | data: &target->thread.evr, |
49 | start_pos: 0, end_pos: sizeof(target->thread.evr)); |
50 | |
51 | BUILD_BUG_ON(offsetof(struct thread_struct, acc) + sizeof(u64) != |
52 | offsetof(struct thread_struct, spefscr)); |
53 | |
54 | if (!ret) |
55 | ret = user_regset_copyin(pos: &pos, count: &count, kbuf: &kbuf, ubuf: &ubuf, |
56 | data: &target->thread.acc, |
57 | start_pos: sizeof(target->thread.evr), end_pos: -1); |
58 | |
59 | return ret; |
60 | } |
61 | |