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