]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/x86/ia32/ia32_signal.c
a05bf0fb741530b001c09a63553bbcff4d68c43d
[linux-2.6-omap-h63xx.git] / arch / x86 / ia32 / ia32_signal.c
1 /*
2  *  linux/arch/x86_64/ia32/ia32_signal.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  *
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  */
10
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>
34
35 #define DEBUG_SIG 0
36
37 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
38
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)
43
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);
46
47 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
48 {
49         int err;
50
51         if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
52                 return -EFAULT;
53
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);
62
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 {
68                 /*
69                  * First 32bits of unions are always present:
70                  * si_pid === si_band === si_tid === si_addr(LS half)
71                  */
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;
100                 }
101         }
102         return err;
103 }
104
105 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
106 {
107         int err;
108         u32 ptr32;
109
110         if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
111                 return -EFAULT;
112
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);
116
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);
121
122         return err;
123 }
124
125 asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
126 {
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);
133
134         current->state = TASK_INTERRUPTIBLE;
135         schedule();
136         set_restore_sigmask();
137         return -ERESTARTNOHAND;
138 }
139
140 asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
141                                   stack_ia32_t __user *uoss_ptr,
142                                   struct pt_regs *regs)
143 {
144         stack_t uss, uoss;
145         int ret;
146         mm_segment_t seg;
147
148         if (uss_ptr) {
149                 u32 ptr;
150
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);
158         }
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;
169         }
170         return ret;
171 }
172
173 /*
174  * Do a signal return; undo the signal stack.
175  */
176
177 struct sigframe
178 {
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 */
186 };
187
188 struct rt_sigframe
189 {
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 */
198 };
199
200 #define COPY(x)         {               \
201         unsigned int reg;               \
202         err |= __get_user(reg, &sc->x); \
203         regs->x = reg;                  \
204 }
205
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); }
213
214 static int ia32_restore_sigcontext(struct pt_regs *regs,
215                                    struct sigcontext_ia32 __user *sc,
216                                    unsigned int *peax)
217 {
218         unsigned int tmpflags, gs, oldgs, err = 0;
219         struct _fpstate_ia32 __user *buf;
220         u32 tmp;
221
222         /* Always make any pending restarted system calls return -EINTR */
223         current_thread_info()->restart_block.fn = do_no_restart_syscall;
224
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
230
231         /*
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.
236          */
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);
242
243         RELOAD_SEG(fs, 3);
244         RELOAD_SEG(ds, 3);
245         RELOAD_SEG(es, 3);
246
247         COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
248         COPY(dx); COPY(cx); COPY(ip);
249         /* Don't touch extended registers */
250
251         err |= __get_user(regs->cs, &sc->cs);
252         regs->cs |= 3;
253         err |= __get_user(regs->ss, &sc->ss);
254         regs->ss |= 3;
255
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;
260
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;
269
270                 if (used_math()) {
271                         clear_fpu(me);
272                         clear_used_math();
273                 }
274         }
275
276         err |= __get_user(tmp, &sc->ax);
277         *peax = tmp;
278
279         return err;
280
281 badframe:
282         return 1;
283 }
284
285 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
286 {
287         struct sigframe __user *frame = (struct sigframe __user *)(regs->sp-8);
288         sigset_t set;
289         unsigned int ax;
290
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;
299
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);
305
306         if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
307                 goto badframe;
308         return ax;
309
310 badframe:
311         signal_fault(regs, frame, "32bit sigreturn");
312         return 0;
313 }
314
315 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
316 {
317         struct rt_sigframe __user *frame;
318         sigset_t set;
319         unsigned int ax;
320         struct pt_regs tregs;
321
322         frame = (struct rt_sigframe __user *)(regs->sp - 4);
323
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;
328
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);
334
335         if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
336                 goto badframe;
337
338         tregs = *regs;
339         if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
340                 goto badframe;
341
342         return ax;
343
344 badframe:
345         signal_fault(regs, frame, "32bit rt sigreturn");
346         return 0;
347 }
348
349 /*
350  * Set up a signal frame.
351  */
352
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)
356 {
357         int tmp, err = 0;
358
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);
368
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);
384
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);
393         }
394
395         /* non-iBCS2 extensions.. */
396         err |= __put_user(mask, &sc->oldmask);
397         err |= __put_user(current->thread.cr2, &sc->cr2);
398
399         return err;
400 }
401
402 /*
403  * Determine which stack to use..
404  */
405 static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
406                                  size_t frame_size,
407                                  struct _fpstate_ia32 **fpstate)
408 {
409         unsigned long sp;
410
411         /* Default to using normal stack */
412         sp = regs->sp;
413
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;
418         }
419
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;
425
426         if (used_math()) {
427                 sp = sp - sig_xstate_ia32_size;
428                 *fpstate = (struct _fpstate_ia32 *) sp;
429         }
430
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;
436 }
437
438 int ia32_setup_frame(int sig, struct k_sigaction *ka,
439                      compat_sigset_t *set, struct pt_regs *regs)
440 {
441         struct sigframe __user *frame;
442         void __user *restorer;
443         int err = 0;
444         struct _fpstate_ia32 __user *fpstate = NULL;
445
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 */
456                 0,
457         };
458
459         frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
460
461         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
462                 goto give_sigsegv;
463
464         err |= __put_user(sig, &frame->sig);
465         if (err)
466                 goto give_sigsegv;
467
468         err |= ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]);
469         if (err)
470                 goto give_sigsegv;
471
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;
477         }
478
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;
488         }
489         err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
490
491         /*
492          * These are actually not used anymore, but left because some
493          * gdb versions depend on them as a marker.
494          */
495         err |= __copy_to_user(frame->retcode, &code, 8);
496         if (err)
497                 goto give_sigsegv;
498
499         /* Set up registers for signal handler */
500         regs->sp = (unsigned long) frame;
501         regs->ip = (unsigned long) ka->sa.sa_handler;
502
503         /* Make -mregparm=3 work */
504         regs->ax = sig;
505         regs->dx = 0;
506         regs->cx = 0;
507
508         asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
509         asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
510
511         regs->cs = __USER32_CS;
512         regs->ss = __USER32_DS;
513
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
518
519         return 0;
520
521 give_sigsegv:
522         force_sigsegv(sig, current);
523         return -EFAULT;
524 }
525
526 int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
527                         compat_sigset_t *set, struct pt_regs *regs)
528 {
529         struct rt_sigframe __user *frame;
530         void __user *restorer;
531         int err = 0;
532         struct _fpstate_ia32 __user *fpstate = NULL;
533
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,
545                 0,
546         };
547
548         frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
549
550         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
551                 goto give_sigsegv;
552
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;
559
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;
572
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);
579
580         /*
581          * Not actually used anymore, but left because some gdb
582          * versions need it.
583          */
584         err |= __copy_to_user(frame->retcode, &code, 8);
585         if (err)
586                 goto give_sigsegv;
587
588         /* Set up registers for signal handler */
589         regs->sp = (unsigned long) frame;
590         regs->ip = (unsigned long) ka->sa.sa_handler;
591
592         /* Make -mregparm=3 work */
593         regs->ax = sig;
594         regs->dx = (unsigned long) &frame->info;
595         regs->cx = (unsigned long) &frame->uc;
596
597         /* Make -mregparm=3 work */
598         regs->ax = sig;
599         regs->dx = (unsigned long) &frame->info;
600         regs->cx = (unsigned long) &frame->uc;
601
602         asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
603         asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
604
605         regs->cs = __USER32_CS;
606         regs->ss = __USER32_DS;
607
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
612
613         return 0;
614
615 give_sigsegv:
616         force_sigsegv(sig, current);
617         return -EFAULT;
618 }