fed up with those stupid warnings
[mmotm.git] / arch / x86 / ia32 / ia32_signal.c
blob588a7aa937e145f4d0b6e0eb29860b13298ec363
1 /*
2 * linux/arch/x86_64/ia32/ia32_signal.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
6 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
7 * 2000-06-20 Pentium III FXSR, SSE support by Gareth Hughes
8 * 2000-12-* x86-64 compatibility mode signal handling by Andi Kleen
9 */
11 #include <linux/sched.h>
12 #include <linux/mm.h>
13 #include <linux/smp.h>
14 #include <linux/kernel.h>
15 #include <linux/signal.h>
16 #include <linux/errno.h>
17 #include <linux/wait.h>
18 #include <linux/ptrace.h>
19 #include <linux/unistd.h>
20 #include <linux/stddef.h>
21 #include <linux/personality.h>
22 #include <linux/compat.h>
23 #include <linux/binfmts.h>
24 #include <asm/ucontext.h>
25 #include <asm/uaccess.h>
26 #include <asm/i387.h>
27 #include <asm/ptrace.h>
28 #include <asm/ia32_unistd.h>
29 #include <asm/user32.h>
30 #include <asm/sigcontext32.h>
31 #include <asm/proto.h>
32 #include <asm/vdso.h>
33 #include <asm/sigframe.h>
34 #include <asm/sys_ia32.h>
36 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
38 #define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \
39 X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
40 X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
41 X86_EFLAGS_CF)
43 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
45 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
47 int err = 0;
49 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
50 return -EFAULT;
52 put_user_try {
53 /* If you change siginfo_t structure, please make sure that
54 this code is fixed accordingly.
55 It should never copy any pad contained in the structure
56 to avoid security leaks, but must copy the generic
57 3 ints plus the relevant union member. */
58 put_user_ex(from->si_signo, &to->si_signo);
59 put_user_ex(from->si_errno, &to->si_errno);
60 put_user_ex((short)from->si_code, &to->si_code);
62 if (from->si_code < 0) {
63 put_user_ex(from->si_pid, &to->si_pid);
64 put_user_ex(from->si_uid, &to->si_uid);
65 put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
66 } else {
68 * First 32bits of unions are always present:
69 * si_pid === si_band === si_tid === si_addr(LS half)
71 put_user_ex(from->_sifields._pad[0],
72 &to->_sifields._pad[0]);
73 switch (from->si_code >> 16) {
74 case __SI_FAULT >> 16:
75 break;
76 case __SI_CHLD >> 16:
77 put_user_ex(from->si_utime, &to->si_utime);
78 put_user_ex(from->si_stime, &to->si_stime);
79 put_user_ex(from->si_status, &to->si_status);
80 /* FALL THROUGH */
81 default:
82 case __SI_KILL >> 16:
83 put_user_ex(from->si_uid, &to->si_uid);
84 break;
85 case __SI_POLL >> 16:
86 put_user_ex(from->si_fd, &to->si_fd);
87 break;
88 case __SI_TIMER >> 16:
89 put_user_ex(from->si_overrun, &to->si_overrun);
90 put_user_ex(ptr_to_compat(from->si_ptr),
91 &to->si_ptr);
92 break;
93 /* This is not generated by the kernel as of now. */
94 case __SI_RT >> 16:
95 case __SI_MESGQ >> 16:
96 put_user_ex(from->si_uid, &to->si_uid);
97 put_user_ex(from->si_int, &to->si_int);
98 break;
101 } put_user_catch(err);
103 return err;
106 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
108 int err = 0;
109 u32 ptr32;
111 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
112 return -EFAULT;
114 get_user_try {
115 get_user_ex(to->si_signo, &from->si_signo);
116 get_user_ex(to->si_errno, &from->si_errno);
117 get_user_ex(to->si_code, &from->si_code);
119 get_user_ex(to->si_pid, &from->si_pid);
120 get_user_ex(to->si_uid, &from->si_uid);
121 get_user_ex(ptr32, &from->si_ptr);
122 to->si_ptr = compat_ptr(ptr32);
123 } get_user_catch(err);
125 return err;
128 asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
130 mask &= _BLOCKABLE;
131 spin_lock_irq(&current->sighand->siglock);
132 current->saved_sigmask = current->blocked;
133 siginitset(&current->blocked, mask);
134 recalc_sigpending();
135 spin_unlock_irq(&current->sighand->siglock);
137 current->state = TASK_INTERRUPTIBLE;
138 schedule();
139 set_restore_sigmask();
140 return -ERESTARTNOHAND;
143 asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
144 stack_ia32_t __user *uoss_ptr,
145 struct pt_regs *regs)
147 stack_t uss, uoss;
148 int ret, err = 0;
149 mm_segment_t seg;
151 if (uss_ptr) {
152 u32 ptr;
154 memset(&uss, 0, sizeof(stack_t));
155 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)))
156 return -EFAULT;
158 get_user_try {
159 get_user_ex(ptr, &uss_ptr->ss_sp);
160 get_user_ex(uss.ss_flags, &uss_ptr->ss_flags);
161 get_user_ex(uss.ss_size, &uss_ptr->ss_size);
162 } get_user_catch(err);
164 if (err)
165 return -EFAULT;
166 uss.ss_sp = compat_ptr(ptr);
168 seg = get_fs();
169 set_fs(KERNEL_DS);
170 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
171 set_fs(seg);
172 if (ret >= 0 && uoss_ptr) {
173 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
174 return -EFAULT;
176 put_user_try {
177 put_user_ex(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp);
178 put_user_ex(uoss.ss_flags, &uoss_ptr->ss_flags);
179 put_user_ex(uoss.ss_size, &uoss_ptr->ss_size);
180 } put_user_catch(err);
182 if (err)
183 ret = -EFAULT;
185 return ret;
189 * Do a signal return; undo the signal stack.
191 #define loadsegment_gs(v) load_gs_index(v)
192 #define loadsegment_fs(v) loadsegment(fs, v)
193 #define loadsegment_ds(v) loadsegment(ds, v)
194 #define loadsegment_es(v) loadsegment(es, v)
196 #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
197 #define set_user_seg(seg, v) loadsegment_##seg(v)
199 #define COPY(x) { \
200 get_user_ex(regs->x, &sc->x); \
203 #define GET_SEG(seg) ({ \
204 unsigned short tmp; \
205 get_user_ex(tmp, &sc->seg); \
206 tmp; \
209 #define COPY_SEG_CPL3(seg) do { \
210 regs->seg = GET_SEG(seg) | 3; \
211 } while (0)
213 #define RELOAD_SEG(seg) { \
214 unsigned int pre = GET_SEG(seg); \
215 unsigned int cur = get_user_seg(seg); \
216 pre |= 3; \
217 if (pre != cur) \
218 set_user_seg(seg, pre); \
221 static int ia32_restore_sigcontext(struct pt_regs *regs,
222 struct sigcontext_ia32 __user *sc,
223 unsigned int *pax)
225 unsigned int tmpflags, err = 0;
226 void __user *buf;
227 u32 tmp;
229 /* Always make any pending restarted system calls return -EINTR */
230 current_thread_info()->restart_block.fn = do_no_restart_syscall;
232 get_user_try {
234 * Reload fs and gs if they have changed in the signal
235 * handler. This does not handle long fs/gs base changes in
236 * the handler, but does not clobber them at least in the
237 * normal case.
239 RELOAD_SEG(gs);
240 RELOAD_SEG(fs);
241 RELOAD_SEG(ds);
242 RELOAD_SEG(es);
244 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
245 COPY(dx); COPY(cx); COPY(ip);
246 /* Don't touch extended registers */
248 COPY_SEG_CPL3(cs);
249 COPY_SEG_CPL3(ss);
251 get_user_ex(tmpflags, &sc->flags);
252 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
253 /* disable syscall checks */
254 regs->orig_ax = -1;
256 get_user_ex(tmp, &sc->fpstate);
257 buf = compat_ptr(tmp);
258 err |= restore_i387_xstate_ia32(buf);
260 get_user_ex(*pax, &sc->ax);
261 } get_user_catch(err);
263 return err;
266 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
268 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
269 sigset_t set;
270 unsigned int ax;
272 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
273 goto badframe;
274 if (__get_user(set.sig[0], &frame->sc.oldmask)
275 || (_COMPAT_NSIG_WORDS > 1
276 && __copy_from_user((((char *) &set.sig) + 4),
277 &frame->extramask,
278 sizeof(frame->extramask))))
279 goto badframe;
281 sigdelsetmask(&set, ~_BLOCKABLE);
282 spin_lock_irq(&current->sighand->siglock);
283 current->blocked = set;
284 recalc_sigpending();
285 spin_unlock_irq(&current->sighand->siglock);
287 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
288 goto badframe;
289 return ax;
291 badframe:
292 signal_fault(regs, frame, "32bit sigreturn");
293 return 0;
296 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
298 struct rt_sigframe_ia32 __user *frame;
299 sigset_t set;
300 unsigned int ax;
301 struct pt_regs tregs;
303 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
305 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
306 goto badframe;
307 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
308 goto badframe;
310 sigdelsetmask(&set, ~_BLOCKABLE);
311 spin_lock_irq(&current->sighand->siglock);
312 current->blocked = set;
313 recalc_sigpending();
314 spin_unlock_irq(&current->sighand->siglock);
316 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
317 goto badframe;
319 tregs = *regs;
320 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
321 goto badframe;
323 return ax;
325 badframe:
326 signal_fault(regs, frame, "32bit rt sigreturn");
327 return 0;
331 * Set up a signal frame.
334 static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
335 void __user *fpstate,
336 struct pt_regs *regs, unsigned int mask)
338 int err = 0;
340 put_user_try {
341 put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
342 put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
343 put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
344 put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
346 put_user_ex(regs->di, &sc->di);
347 put_user_ex(regs->si, &sc->si);
348 put_user_ex(regs->bp, &sc->bp);
349 put_user_ex(regs->sp, &sc->sp);
350 put_user_ex(regs->bx, &sc->bx);
351 put_user_ex(regs->dx, &sc->dx);
352 put_user_ex(regs->cx, &sc->cx);
353 put_user_ex(regs->ax, &sc->ax);
354 put_user_ex(current->thread.trap_no, &sc->trapno);
355 put_user_ex(current->thread.error_code, &sc->err);
356 put_user_ex(regs->ip, &sc->ip);
357 put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
358 put_user_ex(regs->flags, &sc->flags);
359 put_user_ex(regs->sp, &sc->sp_at_signal);
360 put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
362 put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
364 /* non-iBCS2 extensions.. */
365 put_user_ex(mask, &sc->oldmask);
366 put_user_ex(current->thread.cr2, &sc->cr2);
367 } put_user_catch(err);
369 return err;
373 * Determine which stack to use..
375 static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
376 size_t frame_size,
377 void **fpstate)
379 unsigned long sp;
381 /* Default to using normal stack */
382 sp = regs->sp;
384 /* This is the X/Open sanctioned signal stack switching. */
385 if (ka->sa.sa_flags & SA_ONSTACK) {
386 if (sas_ss_flags(sp) == 0)
387 sp = current->sas_ss_sp + current->sas_ss_size;
390 /* This is the legacy signal stack switching. */
391 else if ((regs->ss & 0xffff) != __USER32_DS &&
392 !(ka->sa.sa_flags & SA_RESTORER) &&
393 ka->sa.sa_restorer)
394 sp = (unsigned long) ka->sa.sa_restorer;
396 if (used_math()) {
397 sp = sp - sig_xstate_ia32_size;
398 *fpstate = (struct _fpstate_ia32 *) sp;
399 if (save_i387_xstate_ia32(*fpstate) < 0)
400 return (void __user *) -1L;
403 sp -= frame_size;
404 /* Align the stack pointer according to the i386 ABI,
405 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
406 sp = ((sp + 4) & -16ul) - 4;
407 return (void __user *) sp;
410 int ia32_setup_frame(int sig, struct k_sigaction *ka,
411 compat_sigset_t *set, struct pt_regs *regs)
413 struct sigframe_ia32 __user *frame;
414 void __user *restorer;
415 int err = 0;
416 void __user *fpstate = NULL;
418 /* copy_to_user optimizes that into a single 8 byte store */
419 static const struct {
420 u16 poplmovl;
421 u32 val;
422 u16 int80;
423 } __attribute__((packed)) code = {
424 0xb858, /* popl %eax ; movl $...,%eax */
425 __NR_ia32_sigreturn,
426 0x80cd, /* int $0x80 */
429 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
431 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
432 return -EFAULT;
434 if (__put_user(sig, &frame->sig))
435 return -EFAULT;
437 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
438 return -EFAULT;
440 if (_COMPAT_NSIG_WORDS > 1) {
441 if (__copy_to_user(frame->extramask, &set->sig[1],
442 sizeof(frame->extramask)))
443 return -EFAULT;
446 if (ka->sa.sa_flags & SA_RESTORER) {
447 restorer = ka->sa.sa_restorer;
448 } else {
449 /* Return stub is in 32bit vsyscall page */
450 if (current->mm->context.vdso)
451 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
452 sigreturn);
453 else
454 restorer = &frame->retcode;
457 put_user_try {
458 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
461 * These are actually not used anymore, but left because some
462 * gdb versions depend on them as a marker.
464 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
465 } put_user_catch(err);
467 if (err)
468 return -EFAULT;
470 /* Set up registers for signal handler */
471 regs->sp = (unsigned long) frame;
472 regs->ip = (unsigned long) ka->sa.sa_handler;
474 /* Make -mregparm=3 work */
475 regs->ax = sig;
476 regs->dx = 0;
477 regs->cx = 0;
479 loadsegment(ds, __USER32_DS);
480 loadsegment(es, __USER32_DS);
482 regs->cs = __USER32_CS;
483 regs->ss = __USER32_DS;
485 return 0;
488 int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
489 compat_sigset_t *set, struct pt_regs *regs)
491 struct rt_sigframe_ia32 __user *frame;
492 void __user *restorer;
493 int err = 0;
494 void __user *fpstate = NULL;
496 /* __copy_to_user optimizes that into a single 8 byte store */
497 static const struct {
498 u8 movl;
499 u32 val;
500 u16 int80;
501 u8 pad;
502 } __attribute__((packed)) code = {
503 0xb8,
504 __NR_ia32_rt_sigreturn,
505 0x80cd,
509 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
511 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
512 return -EFAULT;
514 put_user_try {
515 put_user_ex(sig, &frame->sig);
516 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
517 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
518 err |= copy_siginfo_to_user32(&frame->info, info);
520 /* Create the ucontext. */
521 if (cpu_has_xsave)
522 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
523 else
524 put_user_ex(0, &frame->uc.uc_flags);
525 put_user_ex(0, &frame->uc.uc_link);
526 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
527 put_user_ex(sas_ss_flags(regs->sp),
528 &frame->uc.uc_stack.ss_flags);
529 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
530 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
531 regs, set->sig[0]);
532 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
534 if (ka->sa.sa_flags & SA_RESTORER)
535 restorer = ka->sa.sa_restorer;
536 else
537 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
538 rt_sigreturn);
539 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
542 * Not actually used anymore, but left because some gdb
543 * versions need it.
545 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
546 } put_user_catch(err);
548 if (err)
549 return -EFAULT;
551 /* Set up registers for signal handler */
552 regs->sp = (unsigned long) frame;
553 regs->ip = (unsigned long) ka->sa.sa_handler;
555 /* Make -mregparm=3 work */
556 regs->ax = sig;
557 regs->dx = (unsigned long) &frame->info;
558 regs->cx = (unsigned long) &frame->uc;
560 loadsegment(ds, __USER32_DS);
561 loadsegment(es, __USER32_DS);
563 regs->cs = __USER32_CS;
564 regs->ss = __USER32_DS;
566 return 0;