[IA64] ia32_signal.c: erroneous use of memset/memcpy
[linux-2.6] / arch / ia64 / ia32 / ia32_signal.c
1 /*
2  * IA32 Architecture-specific signal handling support.
3  *
4  * Copyright (C) 1999, 2001-2002, 2005 Hewlett-Packard Co
5  *      David Mosberger-Tang <davidm@hpl.hp.com>
6  * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
7  * Copyright (C) 2000 VA Linux Co
8  * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
9  *
10  * Derived from i386 and Alpha versions.
11  */
12
13 #include <linux/errno.h>
14 #include <linux/kernel.h>
15 #include <linux/mm.h>
16 #include <linux/personality.h>
17 #include <linux/ptrace.h>
18 #include <linux/sched.h>
19 #include <linux/signal.h>
20 #include <linux/smp.h>
21 #include <linux/smp_lock.h>
22 #include <linux/stddef.h>
23 #include <linux/syscalls.h>
24 #include <linux/unistd.h>
25 #include <linux/wait.h>
26 #include <linux/compat.h>
27
28 #include <asm/intrinsics.h>
29 #include <asm/uaccess.h>
30 #include <asm/rse.h>
31 #include <asm/sigcontext.h>
32 #include <asm/segment.h>
33
34 #include "ia32priv.h"
35
36 #include "../kernel/sigframe.h"
37
38 #define A(__x)          ((unsigned long)(__x))
39
40 #define DEBUG_SIG       0
41 #define _BLOCKABLE      (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
42
43 #define __IA32_NR_sigreturn            119
44 #define __IA32_NR_rt_sigreturn         173
45
46 struct sigframe_ia32
47 {
48        int pretcode;
49        int sig;
50        struct sigcontext_ia32 sc;
51        struct _fpstate_ia32 fpstate;
52        unsigned int extramask[_COMPAT_NSIG_WORDS-1];
53        char retcode[8];
54 };
55
56 struct rt_sigframe_ia32
57 {
58        int pretcode;
59        int sig;
60        int pinfo;
61        int puc;
62        compat_siginfo_t info;
63        struct ucontext_ia32 uc;
64        struct _fpstate_ia32 fpstate;
65        char retcode[8];
66 };
67
68 int
69 copy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from)
70 {
71         unsigned long tmp;
72         int err;
73
74         if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
75                 return -EFAULT;
76
77         err = __get_user(to->si_signo, &from->si_signo);
78         err |= __get_user(to->si_errno, &from->si_errno);
79         err |= __get_user(to->si_code, &from->si_code);
80
81         if (to->si_code < 0)
82                 err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
83         else {
84                 switch (to->si_code >> 16) {
85                       case __SI_CHLD >> 16:
86                         err |= __get_user(to->si_utime, &from->si_utime);
87                         err |= __get_user(to->si_stime, &from->si_stime);
88                         err |= __get_user(to->si_status, &from->si_status);
89                       default:
90                         err |= __get_user(to->si_pid, &from->si_pid);
91                         err |= __get_user(to->si_uid, &from->si_uid);
92                         break;
93                       case __SI_FAULT >> 16:
94                         err |= __get_user(tmp, &from->si_addr);
95                         to->si_addr = (void __user *) tmp;
96                         break;
97                       case __SI_POLL >> 16:
98                         err |= __get_user(to->si_band, &from->si_band);
99                         err |= __get_user(to->si_fd, &from->si_fd);
100                         break;
101                       case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
102                       case __SI_MESGQ >> 16:
103                         err |= __get_user(to->si_pid, &from->si_pid);
104                         err |= __get_user(to->si_uid, &from->si_uid);
105                         err |= __get_user(to->si_int, &from->si_int);
106                         break;
107                 }
108         }
109         return err;
110 }
111
112 int
113 copy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from)
114 {
115         unsigned int addr;
116         int err;
117
118         if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
119                 return -EFAULT;
120
121         /* If you change siginfo_t structure, please be sure
122            this code is fixed accordingly.
123            It should never copy any pad contained in the structure
124            to avoid security leaks, but must copy the generic
125            3 ints plus the relevant union member.
126            This routine must convert siginfo from 64bit to 32bit as well
127            at the same time.  */
128         err = __put_user(from->si_signo, &to->si_signo);
129         err |= __put_user(from->si_errno, &to->si_errno);
130         err |= __put_user((short)from->si_code, &to->si_code);
131         if (from->si_code < 0)
132                 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
133         else {
134                 switch (from->si_code >> 16) {
135                 case __SI_CHLD >> 16:
136                         err |= __put_user(from->si_utime, &to->si_utime);
137                         err |= __put_user(from->si_stime, &to->si_stime);
138                         err |= __put_user(from->si_status, &to->si_status);
139                 default:
140                         err |= __put_user(from->si_pid, &to->si_pid);
141                         err |= __put_user(from->si_uid, &to->si_uid);
142                         break;
143                 case __SI_FAULT >> 16:
144                         /* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */
145                         err |= __put_user(from->_sifields._pad[0], &to->si_addr);
146                         break;
147                 case __SI_POLL >> 16:
148                         err |= __put_user(from->si_band, &to->si_band);
149                         err |= __put_user(from->si_fd, &to->si_fd);
150                         break;
151                 case __SI_TIMER >> 16:
152                         err |= __put_user(from->si_tid, &to->si_tid);
153                         err |= __put_user(from->si_overrun, &to->si_overrun);
154                         addr = (unsigned long) from->si_ptr;
155                         err |= __put_user(addr, &to->si_ptr);
156                         break;
157                 case __SI_RT >> 16:     /* Not generated by the kernel as of now.  */
158                 case __SI_MESGQ >> 16:
159                         err |= __put_user(from->si_uid, &to->si_uid);
160                         err |= __put_user(from->si_pid, &to->si_pid);
161                         addr = (unsigned long) from->si_ptr;
162                         err |= __put_user(addr, &to->si_ptr);
163                         break;
164                 }
165         }
166         return err;
167 }
168
169
170 /*
171  *  SAVE and RESTORE of ia32 fpstate info, from ia64 current state
172  *  Used in exception handler to pass the fpstate to the user, and restore
173  *  the fpstate while returning from the exception handler.
174  *
175  *    fpstate info and their mapping to IA64 regs:
176  *    fpstate    REG(BITS)      Attribute    Comments
177  *    cw         ar.fcr(0:12)                with bits 7 and 6 not used
178  *    sw         ar.fsr(0:15)
179  *    tag        ar.fsr(16:31)               with odd numbered bits not used
180  *                                           (read returns 0, writes ignored)
181  *    ipoff      ar.fir(0:31)
182  *    cssel      ar.fir(32:47)
183  *    dataoff    ar.fdr(0:31)
184  *    datasel    ar.fdr(32:47)
185  *
186  *    _st[(0+TOS)%8]   f8
187  *    _st[(1+TOS)%8]   f9
188  *    _st[(2+TOS)%8]   f10
189  *    _st[(3+TOS)%8]   f11                   (f8..f11 from ptregs)
190  *      : :            :                     (f12..f15 from live reg)
191  *      : :            :
192  *    _st[(7+TOS)%8]   f15                   TOS=sw.top(bits11:13)
193  *
194  *    status     Same as sw     RO
195  *    magic      0                           as X86_FXSR_MAGIC in ia32
196  *    mxcsr      Bits(7:15)=ar.fcr(39:47)
197  *               Bits(0:5) =ar.fsr(32:37)    with bit 6 reserved
198  *    _xmm[0..7] f16..f31                    (live registers)
199  *                                           with _xmm[0]
200  *                                             Bit(64:127)=f17(0:63)
201  *                                             Bit(0:63)=f16(0:63)
202  *    All other fields unused...
203  */
204
205 static int
206 save_ia32_fpstate_live (struct _fpstate_ia32 __user *save)
207 {
208         struct task_struct *tsk = current;
209         struct pt_regs *ptp;
210         struct _fpreg_ia32 *fpregp;
211         char buf[32];
212         unsigned long fsr, fcr, fir, fdr;
213         unsigned long new_fsr;
214         unsigned long num128[2];
215         unsigned long mxcsr=0;
216         int fp_tos, fr8_st_map;
217
218         if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
219                 return -EFAULT;
220
221         /* Read in fsr, fcr, fir, fdr and copy onto fpstate */
222         fsr = ia64_getreg(_IA64_REG_AR_FSR);
223         fcr = ia64_getreg(_IA64_REG_AR_FCR);
224         fir = ia64_getreg(_IA64_REG_AR_FIR);
225         fdr = ia64_getreg(_IA64_REG_AR_FDR);
226
227         /*
228          * We need to clear the exception state before calling the signal handler. Clear
229          * the bits 15, bits 0-7 in fp status word. Similar to the functionality of fnclex
230          * instruction.
231          */
232         new_fsr = fsr & ~0x80ff;
233         ia64_setreg(_IA64_REG_AR_FSR, new_fsr);
234
235         __put_user(fcr & 0xffff, &save->cw);
236         __put_user(fsr & 0xffff, &save->sw);
237         __put_user((fsr>>16) & 0xffff, &save->tag);
238         __put_user(fir, &save->ipoff);
239         __put_user((fir>>32) & 0xffff, &save->cssel);
240         __put_user(fdr, &save->dataoff);
241         __put_user((fdr>>32) & 0xffff, &save->datasel);
242         __put_user(fsr & 0xffff, &save->status);
243
244         mxcsr = ((fcr>>32) & 0xff80) | ((fsr>>32) & 0x3f);
245         __put_user(mxcsr & 0xffff, &save->mxcsr);
246         __put_user( 0, &save->magic); //#define X86_FXSR_MAGIC   0x0000
247
248         /*
249          * save f8..f11  from pt_regs
250          * save f12..f15 from live register set
251          */
252         /*
253          *  Find the location where f8 has to go in fp reg stack.  This depends on
254          *  TOP(11:13) field of sw. Other f reg continue sequentially from where f8 maps
255          *  to.
256          */
257         fp_tos = (fsr>>11)&0x7;
258         fr8_st_map = (8-fp_tos)&0x7;
259         ptp = ia64_task_regs(tsk);
260         fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
261         ia64f2ia32f(fpregp, &ptp->f8);
262         copy_to_user(&save->_st[(0+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
263         ia64f2ia32f(fpregp, &ptp->f9);
264         copy_to_user(&save->_st[(1+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
265         ia64f2ia32f(fpregp, &ptp->f10);
266         copy_to_user(&save->_st[(2+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
267         ia64f2ia32f(fpregp, &ptp->f11);
268         copy_to_user(&save->_st[(3+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
269
270         ia64_stfe(fpregp, 12);
271         copy_to_user(&save->_st[(4+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
272         ia64_stfe(fpregp, 13);
273         copy_to_user(&save->_st[(5+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
274         ia64_stfe(fpregp, 14);
275         copy_to_user(&save->_st[(6+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
276         ia64_stfe(fpregp, 15);
277         copy_to_user(&save->_st[(7+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
278
279         ia64_stf8(&num128[0], 16);
280         ia64_stf8(&num128[1], 17);
281         copy_to_user(&save->_xmm[0], num128, sizeof(struct _xmmreg_ia32));
282
283         ia64_stf8(&num128[0], 18);
284         ia64_stf8(&num128[1], 19);
285         copy_to_user(&save->_xmm[1], num128, sizeof(struct _xmmreg_ia32));
286
287         ia64_stf8(&num128[0], 20);
288         ia64_stf8(&num128[1], 21);
289         copy_to_user(&save->_xmm[2], num128, sizeof(struct _xmmreg_ia32));
290
291         ia64_stf8(&num128[0], 22);
292         ia64_stf8(&num128[1], 23);
293         copy_to_user(&save->_xmm[3], num128, sizeof(struct _xmmreg_ia32));
294
295         ia64_stf8(&num128[0], 24);
296         ia64_stf8(&num128[1], 25);
297         copy_to_user(&save->_xmm[4], num128, sizeof(struct _xmmreg_ia32));
298
299         ia64_stf8(&num128[0], 26);
300         ia64_stf8(&num128[1], 27);
301         copy_to_user(&save->_xmm[5], num128, sizeof(struct _xmmreg_ia32));
302
303         ia64_stf8(&num128[0], 28);
304         ia64_stf8(&num128[1], 29);
305         copy_to_user(&save->_xmm[6], num128, sizeof(struct _xmmreg_ia32));
306
307         ia64_stf8(&num128[0], 30);
308         ia64_stf8(&num128[1], 31);
309         copy_to_user(&save->_xmm[7], num128, sizeof(struct _xmmreg_ia32));
310         return 0;
311 }
312
313 static int
314 restore_ia32_fpstate_live (struct _fpstate_ia32 __user *save)
315 {
316         struct task_struct *tsk = current;
317         struct pt_regs *ptp;
318         unsigned int lo, hi;
319         unsigned long num128[2];
320         unsigned long num64, mxcsr;
321         struct _fpreg_ia32 *fpregp;
322         char buf[32];
323         unsigned long fsr, fcr, fir, fdr;
324         int fp_tos, fr8_st_map;
325
326         if (!access_ok(VERIFY_READ, save, sizeof(*save)))
327                 return(-EFAULT);
328
329         /*
330          * Updating fsr, fcr, fir, fdr.
331          * Just a bit more complicated than save.
332          * - Need to make sure that we don't write any value other than the
333          *   specific fpstate info
334          * - Need to make sure that the untouched part of frs, fdr, fir, fcr
335          *   should remain same while writing.
336          * So, we do a read, change specific fields and write.
337          */
338         fsr = ia64_getreg(_IA64_REG_AR_FSR);
339         fcr = ia64_getreg(_IA64_REG_AR_FCR);
340         fir = ia64_getreg(_IA64_REG_AR_FIR);
341         fdr = ia64_getreg(_IA64_REG_AR_FDR);
342
343         __get_user(mxcsr, (unsigned int __user *)&save->mxcsr);
344         /* setting bits 0..5 8..12 with cw and 39..47 from mxcsr */
345         __get_user(lo, (unsigned int __user *)&save->cw);
346         num64 = mxcsr & 0xff10;
347         num64 = (num64 << 32) | (lo & 0x1f3f);
348         fcr = (fcr & (~0xff1000001f3fUL)) | num64;
349
350         /* setting bits 0..31 with sw and tag and 32..37 from mxcsr */
351         __get_user(lo, (unsigned int __user *)&save->sw);
352         /* set bits 15,7 (fsw.b, fsw.es) to reflect the current error status */
353         if ( !(lo & 0x7f) )
354                 lo &= (~0x8080);
355         __get_user(hi, (unsigned int __user *)&save->tag);
356         num64 = mxcsr & 0x3f;
357         num64 = (num64 << 16) | (hi & 0xffff);
358         num64 = (num64 << 16) | (lo & 0xffff);
359         fsr = (fsr & (~0x3fffffffffUL)) | num64;
360
361         /* setting bits 0..47 with cssel and ipoff */
362         __get_user(lo, (unsigned int __user *)&save->ipoff);
363         __get_user(hi, (unsigned int __user *)&save->cssel);
364         num64 = hi & 0xffff;
365         num64 = (num64 << 32) | lo;
366         fir = (fir & (~0xffffffffffffUL)) | num64;
367
368         /* setting bits 0..47 with datasel and dataoff */
369         __get_user(lo, (unsigned int __user *)&save->dataoff);
370         __get_user(hi, (unsigned int __user *)&save->datasel);
371         num64 = hi & 0xffff;
372         num64 = (num64 << 32) | lo;
373         fdr = (fdr & (~0xffffffffffffUL)) | num64;
374
375         ia64_setreg(_IA64_REG_AR_FSR, fsr);
376         ia64_setreg(_IA64_REG_AR_FCR, fcr);
377         ia64_setreg(_IA64_REG_AR_FIR, fir);
378         ia64_setreg(_IA64_REG_AR_FDR, fdr);
379
380         /*
381          * restore f8..f11 onto pt_regs
382          * restore f12..f15 onto live registers
383          */
384         /*
385          *  Find the location where f8 has to go in fp reg stack.  This depends on
386          *  TOP(11:13) field of sw. Other f reg continue sequentially from where f8 maps
387          *  to.
388          */
389         fp_tos = (fsr>>11)&0x7;
390         fr8_st_map = (8-fp_tos)&0x7;
391         fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
392
393         ptp = ia64_task_regs(tsk);
394         copy_from_user(fpregp, &save->_st[(0+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
395         ia32f2ia64f(&ptp->f8, fpregp);
396         copy_from_user(fpregp, &save->_st[(1+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
397         ia32f2ia64f(&ptp->f9, fpregp);
398         copy_from_user(fpregp, &save->_st[(2+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
399         ia32f2ia64f(&ptp->f10, fpregp);
400         copy_from_user(fpregp, &save->_st[(3+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
401         ia32f2ia64f(&ptp->f11, fpregp);
402
403         copy_from_user(fpregp, &save->_st[(4+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
404         ia64_ldfe(12, fpregp);
405         copy_from_user(fpregp, &save->_st[(5+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
406         ia64_ldfe(13, fpregp);
407         copy_from_user(fpregp, &save->_st[(6+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
408         ia64_ldfe(14, fpregp);
409         copy_from_user(fpregp, &save->_st[(7+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
410         ia64_ldfe(15, fpregp);
411
412         copy_from_user(num128, &save->_xmm[0], sizeof(struct _xmmreg_ia32));
413         ia64_ldf8(16, &num128[0]);
414         ia64_ldf8(17, &num128[1]);
415
416         copy_from_user(num128, &save->_xmm[1], sizeof(struct _xmmreg_ia32));
417         ia64_ldf8(18, &num128[0]);
418         ia64_ldf8(19, &num128[1]);
419
420         copy_from_user(num128, &save->_xmm[2], sizeof(struct _xmmreg_ia32));
421         ia64_ldf8(20, &num128[0]);
422         ia64_ldf8(21, &num128[1]);
423
424         copy_from_user(num128, &save->_xmm[3], sizeof(struct _xmmreg_ia32));
425         ia64_ldf8(22, &num128[0]);
426         ia64_ldf8(23, &num128[1]);
427
428         copy_from_user(num128, &save->_xmm[4], sizeof(struct _xmmreg_ia32));
429         ia64_ldf8(24, &num128[0]);
430         ia64_ldf8(25, &num128[1]);
431
432         copy_from_user(num128, &save->_xmm[5], sizeof(struct _xmmreg_ia32));
433         ia64_ldf8(26, &num128[0]);
434         ia64_ldf8(27, &num128[1]);
435
436         copy_from_user(num128, &save->_xmm[6], sizeof(struct _xmmreg_ia32));
437         ia64_ldf8(28, &num128[0]);
438         ia64_ldf8(29, &num128[1]);
439
440         copy_from_user(num128, &save->_xmm[7], sizeof(struct _xmmreg_ia32));
441         ia64_ldf8(30, &num128[0]);
442         ia64_ldf8(31, &num128[1]);
443         return 0;
444 }
445
446 static inline void
447 sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int restorer)
448 {
449         if (handler + 1 <= 2)
450                 /* SIG_DFL, SIG_IGN, or SIG_ERR: must sign-extend to 64-bits */
451                 sa->sa.sa_handler = (__sighandler_t) A((int) handler);
452         else
453                 sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler);
454 }
455
456 long
457 __ia32_rt_sigsuspend (compat_sigset_t *sset, unsigned int sigsetsize, struct sigscratch *scr)
458 {
459         extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall);
460         sigset_t oldset, set;
461
462         scr->scratch_unat = 0;  /* avoid leaking kernel bits to user level */
463         memset(&set, 0, sizeof(set));
464
465         memcpy(&set.sig, &sset->sig, sigsetsize);
466
467         sigdelsetmask(&set, ~_BLOCKABLE);
468
469         spin_lock_irq(&current->sighand->siglock);
470         {
471                 oldset = current->blocked;
472                 current->blocked = set;
473                 recalc_sigpending();
474         }
475         spin_unlock_irq(&current->sighand->siglock);
476
477         /*
478          * The return below usually returns to the signal handler.  We need to pre-set the
479          * correct error code here to ensure that the right values get saved in sigcontext
480          * by ia64_do_signal.
481          */
482         scr->pt.r8 = -EINTR;
483         while (1) {
484                 current->state = TASK_INTERRUPTIBLE;
485                 schedule();
486                 if (ia64_do_signal(&oldset, scr, 1))
487                         return -EINTR;
488         }
489 }
490
491 asmlinkage long
492 ia32_rt_sigsuspend (compat_sigset_t __user *uset, unsigned int sigsetsize, struct sigscratch *scr)
493 {
494         compat_sigset_t set;
495
496         if (sigsetsize > sizeof(compat_sigset_t))
497                 return -EINVAL;
498
499         if (copy_from_user(&set.sig, &uset->sig, sigsetsize))
500                 return -EFAULT;
501
502         return __ia32_rt_sigsuspend(&set, sigsetsize, scr);
503 }
504
505 asmlinkage long
506 ia32_sigsuspend (unsigned int mask, struct sigscratch *scr)
507 {
508         return __ia32_rt_sigsuspend((compat_sigset_t *) &mask, sizeof(mask), scr);
509 }
510
511 asmlinkage long
512 sys32_signal (int sig, unsigned int handler)
513 {
514         struct k_sigaction new_sa, old_sa;
515         int ret;
516
517         sigact_set_handler(&new_sa, handler, 0);
518         new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;
519
520         ret = do_sigaction(sig, &new_sa, &old_sa);
521
522         return ret ? ret : IA32_SA_HANDLER(&old_sa);
523 }
524
525 asmlinkage long
526 sys32_rt_sigaction (int sig, struct sigaction32 __user *act,
527                     struct sigaction32 __user *oact, unsigned int sigsetsize)
528 {
529         struct k_sigaction new_ka, old_ka;
530         unsigned int handler, restorer;
531         int ret;
532
533         /* XXX: Don't preclude handling different sized sigset_t's.  */
534         if (sigsetsize != sizeof(compat_sigset_t))
535                 return -EINVAL;
536
537         if (act) {
538                 ret = get_user(handler, &act->sa_handler);
539                 ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
540                 ret |= get_user(restorer, &act->sa_restorer);
541                 ret |= copy_from_user(&new_ka.sa.sa_mask, &act->sa_mask, sizeof(compat_sigset_t));
542                 if (ret)
543                         return -EFAULT;
544
545                 sigact_set_handler(&new_ka, handler, restorer);
546         }
547
548         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
549
550         if (!ret && oact) {
551                 ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
552                 ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
553                 ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
554                 ret |= copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(compat_sigset_t));
555         }
556         return ret;
557 }
558
559
560 asmlinkage long
561 sys32_rt_sigprocmask (int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
562                       unsigned int sigsetsize)
563 {
564         mm_segment_t old_fs = get_fs();
565         sigset_t s;
566         long ret;
567
568         if (sigsetsize > sizeof(s))
569                 return -EINVAL;
570
571         if (set) {
572                 memset(&s, 0, sizeof(s));
573                 if (copy_from_user(&s.sig, set, sigsetsize))
574                         return -EFAULT;
575         }
576         set_fs(KERNEL_DS);
577         ret = sys_rt_sigprocmask(how,
578                                  set ? (sigset_t __user *) &s : NULL,
579                                  oset ? (sigset_t __user *) &s : NULL, sizeof(s));
580         set_fs(old_fs);
581         if (ret)
582                 return ret;
583         if (oset) {
584                 if (copy_to_user(oset, &s.sig, sigsetsize))
585                         return -EFAULT;
586         }
587         return 0;
588 }
589
590 asmlinkage long
591 sys32_rt_sigqueueinfo (int pid, int sig, compat_siginfo_t __user *uinfo)
592 {
593         mm_segment_t old_fs = get_fs();
594         siginfo_t info;
595         int ret;
596
597         if (copy_siginfo_from_user32(&info, uinfo))
598                 return -EFAULT;
599         set_fs(KERNEL_DS);
600         ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
601         set_fs(old_fs);
602         return ret;
603 }
604
605 asmlinkage long
606 sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact)
607 {
608         struct k_sigaction new_ka, old_ka;
609         unsigned int handler, restorer;
610         int ret;
611
612         if (act) {
613                 compat_old_sigset_t mask;
614
615                 ret = get_user(handler, &act->sa_handler);
616                 ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
617                 ret |= get_user(restorer, &act->sa_restorer);
618                 ret |= get_user(mask, &act->sa_mask);
619                 if (ret)
620                         return ret;
621
622                 sigact_set_handler(&new_ka, handler, restorer);
623                 siginitset(&new_ka.sa.sa_mask, mask);
624         }
625
626         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
627
628         if (!ret && oact) {
629                 ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
630                 ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
631                 ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
632                 ret |= put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
633         }
634
635         return ret;
636 }
637
638 static int
639 setup_sigcontext_ia32 (struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate,
640                        struct pt_regs *regs, unsigned long mask)
641 {
642         int  err = 0;
643         unsigned long flag;
644
645         if (!access_ok(VERIFY_WRITE, sc, sizeof(*sc)))
646                 return -EFAULT;
647
648         err |= __put_user((regs->r16 >> 32) & 0xffff, (unsigned int __user *)&sc->fs);
649         err |= __put_user((regs->r16 >> 48) & 0xffff, (unsigned int __user *)&sc->gs);
650         err |= __put_user((regs->r16 >> 16) & 0xffff, (unsigned int __user *)&sc->es);
651         err |= __put_user(regs->r16 & 0xffff, (unsigned int __user *)&sc->ds);
652         err |= __put_user(regs->r15, &sc->edi);
653         err |= __put_user(regs->r14, &sc->esi);
654         err |= __put_user(regs->r13, &sc->ebp);
655         err |= __put_user(regs->r12, &sc->esp);
656         err |= __put_user(regs->r11, &sc->ebx);
657         err |= __put_user(regs->r10, &sc->edx);
658         err |= __put_user(regs->r9, &sc->ecx);
659         err |= __put_user(regs->r8, &sc->eax);
660 #if 0
661         err |= __put_user(current->tss.trap_no, &sc->trapno);
662         err |= __put_user(current->tss.error_code, &sc->err);
663 #endif
664         err |= __put_user(regs->cr_iip, &sc->eip);
665         err |= __put_user(regs->r17 & 0xffff, (unsigned int __user *)&sc->cs);
666         /*
667          *  `eflags' is in an ar register for this context
668          */
669         flag = ia64_getreg(_IA64_REG_AR_EFLAG);
670         err |= __put_user((unsigned int)flag, &sc->eflags);
671         err |= __put_user(regs->r12, &sc->esp_at_signal);
672         err |= __put_user((regs->r17 >> 16) & 0xffff, (unsigned int __user *)&sc->ss);
673
674         if ( save_ia32_fpstate_live(fpstate) < 0 )
675                 err = -EFAULT;
676         else
677                 err |= __put_user((u32)(u64)fpstate, &sc->fpstate);
678
679 #if 0
680         tmp = save_i387(fpstate);
681         if (tmp < 0)
682                 err = 1;
683         else
684                 err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
685
686         /* non-iBCS2 extensions.. */
687 #endif
688         err |= __put_user(mask, &sc->oldmask);
689 #if 0
690         err |= __put_user(current->tss.cr2, &sc->cr2);
691 #endif
692         return err;
693 }
694
695 static int
696 restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 __user *sc, int *peax)
697 {
698         unsigned int err = 0;
699
700         /* Always make any pending restarted system calls return -EINTR */
701         current_thread_info()->restart_block.fn = do_no_restart_syscall;
702
703         if (!access_ok(VERIFY_READ, sc, sizeof(*sc)))
704                 return(-EFAULT);
705
706 #define COPY(ia64x, ia32x)      err |= __get_user(regs->ia64x, &sc->ia32x)
707
708 #define copyseg_gs(tmp)         (regs->r16 |= (unsigned long) (tmp) << 48)
709 #define copyseg_fs(tmp)         (regs->r16 |= (unsigned long) (tmp) << 32)
710 #define copyseg_cs(tmp)         (regs->r17 |= tmp)
711 #define copyseg_ss(tmp)         (regs->r17 |= (unsigned long) (tmp) << 16)
712 #define copyseg_es(tmp)         (regs->r16 |= (unsigned long) (tmp) << 16)
713 #define copyseg_ds(tmp)         (regs->r16 |= tmp)
714
715 #define COPY_SEG(seg)                                   \
716         {                                               \
717                 unsigned short tmp;                     \
718                 err |= __get_user(tmp, &sc->seg);       \
719                 copyseg_##seg(tmp);                     \
720         }
721 #define COPY_SEG_STRICT(seg)                            \
722         {                                               \
723                 unsigned short tmp;                     \
724                 err |= __get_user(tmp, &sc->seg);       \
725                 copyseg_##seg(tmp|3);                   \
726         }
727
728         /* To make COPY_SEGs easier, we zero r16, r17 */
729         regs->r16 = 0;
730         regs->r17 = 0;
731
732         COPY_SEG(gs);
733         COPY_SEG(fs);
734         COPY_SEG(es);
735         COPY_SEG(ds);
736         COPY(r15, edi);
737         COPY(r14, esi);
738         COPY(r13, ebp);
739         COPY(r12, esp);
740         COPY(r11, ebx);
741         COPY(r10, edx);
742         COPY(r9, ecx);
743         COPY(cr_iip, eip);
744         COPY_SEG_STRICT(cs);
745         COPY_SEG_STRICT(ss);
746         ia32_load_segment_descriptors(current);
747         {
748                 unsigned int tmpflags;
749                 unsigned long flag;
750
751                 /*
752                  *  IA32 `eflags' is not part of `pt_regs', it's in an ar register which
753                  *  is part of the thread context.  Fortunately, we are executing in the
754                  *  IA32 process's context.
755                  */
756                 err |= __get_user(tmpflags, &sc->eflags);
757                 flag = ia64_getreg(_IA64_REG_AR_EFLAG);
758                 flag &= ~0x40DD5;
759                 flag |= (tmpflags & 0x40DD5);
760                 ia64_setreg(_IA64_REG_AR_EFLAG, flag);
761
762                 regs->r1 = -1;  /* disable syscall checks, r1 is orig_eax */
763         }
764
765         {
766                 struct _fpstate_ia32 __user *buf = NULL;
767                 u32    fpstate_ptr;
768                 err |= get_user(fpstate_ptr, &(sc->fpstate));
769                 buf = compat_ptr(fpstate_ptr);
770                 if (buf) {
771                         err |= restore_ia32_fpstate_live(buf);
772                 }
773         }
774
775 #if 0
776         {
777                 struct _fpstate * buf;
778                 err |= __get_user(buf, &sc->fpstate);
779                 if (buf) {
780                         if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
781                                 goto badframe;
782                         err |= restore_i387(buf);
783                 }
784         }
785 #endif
786
787         err |= __get_user(*peax, &sc->eax);
788         return err;
789
790 #if 0
791   badframe:
792         return 1;
793 #endif
794 }
795
796 /*
797  * Determine which stack to use..
798  */
799 static inline void __user *
800 get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
801 {
802         unsigned long esp;
803
804         /* Default to using normal stack (truncate off sign-extension of bit 31: */
805         esp = (unsigned int) regs->r12;
806
807         /* This is the X/Open sanctioned signal stack switching.  */
808         if (ka->sa.sa_flags & SA_ONSTACK) {
809                 if (!on_sig_stack(esp))
810                         esp = current->sas_ss_sp + current->sas_ss_size;
811         }
812         /* Legacy stack switching not supported */
813
814         return (void __user *)((esp - frame_size) & -8ul);
815 }
816
817 static int
818 setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs)
819 {
820         struct exec_domain *ed = current_thread_info()->exec_domain;
821         struct sigframe_ia32 __user *frame;
822         int err = 0;
823
824         frame = get_sigframe(ka, regs, sizeof(*frame));
825
826         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
827                 goto give_sigsegv;
828
829         err |= __put_user((ed && ed->signal_invmap && sig < 32
830                            ? (int)(ed->signal_invmap[sig]) : sig), &frame->sig);
831
832         err |= setup_sigcontext_ia32(&frame->sc, &frame->fpstate, regs, set->sig[0]);
833
834         if (_COMPAT_NSIG_WORDS > 1)
835                 err |= __copy_to_user(frame->extramask, (char *) &set->sig + 4,
836                                       sizeof(frame->extramask));
837
838         /* Set up to return from userspace.  If provided, use a stub
839            already in userspace.  */
840         if (ka->sa.sa_flags & SA_RESTORER) {
841                 unsigned int restorer = IA32_SA_RESTORER(ka);
842                 err |= __put_user(restorer, &frame->pretcode);
843         } else {
844                 /* Pointing to restorer in ia32 gate page */
845                 err |= __put_user(IA32_GATE_OFFSET, &frame->pretcode);
846         }
847
848         /* This is popl %eax ; movl $,%eax ; int $0x80
849          * and there for historical reasons only.
850          * See arch/i386/kernel/signal.c
851          */
852
853         err |= __put_user(0xb858, (short __user *)(frame->retcode+0));
854         err |= __put_user(__IA32_NR_sigreturn, (int __user *)(frame->retcode+2));
855         err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
856
857         if (err)
858                 goto give_sigsegv;
859
860         /* Set up registers for signal handler */
861         regs->r12 = (unsigned long) frame;
862         regs->cr_iip = IA32_SA_HANDLER(ka);
863
864         set_fs(USER_DS);
865
866 #if 0
867         regs->eflags &= ~TF_MASK;
868 #endif
869
870 #if 0
871         printk("SIG deliver (%s:%d): sig=%d sp=%p pc=%lx ra=%x\n",
872                current->comm, current->pid, sig, (void *) frame, regs->cr_iip, frame->pretcode);
873 #endif
874
875         return 1;
876
877   give_sigsegv:
878         force_sigsegv(sig, current);
879         return 0;
880 }
881
882 static int
883 setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info,
884                      sigset_t *set, struct pt_regs * regs)
885 {
886         struct exec_domain *ed = current_thread_info()->exec_domain;
887         compat_uptr_t pinfo, puc;
888         struct rt_sigframe_ia32 __user *frame;
889         int err = 0;
890
891         frame = get_sigframe(ka, regs, sizeof(*frame));
892
893         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
894                 goto give_sigsegv;
895
896         err |= __put_user((ed && ed->signal_invmap
897                            && sig < 32 ? ed->signal_invmap[sig] : sig), &frame->sig);
898
899         pinfo = (long __user) &frame->info;
900         puc = (long __user) &frame->uc;
901         err |= __put_user(pinfo, &frame->pinfo);
902         err |= __put_user(puc, &frame->puc);
903         err |= copy_siginfo_to_user32(&frame->info, info);
904
905         /* Create the ucontext.  */
906         err |= __put_user(0, &frame->uc.uc_flags);
907         err |= __put_user(0, &frame->uc.uc_link);
908         err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
909         err |= __put_user(sas_ss_flags(regs->r12), &frame->uc.uc_stack.ss_flags);
910         err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
911         err |= setup_sigcontext_ia32(&frame->uc.uc_mcontext, &frame->fpstate, regs, set->sig[0]);
912         err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
913         if (err)
914                 goto give_sigsegv;
915
916         /* Set up to return from userspace.  If provided, use a stub
917            already in userspace.  */
918         if (ka->sa.sa_flags & SA_RESTORER) {
919                 unsigned int restorer = IA32_SA_RESTORER(ka);
920                 err |= __put_user(restorer, &frame->pretcode);
921         } else {
922                 /* Pointing to rt_restorer in ia32 gate page */
923                 err |= __put_user(IA32_GATE_OFFSET + 8, &frame->pretcode);
924         }
925
926         /* This is movl $,%eax ; int $0x80
927          * and there for historical reasons only.
928          * See arch/i386/kernel/signal.c
929          */
930
931         err |= __put_user(0xb8, (char __user *)(frame->retcode+0));
932         err |= __put_user(__IA32_NR_rt_sigreturn, (int __user *)(frame->retcode+1));
933         err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
934
935         if (err)
936                 goto give_sigsegv;
937
938         /* Set up registers for signal handler */
939         regs->r12 = (unsigned long) frame;
940         regs->cr_iip = IA32_SA_HANDLER(ka);
941
942         set_fs(USER_DS);
943
944 #if 0
945         regs->eflags &= ~TF_MASK;
946 #endif
947
948 #if 0
949         printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%x\n",
950                current->comm, current->pid, (void *) frame, regs->cr_iip, frame->pretcode);
951 #endif
952
953         return 1;
954
955 give_sigsegv:
956         force_sigsegv(sig, current);
957         return 0;
958 }
959
960 int
961 ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info,
962                    sigset_t *set, struct pt_regs *regs)
963 {
964        /* Set up the stack frame */
965        if (ka->sa.sa_flags & SA_SIGINFO)
966                return setup_rt_frame_ia32(sig, ka, info, set, regs);
967        else
968                return setup_frame_ia32(sig, ka, set, regs);
969 }
970
971 asmlinkage long
972 sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5,
973                  int arg6, int arg7, struct pt_regs regs)
974 {
975         unsigned long esp = (unsigned int) regs.r12;
976         struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(esp - 8);
977         sigset_t set;
978         int eax;
979
980         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
981                 goto badframe;
982
983         if (__get_user(set.sig[0], &frame->sc.oldmask)
984             || (_COMPAT_NSIG_WORDS > 1 && __copy_from_user((char *) &set.sig + 4, &frame->extramask,
985                                                          sizeof(frame->extramask))))
986                 goto badframe;
987
988         sigdelsetmask(&set, ~_BLOCKABLE);
989         spin_lock_irq(&current->sighand->siglock);
990         current->blocked = set;
991         recalc_sigpending();
992         spin_unlock_irq(&current->sighand->siglock);
993
994         if (restore_sigcontext_ia32(&regs, &frame->sc, &eax))
995                 goto badframe;
996         return eax;
997
998   badframe:
999         force_sig(SIGSEGV, current);
1000         return 0;
1001 }
1002
1003 asmlinkage long
1004 sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4,
1005                     int arg5, int arg6, int arg7, struct pt_regs regs)
1006 {
1007         unsigned long esp = (unsigned int) regs.r12;
1008         struct rt_sigframe_ia32 __user *frame = (struct rt_sigframe_ia32 __user *)(esp - 4);
1009         sigset_t set;
1010         int eax;
1011
1012         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
1013                 goto badframe;
1014         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
1015                 goto badframe;
1016
1017         sigdelsetmask(&set, ~_BLOCKABLE);
1018         spin_lock_irq(&current->sighand->siglock);
1019         current->blocked =  set;
1020         recalc_sigpending();
1021         spin_unlock_irq(&current->sighand->siglock);
1022
1023         if (restore_sigcontext_ia32(&regs, &frame->uc.uc_mcontext, &eax))
1024                 goto badframe;
1025
1026         /* It is more difficult to avoid calling this function than to
1027            call it and ignore errors.  */
1028         do_sigaltstack((stack_t __user *) &frame->uc.uc_stack, NULL, esp);
1029
1030         return eax;
1031
1032   badframe:
1033         force_sig(SIGSEGV, current);
1034         return 0;
1035 }