Loading...
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
13void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk,
14 size_t frame_size, int is_32);
15
16extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
17 struct task_struct *tsk);
18
19extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
20 struct task_struct *tsk);
21
22static 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
32extern unsigned long copy_vsx_to_user(void __user *to,
33 struct task_struct *task);
34extern unsigned long copy_ckvsx_to_user(void __user *to,
35 struct task_struct *task);
36extern unsigned long copy_vsx_from_user(struct task_struct *task,
37 void __user *from);
38extern unsigned long copy_ckvsx_from_user(struct task_struct *task,
39 void __user *from);
40unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
41unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
42unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
43unsigned 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
136static inline unsigned long
137copy_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
143static inline unsigned long
144copy_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
155inline 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
161static inline unsigned long
162copy_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
173static inline unsigned long
174copy_fpr_to_user(void __user *to, struct task_struct *task)
175{
176 return 0;
177}
178
179static inline unsigned long
180copy_fpr_from_user(struct task_struct *task, void __user *from)
181{
182 return 0;
183}
184#endif
185
186#ifdef CONFIG_PPC64
187
188extern int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
189 struct task_struct *tsk);
190
191#else /* CONFIG_PPC64 */
192
193extern long sys_rt_sigreturn(void);
194extern long sys_sigreturn(void);
195
196static 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
204void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
205 const char *where, void __user *ptr);
206
207#endif /* _POWERPC_ARCH_SIGNAL_H */
1/* SPDX-License-Identifier: GPL-2.0-or-later
2 *
3 * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation
4 * Extracted from signal_32.c and signal_64.c
5 */
6
7#ifndef _POWERPC_ARCH_SIGNAL_H
8#define _POWERPC_ARCH_SIGNAL_H
9
10void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk,
11 size_t frame_size, int is_32);
12
13extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
14 struct task_struct *tsk);
15
16extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
17 struct task_struct *tsk);
18
19static inline int __get_user_sigset(sigset_t *dst, const sigset_t __user *src)
20{
21 BUILD_BUG_ON(sizeof(sigset_t) != sizeof(u64));
22
23 return __get_user(dst->sig[0], (u64 __user *)&src->sig[0]);
24}
25#define unsafe_get_user_sigset(dst, src, label) do { \
26 sigset_t *__dst = dst; \
27 const sigset_t __user *__src = src; \
28 int i; \
29 \
30 for (i = 0; i < _NSIG_WORDS; i++) \
31 unsafe_get_user(__dst->sig[i], &__src->sig[i], label); \
32} while (0)
33
34#ifdef CONFIG_VSX
35extern unsigned long copy_vsx_to_user(void __user *to,
36 struct task_struct *task);
37extern unsigned long copy_ckvsx_to_user(void __user *to,
38 struct task_struct *task);
39extern unsigned long copy_vsx_from_user(struct task_struct *task,
40 void __user *from);
41extern unsigned long copy_ckvsx_from_user(struct task_struct *task,
42 void __user *from);
43unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
44unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
45unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
46unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from);
47
48#define unsafe_copy_fpr_to_user(to, task, label) do { \
49 struct task_struct *__t = task; \
50 u64 __user *buf = (u64 __user *)to; \
51 int i; \
52 \
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); \
56} while (0)
57
58#define unsafe_copy_vsx_to_user(to, task, label) do { \
59 struct task_struct *__t = task; \
60 u64 __user *buf = (u64 __user *)to; \
61 int i; \
62 \
63 for (i = 0; i < ELF_NVSRHALFREG ; i++) \
64 unsafe_put_user(__t->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
65 &buf[i], label);\
66} while (0)
67
68#define unsafe_copy_fpr_from_user(task, from, label) do { \
69 struct task_struct *__t = task; \
70 u64 __user *buf = (u64 __user *)from; \
71 int i; \
72 \
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); \
76} while (0)
77
78#define unsafe_copy_vsx_from_user(task, from, label) do { \
79 struct task_struct *__t = task; \
80 u64 __user *buf = (u64 __user *)from; \
81 int i; \
82 \
83 for (i = 0; i < ELF_NVSRHALFREG ; i++) \
84 unsafe_get_user(__t->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
85 &buf[i], label); \
86} while (0)
87
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; \
92 int i; \
93 \
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); \
97} while (0)
98
99#define unsafe_copy_ckvsx_to_user(to, task, label) do { \
100 struct task_struct *__t = task; \
101 u64 __user *buf = (u64 __user *)to; \
102 int i; \
103 \
104 for (i = 0; i < ELF_NVSRHALFREG ; i++) \
105 unsafe_put_user(__t->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
106 &buf[i], label);\
107} while (0)
108
109#define unsafe_copy_ckfpr_from_user(task, from, label) do { \
110 struct task_struct *__t = task; \
111 u64 __user *buf = (u64 __user *)from; \
112 int i; \
113 \
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); \
117} while (0)
118
119#define unsafe_copy_ckvsx_from_user(task, from, label) do { \
120 struct task_struct *__t = task; \
121 u64 __user *buf = (u64 __user *)from; \
122 int i; \
123 \
124 for (i = 0; i < ELF_NVSRHALFREG ; i++) \
125 unsafe_get_user(__t->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
126 &buf[i], label); \
127} while (0)
128#endif
129#elif defined(CONFIG_PPC_FPU_REGS)
130
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)
134
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)
138
139static inline unsigned long
140copy_fpr_to_user(void __user *to, struct task_struct *task)
141{
142 return __copy_to_user(to, task->thread.fp_state.fpr,
143 ELF_NFPREG * sizeof(double));
144}
145
146static inline unsigned long
147copy_fpr_from_user(struct task_struct *task, void __user *from)
148{
149 return __copy_from_user(task->thread.fp_state.fpr, from,
150 ELF_NFPREG * sizeof(double));
151}
152
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)
157
158inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task)
159{
160 return __copy_to_user(to, task->thread.ckfp_state.fpr,
161 ELF_NFPREG * sizeof(double));
162}
163
164static inline unsigned long
165copy_ckfpr_from_user(struct task_struct *task, void __user *from)
166{
167 return __copy_from_user(task->thread.ckfp_state.fpr, from,
168 ELF_NFPREG * sizeof(double));
169}
170#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
171#else
172#define unsafe_copy_fpr_to_user(to, task, label) do { if (0) goto label;} while (0)
173
174#define unsafe_copy_fpr_from_user(task, from, label) do { if (0) goto label;} while (0)
175
176static inline unsigned long
177copy_fpr_to_user(void __user *to, struct task_struct *task)
178{
179 return 0;
180}
181
182static inline unsigned long
183copy_fpr_from_user(struct task_struct *task, void __user *from)
184{
185 return 0;
186}
187#endif
188
189#ifdef CONFIG_PPC64
190
191extern int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
192 struct task_struct *tsk);
193
194#else /* CONFIG_PPC64 */
195
196static 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
204void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
205 const char *where, void __user *ptr);
206
207#endif /* _POWERPC_ARCH_SIGNAL_H */