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