arm64: dts: qcom: sm8550: add TRNG node
[linux-modified.git] / arch / powerpc / kernel / ptrace / ptrace-altivec.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 #include <linux/regset.h>
4 #include <linux/elf.h>
5
6 #include <asm/switch_to.h>
7
8 #include "ptrace-decl.h"
9
10 /*
11  * Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
12  * The transfer totals 34 quadword.  Quadwords 0-31 contain the
13  * corresponding vector registers.  Quadword 32 contains the vscr as the
14  * last word (offset 12) within that quadword.  Quadword 33 contains the
15  * vrsave as the first word (offset 0) within the quadword.
16  *
17  * This definition of the VMX state is compatible with the current PPC32
18  * ptrace interface.  This allows signal handling and ptrace to use the
19  * same structures.  This also simplifies the implementation of a bi-arch
20  * (combined (32- and 64-bit) gdb.
21  */
22
23 int vr_active(struct task_struct *target, const struct user_regset *regset)
24 {
25         flush_altivec_to_thread(target);
26         return target->thread.used_vr ? regset->n : 0;
27 }
28
29 /*
30  * Regardless of transactions, 'vr_state' holds the current running
31  * value of all the VMX registers and 'ckvr_state' holds the last
32  * checkpointed value of all the VMX registers for the current
33  * transaction to fall back on in case it aborts.
34  *
35  * Userspace interface buffer layout:
36  *
37  * struct data {
38  *      vector128       vr[32];
39  *      vector128       vscr;
40  *      vector128       vrsave;
41  * };
42  */
43 int vr_get(struct task_struct *target, const struct user_regset *regset,
44            struct membuf to)
45 {
46         union {
47                 elf_vrreg_t reg;
48                 u32 word;
49         } vrsave;
50
51         flush_altivec_to_thread(target);
52
53         BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
54                      offsetof(struct thread_vr_state, vr[32]));
55
56         membuf_write(&to, &target->thread.vr_state, 33 * sizeof(vector128));
57         /*
58          * Copy out only the low-order word of vrsave.
59          */
60         memset(&vrsave, 0, sizeof(vrsave));
61         vrsave.word = target->thread.vrsave;
62         return membuf_write(&to, &vrsave, sizeof(vrsave));
63 }
64
65 /*
66  * Regardless of transactions, 'vr_state' holds the current running
67  * value of all the VMX registers and 'ckvr_state' holds the last
68  * checkpointed value of all the VMX registers for the current
69  * transaction to fall back on in case it aborts.
70  *
71  * Userspace interface buffer layout:
72  *
73  * struct data {
74  *      vector128       vr[32];
75  *      vector128       vscr;
76  *      vector128       vrsave;
77  * };
78  */
79 int vr_set(struct task_struct *target, const struct user_regset *regset,
80            unsigned int pos, unsigned int count,
81            const void *kbuf, const void __user *ubuf)
82 {
83         int ret;
84
85         flush_altivec_to_thread(target);
86
87         BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
88                      offsetof(struct thread_vr_state, vr[32]));
89
90         ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
91                                  &target->thread.vr_state, 0,
92                                  33 * sizeof(vector128));
93         if (!ret && count > 0) {
94                 /*
95                  * We use only the first word of vrsave.
96                  */
97                 int start, end;
98                 union {
99                         elf_vrreg_t reg;
100                         u32 word;
101                 } vrsave;
102                 memset(&vrsave, 0, sizeof(vrsave));
103
104                 vrsave.word = target->thread.vrsave;
105
106                 start = 33 * sizeof(vector128);
107                 end = start + sizeof(vrsave);
108                 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
109                                          start, end);
110                 if (!ret)
111                         target->thread.vrsave = vrsave.word;
112         }
113
114         return ret;
115 }