ASoC: fsl: Add S/PDIF CPU DAI driver
[deliverable/linux.git] / arch / parisc / kernel / signal32.c
1 /* Signal support for 32-bit kernel builds
2 *
3 * Copyright (C) 2001 Matthew Wilcox <willy at parisc-linux.org>
4 * Copyright (C) 2006 Kyle McMartin <kyle at parisc-linux.org>
5 *
6 * Code was mostly borrowed from kernel/signal.c.
7 * See kernel/signal.c for additional Copyrights.
8 *
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24
25 #include <linux/compat.h>
26 #include <linux/module.h>
27 #include <linux/unistd.h>
28 #include <linux/init.h>
29 #include <linux/sched.h>
30 #include <linux/syscalls.h>
31 #include <linux/types.h>
32 #include <linux/errno.h>
33
34 #include <asm/uaccess.h>
35
36 #include "signal32.h"
37 #include "sys32.h"
38
39 #define DEBUG_COMPAT_SIG 0
40 #define DEBUG_COMPAT_SIG_LEVEL 2
41
42 #if DEBUG_COMPAT_SIG
43 #define DBG(LEVEL, ...) \
44 ((DEBUG_COMPAT_SIG_LEVEL >= LEVEL) \
45 ? printk(__VA_ARGS__) : (void) 0)
46 #else
47 #define DBG(LEVEL, ...)
48 #endif
49
50 inline void
51 sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
52 {
53 s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
54 }
55
56 inline void
57 sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
58 {
59 s32->sig[0] = s64->sig[0] & 0xffffffffUL;
60 s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
61 }
62
63 long
64 restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
65 struct pt_regs *regs)
66 {
67 long err = 0;
68 compat_uint_t compat_reg;
69 compat_uint_t compat_regt;
70 int regn;
71
72 /* When loading 32-bit values into 64-bit registers make
73 sure to clear the upper 32-bits */
74 DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
75 DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
76 DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
77 for(regn=0; regn < 32; regn++){
78 err |= __get_user(compat_reg,&sc->sc_gr[regn]);
79 regs->gr[regn] = compat_reg;
80 /* Load upper half */
81 err |= __get_user(compat_regt,&rf->rf_gr[regn]);
82 regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
83 DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n",
84 regn, regs->gr[regn], compat_regt, compat_reg);
85 }
86 DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
87 /* XXX: BE WARNED FR's are 64-BIT! */
88 err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
89
90 /* Better safe than sorry, pass __get_user two things of
91 the same size and let gcc do the upward conversion to
92 64-bits */
93 err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
94 /* Load upper half */
95 err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
96 regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
97 DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
98 DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n",
99 &sc->sc_iaoq[0], compat_reg);
100
101 err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
102 /* Load upper half */
103 err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
104 regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
105 DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
106 DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n",
107 &sc->sc_iaoq[1],compat_reg);
108 DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n",
109 regs->iaoq[0],regs->iaoq[1]);
110
111 err |= __get_user(compat_reg, &sc->sc_iasq[0]);
112 /* Load the upper half for iasq */
113 err |= __get_user(compat_regt, &rf->rf_iasq[0]);
114 regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
115 DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
116
117 err |= __get_user(compat_reg, &sc->sc_iasq[1]);
118 /* Load the upper half for iasq */
119 err |= __get_user(compat_regt, &rf->rf_iasq[1]);
120 regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
121 DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
122 DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n",
123 regs->iasq[0],regs->iasq[1]);
124
125 err |= __get_user(compat_reg, &sc->sc_sar);
126 /* Load the upper half for sar */
127 err |= __get_user(compat_regt, &rf->rf_sar);
128 regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg;
129 DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);
130 DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);
131 DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
132
133 return err;
134 }
135
136 /*
137 * Set up the sigcontext structure for this process.
138 * This is not an easy task if the kernel is 64-bit, it will require
139 * that we examine the process personality to determine if we need to
140 * truncate for a 32-bit userspace.
141 */
142 long
143 setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
144 struct pt_regs *regs, int in_syscall)
145 {
146 compat_int_t flags = 0;
147 long err = 0;
148 compat_uint_t compat_reg;
149 compat_uint_t compat_regb;
150 int regn;
151
152 if (on_sig_stack((unsigned long) sc))
153 flags |= PARISC_SC_FLAG_ONSTACK;
154
155 if (in_syscall) {
156
157 DBG(1,"setup_sigcontext32: in_syscall\n");
158
159 flags |= PARISC_SC_FLAG_IN_SYSCALL;
160 /* Truncate gr31 */
161 compat_reg = (compat_uint_t)(regs->gr[31]);
162 /* regs->iaoq is undefined in the syscall return path */
163 err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
164 DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
165 &sc->sc_iaoq[0], compat_reg);
166
167 /* Store upper half */
168 compat_reg = (compat_uint_t)(regs->gr[31] >> 32);
169 err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
170 DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
171
172
173 compat_reg = (compat_uint_t)(regs->gr[31]+4);
174 err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
175 DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
176 &sc->sc_iaoq[1], compat_reg);
177 /* Store upper half */
178 compat_reg = (compat_uint_t)((regs->gr[31]+4) >> 32);
179 err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
180 DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
181
182 /* Truncate sr3 */
183 compat_reg = (compat_uint_t)(regs->sr[3]);
184 err |= __put_user(compat_reg, &sc->sc_iasq[0]);
185 err |= __put_user(compat_reg, &sc->sc_iasq[1]);
186
187 /* Store upper half */
188 compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
189 err |= __put_user(compat_reg, &rf->rf_iasq[0]);
190 err |= __put_user(compat_reg, &rf->rf_iasq[1]);
191
192 DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
193 DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
194 DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",
195 regs->gr[31], regs->gr[31]+4);
196
197 } else {
198
199 compat_reg = (compat_uint_t)(regs->iaoq[0]);
200 err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
201 DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
202 &sc->sc_iaoq[0], compat_reg);
203 /* Store upper half */
204 compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
205 err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
206 DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
207
208 compat_reg = (compat_uint_t)(regs->iaoq[1]);
209 err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
210 DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
211 &sc->sc_iaoq[1], compat_reg);
212 /* Store upper half */
213 compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
214 err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
215 DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
216
217
218 compat_reg = (compat_uint_t)(regs->iasq[0]);
219 err |= __put_user(compat_reg, &sc->sc_iasq[0]);
220 DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
221 &sc->sc_iasq[0], compat_reg);
222 /* Store upper half */
223 compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
224 err |= __put_user(compat_reg, &rf->rf_iasq[0]);
225 DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
226
227
228 compat_reg = (compat_uint_t)(regs->iasq[1]);
229 err |= __put_user(compat_reg, &sc->sc_iasq[1]);
230 DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
231 &sc->sc_iasq[1], compat_reg);
232 /* Store upper half */
233 compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
234 err |= __put_user(compat_reg, &rf->rf_iasq[1]);
235 DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
236
237 /* Print out the IAOQ for debugging */
238 DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n",
239 regs->iaoq[0], regs->iaoq[1]);
240 }
241
242 err |= __put_user(flags, &sc->sc_flags);
243
244 DBG(1,"setup_sigcontext32: Truncating general registers.\n");
245
246 for(regn=0; regn < 32; regn++){
247 /* Truncate a general register */
248 compat_reg = (compat_uint_t)(regs->gr[regn]);
249 err |= __put_user(compat_reg, &sc->sc_gr[regn]);
250 /* Store upper half */
251 compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
252 err |= __put_user(compat_regb, &rf->rf_gr[regn]);
253
254 /* DEBUG: Write out the "upper / lower" register data */
255 DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn,
256 compat_regb, compat_reg);
257 }
258
259 /* Copy the floating point registers (same size)
260 XXX: BE WARNED FR's are 64-BIT! */
261 DBG(1,"setup_sigcontext32: Copying from regs to sc, "
262 "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
263 sizeof(regs->fr), sizeof(sc->sc_fr));
264 err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
265
266 compat_reg = (compat_uint_t)(regs->sar);
267 err |= __put_user(compat_reg, &sc->sc_sar);
268 DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
269 /* Store upper half */
270 compat_reg = (compat_uint_t)(regs->sar >> 32);
271 err |= __put_user(compat_reg, &rf->rf_sar);
272 DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
273 DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
274
275 return err;
276 }
277
278 int
279 copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
280 {
281 compat_uptr_t addr;
282 int err;
283
284 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
285 return -EFAULT;
286
287 err = __get_user(to->si_signo, &from->si_signo);
288 err |= __get_user(to->si_errno, &from->si_errno);
289 err |= __get_user(to->si_code, &from->si_code);
290
291 if (to->si_code < 0)
292 err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
293 else {
294 switch (to->si_code >> 16) {
295 case __SI_CHLD >> 16:
296 err |= __get_user(to->si_utime, &from->si_utime);
297 err |= __get_user(to->si_stime, &from->si_stime);
298 err |= __get_user(to->si_status, &from->si_status);
299 default:
300 err |= __get_user(to->si_pid, &from->si_pid);
301 err |= __get_user(to->si_uid, &from->si_uid);
302 break;
303 case __SI_FAULT >> 16:
304 err |= __get_user(addr, &from->si_addr);
305 to->si_addr = compat_ptr(addr);
306 break;
307 case __SI_POLL >> 16:
308 err |= __get_user(to->si_band, &from->si_band);
309 err |= __get_user(to->si_fd, &from->si_fd);
310 break;
311 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
312 case __SI_MESGQ >> 16:
313 err |= __get_user(to->si_pid, &from->si_pid);
314 err |= __get_user(to->si_uid, &from->si_uid);
315 err |= __get_user(to->si_int, &from->si_int);
316 break;
317 }
318 }
319 return err;
320 }
321
322 int
323 copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
324 {
325 compat_uptr_t addr;
326 compat_int_t val;
327 int err;
328
329 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
330 return -EFAULT;
331
332 /* If you change siginfo_t structure, please be sure
333 this code is fixed accordingly.
334 It should never copy any pad contained in the structure
335 to avoid security leaks, but must copy the generic
336 3 ints plus the relevant union member.
337 This routine must convert siginfo from 64bit to 32bit as well
338 at the same time. */
339 err = __put_user(from->si_signo, &to->si_signo);
340 err |= __put_user(from->si_errno, &to->si_errno);
341 err |= __put_user((short)from->si_code, &to->si_code);
342 if (from->si_code < 0)
343 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
344 else {
345 switch (from->si_code >> 16) {
346 case __SI_CHLD >> 16:
347 err |= __put_user(from->si_utime, &to->si_utime);
348 err |= __put_user(from->si_stime, &to->si_stime);
349 err |= __put_user(from->si_status, &to->si_status);
350 default:
351 err |= __put_user(from->si_pid, &to->si_pid);
352 err |= __put_user(from->si_uid, &to->si_uid);
353 break;
354 case __SI_FAULT >> 16:
355 addr = ptr_to_compat(from->si_addr);
356 err |= __put_user(addr, &to->si_addr);
357 break;
358 case __SI_POLL >> 16:
359 err |= __put_user(from->si_band, &to->si_band);
360 err |= __put_user(from->si_fd, &to->si_fd);
361 break;
362 case __SI_TIMER >> 16:
363 err |= __put_user(from->si_tid, &to->si_tid);
364 err |= __put_user(from->si_overrun, &to->si_overrun);
365 val = (compat_int_t)from->si_int;
366 err |= __put_user(val, &to->si_int);
367 break;
368 case __SI_RT >> 16: /* Not generated by the kernel as of now. */
369 case __SI_MESGQ >> 16:
370 err |= __put_user(from->si_uid, &to->si_uid);
371 err |= __put_user(from->si_pid, &to->si_pid);
372 val = (compat_int_t)from->si_int;
373 err |= __put_user(val, &to->si_int);
374 break;
375 }
376 }
377 return err;
378 }
This page took 0.040578 seconds and 5 git commands to generate.