Commit | Line | Data |
---|---|---|
6fcb1397 GU |
1 | /* SPDX-License-Identifier: GPL-2.0-or-later |
2 | * | |
446957ba | 3 | * Copyright (c) 2007 Benjamin Herrenschmidt, IBM Corporation |
22e38f29 | 4 | * Extracted from signal_32.c and signal_64.c |
22e38f29 BH |
5 | */ |
6 | ||
7 | #ifndef _POWERPC_ARCH_SIGNAL_H | |
8 | #define _POWERPC_ARCH_SIGNAL_H | |
9 | ||
c180cb30 CL |
10 | void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk, |
11 | size_t frame_size, int is_32); | |
f478f543 | 12 | |
129b69df | 13 | extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset, |
d1199431 | 14 | struct task_struct *tsk); |
f478f543 | 15 | |
129b69df | 16 | extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, |
d1199431 | 17 | struct task_struct *tsk); |
f478f543 | 18 | |
d3ccc978 CR |
19 | static 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 | } | |
5499802b CL |
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) | |
d3ccc978 | 33 | |
6a274c08 MN |
34 | #ifdef CONFIG_VSX |
35 | extern unsigned long copy_vsx_to_user(void __user *to, | |
36 | struct task_struct *task); | |
000ec280 | 37 | extern unsigned long copy_ckvsx_to_user(void __user *to, |
2b0a576d | 38 | struct task_struct *task); |
6a274c08 MN |
39 | extern unsigned long copy_vsx_from_user(struct task_struct *task, |
40 | void __user *from); | |
000ec280 | 41 | extern unsigned long copy_ckvsx_from_user(struct task_struct *task, |
2b0a576d | 42 | void __user *from); |
95593e93 CL |
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); | |
b3484a1d CL |
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 | ||
609355df CR |
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 | ||
b3484a1d CL |
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) | |
7c11f889 CL |
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) | |
b3484a1d | 128 | #endif |
b6254ced | 129 | #elif defined(CONFIG_PPC_FPU_REGS) |
b3484a1d CL |
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 | ||
609355df CR |
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 | ||
95593e93 CL |
139 | static inline unsigned long |
140 | copy_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 | ||
146 | static inline unsigned long | |
147 | copy_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 | |
b3484a1d CL |
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 | ||
95593e93 CL |
158 | inline 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 | ||
164 | static inline unsigned long | |
165 | copy_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 */ | |
b6254ced | 171 | #else |
bc581dba | 172 | #define unsafe_copy_fpr_to_user(to, task, label) do { if (0) goto label;} while (0) |
b3484a1d | 173 | |
bc581dba | 174 | #define unsafe_copy_fpr_from_user(task, from, label) do { if (0) goto label;} while (0) |
609355df | 175 | |
b6254ced CL |
176 | static inline unsigned long |
177 | copy_fpr_to_user(void __user *to, struct task_struct *task) | |
178 | { | |
179 | return 0; | |
180 | } | |
181 | ||
182 | static inline unsigned long | |
183 | copy_fpr_from_user(struct task_struct *task, void __user *from) | |
184 | { | |
185 | return 0; | |
186 | } | |
6a274c08 | 187 | #endif |
2f97cd39 BH |
188 | |
189 | #ifdef CONFIG_PPC64 | |
190 | ||
129b69df | 191 | extern int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, |
d1199431 | 192 | struct task_struct *tsk); |
22e38f29 | 193 | |
2f97cd39 BH |
194 | #else /* CONFIG_PPC64 */ |
195 | ||
129b69df | 196 | static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set, |
d1199431 | 197 | struct task_struct *tsk) |
2f97cd39 BH |
198 | { |
199 | return -EFAULT; | |
200 | } | |
201 | ||
202 | #endif /* !defined(CONFIG_PPC64) */ | |
203 | ||
7fe8f773 CL |
204 | void signal_fault(struct task_struct *tsk, struct pt_regs *regs, |
205 | const char *where, void __user *ptr); | |
206 | ||
22e38f29 | 207 | #endif /* _POWERPC_ARCH_SIGNAL_H */ |