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 | * Regardless of transactions, 'fp_state' holds the current running |
11 | * value of all FPR registers and 'ckfp_state' holds the last checkpointed |
12 | * value of all FPR registers for the current transaction. |
13 | * |
14 | * Userspace interface buffer layout: |
15 | * |
16 | * struct data { |
17 | * u64 fpr[32]; |
18 | * u64 fpscr; |
19 | * }; |
20 | */ |
21 | int fpr_get(struct task_struct *target, const struct user_regset *regset, |
22 | struct membuf to) |
23 | { |
24 | #ifdef CONFIG_PPC_FPU_REGS |
25 | BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) != |
26 | offsetof(struct thread_fp_state, fpr[32])); |
27 | |
28 | flush_fp_to_thread(target); |
29 | |
30 | return membuf_write(&to, &target->thread.fp_state, 33 * sizeof(u64)); |
31 | #else |
32 | return membuf_write(s: &to, v: &empty_zero_page, size: 33 * sizeof(u64)); |
33 | #endif |
34 | } |
35 | |
36 | /* |
37 | * Regardless of transactions, 'fp_state' holds the current running |
38 | * value of all FPR registers and 'ckfp_state' holds the last checkpointed |
39 | * value of all FPR registers for the current transaction. |
40 | * |
41 | * Userspace interface buffer layout: |
42 | * |
43 | * struct data { |
44 | * u64 fpr[32]; |
45 | * u64 fpscr; |
46 | * }; |
47 | * |
48 | */ |
49 | int fpr_set(struct task_struct *target, const struct user_regset *regset, |
50 | unsigned int pos, unsigned int count, |
51 | const void *kbuf, const void __user *ubuf) |
52 | { |
53 | #ifdef CONFIG_PPC_FPU_REGS |
54 | BUILD_BUG_ON(offsetof(struct thread_fp_state, fpscr) != |
55 | offsetof(struct thread_fp_state, fpr[32])); |
56 | |
57 | flush_fp_to_thread(target); |
58 | |
59 | return user_regset_copyin(&pos, &count, &kbuf, &ubuf, |
60 | &target->thread.fp_state, 0, -1); |
61 | #else |
62 | return 0; |
63 | #endif |
64 | } |
65 | |