blob: 7b38b73e7827f970aaf037eb5ac20d3530317629 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032
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
45struct 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
55struct 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
67int
68copy_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
111int
112copy_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
204static int
205save_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;
Al Viro64505782006-01-12 01:06:06 -0800258 ptp = task_pt_regs(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700259 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
312static int
313restore_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
Al Viro64505782006-01-12 01:06:06 -0800392 ptp = task_pt_regs(tsk);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700393 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
445static inline void
446sigact_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
455long
456__ia32_rt_sigsuspend (compat_sigset_t *sset, unsigned int sigsetsize, struct sigscratch *scr)
457{
458 extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall);
459 sigset_t oldset, set;
460
461 scr->scratch_unat = 0; /* avoid leaking kernel bits to user level */
Arun Sharma71306672005-04-22 13:06:47 -0700462 memset(&set, 0, sizeof(set));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700463
Arun Sharma71306672005-04-22 13:06:47 -0700464 memcpy(&set.sig, &sset->sig, sigsetsize);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700465
466 sigdelsetmask(&set, ~_BLOCKABLE);
467
468 spin_lock_irq(&current->sighand->siglock);
469 {
470 oldset = current->blocked;
471 current->blocked = set;
472 recalc_sigpending();
473 }
474 spin_unlock_irq(&current->sighand->siglock);
475
476 /*
477 * The return below usually returns to the signal handler. We need to pre-set the
478 * correct error code here to ensure that the right values get saved in sigcontext
479 * by ia64_do_signal.
480 */
481 scr->pt.r8 = -EINTR;
482 while (1) {
483 current->state = TASK_INTERRUPTIBLE;
484 schedule();
485 if (ia64_do_signal(&oldset, scr, 1))
486 return -EINTR;
487 }
488}
489
490asmlinkage long
491ia32_rt_sigsuspend (compat_sigset_t __user *uset, unsigned int sigsetsize, struct sigscratch *scr)
492{
493 compat_sigset_t set;
494
495 if (sigsetsize > sizeof(compat_sigset_t))
496 return -EINVAL;
497
498 if (copy_from_user(&set.sig, &uset->sig, sigsetsize))
499 return -EFAULT;
500
501 return __ia32_rt_sigsuspend(&set, sigsetsize, scr);
502}
503
504asmlinkage long
505ia32_sigsuspend (unsigned int mask, struct sigscratch *scr)
506{
507 return __ia32_rt_sigsuspend((compat_sigset_t *) &mask, sizeof(mask), scr);
508}
509
510asmlinkage long
511sys32_signal (int sig, unsigned int handler)
512{
513 struct k_sigaction new_sa, old_sa;
514 int ret;
515
516 sigact_set_handler(&new_sa, handler, 0);
517 new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;
Tony Luck1ff0be12006-02-09 14:41:41 -0800518 sigemptyset(&new_sa.sa.sa_mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700519
520 ret = do_sigaction(sig, &new_sa, &old_sa);
521
522 return ret ? ret : IA32_SA_HANDLER(&old_sa);
523}
524
525asmlinkage long
526sys32_rt_sigaction (int sig, struct sigaction32 __user *act,
527 struct sigaction32 __user *oact, unsigned int sigsetsize)
528{
529 struct k_sigaction new_ka, old_ka;
530 unsigned int handler, restorer;
531 int ret;
532
533 /* XXX: Don't preclude handling different sized sigset_t's. */
534 if (sigsetsize != sizeof(compat_sigset_t))
535 return -EINVAL;
536
537 if (act) {
538 ret = get_user(handler, &act->sa_handler);
539 ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
540 ret |= get_user(restorer, &act->sa_restorer);
541 ret |= copy_from_user(&new_ka.sa.sa_mask, &act->sa_mask, sizeof(compat_sigset_t));
542 if (ret)
543 return -EFAULT;
544
545 sigact_set_handler(&new_ka, handler, restorer);
546 }
547
548 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
549
550 if (!ret && oact) {
551 ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
552 ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
553 ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
554 ret |= copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(compat_sigset_t));
555 }
556 return ret;
557}
558
559
560asmlinkage long
561sys32_rt_sigprocmask (int how, compat_sigset_t __user *set, compat_sigset_t __user *oset,
562 unsigned int sigsetsize)
563{
564 mm_segment_t old_fs = get_fs();
565 sigset_t s;
566 long ret;
567
568 if (sigsetsize > sizeof(s))
569 return -EINVAL;
570
571 if (set) {
572 memset(&s, 0, sizeof(s));
573 if (copy_from_user(&s.sig, set, sigsetsize))
574 return -EFAULT;
575 }
576 set_fs(KERNEL_DS);
577 ret = sys_rt_sigprocmask(how,
578 set ? (sigset_t __user *) &s : NULL,
579 oset ? (sigset_t __user *) &s : NULL, sizeof(s));
580 set_fs(old_fs);
581 if (ret)
582 return ret;
583 if (oset) {
584 if (copy_to_user(oset, &s.sig, sigsetsize))
585 return -EFAULT;
586 }
587 return 0;
588}
589
590asmlinkage long
591sys32_rt_sigqueueinfo (int pid, int sig, compat_siginfo_t __user *uinfo)
592{
593 mm_segment_t old_fs = get_fs();
594 siginfo_t info;
595 int ret;
596
597 if (copy_siginfo_from_user32(&info, uinfo))
598 return -EFAULT;
599 set_fs(KERNEL_DS);
600 ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);
601 set_fs(old_fs);
602 return ret;
603}
604
605asmlinkage long
606sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigaction32 __user *oact)
607{
608 struct k_sigaction new_ka, old_ka;
609 unsigned int handler, restorer;
610 int ret;
611
612 if (act) {
613 compat_old_sigset_t mask;
614
615 ret = get_user(handler, &act->sa_handler);
616 ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
617 ret |= get_user(restorer, &act->sa_restorer);
618 ret |= get_user(mask, &act->sa_mask);
619 if (ret)
620 return ret;
621
622 sigact_set_handler(&new_ka, handler, restorer);
623 siginitset(&new_ka.sa.sa_mask, mask);
624 }
625
626 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
627
628 if (!ret && oact) {
629 ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
630 ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
631 ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
632 ret |= put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
633 }
634
635 return ret;
636}
637
638static int
639setup_sigcontext_ia32 (struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate,
640 struct pt_regs *regs, unsigned long mask)
641{
642 int err = 0;
643 unsigned long flag;
644
645 if (!access_ok(VERIFY_WRITE, sc, sizeof(*sc)))
646 return -EFAULT;
647
648 err |= __put_user((regs->r16 >> 32) & 0xffff, (unsigned int __user *)&sc->fs);
649 err |= __put_user((regs->r16 >> 48) & 0xffff, (unsigned int __user *)&sc->gs);
650 err |= __put_user((regs->r16 >> 16) & 0xffff, (unsigned int __user *)&sc->es);
651 err |= __put_user(regs->r16 & 0xffff, (unsigned int __user *)&sc->ds);
652 err |= __put_user(regs->r15, &sc->edi);
653 err |= __put_user(regs->r14, &sc->esi);
654 err |= __put_user(regs->r13, &sc->ebp);
655 err |= __put_user(regs->r12, &sc->esp);
656 err |= __put_user(regs->r11, &sc->ebx);
657 err |= __put_user(regs->r10, &sc->edx);
658 err |= __put_user(regs->r9, &sc->ecx);
659 err |= __put_user(regs->r8, &sc->eax);
660#if 0
661 err |= __put_user(current->tss.trap_no, &sc->trapno);
662 err |= __put_user(current->tss.error_code, &sc->err);
663#endif
664 err |= __put_user(regs->cr_iip, &sc->eip);
665 err |= __put_user(regs->r17 & 0xffff, (unsigned int __user *)&sc->cs);
666 /*
667 * `eflags' is in an ar register for this context
668 */
669 flag = ia64_getreg(_IA64_REG_AR_EFLAG);
670 err |= __put_user((unsigned int)flag, &sc->eflags);
671 err |= __put_user(regs->r12, &sc->esp_at_signal);
672 err |= __put_user((regs->r17 >> 16) & 0xffff, (unsigned int __user *)&sc->ss);
673
674 if ( save_ia32_fpstate_live(fpstate) < 0 )
675 err = -EFAULT;
676 else
677 err |= __put_user((u32)(u64)fpstate, &sc->fpstate);
678
679#if 0
680 tmp = save_i387(fpstate);
681 if (tmp < 0)
682 err = 1;
683 else
684 err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
685
686 /* non-iBCS2 extensions.. */
687#endif
688 err |= __put_user(mask, &sc->oldmask);
689#if 0
690 err |= __put_user(current->tss.cr2, &sc->cr2);
691#endif
692 return err;
693}
694
695static int
696restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 __user *sc, int *peax)
697{
698 unsigned int err = 0;
699
700 /* Always make any pending restarted system calls return -EINTR */
701 current_thread_info()->restart_block.fn = do_no_restart_syscall;
702
703 if (!access_ok(VERIFY_READ, sc, sizeof(*sc)))
704 return(-EFAULT);
705
706#define COPY(ia64x, ia32x) err |= __get_user(regs->ia64x, &sc->ia32x)
707
708#define copyseg_gs(tmp) (regs->r16 |= (unsigned long) (tmp) << 48)
709#define copyseg_fs(tmp) (regs->r16 |= (unsigned long) (tmp) << 32)
710#define copyseg_cs(tmp) (regs->r17 |= tmp)
711#define copyseg_ss(tmp) (regs->r17 |= (unsigned long) (tmp) << 16)
712#define copyseg_es(tmp) (regs->r16 |= (unsigned long) (tmp) << 16)
713#define copyseg_ds(tmp) (regs->r16 |= tmp)
714
715#define COPY_SEG(seg) \
716 { \
717 unsigned short tmp; \
718 err |= __get_user(tmp, &sc->seg); \
719 copyseg_##seg(tmp); \
720 }
721#define COPY_SEG_STRICT(seg) \
722 { \
723 unsigned short tmp; \
724 err |= __get_user(tmp, &sc->seg); \
725 copyseg_##seg(tmp|3); \
726 }
727
728 /* To make COPY_SEGs easier, we zero r16, r17 */
729 regs->r16 = 0;
730 regs->r17 = 0;
731
732 COPY_SEG(gs);
733 COPY_SEG(fs);
734 COPY_SEG(es);
735 COPY_SEG(ds);
736 COPY(r15, edi);
737 COPY(r14, esi);
738 COPY(r13, ebp);
739 COPY(r12, esp);
740 COPY(r11, ebx);
741 COPY(r10, edx);
742 COPY(r9, ecx);
743 COPY(cr_iip, eip);
744 COPY_SEG_STRICT(cs);
745 COPY_SEG_STRICT(ss);
746 ia32_load_segment_descriptors(current);
747 {
748 unsigned int tmpflags;
749 unsigned long flag;
750
751 /*
752 * IA32 `eflags' is not part of `pt_regs', it's in an ar register which
753 * is part of the thread context. Fortunately, we are executing in the
754 * IA32 process's context.
755 */
756 err |= __get_user(tmpflags, &sc->eflags);
757 flag = ia64_getreg(_IA64_REG_AR_EFLAG);
758 flag &= ~0x40DD5;
759 flag |= (tmpflags & 0x40DD5);
760 ia64_setreg(_IA64_REG_AR_EFLAG, flag);
761
762 regs->r1 = -1; /* disable syscall checks, r1 is orig_eax */
763 }
764
765 {
766 struct _fpstate_ia32 __user *buf = NULL;
767 u32 fpstate_ptr;
768 err |= get_user(fpstate_ptr, &(sc->fpstate));
769 buf = compat_ptr(fpstate_ptr);
770 if (buf) {
771 err |= restore_ia32_fpstate_live(buf);
772 }
773 }
774
775#if 0
776 {
777 struct _fpstate * buf;
778 err |= __get_user(buf, &sc->fpstate);
779 if (buf) {
780 if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
781 goto badframe;
782 err |= restore_i387(buf);
783 }
784 }
785#endif
786
787 err |= __get_user(*peax, &sc->eax);
788 return err;
789
790#if 0
791 badframe:
792 return 1;
793#endif
794}
795
796/*
797 * Determine which stack to use..
798 */
799static inline void __user *
800get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
801{
802 unsigned long esp;
803
804 /* Default to using normal stack (truncate off sign-extension of bit 31: */
805 esp = (unsigned int) regs->r12;
806
807 /* This is the X/Open sanctioned signal stack switching. */
808 if (ka->sa.sa_flags & SA_ONSTACK) {
809 if (!on_sig_stack(esp))
810 esp = current->sas_ss_sp + current->sas_ss_size;
811 }
812 /* Legacy stack switching not supported */
813
Markus F.X.J. Oberhumer66761522007-04-23 12:00:05 +0200814 esp -= frame_size;
815 /* Align the stack pointer according to the i386 ABI,
816 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
817 esp = ((esp + 4) & -16ul) - 4;
818 return (void __user *) esp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819}
820
821static int
822setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs)
823{
824 struct exec_domain *ed = current_thread_info()->exec_domain;
825 struct sigframe_ia32 __user *frame;
826 int err = 0;
827
828 frame = get_sigframe(ka, regs, sizeof(*frame));
829
830 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
831 goto give_sigsegv;
832
833 err |= __put_user((ed && ed->signal_invmap && sig < 32
834 ? (int)(ed->signal_invmap[sig]) : sig), &frame->sig);
835
836 err |= setup_sigcontext_ia32(&frame->sc, &frame->fpstate, regs, set->sig[0]);
837
838 if (_COMPAT_NSIG_WORDS > 1)
839 err |= __copy_to_user(frame->extramask, (char *) &set->sig + 4,
840 sizeof(frame->extramask));
841
842 /* Set up to return from userspace. If provided, use a stub
843 already in userspace. */
844 if (ka->sa.sa_flags & SA_RESTORER) {
845 unsigned int restorer = IA32_SA_RESTORER(ka);
846 err |= __put_user(restorer, &frame->pretcode);
847 } else {
848 /* Pointing to restorer in ia32 gate page */
849 err |= __put_user(IA32_GATE_OFFSET, &frame->pretcode);
850 }
851
852 /* This is popl %eax ; movl $,%eax ; int $0x80
853 * and there for historical reasons only.
854 * See arch/i386/kernel/signal.c
855 */
856
857 err |= __put_user(0xb858, (short __user *)(frame->retcode+0));
858 err |= __put_user(__IA32_NR_sigreturn, (int __user *)(frame->retcode+2));
859 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
860
861 if (err)
862 goto give_sigsegv;
863
864 /* Set up registers for signal handler */
865 regs->r12 = (unsigned long) frame;
866 regs->cr_iip = IA32_SA_HANDLER(ka);
867
868 set_fs(USER_DS);
869
870#if 0
871 regs->eflags &= ~TF_MASK;
872#endif
873
874#if 0
875 printk("SIG deliver (%s:%d): sig=%d sp=%p pc=%lx ra=%x\n",
876 current->comm, current->pid, sig, (void *) frame, regs->cr_iip, frame->pretcode);
877#endif
878
879 return 1;
880
881 give_sigsegv:
882 force_sigsegv(sig, current);
883 return 0;
884}
885
886static int
887setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info,
888 sigset_t *set, struct pt_regs * regs)
889{
890 struct exec_domain *ed = current_thread_info()->exec_domain;
891 compat_uptr_t pinfo, puc;
892 struct rt_sigframe_ia32 __user *frame;
893 int err = 0;
894
895 frame = get_sigframe(ka, regs, sizeof(*frame));
896
897 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
898 goto give_sigsegv;
899
900 err |= __put_user((ed && ed->signal_invmap
901 && sig < 32 ? ed->signal_invmap[sig] : sig), &frame->sig);
902
903 pinfo = (long __user) &frame->info;
904 puc = (long __user) &frame->uc;
905 err |= __put_user(pinfo, &frame->pinfo);
906 err |= __put_user(puc, &frame->puc);
907 err |= copy_siginfo_to_user32(&frame->info, info);
908
909 /* Create the ucontext. */
910 err |= __put_user(0, &frame->uc.uc_flags);
911 err |= __put_user(0, &frame->uc.uc_link);
912 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
913 err |= __put_user(sas_ss_flags(regs->r12), &frame->uc.uc_stack.ss_flags);
914 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
915 err |= setup_sigcontext_ia32(&frame->uc.uc_mcontext, &frame->fpstate, regs, set->sig[0]);
916 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
917 if (err)
918 goto give_sigsegv;
919
920 /* Set up to return from userspace. If provided, use a stub
921 already in userspace. */
922 if (ka->sa.sa_flags & SA_RESTORER) {
923 unsigned int restorer = IA32_SA_RESTORER(ka);
924 err |= __put_user(restorer, &frame->pretcode);
925 } else {
926 /* Pointing to rt_restorer in ia32 gate page */
927 err |= __put_user(IA32_GATE_OFFSET + 8, &frame->pretcode);
928 }
929
930 /* This is movl $,%eax ; int $0x80
931 * and there for historical reasons only.
932 * See arch/i386/kernel/signal.c
933 */
934
935 err |= __put_user(0xb8, (char __user *)(frame->retcode+0));
936 err |= __put_user(__IA32_NR_rt_sigreturn, (int __user *)(frame->retcode+1));
937 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
938
939 if (err)
940 goto give_sigsegv;
941
942 /* Set up registers for signal handler */
943 regs->r12 = (unsigned long) frame;
944 regs->cr_iip = IA32_SA_HANDLER(ka);
945
946 set_fs(USER_DS);
947
948#if 0
949 regs->eflags &= ~TF_MASK;
950#endif
951
952#if 0
953 printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%x\n",
954 current->comm, current->pid, (void *) frame, regs->cr_iip, frame->pretcode);
955#endif
956
957 return 1;
958
959give_sigsegv:
960 force_sigsegv(sig, current);
961 return 0;
962}
963
964int
965ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info,
966 sigset_t *set, struct pt_regs *regs)
967{
968 /* Set up the stack frame */
969 if (ka->sa.sa_flags & SA_SIGINFO)
970 return setup_rt_frame_ia32(sig, ka, info, set, regs);
971 else
972 return setup_frame_ia32(sig, ka, set, regs);
973}
974
975asmlinkage long
976sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5,
977 int arg6, int arg7, struct pt_regs regs)
978{
979 unsigned long esp = (unsigned int) regs.r12;
980 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(esp - 8);
981 sigset_t set;
982 int eax;
983
984 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
985 goto badframe;
986
987 if (__get_user(set.sig[0], &frame->sc.oldmask)
988 || (_COMPAT_NSIG_WORDS > 1 && __copy_from_user((char *) &set.sig + 4, &frame->extramask,
989 sizeof(frame->extramask))))
990 goto badframe;
991
992 sigdelsetmask(&set, ~_BLOCKABLE);
993 spin_lock_irq(&current->sighand->siglock);
994 current->blocked = set;
995 recalc_sigpending();
996 spin_unlock_irq(&current->sighand->siglock);
997
998 if (restore_sigcontext_ia32(&regs, &frame->sc, &eax))
999 goto badframe;
1000 return eax;
1001
1002 badframe:
1003 force_sig(SIGSEGV, current);
1004 return 0;
1005}
1006
1007asmlinkage long
1008sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4,
1009 int arg5, int arg6, int arg7, struct pt_regs regs)
1010{
1011 unsigned long esp = (unsigned int) regs.r12;
1012 struct rt_sigframe_ia32 __user *frame = (struct rt_sigframe_ia32 __user *)(esp - 4);
1013 sigset_t set;
1014 int eax;
1015
1016 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
1017 goto badframe;
1018 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
1019 goto badframe;
1020
1021 sigdelsetmask(&set, ~_BLOCKABLE);
1022 spin_lock_irq(&current->sighand->siglock);
1023 current->blocked = set;
1024 recalc_sigpending();
1025 spin_unlock_irq(&current->sighand->siglock);
1026
1027 if (restore_sigcontext_ia32(&regs, &frame->uc.uc_mcontext, &eax))
1028 goto badframe;
1029
1030 /* It is more difficult to avoid calling this function than to
1031 call it and ignore errors. */
1032 do_sigaltstack((stack_t __user *) &frame->uc.uc_stack, NULL, esp);
1033
1034 return eax;
1035
1036 badframe:
1037 force_sig(SIGSEGV, current);
1038 return 0;
1039}