MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / arch / ia64 / ia32 / ia32_signal.c
blob7f2fc27045e9af296af5cde259ed41fcae615193
1 /*
2 * IA32 Architecture-specific signal handling support.
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>
10 * Derived from i386 and Alpha versions.
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>
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>
34 #include "ia32priv.h"
36 #include "../kernel/sigframe.h"
38 #define A(__x) ((unsigned long)(__x))
40 #define DEBUG_SIG 0
41 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
43 #define __IA32_NR_sigreturn 119
44 #define __IA32_NR_rt_sigreturn 173
46 struct sigframe_ia32
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];
56 struct rt_sigframe_ia32
58 int pretcode;
59 int sig;
60 int pinfo;
61 int puc;
62 siginfo_t32 info;
63 struct ucontext_ia32 uc;
64 struct _fpstate_ia32 fpstate;
65 char retcode[8];
68 int
69 copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 __user *from)
71 unsigned long tmp;
72 int err;
74 if (!access_ok(VERIFY_READ, from, sizeof(siginfo_t32)))
75 return -EFAULT;
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);
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;
109 return err;
113 copy_siginfo_to_user32 (siginfo_t32 __user *to, siginfo_t *from)
115 unsigned int addr;
116 int err;
118 if (!access_ok(VERIFY_WRITE, to, sizeof(siginfo_t32)))
119 return -EFAULT;
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;
166 return err;
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.
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)
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)
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...
205 static int
206 save_ia32_fpstate_live (struct _fpstate_ia32 __user *save)
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;
218 if (!access_ok(VERIFY_WRITE, save, sizeof(*save)))
219 return -EFAULT;
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);
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.
232 new_fsr = fsr & ~0x80ff;
233 ia64_setreg(_IA64_REG_AR_FSR, new_fsr);
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);
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
249 * save f8..f11 from pt_regs
250 * save f12..f15 from live register set
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.
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));
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));
279 ia64_stf8(&num128[0], 16);
280 ia64_stf8(&num128[1], 17);
281 copy_to_user(&save->_xmm[0], num128, sizeof(struct _xmmreg_ia32));
283 ia64_stf8(&num128[0], 18);
284 ia64_stf8(&num128[1], 19);
285 copy_to_user(&save->_xmm[1], num128, sizeof(struct _xmmreg_ia32));
287 ia64_stf8(&num128[0], 20);
288 ia64_stf8(&num128[1], 21);
289 copy_to_user(&save->_xmm[2], num128, sizeof(struct _xmmreg_ia32));
291 ia64_stf8(&num128[0], 22);
292 ia64_stf8(&num128[1], 23);
293 copy_to_user(&save->_xmm[3], num128, sizeof(struct _xmmreg_ia32));
295 ia64_stf8(&num128[0], 24);
296 ia64_stf8(&num128[1], 25);
297 copy_to_user(&save->_xmm[4], num128, sizeof(struct _xmmreg_ia32));
299 ia64_stf8(&num128[0], 26);
300 ia64_stf8(&num128[1], 27);
301 copy_to_user(&save->_xmm[5], num128, sizeof(struct _xmmreg_ia32));
303 ia64_stf8(&num128[0], 28);
304 ia64_stf8(&num128[1], 29);
305 copy_to_user(&save->_xmm[6], num128, sizeof(struct _xmmreg_ia32));
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;
313 static int
314 restore_ia32_fpstate_live (struct _fpstate_ia32 __user *save)
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;
326 if (!access_ok(VERIFY_READ, save, sizeof(*save)))
327 return(-EFAULT);
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.
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);
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;
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;
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;
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;
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);
381 * restore f8..f11 onto pt_regs
382 * restore f12..f15 onto live registers
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.
389 fp_tos = (fsr>>11)&0x7;
390 fr8_st_map = (8-fp_tos)&0x7;
391 fpregp = (struct _fpreg_ia32 *)(((unsigned long)buf + 15) & ~15);
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);
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);
412 copy_from_user(num128, &save->_xmm[0], sizeof(struct _xmmreg_ia32));
413 ia64_ldf8(16, &num128[0]);
414 ia64_ldf8(17, &num128[1]);
416 copy_from_user(num128, &save->_xmm[1], sizeof(struct _xmmreg_ia32));
417 ia64_ldf8(18, &num128[0]);
418 ia64_ldf8(19, &num128[1]);
420 copy_from_user(num128, &save->_xmm[2], sizeof(struct _xmmreg_ia32));
421 ia64_ldf8(20, &num128[0]);
422 ia64_ldf8(21, &num128[1]);
424 copy_from_user(num128, &save->_xmm[3], sizeof(struct _xmmreg_ia32));
425 ia64_ldf8(22, &num128[0]);
426 ia64_ldf8(23, &num128[1]);
428 copy_from_user(num128, &save->_xmm[4], sizeof(struct _xmmreg_ia32));
429 ia64_ldf8(24, &num128[0]);
430 ia64_ldf8(25, &num128[1]);
432 copy_from_user(num128, &save->_xmm[5], sizeof(struct _xmmreg_ia32));
433 ia64_ldf8(26, &num128[0]);
434 ia64_ldf8(27, &num128[1]);
436 copy_from_user(num128, &save->_xmm[6], sizeof(struct _xmmreg_ia32));
437 ia64_ldf8(28, &num128[0]);
438 ia64_ldf8(29, &num128[1]);
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;
446 static inline void
447 sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int restorer)
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);
456 long
457 __ia32_rt_sigsuspend (compat_sigset_t *sset, unsigned int sigsetsize, struct sigscratch *scr)
459 extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall);
460 sigset_t oldset, set;
462 scr->scratch_unat = 0; /* avoid leaking kernel bits to user level */
463 memset(&set, 0, sizeof(&set));
465 if (memcpy(&set.sig, &sset->sig, sigsetsize))
466 return -EFAULT;
468 sigdelsetmask(&set, ~_BLOCKABLE);
470 spin_lock_irq(&current->sighand->siglock);
472 oldset = current->blocked;
473 current->blocked = set;
474 recalc_sigpending();
476 spin_unlock_irq(&current->sighand->siglock);
479 * The return below usually returns to the signal handler. We need to pre-set the
480 * correct error code here to ensure that the right values get saved in sigcontext
481 * by ia64_do_signal.
483 scr->pt.r8 = -EINTR;
484 while (1) {
485 current->state = TASK_INTERRUPTIBLE;
486 schedule();
487 if (ia64_do_signal(&oldset, scr, 1))
488 return -EINTR;
492 asmlinkage long
493 ia32_rt_sigsuspend (compat_sigset_t __user *uset, unsigned int sigsetsize, struct sigscratch *scr)
495 compat_sigset_t set;
497 if (sigsetsize > sizeof(compat_sigset_t))
498 return -EINVAL;
500 if (copy_from_user(&set.sig, &uset->sig, sigsetsize))
501 return -EFAULT;
503 return __ia32_rt_sigsuspend(&set, sigsetsize, scr);
506 asmlinkage long
507 ia32_sigsuspend (unsigned int mask, struct sigscratch *scr)
509 return __ia32_rt_sigsuspend((compat_sigset_t *) &mask, sizeof(mask), scr);
512 asmlinkage long
513 sys32_signal (int sig, unsigned int handler)
515 struct k_sigaction new_sa, old_sa;
516 int ret;
518 sigact_set_handler(&new_sa, handler, 0);
519 new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;
521 ret = do_sigaction(sig, &new_sa, &old_sa);
523 return ret ? ret : IA32_SA_HANDLER(&old_sa);
526 asmlinkage long
527 sys32_rt_sigaction (int sig, struct sigaction32 __user *act,
528 struct sigaction32 __user *oact, unsigned int sigsetsize)
530 struct k_sigaction new_ka, old_ka;
531 unsigned int handler, restorer;
532 int ret;
534 /* XXX: Don't preclude handling different sized sigset_t's. */
535 if (sigsetsize != sizeof(compat_sigset_t))
536 return -EINVAL;
538 if (act) {
539 ret = get_user(handler, &act->sa_handler);
540 ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
541 ret |= get_user(restorer, &act->sa_restorer);
542 ret |= copy_from_user(&new_ka.sa.sa_mask, &act->sa_mask, sizeof(compat_sigset_t));
543 if (ret)
544 return -EFAULT;
546 sigact_set_handler(&new_ka, handler, restorer);
549 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
551 if (!ret && oact) {
552 ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
553 ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
554 ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
555 ret |= copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(compat_sigset_t));
557 return ret;
561 asmlinkage long
562 sys32_rt_sigprocmask (int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
563 unsigned int sigsetsize)
565 mm_segment_t old_fs = get_fs();
566 sigset_t s;
567 long ret;
569 if (sigsetsize > sizeof(s))
570 return -EINVAL;
572 if (set) {
573 memset(&s, 0, sizeof(s));
574 if (copy_from_user(&s.sig, set, sigsetsize))
575 return -EFAULT;
577 set_fs(KERNEL_DS);
578 ret = sys_rt_sigprocmask(how,
579 set ? (sigset_t __user *) &s : NULL,
580 oset ? (sigset_t __user *) &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;
588 return 0;
591 asmlinkage long
592 sys32_rt_sigtimedwait (compat_sigset_t __user *uthese, siginfo_t32 __user *uinfo,
593 struct compat_timespec __user *uts, unsigned int sigsetsize)
595 mm_segment_t old_fs = get_fs();
596 struct timespec t;
597 siginfo_t info;
598 sigset_t s;
599 int ret;
601 if (copy_from_user(&s.sig, uthese, sizeof(compat_sigset_t)))
602 return -EFAULT;
603 if (uts && get_compat_timespec(&t, uts))
604 return -EFAULT;
605 set_fs(KERNEL_DS);
606 ret = sys_rt_sigtimedwait((sigset_t __user *) &s,
607 uinfo ? (siginfo_t __user *) &info : NULL,
608 uts ? (struct timespec __user *) &t : NULL,
609 sigsetsize);
610 set_fs(old_fs);
611 if (ret >= 0 && uinfo) {
612 if (copy_siginfo_to_user32(uinfo, &info))
613 return -EFAULT;
615 return ret;
618 asmlinkage long
619 sys32_rt_sigqueueinfo (int pid, int sig, siginfo_t32 __user *uinfo)
621 mm_segment_t old_fs = get_fs();
622 siginfo_t info;
623 int ret;
625 if (copy_siginfo_from_user32(&info, uinfo))
626 return -EFAULT;
627 set_fs(KERNEL_DS);
628 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
629 set_fs(old_fs);
630 return ret;
633 asmlinkage long
634 sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact)
636 struct k_sigaction new_ka, old_ka;
637 unsigned int handler, restorer;
638 int ret;
640 if (act) {
641 compat_old_sigset_t mask;
643 ret = get_user(handler, &act->sa_handler);
644 ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
645 ret |= get_user(restorer, &act->sa_restorer);
646 ret |= get_user(mask, &act->sa_mask);
647 if (ret)
648 return ret;
650 sigact_set_handler(&new_ka, handler, restorer);
651 siginitset(&new_ka.sa.sa_mask, mask);
654 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
656 if (!ret && oact) {
657 ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
658 ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
659 ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
660 ret |= put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
663 return ret;
666 static int
667 setup_sigcontext_ia32 (struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate,
668 struct pt_regs *regs, unsigned long mask)
670 int err = 0;
671 unsigned long flag;
673 if (!access_ok(VERIFY_WRITE, sc, sizeof(*sc)))
674 return -EFAULT;
676 err |= __put_user((regs->r16 >> 32) & 0xffff, (unsigned int __user *)&sc->fs);
677 err |= __put_user((regs->r16 >> 48) & 0xffff, (unsigned int __user *)&sc->gs);
678 err |= __put_user((regs->r16 >> 16) & 0xffff, (unsigned int __user *)&sc->es);
679 err |= __put_user(regs->r16 & 0xffff, (unsigned int __user *)&sc->ds);
680 err |= __put_user(regs->r15, &sc->edi);
681 err |= __put_user(regs->r14, &sc->esi);
682 err |= __put_user(regs->r13, &sc->ebp);
683 err |= __put_user(regs->r12, &sc->esp);
684 err |= __put_user(regs->r11, &sc->ebx);
685 err |= __put_user(regs->r10, &sc->edx);
686 err |= __put_user(regs->r9, &sc->ecx);
687 err |= __put_user(regs->r8, &sc->eax);
688 #if 0
689 err |= __put_user(current->tss.trap_no, &sc->trapno);
690 err |= __put_user(current->tss.error_code, &sc->err);
691 #endif
692 err |= __put_user(regs->cr_iip, &sc->eip);
693 err |= __put_user(regs->r17 & 0xffff, (unsigned int __user *)&sc->cs);
695 * `eflags' is in an ar register for this context
697 flag = ia64_getreg(_IA64_REG_AR_EFLAG);
698 err |= __put_user((unsigned int)flag, &sc->eflags);
699 err |= __put_user(regs->r12, &sc->esp_at_signal);
700 err |= __put_user((regs->r17 >> 16) & 0xffff, (unsigned int __user *)&sc->ss);
702 if ( save_ia32_fpstate_live(fpstate) < 0 )
703 err = -EFAULT;
704 else
705 err |= __put_user((u32)(u64)fpstate, &sc->fpstate);
707 #if 0
708 tmp = save_i387(fpstate);
709 if (tmp < 0)
710 err = 1;
711 else
712 err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
714 /* non-iBCS2 extensions.. */
715 #endif
716 err |= __put_user(mask, &sc->oldmask);
717 #if 0
718 err |= __put_user(current->tss.cr2, &sc->cr2);
719 #endif
720 return err;
723 static int
724 restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 __user *sc, int *peax)
726 unsigned int err = 0;
728 /* Always make any pending restarted system calls return -EINTR */
729 current_thread_info()->restart_block.fn = do_no_restart_syscall;
731 if (!access_ok(VERIFY_READ, sc, sizeof(*sc)))
732 return(-EFAULT);
734 #define COPY(ia64x, ia32x) err |= __get_user(regs->ia64x, &sc->ia32x)
736 #define copyseg_gs(tmp) (regs->r16 |= (unsigned long) (tmp) << 48)
737 #define copyseg_fs(tmp) (regs->r16 |= (unsigned long) (tmp) << 32)
738 #define copyseg_cs(tmp) (regs->r17 |= tmp)
739 #define copyseg_ss(tmp) (regs->r17 |= (unsigned long) (tmp) << 16)
740 #define copyseg_es(tmp) (regs->r16 |= (unsigned long) (tmp) << 16)
741 #define copyseg_ds(tmp) (regs->r16 |= tmp)
743 #define COPY_SEG(seg) \
745 unsigned short tmp; \
746 err |= __get_user(tmp, &sc->seg); \
747 copyseg_##seg(tmp); \
749 #define COPY_SEG_STRICT(seg) \
751 unsigned short tmp; \
752 err |= __get_user(tmp, &sc->seg); \
753 copyseg_##seg(tmp|3); \
756 /* To make COPY_SEGs easier, we zero r16, r17 */
757 regs->r16 = 0;
758 regs->r17 = 0;
760 COPY_SEG(gs);
761 COPY_SEG(fs);
762 COPY_SEG(es);
763 COPY_SEG(ds);
764 COPY(r15, edi);
765 COPY(r14, esi);
766 COPY(r13, ebp);
767 COPY(r12, esp);
768 COPY(r11, ebx);
769 COPY(r10, edx);
770 COPY(r9, ecx);
771 COPY(cr_iip, eip);
772 COPY_SEG_STRICT(cs);
773 COPY_SEG_STRICT(ss);
774 ia32_load_segment_descriptors(current);
776 unsigned int tmpflags;
777 unsigned long flag;
780 * IA32 `eflags' is not part of `pt_regs', it's in an ar register which
781 * is part of the thread context. Fortunately, we are executing in the
782 * IA32 process's context.
784 err |= __get_user(tmpflags, &sc->eflags);
785 flag = ia64_getreg(_IA64_REG_AR_EFLAG);
786 flag &= ~0x40DD5;
787 flag |= (tmpflags & 0x40DD5);
788 ia64_setreg(_IA64_REG_AR_EFLAG, flag);
790 regs->r1 = -1; /* disable syscall checks, r1 is orig_eax */
794 struct _fpstate_ia32 __user *buf = NULL;
795 u32 fpstate_ptr;
796 err |= get_user(fpstate_ptr, &(sc->fpstate));
797 buf = compat_ptr(fpstate_ptr);
798 if (buf) {
799 err |= restore_ia32_fpstate_live(buf);
803 #if 0
805 struct _fpstate * buf;
806 err |= __get_user(buf, &sc->fpstate);
807 if (buf) {
808 if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
809 goto badframe;
810 err |= restore_i387(buf);
813 #endif
815 err |= __get_user(*peax, &sc->eax);
816 return err;
818 #if 0
819 badframe:
820 return 1;
821 #endif
825 * Determine which stack to use..
827 static inline void __user *
828 get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
830 unsigned long esp;
832 /* Default to using normal stack (truncate off sign-extension of bit 31: */
833 esp = (unsigned int) regs->r12;
835 /* This is the X/Open sanctioned signal stack switching. */
836 if (ka->sa.sa_flags & SA_ONSTACK) {
837 if (!on_sig_stack(esp))
838 esp = current->sas_ss_sp + current->sas_ss_size;
840 /* Legacy stack switching not supported */
842 return (void __user *)((esp - frame_size) & -8ul);
845 static int
846 setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs)
848 struct exec_domain *ed = current_thread_info()->exec_domain;
849 struct sigframe_ia32 __user *frame;
850 int err = 0;
852 frame = get_sigframe(ka, regs, sizeof(*frame));
854 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
855 goto give_sigsegv;
857 err |= __put_user((ed && ed->signal_invmap && sig < 32
858 ? (int)(ed->signal_invmap[sig]) : sig), &frame->sig);
860 err |= setup_sigcontext_ia32(&frame->sc, &frame->fpstate, regs, set->sig[0]);
862 if (_COMPAT_NSIG_WORDS > 1)
863 err |= __copy_to_user(frame->extramask, (char *) &set->sig + 4,
864 sizeof(frame->extramask));
866 /* Set up to return from userspace. If provided, use a stub
867 already in userspace. */
868 if (ka->sa.sa_flags & SA_RESTORER) {
869 unsigned int restorer = IA32_SA_RESTORER(ka);
870 err |= __put_user(restorer, &frame->pretcode);
871 } else {
872 /* Pointing to restorer in ia32 gate page */
873 err |= __put_user(IA32_GATE_OFFSET, &frame->pretcode);
876 /* This is popl %eax ; movl $,%eax ; int $0x80
877 * and there for historical reasons only.
878 * See arch/i386/kernel/signal.c
881 err |= __put_user(0xb858, (short __user *)(frame->retcode+0));
882 err |= __put_user(__IA32_NR_sigreturn, (int __user *)(frame->retcode+2));
883 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
885 if (err)
886 goto give_sigsegv;
888 /* Set up registers for signal handler */
889 regs->r12 = (unsigned long) frame;
890 regs->cr_iip = IA32_SA_HANDLER(ka);
892 set_fs(USER_DS);
894 #if 0
895 regs->eflags &= ~TF_MASK;
896 #endif
898 #if 0
899 printk("SIG deliver (%s:%d): sig=%d sp=%p pc=%lx ra=%x\n",
900 current->comm, current->pid, sig, (void *) frame, regs->cr_iip, frame->pretcode);
901 #endif
903 return 1;
905 give_sigsegv:
906 force_sigsegv(sig, current);
907 return 0;
910 static int
911 setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info,
912 sigset_t *set, struct pt_regs * regs)
914 struct exec_domain *ed = current_thread_info()->exec_domain;
915 compat_uptr_t pinfo, puc;
916 struct rt_sigframe_ia32 __user *frame;
917 int err = 0;
919 frame = get_sigframe(ka, regs, sizeof(*frame));
921 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
922 goto give_sigsegv;
924 err |= __put_user((ed && ed->signal_invmap
925 && sig < 32 ? ed->signal_invmap[sig] : sig), &frame->sig);
927 pinfo = (long __user) &frame->info;
928 puc = (long __user) &frame->uc;
929 err |= __put_user(pinfo, &frame->pinfo);
930 err |= __put_user(puc, &frame->puc);
931 err |= copy_siginfo_to_user32(&frame->info, info);
933 /* Create the ucontext. */
934 err |= __put_user(0, &frame->uc.uc_flags);
935 err |= __put_user(0, &frame->uc.uc_link);
936 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
937 err |= __put_user(sas_ss_flags(regs->r12), &frame->uc.uc_stack.ss_flags);
938 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
939 err |= setup_sigcontext_ia32(&frame->uc.uc_mcontext, &frame->fpstate, regs, set->sig[0]);
940 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
941 if (err)
942 goto give_sigsegv;
944 /* Set up to return from userspace. If provided, use a stub
945 already in userspace. */
946 if (ka->sa.sa_flags & SA_RESTORER) {
947 unsigned int restorer = IA32_SA_RESTORER(ka);
948 err |= __put_user(restorer, &frame->pretcode);
949 } else {
950 /* Pointing to rt_restorer in ia32 gate page */
951 err |= __put_user(IA32_GATE_OFFSET + 8, &frame->pretcode);
954 /* This is movl $,%eax ; int $0x80
955 * and there for historical reasons only.
956 * See arch/i386/kernel/signal.c
959 err |= __put_user(0xb8, (char __user *)(frame->retcode+0));
960 err |= __put_user(__IA32_NR_rt_sigreturn, (int __user *)(frame->retcode+1));
961 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
963 if (err)
964 goto give_sigsegv;
966 /* Set up registers for signal handler */
967 regs->r12 = (unsigned long) frame;
968 regs->cr_iip = IA32_SA_HANDLER(ka);
970 set_fs(USER_DS);
972 #if 0
973 regs->eflags &= ~TF_MASK;
974 #endif
976 #if 0
977 printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%x\n",
978 current->comm, current->pid, (void *) frame, regs->cr_iip, frame->pretcode);
979 #endif
981 return 1;
983 give_sigsegv:
984 force_sigsegv(sig, current);
985 return 0;
989 ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info,
990 sigset_t *set, struct pt_regs *regs)
992 /* Set up the stack frame */
993 if (ka->sa.sa_flags & SA_SIGINFO)
994 return setup_rt_frame_ia32(sig, ka, info, set, regs);
995 else
996 return setup_frame_ia32(sig, ka, set, regs);
999 asmlinkage long
1000 sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7,
1001 unsigned long stack)
1003 struct pt_regs *regs = (struct pt_regs *) &stack;
1004 unsigned long esp = (unsigned int) regs->r12;
1005 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(esp - 8);
1006 sigset_t set;
1007 int eax;
1009 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
1010 goto badframe;
1012 if (__get_user(set.sig[0], &frame->sc.oldmask)
1013 || (_COMPAT_NSIG_WORDS > 1 && __copy_from_user((char *) &set.sig + 4, &frame->extramask,
1014 sizeof(frame->extramask))))
1015 goto badframe;
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);
1023 if (restore_sigcontext_ia32(regs, &frame->sc, &eax))
1024 goto badframe;
1025 return eax;
1027 badframe:
1028 force_sig(SIGSEGV, current);
1029 return 0;
1032 asmlinkage long
1033 sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7,
1034 unsigned long stack)
1036 struct pt_regs *regs = (struct pt_regs *) &stack;
1037 unsigned long esp = (unsigned int) regs->r12;
1038 struct rt_sigframe_ia32 __user *frame = (struct rt_sigframe_ia32 __user *)(esp - 4);
1039 sigset_t set;
1040 int eax;
1042 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
1043 goto badframe;
1044 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
1045 goto badframe;
1047 sigdelsetmask(&set, ~_BLOCKABLE);
1048 spin_lock_irq(&current->sighand->siglock);
1049 current->blocked = set;
1050 recalc_sigpending();
1051 spin_unlock_irq(&current->sighand->siglock);
1053 if (restore_sigcontext_ia32(regs, &frame->uc.uc_mcontext, &eax))
1054 goto badframe;
1056 /* It is more difficult to avoid calling this function than to
1057 call it and ignore errors. */
1058 do_sigaltstack((stack_t __user *) &frame->uc.uc_stack, NULL, esp);
1060 return eax;
1062 badframe:
1063 force_sig(SIGSEGV, current);
1064 return 0;