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