import of upstream 2.4.34.4 from kernel.org
[linux-2.4.git] / arch / x86_64 / 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  *  $Id: ia32_signal.c,v 1.32 2003/09/06 18:10:44 ak Exp $
11  */
12
13 #include <linux/sched.h>
14 #include <linux/mm.h>
15 #include <linux/smp.h>
16 #include <linux/smp_lock.h>
17 #include <linux/kernel.h>
18 #include <linux/signal.h>
19 #include <linux/errno.h>
20 #include <linux/wait.h>
21 #include <linux/ptrace.h>
22 #include <linux/unistd.h>
23 #include <linux/stddef.h>
24 #include <linux/personality.h>
25 #include <asm/ucontext.h>
26 #include <asm/uaccess.h>
27 #include <asm/i387.h>
28 #include <asm/ia32.h>
29 #include <asm/ptrace.h>
30 #include <asm/ia32_unistd.h>
31 #include <asm/user32.h>
32 #include <asm/sigcontext32.h>
33 #include <asm/fpu32.h>
34
35 #define ptr_to_u32(x) ((u32)(u64)(x))   /* avoid gcc warning */ 
36 #define u32_to_ptr(x) ((void *)(u64)(x))
37
38 #define DEBUG_SIG 0
39
40 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
41
42 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
43 void signal_fault(struct pt_regs *regs, void *frame, char *where);
44
45 static int ia32_copy_siginfo_to_user(siginfo_t32 *to, siginfo_t *from)
46 {
47         if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
48                 return -EFAULT;
49         if (from->si_code < 0) { 
50                 /* the only field that's different is the alignment
51                    of the pointer in sigval_t. Move that 4 bytes down including
52                    padding. */
53                 memmove(&((siginfo_t32 *)&from)->si_int,
54                         &from->si_int, 
55                         sizeof(siginfo_t) - offsetof(siginfo_t, si_int));
56                 /* last 4 bytes stay the same */
57                 return __copy_to_user(to, from, sizeof(siginfo_t32));
58         } else {
59                 int err;
60
61                 /* If you change siginfo_t structure, please be sure
62                    this code is fixed accordingly.
63                    It should never copy any pad contained in the structure
64                    to avoid security leaks, but must copy the generic
65                    3 ints plus the relevant union member.  */
66                 err = __put_user(from->si_signo, &to->si_signo);
67                 err |= __put_user(from->si_errno, &to->si_errno);
68                 err |= __put_user(from->si_code, &to->si_code);
69                 /* First 32bits of unions are always present.  */
70                 err |= __put_user(from->si_pid, &to->si_pid);
71                 switch (from->si_code >> 16) {
72                 case __SI_FAULT >> 16:
73                         break;
74                 case __SI_CHLD >> 16:
75                         err |= __put_user(from->si_utime, &to->si_utime);
76                         err |= __put_user(from->si_stime, &to->si_stime);
77                         err |= __put_user(from->si_status, &to->si_status);
78                 default:
79                         err |= __put_user(from->si_uid, &to->si_uid);
80                         break;
81                 case __SI_POLL >> 16:
82                         err |= __put_user(from->si_band, &to->si_band); 
83                         err |= __put_user(from->si_fd, &to->si_fd); 
84                         break;
85                 /* case __SI_RT: This is not generated by the kernel as of now.  */
86                 }
87                 return err;
88         }
89 }
90
91 asmlinkage long
92 sys32_sigsuspend(int history0, int history1, old_sigset_t mask, struct pt_regs regs)
93 {
94         sigset_t saveset;
95
96         mask &= _BLOCKABLE;
97         spin_lock_irq(&current->sigmask_lock);
98         saveset = current->blocked;
99         siginitset(&current->blocked, mask);
100         recalc_sigpending(current);
101         spin_unlock_irq(&current->sigmask_lock);
102
103         regs.rax = -EINTR;
104         while (1) {
105                 current->state = TASK_INTERRUPTIBLE;
106                 schedule();
107                 if (do_signal(&regs, &saveset))
108                         return -EINTR;
109         }
110 }
111
112 asmlinkage long
113 sys32_sigaltstack(const stack_ia32_t *uss_ptr, stack_ia32_t *uoss_ptr, 
114                                   struct pt_regs regs)
115 {
116         stack_t uss,uoss; 
117         int ret;
118         mm_segment_t seg; 
119         if (uss_ptr) {
120                 u32 val32;
121                 memset(&uss, 0, sizeof(stack_t));
122         if (!access_ok(VERIFY_READ,uss_ptr,sizeof(stack_ia32_t)) ||
123                     __get_user(val32, &uss_ptr->ss_sp) ||
124                     __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
125                     __get_user(uss.ss_size, &uss_ptr->ss_size))
126                 return -EFAULT;
127                 uss.ss_sp = u32_to_ptr(val32);  
128         }
129         seg = get_fs(); 
130         set_fs(KERNEL_DS); 
131         ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs.rsp);
132         set_fs(seg); 
133         if (ret >= 0 && uoss_ptr)  {
134                 if (!access_ok(VERIFY_WRITE,uoss_ptr,sizeof(stack_ia32_t)) ||
135                     __put_user(ptr_to_u32(uoss.ss_sp), &uoss_ptr->ss_sp) ||
136                     __put_user((u32)uoss.ss_flags, &uoss_ptr->ss_flags) ||
137                     __put_user((u32)uoss.ss_size, &uoss_ptr->ss_size))
138                         ret = -EFAULT;
139         }       
140         return ret;     
141 }
142
143 /*
144  * Do a signal return; undo the signal stack.
145  */
146
147 struct sigframe
148 {
149         u32 pretcode;
150         int sig;
151         struct sigcontext_ia32 sc;
152         struct _fpstate_ia32 fpstate;
153         unsigned int extramask[_IA32_NSIG_WORDS-1];
154         char retcode[8];
155 };
156
157 struct rt_sigframe
158 {
159         u32 pretcode;
160         int sig;
161         u32 pinfo;
162         u32 puc;
163         struct siginfo32 info;
164         struct ucontext_ia32 uc;
165         struct _fpstate_ia32 fpstate;
166         char retcode[8];
167 };
168
169 static int
170 ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsigned int *peax)
171 {
172         unsigned int err = 0;
173         
174 #if DEBUG_SIG
175         printk("SIG restore_sigcontext: sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
176                 sc, sc->err, sc->eip, sc->cs, sc->eflags);
177 #endif
178 #define COPY(x)         { \
179         unsigned int reg;       \
180         err |= __get_user(reg, &sc->e ##x);     \
181         regs->r ## x = reg;                     \
182 }
183
184 #define RELOAD_SEG(seg,mask)                                            \
185         { unsigned int cur;                             \
186           unsigned short pre;                           \
187           err |= __get_user(pre, &sc->seg);                             \
188           asm volatile("movl %%" #seg ",%0" : "=r" (cur));              \
189           pre |= mask;                                                  \
190           if (pre != cur) loadsegment(seg,pre); }
191
192         /* Reload fs and gs if they have changed in the signal handler.
193            This does not handle long gs base changes in the handler, but 
194            does not clobber it at least in the normal case. */ 
195         
196         {
197                 unsigned short gs; 
198                 unsigned int curgs;
199                 err |= __get_user(gs, &sc->gs);
200                 asm volatile("movl %%gs,%0" : "=r" (curgs));            
201                 if (gs != curgs) 
202                         load_gs_index(gs | 3); 
203         } 
204         RELOAD_SEG(fs,3);
205         RELOAD_SEG(ds,3);
206         RELOAD_SEG(es,3);
207
208         COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
209         COPY(dx); COPY(cx); COPY(ip);
210         /* Don't touch extended registers */ 
211
212         err |= __get_user(regs->cs, &sc->cs); 
213         regs->cs |= 3;  
214         err |= __get_user(regs->ss, &sc->ss); 
215         regs->ss |= 3; 
216         
217         {
218                 unsigned int tmpflags;
219                 err |= __get_user(tmpflags, &sc->eflags);
220                 regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
221                 regs->orig_rax = -1;            /* disable syscall checks */
222         }
223
224         {
225                 u32 tmp;
226                 struct _fpstate_ia32 * buf;
227                 err |= __get_user(tmp, &sc->fpstate);
228                 buf = (struct _fpstate_ia32 *) (u64)tmp;
229                 if (buf) {
230                         if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
231                                 return 1;
232                         err |= restore_i387_ia32(current, buf, 0);
233                 }
234         }
235
236         { 
237                 u32 tmp;
238                 err |= __get_user(tmp, &sc->eax);
239                 *peax = tmp;
240         }
241         return err;
242 }
243
244 asmlinkage long sys32_sigreturn(struct pt_regs regs)
245 {
246         struct sigframe *frame = (struct sigframe *)(regs.rsp - 8);
247         sigset_t set;
248         unsigned int eax;
249
250         if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
251                 goto badframe;
252         if (__get_user(set.sig[0], &frame->sc.oldmask)
253             || (_IA32_NSIG_WORDS > 1
254                 && __copy_from_user((((char *) &set.sig) + 4), &frame->extramask,
255                                     sizeof(frame->extramask))))
256                 goto badframe;
257
258         sigdelsetmask(&set, ~_BLOCKABLE);
259         spin_lock_irq(&current->sigmask_lock);
260         current->blocked = set;
261         recalc_sigpending(current);
262         spin_unlock_irq(&current->sigmask_lock);
263         
264         if (ia32_restore_sigcontext(&regs, &frame->sc, &eax))
265                 goto badframe;
266         return eax;
267
268 badframe:
269         signal_fault(&regs,frame,"32bit sigreturn");
270         return 0;
271 }       
272
273 asmlinkage long sys32_rt_sigreturn(struct pt_regs regs)
274 {
275         struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 4);
276         sigset_t set;
277         stack_t st;
278         unsigned int eax;
279
280         if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
281                 goto badframe;
282         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
283                 goto badframe;
284
285         sigdelsetmask(&set, ~_BLOCKABLE);
286         spin_lock_irq(&current->sigmask_lock);
287         current->blocked = set;
288         recalc_sigpending(current);
289         spin_unlock_irq(&current->sigmask_lock);
290         
291         if (ia32_restore_sigcontext(&regs, &frame->uc.uc_mcontext, &eax))
292                 goto badframe;
293
294         if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
295                 goto badframe;
296         /* It is more difficult to avoid calling this function than to
297            call it and ignore errors.  */
298         {
299                 mm_segment_t oldds = get_fs(); 
300                 set_fs(KERNEL_DS); 
301                 do_sigaltstack(&st, NULL, regs.rsp);
302                 set_fs(oldds);  
303         }
304
305         return eax;
306
307 badframe:
308         signal_fault(&regs,frame,"32bit rt sigreturn");
309         return 0;
310 }       
311
312 /*
313  * Set up a signal frame.
314  */
315
316 static int
317 ia32_setup_sigcontext(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
318                  struct pt_regs *regs, unsigned int mask)
319 {
320         int tmp, err = 0;
321
322         tmp = 0;
323         __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
324         err |= __put_user(tmp, (unsigned int *)&sc->gs);
325         __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
326         err |= __put_user(tmp, (unsigned int *)&sc->fs);
327         __asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp));
328         err |= __put_user(tmp, (unsigned int *)&sc->ds);
329         __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
330         err |= __put_user(tmp, (unsigned int *)&sc->es);
331
332         err |= __put_user((u32)regs->rdi, &sc->edi);
333         err |= __put_user((u32)regs->rsi, &sc->esi);
334         err |= __put_user((u32)regs->rbp, &sc->ebp);
335         err |= __put_user((u32)regs->rsp, &sc->esp);
336         err |= __put_user((u32)regs->rbx, &sc->ebx);
337         err |= __put_user((u32)regs->rdx, &sc->edx);
338         err |= __put_user((u32)regs->rcx, &sc->ecx);
339         err |= __put_user((u32)regs->rax, &sc->eax);
340         err |= __put_user((u32)regs->cs, &sc->cs); 
341         err |= __put_user((u32)regs->ss, &sc->ss); 
342         err |= __put_user(current->thread.trap_no, &sc->trapno);
343         err |= __put_user(current->thread.error_code, &sc->err);
344         err |= __put_user((u32)regs->rip, &sc->eip);
345         err |= __put_user((u32)regs->eflags, &sc->eflags);
346         err |= __put_user((u32)regs->rsp, &sc->esp_at_signal);
347
348         tmp = save_i387_ia32(current, fpstate, regs, 0);
349         if (tmp < 0)
350           err = -EFAULT;
351         else { 
352                 /* trigger finit in signal handler */
353                 current->used_math = 0;
354                 stts();
355           err |= __put_user((u32)(u64)(tmp ? fpstate : NULL), &sc->fpstate);
356         } 
357
358         /* non-iBCS2 extensions.. */
359         err |= __put_user(mask, &sc->oldmask);
360         err |= __put_user(current->thread.cr2, &sc->cr2);
361
362         return err;
363 }
364
365 /*
366  * Determine which stack to use..
367  */
368 static inline void *
369 get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
370 {
371         unsigned long rsp;
372
373         /* Default to using normal stack */
374         rsp = regs->rsp;
375
376         /* This is the X/Open sanctioned signal stack switching.  */
377         if (ka->sa.sa_flags & SA_ONSTACK) {
378                 if (! on_sig_stack(rsp))
379                         rsp = current->sas_ss_sp + current->sas_ss_size;
380         }
381
382         /* This is the legacy signal stack switching. */
383         else if ((regs->ss & 0xffff) != __USER_DS &&
384                 !(ka->sa.sa_flags & SA_RESTORER) &&
385                  ka->sa.sa_restorer) {
386                 rsp = (unsigned long) ka->sa.sa_restorer;
387         }
388
389         return (void *)((rsp - frame_size) & -8UL);
390 }
391
392 void ia32_setup_frame(int sig, struct k_sigaction *ka,
393                         sigset32_t *set, struct pt_regs * regs)
394 {
395         struct sigframe *frame;
396         int err = 0;
397
398         frame = get_sigframe(ka, regs, sizeof(*frame));
399
400         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
401                 goto give_sigsegv;
402
403         err |= __put_user((current->exec_domain
404                            && current->exec_domain->signal_invmap
405                            && sig < 32
406                            ? current->exec_domain->signal_invmap[sig]
407                            : sig),
408                           &frame->sig);
409         if (err)
410                 goto give_sigsegv;
411
412         err |= ia32_setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
413         if (err)
414                 goto give_sigsegv;
415
416         if (_IA32_NSIG_WORDS > 1) {
417                 err |= __copy_to_user(frame->extramask, &set->sig[1],
418                                       sizeof(frame->extramask));
419         }
420         if (err)
421                 goto give_sigsegv;
422
423         /* Set up to return from userspace.  If provided, use a stub
424            already in userspace.  */
425         if (ka->sa.sa_flags & SA_RESTORER) {
426                 err |= __put_user((u32)(u64)ka->sa.sa_restorer, &frame->pretcode);
427         } else {
428                 err |= __put_user((u32)(u64)frame->retcode, &frame->pretcode);
429                 /* This is popl %eax ; movl $,%eax ; int $0x80 */
430                 err |= __put_user((u16)0xb858, (short *)(frame->retcode+0));
431                 err |= __put_user((u32)__NR_ia32_sigreturn, (int *)(frame->retcode+2));
432                 err |= __put_user((u16)0x80cd, (short *)(frame->retcode+6));
433         }
434
435         if (err)
436                 goto give_sigsegv;
437
438         /* Set up registers for signal handler */
439         regs->rsp = (unsigned long) frame;
440         regs->rip = (unsigned long) ka->sa.sa_handler;
441
442         asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); 
443         asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); 
444
445         regs->cs = __USER32_CS; 
446         regs->ss = __USER32_DS; 
447
448         set_fs(USER_DS);
449         regs->eflags &= ~TF_MASK;
450
451 #if DEBUG_SIG
452         printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
453                 current->comm, current->pid, frame, regs->rip, frame->pretcode);
454 #endif
455
456         return;
457
458 give_sigsegv:
459         if (sig == SIGSEGV)
460                 ka->sa.sa_handler = SIG_DFL;
461         signal_fault(regs,frame,"32bit signal deliver");
462 }
463
464 void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
465                            sigset32_t *set, struct pt_regs * regs)
466 {
467         struct rt_sigframe *frame;
468         int err = 0;
469
470         frame = get_sigframe(ka, regs, sizeof(*frame));
471
472         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
473                 goto give_sigsegv;
474
475         err |= __put_user((current->exec_domain
476                            && current->exec_domain->signal_invmap
477                            && sig < 32
478                            ? current->exec_domain->signal_invmap[sig]
479                            : sig),
480                           &frame->sig);
481         err |= __put_user((u32)(u64)&frame->info, &frame->pinfo);
482         err |= __put_user((u32)(u64)&frame->uc, &frame->puc);
483         err |= ia32_copy_siginfo_to_user(&frame->info, info);
484         if (err)
485                 goto give_sigsegv;
486
487         /* Create the ucontext.  */
488         err |= __put_user(0, &frame->uc.uc_flags);
489         err |= __put_user(0, &frame->uc.uc_link);
490         err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
491         err |= __put_user(sas_ss_flags(regs->rsp),
492                           &frame->uc.uc_stack.ss_flags);
493         err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
494         err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
495                                 regs, set->sig[0]);
496         err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
497         if (err)
498                 goto give_sigsegv;
499
500         /* Set up to return from userspace.  If provided, use a stub
501            already in userspace.  */
502         if (ka->sa.sa_flags & SA_RESTORER) {
503                 err |= __put_user((u32)(u64)ka->sa.sa_restorer, &frame->pretcode);
504         } else {
505                 err |= __put_user(ptr_to_u32(frame->retcode), &frame->pretcode);
506                 /* This is movl $,%eax ; int $0x80 */
507                 err |= __put_user(0xb8, (char *)(frame->retcode+0));
508                 err |= __put_user((u32)__NR_ia32_rt_sigreturn, (int *)(frame->retcode+1));
509                 err |= __put_user(0x80cd, (short *)(frame->retcode+5));
510         }
511
512         if (err)
513                 goto give_sigsegv;
514
515         /* Set up registers for signal handler */
516         regs->rsp = (unsigned long) frame;
517         regs->rip = (unsigned long) ka->sa.sa_handler;
518
519         asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); 
520         asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); 
521
522         regs->cs = __USER32_CS; 
523         regs->ss = __USER32_DS; 
524
525         set_fs(USER_DS);
526         regs->eflags &= ~TF_MASK;
527
528 #if DEBUG_SIG
529         printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
530                 current->comm, current->pid, frame, regs->rip, frame->pretcode);
531 #endif
532
533         return;
534
535 give_sigsegv:
536         if (sig == SIGSEGV)
537                 ka->sa.sa_handler = SIG_DFL;
538         signal_fault(regs,frame,"32bit rt signal deliver");
539 }
540