Merge tag 'hwlock-v5.14' of git://git.kernel.org/pub/scm/linux/kernel/git/andersson...
[linux-2.6-microblaze.git] / arch / powerpc / kernel / signal.h
1 /*
2  *    Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation
3  *    Extracted from signal_32.c and signal_64.c
4  *
5  * This file is subject to the terms and conditions of the GNU General
6  * Public License.  See the file README.legal in the main directory of
7  * this archive for more details.
8  */
9
10 #ifndef _POWERPC_ARCH_SIGNAL_H
11 #define _POWERPC_ARCH_SIGNAL_H
12
13 void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk,
14                           size_t frame_size, int is_32);
15
16 extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
17                            struct task_struct *tsk);
18
19 extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
20                               struct task_struct *tsk);
21
22 static inline int __get_user_sigset(sigset_t *dst, const sigset_t __user *src)
23 {
24         BUILD_BUG_ON(sizeof(sigset_t) != sizeof(u64));
25
26         return __get_user(dst->sig[0], (u64 __user *)&src->sig[0]);
27 }
28 #define unsafe_get_user_sigset(dst, src, label) \
29         unsafe_get_user((dst)->sig[0], (u64 __user *)&(src)->sig[0], label)
30
31 #ifdef CONFIG_VSX
32 extern unsigned long copy_vsx_to_user(void __user *to,
33                                       struct task_struct *task);
34 extern unsigned long copy_ckvsx_to_user(void __user *to,
35                                                struct task_struct *task);
36 extern unsigned long copy_vsx_from_user(struct task_struct *task,
37                                         void __user *from);
38 extern unsigned long copy_ckvsx_from_user(struct task_struct *task,
39                                                  void __user *from);
40 unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
41 unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
42 unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
43 unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from);
44
45 #define unsafe_copy_fpr_to_user(to, task, label)        do {            \
46         struct task_struct *__t = task;                                 \
47         u64 __user *buf = (u64 __user *)to;                             \
48         int i;                                                          \
49                                                                         \
50         for (i = 0; i < ELF_NFPREG - 1 ; i++)                           \
51                 unsafe_put_user(__t->thread.TS_FPR(i), &buf[i], label); \
52         unsafe_put_user(__t->thread.fp_state.fpscr, &buf[i], label);    \
53 } while (0)
54
55 #define unsafe_copy_vsx_to_user(to, task, label)        do {            \
56         struct task_struct *__t = task;                                 \
57         u64 __user *buf = (u64 __user *)to;                             \
58         int i;                                                          \
59                                                                         \
60         for (i = 0; i < ELF_NVSRHALFREG ; i++)                          \
61                 unsafe_put_user(__t->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
62                                 &buf[i], label);\
63 } while (0)
64
65 #define unsafe_copy_fpr_from_user(task, from, label)    do {            \
66         struct task_struct *__t = task;                                 \
67         u64 __user *buf = (u64 __user *)from;                           \
68         int i;                                                          \
69                                                                         \
70         for (i = 0; i < ELF_NFPREG - 1; i++)                            \
71                 unsafe_get_user(__t->thread.TS_FPR(i), &buf[i], label); \
72         unsafe_get_user(__t->thread.fp_state.fpscr, &buf[i], label);    \
73 } while (0)
74
75 #define unsafe_copy_vsx_from_user(task, from, label)    do {            \
76         struct task_struct *__t = task;                                 \
77         u64 __user *buf = (u64 __user *)from;                           \
78         int i;                                                          \
79                                                                         \
80         for (i = 0; i < ELF_NVSRHALFREG ; i++)                          \
81                 unsafe_get_user(__t->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
82                                 &buf[i], label);                        \
83 } while (0)
84
85 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
86 #define unsafe_copy_ckfpr_to_user(to, task, label)      do {            \
87         struct task_struct *__t = task;                                 \
88         u64 __user *buf = (u64 __user *)to;                             \
89         int i;                                                          \
90                                                                         \
91         for (i = 0; i < ELF_NFPREG - 1 ; i++)                           \
92                 unsafe_put_user(__t->thread.TS_CKFPR(i), &buf[i], label);\
93         unsafe_put_user(__t->thread.ckfp_state.fpscr, &buf[i], label);  \
94 } while (0)
95
96 #define unsafe_copy_ckvsx_to_user(to, task, label)      do {            \
97         struct task_struct *__t = task;                                 \
98         u64 __user *buf = (u64 __user *)to;                             \
99         int i;                                                          \
100                                                                         \
101         for (i = 0; i < ELF_NVSRHALFREG ; i++)                          \
102                 unsafe_put_user(__t->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
103                                 &buf[i], label);\
104 } while (0)
105
106 #define unsafe_copy_ckfpr_from_user(task, from, label)  do {            \
107         struct task_struct *__t = task;                                 \
108         u64 __user *buf = (u64 __user *)from;                           \
109         int i;                                                          \
110                                                                         \
111         for (i = 0; i < ELF_NFPREG - 1 ; i++)                           \
112                 unsafe_get_user(__t->thread.TS_CKFPR(i), &buf[i], label);\
113         unsafe_get_user(__t->thread.ckfp_state.fpscr, &buf[i], failed); \
114 } while (0)
115
116 #define unsafe_copy_ckvsx_from_user(task, from, label)  do {            \
117         struct task_struct *__t = task;                                 \
118         u64 __user *buf = (u64 __user *)from;                           \
119         int i;                                                          \
120                                                                         \
121         for (i = 0; i < ELF_NVSRHALFREG ; i++)                          \
122                 unsafe_get_user(__t->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
123                                 &buf[i], label);                        \
124 } while (0)
125 #endif
126 #elif defined(CONFIG_PPC_FPU_REGS)
127
128 #define unsafe_copy_fpr_to_user(to, task, label)                \
129         unsafe_copy_to_user(to, (task)->thread.fp_state.fpr,    \
130                             ELF_NFPREG * sizeof(double), label)
131
132 #define unsafe_copy_fpr_from_user(task, from, label)                    \
133         unsafe_copy_from_user((task)->thread.fp_state.fpr, from,        \
134                             ELF_NFPREG * sizeof(double), label)
135
136 static inline unsigned long
137 copy_fpr_to_user(void __user *to, struct task_struct *task)
138 {
139         return __copy_to_user(to, task->thread.fp_state.fpr,
140                               ELF_NFPREG * sizeof(double));
141 }
142
143 static inline unsigned long
144 copy_fpr_from_user(struct task_struct *task, void __user *from)
145 {
146         return __copy_from_user(task->thread.fp_state.fpr, from,
147                               ELF_NFPREG * sizeof(double));
148 }
149
150 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
151 #define unsafe_copy_ckfpr_to_user(to, task, label)              \
152         unsafe_copy_to_user(to, (task)->thread.ckfp_state.fpr,  \
153                             ELF_NFPREG * sizeof(double), label)
154
155 inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task)
156 {
157         return __copy_to_user(to, task->thread.ckfp_state.fpr,
158                               ELF_NFPREG * sizeof(double));
159 }
160
161 static inline unsigned long
162 copy_ckfpr_from_user(struct task_struct *task, void __user *from)
163 {
164         return __copy_from_user(task->thread.ckfp_state.fpr, from,
165                                 ELF_NFPREG * sizeof(double));
166 }
167 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
168 #else
169 #define unsafe_copy_fpr_to_user(to, task, label) do { if (0) goto label;} while (0)
170
171 #define unsafe_copy_fpr_from_user(task, from, label) do { if (0) goto label;} while (0)
172
173 static inline unsigned long
174 copy_fpr_to_user(void __user *to, struct task_struct *task)
175 {
176         return 0;
177 }
178
179 static inline unsigned long
180 copy_fpr_from_user(struct task_struct *task, void __user *from)
181 {
182         return 0;
183 }
184 #endif
185
186 #ifdef CONFIG_PPC64
187
188 extern int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
189                               struct task_struct *tsk);
190
191 #else /* CONFIG_PPC64 */
192
193 extern long sys_rt_sigreturn(void);
194 extern long sys_sigreturn(void);
195
196 static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
197                                      struct task_struct *tsk)
198 {
199         return -EFAULT;
200 }
201
202 #endif /* !defined(CONFIG_PPC64) */
203
204 void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
205                   const char *where, void __user *ptr);
206
207 #endif  /* _POWERPC_ARCH_SIGNAL_H */