x86, xsave: dynamically allocate sigframes fpstate instead of static allocation
[linux-2.6/mini2440.git] / arch / x86 / ia32 / ia32_signal.c
bloba05bf0fb741530b001c09a63553bbcff4d68c43d
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/ia32.h>
28 #include <asm/ptrace.h>
29 #include <asm/ia32_unistd.h>
30 #include <asm/user32.h>
31 #include <asm/sigcontext32.h>
32 #include <asm/proto.h>
33 #include <asm/vdso.h>
35 #define DEBUG_SIG 0
37 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
39 #define FIX_EFLAGS (X86_EFLAGS_AC | X86_EFLAGS_OF | \
40 X86_EFLAGS_DF | X86_EFLAGS_TF | X86_EFLAGS_SF | \
41 X86_EFLAGS_ZF | X86_EFLAGS_AF | X86_EFLAGS_PF | \
42 X86_EFLAGS_CF)
44 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
45 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
47 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
49 int err;
51 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
52 return -EFAULT;
54 /* If you change siginfo_t structure, please make sure that
55 this code is fixed accordingly.
56 It should never copy any pad contained in the structure
57 to avoid security leaks, but must copy the generic
58 3 ints plus the relevant union member. */
59 err = __put_user(from->si_signo, &to->si_signo);
60 err |= __put_user(from->si_errno, &to->si_errno);
61 err |= __put_user((short)from->si_code, &to->si_code);
63 if (from->si_code < 0) {
64 err |= __put_user(from->si_pid, &to->si_pid);
65 err |= __put_user(from->si_uid, &to->si_uid);
66 err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
67 } else {
69 * First 32bits of unions are always present:
70 * si_pid === si_band === si_tid === si_addr(LS half)
72 err |= __put_user(from->_sifields._pad[0],
73 &to->_sifields._pad[0]);
74 switch (from->si_code >> 16) {
75 case __SI_FAULT >> 16:
76 break;
77 case __SI_CHLD >> 16:
78 err |= __put_user(from->si_utime, &to->si_utime);
79 err |= __put_user(from->si_stime, &to->si_stime);
80 err |= __put_user(from->si_status, &to->si_status);
81 /* FALL THROUGH */
82 default:
83 case __SI_KILL >> 16:
84 err |= __put_user(from->si_uid, &to->si_uid);
85 break;
86 case __SI_POLL >> 16:
87 err |= __put_user(from->si_fd, &to->si_fd);
88 break;
89 case __SI_TIMER >> 16:
90 err |= __put_user(from->si_overrun, &to->si_overrun);
91 err |= __put_user(ptr_to_compat(from->si_ptr),
92 &to->si_ptr);
93 break;
94 /* This is not generated by the kernel as of now. */
95 case __SI_RT >> 16:
96 case __SI_MESGQ >> 16:
97 err |= __put_user(from->si_uid, &to->si_uid);
98 err |= __put_user(from->si_int, &to->si_int);
99 break;
102 return err;
105 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
107 int err;
108 u32 ptr32;
110 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
111 return -EFAULT;
113 err = __get_user(to->si_signo, &from->si_signo);
114 err |= __get_user(to->si_errno, &from->si_errno);
115 err |= __get_user(to->si_code, &from->si_code);
117 err |= __get_user(to->si_pid, &from->si_pid);
118 err |= __get_user(to->si_uid, &from->si_uid);
119 err |= __get_user(ptr32, &from->si_ptr);
120 to->si_ptr = compat_ptr(ptr32);
122 return err;
125 asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
127 mask &= _BLOCKABLE;
128 spin_lock_irq(&current->sighand->siglock);
129 current->saved_sigmask = current->blocked;
130 siginitset(&current->blocked, mask);
131 recalc_sigpending();
132 spin_unlock_irq(&current->sighand->siglock);
134 current->state = TASK_INTERRUPTIBLE;
135 schedule();
136 set_restore_sigmask();
137 return -ERESTARTNOHAND;
140 asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
141 stack_ia32_t __user *uoss_ptr,
142 struct pt_regs *regs)
144 stack_t uss, uoss;
145 int ret;
146 mm_segment_t seg;
148 if (uss_ptr) {
149 u32 ptr;
151 memset(&uss, 0, sizeof(stack_t));
152 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)) ||
153 __get_user(ptr, &uss_ptr->ss_sp) ||
154 __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
155 __get_user(uss.ss_size, &uss_ptr->ss_size))
156 return -EFAULT;
157 uss.ss_sp = compat_ptr(ptr);
159 seg = get_fs();
160 set_fs(KERNEL_DS);
161 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
162 set_fs(seg);
163 if (ret >= 0 && uoss_ptr) {
164 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)) ||
165 __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
166 __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
167 __put_user(uoss.ss_size, &uoss_ptr->ss_size))
168 ret = -EFAULT;
170 return ret;
174 * Do a signal return; undo the signal stack.
177 struct sigframe
179 u32 pretcode;
180 int sig;
181 struct sigcontext_ia32 sc;
182 struct _fpstate_ia32 fpstate_unused; /* look at kernel/sigframe.h */
183 unsigned int extramask[_COMPAT_NSIG_WORDS-1];
184 char retcode[8];
185 /* fp state follows here */
188 struct rt_sigframe
190 u32 pretcode;
191 int sig;
192 u32 pinfo;
193 u32 puc;
194 compat_siginfo_t info;
195 struct ucontext_ia32 uc;
196 char retcode[8];
197 /* fp state follows here */
200 #define COPY(x) { \
201 unsigned int reg; \
202 err |= __get_user(reg, &sc->x); \
203 regs->x = reg; \
206 #define RELOAD_SEG(seg,mask) \
207 { unsigned int cur; \
208 unsigned short pre; \
209 err |= __get_user(pre, &sc->seg); \
210 asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \
211 pre |= mask; \
212 if (pre != cur) loadsegment(seg, pre); }
214 static int ia32_restore_sigcontext(struct pt_regs *regs,
215 struct sigcontext_ia32 __user *sc,
216 unsigned int *peax)
218 unsigned int tmpflags, gs, oldgs, err = 0;
219 struct _fpstate_ia32 __user *buf;
220 u32 tmp;
222 /* Always make any pending restarted system calls return -EINTR */
223 current_thread_info()->restart_block.fn = do_no_restart_syscall;
225 #if DEBUG_SIG
226 printk(KERN_DEBUG "SIG restore_sigcontext: "
227 "sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
228 sc, sc->err, sc->ip, sc->cs, sc->flags);
229 #endif
232 * Reload fs and gs if they have changed in the signal
233 * handler. This does not handle long fs/gs base changes in
234 * the handler, but does not clobber them at least in the
235 * normal case.
237 err |= __get_user(gs, &sc->gs);
238 gs |= 3;
239 asm("movl %%gs,%0" : "=r" (oldgs));
240 if (gs != oldgs)
241 load_gs_index(gs);
243 RELOAD_SEG(fs, 3);
244 RELOAD_SEG(ds, 3);
245 RELOAD_SEG(es, 3);
247 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
248 COPY(dx); COPY(cx); COPY(ip);
249 /* Don't touch extended registers */
251 err |= __get_user(regs->cs, &sc->cs);
252 regs->cs |= 3;
253 err |= __get_user(regs->ss, &sc->ss);
254 regs->ss |= 3;
256 err |= __get_user(tmpflags, &sc->flags);
257 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
258 /* disable syscall checks */
259 regs->orig_ax = -1;
261 err |= __get_user(tmp, &sc->fpstate);
262 buf = compat_ptr(tmp);
263 if (buf) {
264 if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
265 goto badframe;
266 err |= restore_i387_ia32(buf);
267 } else {
268 struct task_struct *me = current;
270 if (used_math()) {
271 clear_fpu(me);
272 clear_used_math();
276 err |= __get_user(tmp, &sc->ax);
277 *peax = tmp;
279 return err;
281 badframe:
282 return 1;
285 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
287 struct sigframe __user *frame = (struct sigframe __user *)(regs->sp-8);
288 sigset_t set;
289 unsigned int ax;
291 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
292 goto badframe;
293 if (__get_user(set.sig[0], &frame->sc.oldmask)
294 || (_COMPAT_NSIG_WORDS > 1
295 && __copy_from_user((((char *) &set.sig) + 4),
296 &frame->extramask,
297 sizeof(frame->extramask))))
298 goto badframe;
300 sigdelsetmask(&set, ~_BLOCKABLE);
301 spin_lock_irq(&current->sighand->siglock);
302 current->blocked = set;
303 recalc_sigpending();
304 spin_unlock_irq(&current->sighand->siglock);
306 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
307 goto badframe;
308 return ax;
310 badframe:
311 signal_fault(regs, frame, "32bit sigreturn");
312 return 0;
315 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
317 struct rt_sigframe __user *frame;
318 sigset_t set;
319 unsigned int ax;
320 struct pt_regs tregs;
322 frame = (struct rt_sigframe __user *)(regs->sp - 4);
324 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
325 goto badframe;
326 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
327 goto badframe;
329 sigdelsetmask(&set, ~_BLOCKABLE);
330 spin_lock_irq(&current->sighand->siglock);
331 current->blocked = set;
332 recalc_sigpending();
333 spin_unlock_irq(&current->sighand->siglock);
335 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
336 goto badframe;
338 tregs = *regs;
339 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
340 goto badframe;
342 return ax;
344 badframe:
345 signal_fault(regs, frame, "32bit rt sigreturn");
346 return 0;
350 * Set up a signal frame.
353 static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
354 struct _fpstate_ia32 __user *fpstate,
355 struct pt_regs *regs, unsigned int mask)
357 int tmp, err = 0;
359 tmp = 0;
360 __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
361 err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
362 __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
363 err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
364 __asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp));
365 err |= __put_user(tmp, (unsigned int __user *)&sc->ds);
366 __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
367 err |= __put_user(tmp, (unsigned int __user *)&sc->es);
369 err |= __put_user((u32)regs->di, &sc->di);
370 err |= __put_user((u32)regs->si, &sc->si);
371 err |= __put_user((u32)regs->bp, &sc->bp);
372 err |= __put_user((u32)regs->sp, &sc->sp);
373 err |= __put_user((u32)regs->bx, &sc->bx);
374 err |= __put_user((u32)regs->dx, &sc->dx);
375 err |= __put_user((u32)regs->cx, &sc->cx);
376 err |= __put_user((u32)regs->ax, &sc->ax);
377 err |= __put_user((u32)regs->cs, &sc->cs);
378 err |= __put_user((u32)regs->ss, &sc->ss);
379 err |= __put_user(current->thread.trap_no, &sc->trapno);
380 err |= __put_user(current->thread.error_code, &sc->err);
381 err |= __put_user((u32)regs->ip, &sc->ip);
382 err |= __put_user((u32)regs->flags, &sc->flags);
383 err |= __put_user((u32)regs->sp, &sc->sp_at_signal);
385 tmp = save_i387_ia32(fpstate);
386 if (tmp < 0)
387 err = -EFAULT;
388 else {
389 clear_used_math();
390 stts();
391 err |= __put_user(ptr_to_compat(tmp ? fpstate : NULL),
392 &sc->fpstate);
395 /* non-iBCS2 extensions.. */
396 err |= __put_user(mask, &sc->oldmask);
397 err |= __put_user(current->thread.cr2, &sc->cr2);
399 return err;
403 * Determine which stack to use..
405 static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
406 size_t frame_size,
407 struct _fpstate_ia32 **fpstate)
409 unsigned long sp;
411 /* Default to using normal stack */
412 sp = regs->sp;
414 /* This is the X/Open sanctioned signal stack switching. */
415 if (ka->sa.sa_flags & SA_ONSTACK) {
416 if (sas_ss_flags(sp) == 0)
417 sp = current->sas_ss_sp + current->sas_ss_size;
420 /* This is the legacy signal stack switching. */
421 else if ((regs->ss & 0xffff) != __USER_DS &&
422 !(ka->sa.sa_flags & SA_RESTORER) &&
423 ka->sa.sa_restorer)
424 sp = (unsigned long) ka->sa.sa_restorer;
426 if (used_math()) {
427 sp = sp - sig_xstate_ia32_size;
428 *fpstate = (struct _fpstate_ia32 *) sp;
431 sp -= frame_size;
432 /* Align the stack pointer according to the i386 ABI,
433 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
434 sp = ((sp + 4) & -16ul) - 4;
435 return (void __user *) sp;
438 int ia32_setup_frame(int sig, struct k_sigaction *ka,
439 compat_sigset_t *set, struct pt_regs *regs)
441 struct sigframe __user *frame;
442 void __user *restorer;
443 int err = 0;
444 struct _fpstate_ia32 __user *fpstate = NULL;
446 /* copy_to_user optimizes that into a single 8 byte store */
447 static const struct {
448 u16 poplmovl;
449 u32 val;
450 u16 int80;
451 u16 pad;
452 } __attribute__((packed)) code = {
453 0xb858, /* popl %eax ; movl $...,%eax */
454 __NR_ia32_sigreturn,
455 0x80cd, /* int $0x80 */
459 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
461 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
462 goto give_sigsegv;
464 err |= __put_user(sig, &frame->sig);
465 if (err)
466 goto give_sigsegv;
468 err |= ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]);
469 if (err)
470 goto give_sigsegv;
472 if (_COMPAT_NSIG_WORDS > 1) {
473 err |= __copy_to_user(frame->extramask, &set->sig[1],
474 sizeof(frame->extramask));
475 if (err)
476 goto give_sigsegv;
479 if (ka->sa.sa_flags & SA_RESTORER) {
480 restorer = ka->sa.sa_restorer;
481 } else {
482 /* Return stub is in 32bit vsyscall page */
483 if (current->mm->context.vdso)
484 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
485 sigreturn);
486 else
487 restorer = &frame->retcode;
489 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
492 * These are actually not used anymore, but left because some
493 * gdb versions depend on them as a marker.
495 err |= __copy_to_user(frame->retcode, &code, 8);
496 if (err)
497 goto give_sigsegv;
499 /* Set up registers for signal handler */
500 regs->sp = (unsigned long) frame;
501 regs->ip = (unsigned long) ka->sa.sa_handler;
503 /* Make -mregparm=3 work */
504 regs->ax = sig;
505 regs->dx = 0;
506 regs->cx = 0;
508 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
509 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
511 regs->cs = __USER32_CS;
512 regs->ss = __USER32_DS;
514 #if DEBUG_SIG
515 printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
516 current->comm, current->pid, frame, regs->ip, frame->pretcode);
517 #endif
519 return 0;
521 give_sigsegv:
522 force_sigsegv(sig, current);
523 return -EFAULT;
526 int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
527 compat_sigset_t *set, struct pt_regs *regs)
529 struct rt_sigframe __user *frame;
530 void __user *restorer;
531 int err = 0;
532 struct _fpstate_ia32 __user *fpstate = NULL;
534 /* __copy_to_user optimizes that into a single 8 byte store */
535 static const struct {
536 u8 movl;
537 u32 val;
538 u16 int80;
539 u16 pad;
540 u8 pad2;
541 } __attribute__((packed)) code = {
542 0xb8,
543 __NR_ia32_rt_sigreturn,
544 0x80cd,
548 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
550 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
551 goto give_sigsegv;
553 err |= __put_user(sig, &frame->sig);
554 err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
555 err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
556 err |= copy_siginfo_to_user32(&frame->info, info);
557 if (err)
558 goto give_sigsegv;
560 /* Create the ucontext. */
561 err |= __put_user(0, &frame->uc.uc_flags);
562 err |= __put_user(0, &frame->uc.uc_link);
563 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
564 err |= __put_user(sas_ss_flags(regs->sp),
565 &frame->uc.uc_stack.ss_flags);
566 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
567 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
568 regs, set->sig[0]);
569 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
570 if (err)
571 goto give_sigsegv;
573 if (ka->sa.sa_flags & SA_RESTORER)
574 restorer = ka->sa.sa_restorer;
575 else
576 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
577 rt_sigreturn);
578 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
581 * Not actually used anymore, but left because some gdb
582 * versions need it.
584 err |= __copy_to_user(frame->retcode, &code, 8);
585 if (err)
586 goto give_sigsegv;
588 /* Set up registers for signal handler */
589 regs->sp = (unsigned long) frame;
590 regs->ip = (unsigned long) ka->sa.sa_handler;
592 /* Make -mregparm=3 work */
593 regs->ax = sig;
594 regs->dx = (unsigned long) &frame->info;
595 regs->cx = (unsigned long) &frame->uc;
597 /* Make -mregparm=3 work */
598 regs->ax = sig;
599 regs->dx = (unsigned long) &frame->info;
600 regs->cx = (unsigned long) &frame->uc;
602 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
603 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
605 regs->cs = __USER32_CS;
606 regs->ss = __USER32_DS;
608 #if DEBUG_SIG
609 printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
610 current->comm, current->pid, frame, regs->ip, frame->pretcode);
611 #endif
613 return 0;
615 give_sigsegv:
616 force_sigsegv(sig, current);
617 return -EFAULT;