[PARISC] disable cr16 clocksource when multiple CPUs are online
[linux-2.6] / 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  *    Code was mostly borrowed from kernel/signal.c.
5  *    See kernel/signal.c for additional Copyrights.
6  *
7  *
8  *    This program is free software; you can redistribute it and/or modify
9  *    it under the terms of the GNU General Public License as published by
10  *    the Free Software Foundation; either version 2 of the License, or
11  *    (at your option) any later version.
12  *
13  *    This program is distributed in the hope that it will be useful,
14  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *    GNU General Public License for more details.
17  *
18  *    You should have received a copy of the GNU General Public License
19  *    along with this program; if not, write to the Free Software
20  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <linux/compat.h>
24 #include <linux/slab.h>
25 #include <linux/module.h>
26 #include <linux/unistd.h>
27 #include <linux/smp_lock.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 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
51
52 inline void
53 sigset_32to64(sigset_t *s64, compat_sigset_t *s32)
54 {
55         s64->sig[0] = s32->sig[0] | ((unsigned long)s32->sig[1] << 32);
56 }
57
58 inline void
59 sigset_64to32(compat_sigset_t *s32, sigset_t *s64)
60 {
61         s32->sig[0] = s64->sig[0] & 0xffffffffUL;
62         s32->sig[1] = (s64->sig[0] >> 32) & 0xffffffffUL;
63 }
64
65 static int
66 put_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
67 {
68         compat_sigset_t s;
69
70         if (sz != sizeof *set) panic("put_sigset32()");
71         sigset_64to32(&s, set);
72
73         return copy_to_user(up, &s, sizeof s);
74 }
75
76 static int
77 get_sigset32(compat_sigset_t __user *up, sigset_t *set, size_t sz)
78 {
79         compat_sigset_t s;
80         int r;
81
82         if (sz != sizeof *set) panic("put_sigset32()");
83
84         if ((r = copy_from_user(&s, up, sz)) == 0) {
85                 sigset_32to64(set, &s);
86         }
87
88         return r;
89 }
90
91 int sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
92                                     unsigned int sigsetsize)
93 {
94         sigset_t old_set, new_set;
95         int ret;
96
97         if (set && get_sigset32(set, &new_set, sigsetsize))
98                 return -EFAULT;
99         
100         KERNEL_SYSCALL(ret, sys_rt_sigprocmask, how, set ? (sigset_t __user *)&new_set : NULL,
101                                  oset ? (sigset_t __user *)&old_set : NULL, sigsetsize);
102
103         if (!ret && oset && put_sigset32(oset, &old_set, sigsetsize))
104                 return -EFAULT;
105
106         return ret;
107 }
108
109
110 int sys32_rt_sigpending(compat_sigset_t __user *uset, unsigned int sigsetsize)
111 {
112         int ret;
113         sigset_t set;
114
115         KERNEL_SYSCALL(ret, sys_rt_sigpending, (sigset_t __user *)&set, sigsetsize);
116
117         if (!ret && put_sigset32(uset, &set, sigsetsize))
118                 return -EFAULT;
119
120         return ret;
121 }
122
123 long
124 sys32_rt_sigaction(int sig, const struct sigaction32 __user *act, struct sigaction32 __user *oact,
125                  size_t sigsetsize)
126 {
127         struct k_sigaction32 new_sa32, old_sa32;
128         struct k_sigaction new_sa, old_sa;
129         int ret = -EINVAL;
130
131         if (act) {
132                 if (copy_from_user(&new_sa32.sa, act, sizeof new_sa32.sa))
133                         return -EFAULT;
134                 new_sa.sa.sa_handler = (__sighandler_t)(unsigned long)new_sa32.sa.sa_handler;
135                 new_sa.sa.sa_flags = new_sa32.sa.sa_flags;
136                 sigset_32to64(&new_sa.sa.sa_mask, &new_sa32.sa.sa_mask);
137         }
138
139         ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
140
141         if (!ret && oact) {
142                 sigset_64to32(&old_sa32.sa.sa_mask, &old_sa.sa.sa_mask);
143                 old_sa32.sa.sa_flags = old_sa.sa.sa_flags;
144                 old_sa32.sa.sa_handler = (__sighandler_t32)(unsigned long)old_sa.sa.sa_handler;
145                 if (copy_to_user(oact, &old_sa32.sa, sizeof old_sa32.sa))
146                         return -EFAULT;
147         }
148         return ret;
149 }
150
151 int 
152 do_sigaltstack32 (const compat_stack_t __user *uss32, compat_stack_t __user *uoss32, unsigned long sp)
153 {
154         compat_stack_t ss32, oss32;
155         stack_t ss, oss;
156         stack_t *ssp = NULL, *ossp = NULL;
157         int ret;
158
159         if (uss32) {
160                 if (copy_from_user(&ss32, uss32, sizeof ss32))
161                         return -EFAULT;
162
163                 ss.ss_sp = (void __user *)(unsigned long)ss32.ss_sp;
164                 ss.ss_flags = ss32.ss_flags;
165                 ss.ss_size = ss32.ss_size;
166
167                 ssp = &ss;
168         }
169
170         if (uoss32)
171                 ossp = &oss;
172
173         KERNEL_SYSCALL(ret, do_sigaltstack, (const stack_t __user *)ssp, (stack_t __user *)ossp, sp);
174
175         if (!ret && uoss32) {
176                 oss32.ss_sp = (unsigned int)(unsigned long)oss.ss_sp;
177                 oss32.ss_flags = oss.ss_flags;
178                 oss32.ss_size = oss.ss_size;
179                 if (copy_to_user(uoss32, &oss32, sizeof *uoss32))
180                         return -EFAULT;
181         }
182
183         return ret;
184 }
185
186 long
187 restore_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf,
188                 struct pt_regs *regs)
189 {
190         long err = 0;
191         compat_uint_t compat_reg;
192         compat_uint_t compat_regt;
193         int regn;
194         
195         /* When loading 32-bit values into 64-bit registers make
196            sure to clear the upper 32-bits */
197         DBG(2,"restore_sigcontext32: PER_LINUX32 process\n");
198         DBG(2,"restore_sigcontext32: sc = 0x%p, rf = 0x%p, regs = 0x%p\n", sc, rf, regs);
199         DBG(2,"restore_sigcontext32: compat_sigcontext is %#lx bytes\n", sizeof(*sc));
200         for(regn=0; regn < 32; regn++){
201                 err |= __get_user(compat_reg,&sc->sc_gr[regn]);
202                 regs->gr[regn] = compat_reg;
203                 /* Load upper half */
204                 err |= __get_user(compat_regt,&rf->rf_gr[regn]);
205                 regs->gr[regn] = ((u64)compat_regt << 32) | (u64)compat_reg;
206                 DBG(3,"restore_sigcontext32: gr%02d = %#lx (%#x / %#x)\n", 
207                                 regn, regs->gr[regn], compat_regt, compat_reg);
208         }
209         DBG(2,"restore_sigcontext32: sc->sc_fr = 0x%p (%#lx)\n",sc->sc_fr, sizeof(sc->sc_fr));
210         /* XXX: BE WARNED FR's are 64-BIT! */
211         err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
212                 
213         /* Better safe than sorry, pass __get_user two things of
214            the same size and let gcc do the upward conversion to 
215            64-bits */           
216         err |= __get_user(compat_reg, &sc->sc_iaoq[0]);
217         /* Load upper half */
218         err |= __get_user(compat_regt, &rf->rf_iaoq[0]);
219         regs->iaoq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
220         DBG(2,"restore_sigcontext32: upper half of iaoq[0] = %#lx\n", compat_regt);
221         DBG(2,"restore_sigcontext32: sc->sc_iaoq[0] = %p => %#x\n", 
222                         &sc->sc_iaoq[0], compat_reg);
223
224         err |= __get_user(compat_reg, &sc->sc_iaoq[1]);
225         /* Load upper half */
226         err |= __get_user(compat_regt, &rf->rf_iaoq[1]);
227         regs->iaoq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
228         DBG(2,"restore_sigcontext32: upper half of iaoq[1] = %#lx\n", compat_regt);
229         DBG(2,"restore_sigcontext32: sc->sc_iaoq[1] = %p => %#x\n", 
230                         &sc->sc_iaoq[1],compat_reg);    
231         DBG(2,"restore_sigcontext32: iaoq is %#lx / %#lx\n", 
232                         regs->iaoq[0],regs->iaoq[1]);           
233                 
234         err |= __get_user(compat_reg, &sc->sc_iasq[0]);
235         /* Load the upper half for iasq */
236         err |= __get_user(compat_regt, &rf->rf_iasq[0]);
237         regs->iasq[0] = ((u64)compat_regt << 32) | (u64)compat_reg;
238         DBG(2,"restore_sigcontext32: upper half of iasq[0] = %#lx\n", compat_regt);
239         
240         err |= __get_user(compat_reg, &sc->sc_iasq[1]);
241         /* Load the upper half for iasq */
242         err |= __get_user(compat_regt, &rf->rf_iasq[1]);
243         regs->iasq[1] = ((u64)compat_regt << 32) | (u64)compat_reg;
244         DBG(2,"restore_sigcontext32: upper half of iasq[1] = %#lx\n", compat_regt);
245         DBG(2,"restore_sigcontext32: iasq is %#lx / %#lx\n", 
246                 regs->iasq[0],regs->iasq[1]);           
247
248         err |= __get_user(compat_reg, &sc->sc_sar);
249         /* Load the upper half for sar */
250         err |= __get_user(compat_regt, &rf->rf_sar);
251         regs->sar = ((u64)compat_regt << 32) | (u64)compat_reg; 
252         DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);  
253         DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);                
254         DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);
255         
256         return err;
257 }
258
259 /*
260  * Set up the sigcontext structure for this process.
261  * This is not an easy task if the kernel is 64-bit, it will require
262  * that we examine the process personality to determine if we need to
263  * truncate for a 32-bit userspace.
264  */
265 long
266 setup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf, 
267                 struct pt_regs *regs, int in_syscall)            
268 {
269         compat_int_t flags = 0;
270         long err = 0;
271         compat_uint_t compat_reg;
272         compat_uint_t compat_regb;
273         int regn;
274         
275         if (on_sig_stack((unsigned long) sc))
276                 flags |= PARISC_SC_FLAG_ONSTACK;
277         
278         if (in_syscall) {
279                 
280                 DBG(1,"setup_sigcontext32: in_syscall\n");
281                 
282                 flags |= PARISC_SC_FLAG_IN_SYSCALL;
283                 /* Truncate gr31 */
284                 compat_reg = (compat_uint_t)(regs->gr[31]);
285                 /* regs->iaoq is undefined in the syscall return path */
286                 err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
287                 DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
288                                 &sc->sc_iaoq[0], compat_reg);
289                 
290                 /* Store upper half */
291                 compat_reg = (compat_uint_t)(regs->gr[32] >> 32);
292                 err |= __put_user(compat_reg, &rf->rf_iaoq[0]);
293                 DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
294                 
295                 
296                 compat_reg = (compat_uint_t)(regs->gr[31]+4);
297                 err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
298                 DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
299                                 &sc->sc_iaoq[1], compat_reg);
300                 /* Store upper half */
301                 compat_reg = (compat_uint_t)((regs->gr[32]+4) >> 32);
302                 err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
303                 DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
304                 
305                 /* Truncate sr3 */
306                 compat_reg = (compat_uint_t)(regs->sr[3]);
307                 err |= __put_user(compat_reg, &sc->sc_iasq[0]);
308                 err |= __put_user(compat_reg, &sc->sc_iasq[1]);         
309                 
310                 /* Store upper half */
311                 compat_reg = (compat_uint_t)(regs->sr[3] >> 32);
312                 err |= __put_user(compat_reg, &rf->rf_iasq[0]);
313                 err |= __put_user(compat_reg, &rf->rf_iasq[1]);         
314                 
315                 DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
316                 DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);            
317                 DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",                         
318                         regs->gr[31], regs->gr[31]+4);
319                 
320         } else {
321                 
322                 compat_reg = (compat_uint_t)(regs->iaoq[0]);
323                 err |= __put_user(compat_reg, &sc->sc_iaoq[0]);
324                 DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",
325                                 &sc->sc_iaoq[0], compat_reg);
326                 /* Store upper half */
327                 compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);
328                 err |= __put_user(compat_reg, &rf->rf_iaoq[0]); 
329                 DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);
330                 
331                 compat_reg = (compat_uint_t)(regs->iaoq[1]);
332                 err |= __put_user(compat_reg, &sc->sc_iaoq[1]);
333                 DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",
334                                 &sc->sc_iaoq[1], compat_reg);
335                 /* Store upper half */
336                 compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);
337                 err |= __put_user(compat_reg, &rf->rf_iaoq[1]);
338                 DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);
339                 
340                 
341                 compat_reg = (compat_uint_t)(regs->iasq[0]);
342                 err |= __put_user(compat_reg, &sc->sc_iasq[0]);
343                 DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",
344                                 &sc->sc_iasq[0], compat_reg);
345                 /* Store upper half */
346                 compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);
347                 err |= __put_user(compat_reg, &rf->rf_iasq[0]);
348                 DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);
349                 
350                 
351                 compat_reg = (compat_uint_t)(regs->iasq[1]);
352                 err |= __put_user(compat_reg, &sc->sc_iasq[1]);
353                 DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",
354                                 &sc->sc_iasq[1], compat_reg);
355                 /* Store upper half */
356                 compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);
357                 err |= __put_user(compat_reg, &rf->rf_iasq[1]);
358                 DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);
359
360                 /* Print out the IAOQ for debugging */          
361                 DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n", 
362                         regs->iaoq[0], regs->iaoq[1]);
363         }
364
365         err |= __put_user(flags, &sc->sc_flags);
366         
367         DBG(1,"setup_sigcontext32: Truncating general registers.\n");
368         
369         for(regn=0; regn < 32; regn++){
370                 /* Truncate a general register */
371                 compat_reg = (compat_uint_t)(regs->gr[regn]);
372                 err |= __put_user(compat_reg, &sc->sc_gr[regn]);
373                 /* Store upper half */
374                 compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);
375                 err |= __put_user(compat_regb, &rf->rf_gr[regn]);
376
377                 /* DEBUG: Write out the "upper / lower" register data */
378                 DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn, 
379                                 compat_regb, compat_reg);
380         }
381         
382         /* Copy the floating point registers (same size)
383            XXX: BE WARNED FR's are 64-BIT! */   
384         DBG(1,"setup_sigcontext32: Copying from regs to sc, "
385               "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",
386                 sizeof(regs->fr), sizeof(sc->sc_fr));
387         err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
388
389         compat_reg = (compat_uint_t)(regs->sar);
390         err |= __put_user(compat_reg, &sc->sc_sar);
391         DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);
392         /* Store upper half */
393         compat_reg = (compat_uint_t)(regs->sar >> 32);
394         err |= __put_user(compat_reg, &rf->rf_sar);     
395         DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);
396         DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);
397
398         return err;
399 }
400
401 int
402 copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
403 {
404         unsigned long tmp;
405         int err;
406
407         if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
408                 return -EFAULT;
409
410         err = __get_user(to->si_signo, &from->si_signo);
411         err |= __get_user(to->si_errno, &from->si_errno);
412         err |= __get_user(to->si_code, &from->si_code);
413
414         if (to->si_code < 0)
415                 err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
416         else {
417                 switch (to->si_code >> 16) {
418                       case __SI_CHLD >> 16:
419                         err |= __get_user(to->si_utime, &from->si_utime);
420                         err |= __get_user(to->si_stime, &from->si_stime);
421                         err |= __get_user(to->si_status, &from->si_status);
422                       default:
423                         err |= __get_user(to->si_pid, &from->si_pid);
424                         err |= __get_user(to->si_uid, &from->si_uid);
425                         break;
426                       case __SI_FAULT >> 16:
427                         err |= __get_user(tmp, &from->si_addr);
428                         to->si_addr = (void __user *) tmp;
429                         break;
430                       case __SI_POLL >> 16:
431                         err |= __get_user(to->si_band, &from->si_band);
432                         err |= __get_user(to->si_fd, &from->si_fd);
433                         break;
434                       case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
435                       case __SI_MESGQ >> 16:
436                         err |= __get_user(to->si_pid, &from->si_pid);
437                         err |= __get_user(to->si_uid, &from->si_uid);
438                         err |= __get_user(to->si_int, &from->si_int);
439                         break;
440                 }
441         }
442         return err;
443 }
444
445 int
446 copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
447 {
448         unsigned int addr;
449         int err;
450
451         if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
452                 return -EFAULT;
453
454         /* If you change siginfo_t structure, please be sure
455            this code is fixed accordingly.
456            It should never copy any pad contained in the structure
457            to avoid security leaks, but must copy the generic
458            3 ints plus the relevant union member.
459            This routine must convert siginfo from 64bit to 32bit as well
460            at the same time.  */
461         err = __put_user(from->si_signo, &to->si_signo);
462         err |= __put_user(from->si_errno, &to->si_errno);
463         err |= __put_user((short)from->si_code, &to->si_code);
464         if (from->si_code < 0)
465                 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
466         else {
467                 switch (from->si_code >> 16) {
468                 case __SI_CHLD >> 16:
469                         err |= __put_user(from->si_utime, &to->si_utime);
470                         err |= __put_user(from->si_stime, &to->si_stime);
471                         err |= __put_user(from->si_status, &to->si_status);
472                 default:
473                         err |= __put_user(from->si_pid, &to->si_pid);
474                         err |= __put_user(from->si_uid, &to->si_uid);
475                         break;
476                 case __SI_FAULT >> 16:
477                         /* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */
478                         err |= __put_user(from->_sifields._pad[0], &to->si_addr);
479                         break;
480                 case __SI_POLL >> 16:
481                         err |= __put_user(from->si_band, &to->si_band);
482                         err |= __put_user(from->si_fd, &to->si_fd);
483                         break;
484                 case __SI_TIMER >> 16:
485                         err |= __put_user(from->si_tid, &to->si_tid);
486                         err |= __put_user(from->si_overrun, &to->si_overrun);
487                         addr = (unsigned long) from->si_ptr;
488                         err |= __put_user(addr, &to->si_ptr);
489                         break;
490                 case __SI_RT >> 16:     /* Not generated by the kernel as of now.  */
491                 case __SI_MESGQ >> 16:
492                         err |= __put_user(from->si_uid, &to->si_uid);
493                         err |= __put_user(from->si_pid, &to->si_pid);
494                         addr = (unsigned long) from->si_ptr;
495                         err |= __put_user(addr, &to->si_ptr);
496                         break;
497                 }
498         }
499         return err;
500 }