1 /* SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation
4 * Extracted from signal_32.c and signal_64.c
7 #ifndef _POWERPC_ARCH_SIGNAL_H
8 #define _POWERPC_ARCH_SIGNAL_H
10 void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk,
11 size_t frame_size, int is_32);
13 extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
14 struct task_struct *tsk);
16 extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
17 struct task_struct *tsk);
19 static inline int __get_user_sigset(sigset_t *dst, const sigset_t __user *src)
21 BUILD_BUG_ON(sizeof(sigset_t) != sizeof(u64));
23 return __get_user(dst->sig[0], (u64 __user *)&src->sig[0]);
25 #define unsafe_get_user_sigset(dst, src, label) do { \
26 sigset_t *__dst = dst; \
27 const sigset_t __user *__src = src; \
30 for (i = 0; i < _NSIG_WORDS; i++) \
31 unsafe_get_user(__dst->sig[i], &__src->sig[i], label); \
35 extern unsigned long copy_vsx_to_user(void __user *to,
36 struct task_struct *task);
37 extern unsigned long copy_ckvsx_to_user(void __user *to,
38 struct task_struct *task);
39 extern unsigned long copy_vsx_from_user(struct task_struct *task,
41 extern unsigned long copy_ckvsx_from_user(struct task_struct *task,
43 unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
44 unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
45 unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
46 unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from);
48 #define unsafe_copy_fpr_to_user(to, task, label) do { \
49 struct task_struct *__t = task; \
50 u64 __user *buf = (u64 __user *)to; \
53 for (i = 0; i < ELF_NFPREG - 1 ; i++) \
54 unsafe_put_user(__t->thread.TS_FPR(i), &buf[i], label); \
55 unsafe_put_user(__t->thread.fp_state.fpscr, &buf[i], label); \
58 #define unsafe_copy_vsx_to_user(to, task, label) do { \
59 struct task_struct *__t = task; \
60 u64 __user *buf = (u64 __user *)to; \
63 for (i = 0; i < ELF_NVSRHALFREG ; i++) \
64 unsafe_put_user(__t->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
68 #define unsafe_copy_fpr_from_user(task, from, label) do { \
69 struct task_struct *__t = task; \
70 u64 __user *buf = (u64 __user *)from; \
73 for (i = 0; i < ELF_NFPREG - 1; i++) \
74 unsafe_get_user(__t->thread.TS_FPR(i), &buf[i], label); \
75 unsafe_get_user(__t->thread.fp_state.fpscr, &buf[i], label); \
78 #define unsafe_copy_vsx_from_user(task, from, label) do { \
79 struct task_struct *__t = task; \
80 u64 __user *buf = (u64 __user *)from; \
83 for (i = 0; i < ELF_NVSRHALFREG ; i++) \
84 unsafe_get_user(__t->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
88 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
89 #define unsafe_copy_ckfpr_to_user(to, task, label) do { \
90 struct task_struct *__t = task; \
91 u64 __user *buf = (u64 __user *)to; \
94 for (i = 0; i < ELF_NFPREG - 1 ; i++) \
95 unsafe_put_user(__t->thread.TS_CKFPR(i), &buf[i], label);\
96 unsafe_put_user(__t->thread.ckfp_state.fpscr, &buf[i], label); \
99 #define unsafe_copy_ckvsx_to_user(to, task, label) do { \
100 struct task_struct *__t = task; \
101 u64 __user *buf = (u64 __user *)to; \
104 for (i = 0; i < ELF_NVSRHALFREG ; i++) \
105 unsafe_put_user(__t->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
109 #define unsafe_copy_ckfpr_from_user(task, from, label) do { \
110 struct task_struct *__t = task; \
111 u64 __user *buf = (u64 __user *)from; \
114 for (i = 0; i < ELF_NFPREG - 1 ; i++) \
115 unsafe_get_user(__t->thread.TS_CKFPR(i), &buf[i], label);\
116 unsafe_get_user(__t->thread.ckfp_state.fpscr, &buf[i], failed); \
119 #define unsafe_copy_ckvsx_from_user(task, from, label) do { \
120 struct task_struct *__t = task; \
121 u64 __user *buf = (u64 __user *)from; \
124 for (i = 0; i < ELF_NVSRHALFREG ; i++) \
125 unsafe_get_user(__t->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
129 #elif defined(CONFIG_PPC_FPU_REGS)
131 #define unsafe_copy_fpr_to_user(to, task, label) \
132 unsafe_copy_to_user(to, (task)->thread.fp_state.fpr, \
133 ELF_NFPREG * sizeof(double), label)
135 #define unsafe_copy_fpr_from_user(task, from, label) \
136 unsafe_copy_from_user((task)->thread.fp_state.fpr, from, \
137 ELF_NFPREG * sizeof(double), label)
139 static inline unsigned long
140 copy_fpr_to_user(void __user *to, struct task_struct *task)
142 return __copy_to_user(to, task->thread.fp_state.fpr,
143 ELF_NFPREG * sizeof(double));
146 static inline unsigned long
147 copy_fpr_from_user(struct task_struct *task, void __user *from)
149 return __copy_from_user(task->thread.fp_state.fpr, from,
150 ELF_NFPREG * sizeof(double));
153 #ifdef CONFIG_PPC_TRANSACTIONAL_MEM
154 #define unsafe_copy_ckfpr_to_user(to, task, label) \
155 unsafe_copy_to_user(to, (task)->thread.ckfp_state.fpr, \
156 ELF_NFPREG * sizeof(double), label)
158 inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task)
160 return __copy_to_user(to, task->thread.ckfp_state.fpr,
161 ELF_NFPREG * sizeof(double));
164 static inline unsigned long
165 copy_ckfpr_from_user(struct task_struct *task, void __user *from)
167 return __copy_from_user(task->thread.ckfp_state.fpr, from,
168 ELF_NFPREG * sizeof(double));
170 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
172 #define unsafe_copy_fpr_to_user(to, task, label) do { if (0) goto label;} while (0)
174 #define unsafe_copy_fpr_from_user(task, from, label) do { if (0) goto label;} while (0)
176 static inline unsigned long
177 copy_fpr_to_user(void __user *to, struct task_struct *task)
182 static inline unsigned long
183 copy_fpr_from_user(struct task_struct *task, void __user *from)
191 extern int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
192 struct task_struct *tsk);
194 #else /* CONFIG_PPC64 */
196 static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
197 struct task_struct *tsk)
202 #endif /* !defined(CONFIG_PPC64) */
204 void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
205 const char *where, void __user *ptr);
207 #endif /* _POWERPC_ARCH_SIGNAL_H */