]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/x86/ia32/ia32_signal.c
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394...
[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;
183         unsigned int extramask[_COMPAT_NSIG_WORDS-1];
184         char retcode[8];
185 };
186
187 struct rt_sigframe
188 {
189         u32 pretcode;
190         int sig;
191         u32 pinfo;
192         u32 puc;
193         compat_siginfo_t info;
194         struct ucontext_ia32 uc;
195         struct _fpstate_ia32 fpstate;
196         char retcode[8];
197 };
198
199 #define COPY(x)         {               \
200         unsigned int reg;               \
201         err |= __get_user(reg, &sc->x); \
202         regs->x = reg;                  \
203 }
204
205 #define RELOAD_SEG(seg,mask)                                            \
206         { unsigned int cur;                                             \
207           unsigned short pre;                                           \
208           err |= __get_user(pre, &sc->seg);                             \
209           asm volatile("movl %%" #seg ",%0" : "=r" (cur));              \
210           pre |= mask;                                                  \
211           if (pre != cur) loadsegment(seg, pre); }
212
213 static int ia32_restore_sigcontext(struct pt_regs *regs,
214                                    struct sigcontext_ia32 __user *sc,
215                                    unsigned int *peax)
216 {
217         unsigned int tmpflags, gs, oldgs, err = 0;
218         struct _fpstate_ia32 __user *buf;
219         u32 tmp;
220
221         /* Always make any pending restarted system calls return -EINTR */
222         current_thread_info()->restart_block.fn = do_no_restart_syscall;
223
224 #if DEBUG_SIG
225         printk(KERN_DEBUG "SIG restore_sigcontext: "
226                "sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
227                sc, sc->err, sc->ip, sc->cs, sc->flags);
228 #endif
229
230         /*
231          * Reload fs and gs if they have changed in the signal
232          * handler.  This does not handle long fs/gs base changes in
233          * the handler, but does not clobber them at least in the
234          * normal case.
235          */
236         err |= __get_user(gs, &sc->gs);
237         gs |= 3;
238         asm("movl %%gs,%0" : "=r" (oldgs));
239         if (gs != oldgs)
240                 load_gs_index(gs);
241
242         RELOAD_SEG(fs, 3);
243         RELOAD_SEG(ds, 3);
244         RELOAD_SEG(es, 3);
245
246         COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
247         COPY(dx); COPY(cx); COPY(ip);
248         /* Don't touch extended registers */
249
250         err |= __get_user(regs->cs, &sc->cs);
251         regs->cs |= 3;
252         err |= __get_user(regs->ss, &sc->ss);
253         regs->ss |= 3;
254
255         err |= __get_user(tmpflags, &sc->flags);
256         regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
257         /* disable syscall checks */
258         regs->orig_ax = -1;
259
260         err |= __get_user(tmp, &sc->fpstate);
261         buf = compat_ptr(tmp);
262         if (buf) {
263                 if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
264                         goto badframe;
265                 err |= restore_i387_ia32(buf);
266         } else {
267                 struct task_struct *me = current;
268
269                 if (used_math()) {
270                         clear_fpu(me);
271                         clear_used_math();
272                 }
273         }
274
275         err |= __get_user(tmp, &sc->ax);
276         *peax = tmp;
277
278         return err;
279
280 badframe:
281         return 1;
282 }
283
284 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
285 {
286         struct sigframe __user *frame = (struct sigframe __user *)(regs->sp-8);
287         sigset_t set;
288         unsigned int ax;
289
290         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
291                 goto badframe;
292         if (__get_user(set.sig[0], &frame->sc.oldmask)
293             || (_COMPAT_NSIG_WORDS > 1
294                 && __copy_from_user((((char *) &set.sig) + 4),
295                                     &frame->extramask,
296                                     sizeof(frame->extramask))))
297                 goto badframe;
298
299         sigdelsetmask(&set, ~_BLOCKABLE);
300         spin_lock_irq(&current->sighand->siglock);
301         current->blocked = set;
302         recalc_sigpending();
303         spin_unlock_irq(&current->sighand->siglock);
304
305         if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
306                 goto badframe;
307         return ax;
308
309 badframe:
310         signal_fault(regs, frame, "32bit sigreturn");
311         return 0;
312 }
313
314 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
315 {
316         struct rt_sigframe __user *frame;
317         sigset_t set;
318         unsigned int ax;
319         struct pt_regs tregs;
320
321         frame = (struct rt_sigframe __user *)(regs->sp - 4);
322
323         if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
324                 goto badframe;
325         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
326                 goto badframe;
327
328         sigdelsetmask(&set, ~_BLOCKABLE);
329         spin_lock_irq(&current->sighand->siglock);
330         current->blocked = set;
331         recalc_sigpending();
332         spin_unlock_irq(&current->sighand->siglock);
333
334         if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
335                 goto badframe;
336
337         tregs = *regs;
338         if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
339                 goto badframe;
340
341         return ax;
342
343 badframe:
344         signal_fault(regs, frame, "32bit rt sigreturn");
345         return 0;
346 }
347
348 /*
349  * Set up a signal frame.
350  */
351
352 static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
353                                  struct _fpstate_ia32 __user *fpstate,
354                                  struct pt_regs *regs, unsigned int mask)
355 {
356         int tmp, err = 0;
357
358         tmp = 0;
359         __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
360         err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
361         __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
362         err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
363         __asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp));
364         err |= __put_user(tmp, (unsigned int __user *)&sc->ds);
365         __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
366         err |= __put_user(tmp, (unsigned int __user *)&sc->es);
367
368         err |= __put_user((u32)regs->di, &sc->di);
369         err |= __put_user((u32)regs->si, &sc->si);
370         err |= __put_user((u32)regs->bp, &sc->bp);
371         err |= __put_user((u32)regs->sp, &sc->sp);
372         err |= __put_user((u32)regs->bx, &sc->bx);
373         err |= __put_user((u32)regs->dx, &sc->dx);
374         err |= __put_user((u32)regs->cx, &sc->cx);
375         err |= __put_user((u32)regs->ax, &sc->ax);
376         err |= __put_user((u32)regs->cs, &sc->cs);
377         err |= __put_user((u32)regs->ss, &sc->ss);
378         err |= __put_user(current->thread.trap_no, &sc->trapno);
379         err |= __put_user(current->thread.error_code, &sc->err);
380         err |= __put_user((u32)regs->ip, &sc->ip);
381         err |= __put_user((u32)regs->flags, &sc->flags);
382         err |= __put_user((u32)regs->sp, &sc->sp_at_signal);
383
384         tmp = save_i387_ia32(fpstate);
385         if (tmp < 0)
386                 err = -EFAULT;
387         else {
388                 clear_used_math();
389                 stts();
390                 err |= __put_user(ptr_to_compat(tmp ? fpstate : NULL),
391                                         &sc->fpstate);
392         }
393
394         /* non-iBCS2 extensions.. */
395         err |= __put_user(mask, &sc->oldmask);
396         err |= __put_user(current->thread.cr2, &sc->cr2);
397
398         return err;
399 }
400
401 /*
402  * Determine which stack to use..
403  */
404 static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
405                                  size_t frame_size)
406 {
407         unsigned long sp;
408
409         /* Default to using normal stack */
410         sp = regs->sp;
411
412         /* This is the X/Open sanctioned signal stack switching.  */
413         if (ka->sa.sa_flags & SA_ONSTACK) {
414                 if (sas_ss_flags(sp) == 0)
415                         sp = current->sas_ss_sp + current->sas_ss_size;
416         }
417
418         /* This is the legacy signal stack switching. */
419         else if ((regs->ss & 0xffff) != __USER_DS &&
420                 !(ka->sa.sa_flags & SA_RESTORER) &&
421                  ka->sa.sa_restorer)
422                 sp = (unsigned long) ka->sa.sa_restorer;
423
424         sp -= frame_size;
425         /* Align the stack pointer according to the i386 ABI,
426          * i.e. so that on function entry ((sp + 4) & 15) == 0. */
427         sp = ((sp + 4) & -16ul) - 4;
428         return (void __user *) sp;
429 }
430
431 int ia32_setup_frame(int sig, struct k_sigaction *ka,
432                      compat_sigset_t *set, struct pt_regs *regs)
433 {
434         struct sigframe __user *frame;
435         void __user *restorer;
436         int err = 0;
437
438         /* copy_to_user optimizes that into a single 8 byte store */
439         static const struct {
440                 u16 poplmovl;
441                 u32 val;
442                 u16 int80;
443                 u16 pad;
444         } __attribute__((packed)) code = {
445                 0xb858,          /* popl %eax ; movl $...,%eax */
446                 __NR_ia32_sigreturn,
447                 0x80cd,         /* int $0x80 */
448                 0,
449         };
450
451         frame = get_sigframe(ka, regs, sizeof(*frame));
452
453         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
454                 goto give_sigsegv;
455
456         err |= __put_user(sig, &frame->sig);
457         if (err)
458                 goto give_sigsegv;
459
460         err |= ia32_setup_sigcontext(&frame->sc, &frame->fpstate, regs,
461                                         set->sig[0]);
462         if (err)
463                 goto give_sigsegv;
464
465         if (_COMPAT_NSIG_WORDS > 1) {
466                 err |= __copy_to_user(frame->extramask, &set->sig[1],
467                                       sizeof(frame->extramask));
468                 if (err)
469                         goto give_sigsegv;
470         }
471
472         if (ka->sa.sa_flags & SA_RESTORER) {
473                 restorer = ka->sa.sa_restorer;
474         } else {
475                 /* Return stub is in 32bit vsyscall page */
476                 if (current->mm->context.vdso)
477                         restorer = VDSO32_SYMBOL(current->mm->context.vdso,
478                                                  sigreturn);
479                 else
480                         restorer = &frame->retcode;
481         }
482         err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
483
484         /*
485          * These are actually not used anymore, but left because some
486          * gdb versions depend on them as a marker.
487          */
488         err |= __copy_to_user(frame->retcode, &code, 8);
489         if (err)
490                 goto give_sigsegv;
491
492         /* Set up registers for signal handler */
493         regs->sp = (unsigned long) frame;
494         regs->ip = (unsigned long) ka->sa.sa_handler;
495
496         /* Make -mregparm=3 work */
497         regs->ax = sig;
498         regs->dx = 0;
499         regs->cx = 0;
500
501         asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
502         asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
503
504         regs->cs = __USER32_CS;
505         regs->ss = __USER32_DS;
506
507 #if DEBUG_SIG
508         printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
509                current->comm, current->pid, frame, regs->ip, frame->pretcode);
510 #endif
511
512         return 0;
513
514 give_sigsegv:
515         force_sigsegv(sig, current);
516         return -EFAULT;
517 }
518
519 int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
520                         compat_sigset_t *set, struct pt_regs *regs)
521 {
522         struct rt_sigframe __user *frame;
523         void __user *restorer;
524         int err = 0;
525
526         /* __copy_to_user optimizes that into a single 8 byte store */
527         static const struct {
528                 u8 movl;
529                 u32 val;
530                 u16 int80;
531                 u16 pad;
532                 u8  pad2;
533         } __attribute__((packed)) code = {
534                 0xb8,
535                 __NR_ia32_rt_sigreturn,
536                 0x80cd,
537                 0,
538         };
539
540         frame = get_sigframe(ka, regs, sizeof(*frame));
541
542         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
543                 goto give_sigsegv;
544
545         err |= __put_user(sig, &frame->sig);
546         err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
547         err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
548         err |= copy_siginfo_to_user32(&frame->info, info);
549         if (err)
550                 goto give_sigsegv;
551
552         /* Create the ucontext.  */
553         err |= __put_user(0, &frame->uc.uc_flags);
554         err |= __put_user(0, &frame->uc.uc_link);
555         err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
556         err |= __put_user(sas_ss_flags(regs->sp),
557                           &frame->uc.uc_stack.ss_flags);
558         err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
559         err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
560                                      regs, set->sig[0]);
561         err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
562         if (err)
563                 goto give_sigsegv;
564
565         if (ka->sa.sa_flags & SA_RESTORER)
566                 restorer = ka->sa.sa_restorer;
567         else
568                 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
569                                          rt_sigreturn);
570         err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
571
572         /*
573          * Not actually used anymore, but left because some gdb
574          * versions need it.
575          */
576         err |= __copy_to_user(frame->retcode, &code, 8);
577         if (err)
578                 goto give_sigsegv;
579
580         /* Set up registers for signal handler */
581         regs->sp = (unsigned long) frame;
582         regs->ip = (unsigned long) ka->sa.sa_handler;
583
584         /* Make -mregparm=3 work */
585         regs->ax = sig;
586         regs->dx = (unsigned long) &frame->info;
587         regs->cx = (unsigned long) &frame->uc;
588
589         /* Make -mregparm=3 work */
590         regs->ax = sig;
591         regs->dx = (unsigned long) &frame->info;
592         regs->cx = (unsigned long) &frame->uc;
593
594         asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
595         asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
596
597         regs->cs = __USER32_CS;
598         regs->ss = __USER32_DS;
599
600 #if DEBUG_SIG
601         printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
602                current->comm, current->pid, frame, regs->ip, frame->pretcode);
603 #endif
604
605         return 0;
606
607 give_sigsegv:
608         force_sigsegv(sig, current);
609         return -EFAULT;
610 }