initial commit with v2.6.9
[linux-2.6.9-moxart.git] / arch / x86_64 / ia32 / ia32_signal.c
blob5fb7d173b913642d8e1c594b5fd44722951b1c1e
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 *
10 * $Id: ia32_signal.c,v 1.22 2002/07/29 10:34:03 ak Exp $
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 <linux/compat.h>
26 #include <asm/ucontext.h>
27 #include <asm/uaccess.h>
28 #include <asm/i387.h>
29 #include <asm/ia32.h>
30 #include <asm/ptrace.h>
31 #include <asm/ia32_unistd.h>
32 #include <asm/user32.h>
33 #include <asm/sigcontext32.h>
34 #include <asm/fpu32.h>
35 #include <asm/proto.h>
36 #include <asm/vsyscall32.h>
38 #define ptr_to_u32(x) ((u32)(u64)(x)) /* avoid gcc warning */
40 #define DEBUG_SIG 0
42 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
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 ia32_copy_siginfo_to_user(siginfo_t32 __user *to, siginfo_t *from)
49 int err;
50 if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
51 return -EFAULT;
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 err = __put_user(from->si_signo, &to->si_signo);
59 err |= __put_user(from->si_errno, &to->si_errno);
60 err |= __put_user((short)from->si_code, &to->si_code);
62 if (from->si_code < 0) {
63 err |= __put_user(from->si_pid, &to->si_pid);
64 err |= __put_user(from->si_uid, &to->si_uid);
65 err |= __put_user((u32)(u64)from->si_ptr, &to->si_ptr);
66 } else {
67 /* First 32bits of unions are always present:
68 * si_pid === si_band === si_tid === si_addr(LS half) */
69 err |= __put_user(from->_sifields._pad[0], &to->_sifields._pad[0]);
70 switch (from->si_code >> 16) {
71 case __SI_FAULT >> 16:
72 break;
73 case __SI_CHLD >> 16:
74 err |= __put_user(from->si_utime, &to->si_utime);
75 err |= __put_user(from->si_stime, &to->si_stime);
76 err |= __put_user(from->si_status, &to->si_status);
77 default:
78 case __SI_KILL >> 16:
79 err |= __put_user(from->si_uid, &to->si_uid);
80 break;
81 case __SI_POLL >> 16:
82 err |= __put_user(from->si_fd, &to->si_fd);
83 break;
84 case __SI_TIMER >> 16:
85 err |= __put_user(from->si_overrun, &to->si_overrun);
86 err |= __put_user((u32)(u64)from->si_ptr, &to->si_ptr);
87 break;
88 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
89 case __SI_MESGQ >> 16:
90 err |= __put_user(from->si_uid, &to->si_uid);
91 err |= __put_user(from->si_int, &to->si_int);
92 break;
95 return err;
98 int ia32_copy_siginfo_from_user(siginfo_t *to, siginfo_t32 __user *from)
100 int err;
101 u32 ptr32;
102 if (!access_ok (VERIFY_READ, from, sizeof(siginfo_t32)))
103 return -EFAULT;
105 err = __get_user(to->si_signo, &from->si_signo);
106 err |= __get_user(to->si_errno, &from->si_errno);
107 err |= __get_user(to->si_code, &from->si_code);
109 err |= __get_user(to->si_pid, &from->si_pid);
110 err |= __get_user(to->si_uid, &from->si_uid);
111 err |= __get_user(ptr32, &from->si_ptr);
112 to->si_ptr = compat_ptr(ptr32);
114 return err;
117 asmlinkage long
118 sys32_sigsuspend(int history0, int history1, old_sigset_t mask,
119 struct pt_regs *regs)
121 sigset_t saveset;
123 mask &= _BLOCKABLE;
124 spin_lock_irq(&current->sighand->siglock);
125 saveset = current->blocked;
126 siginitset(&current->blocked, mask);
127 recalc_sigpending();
128 spin_unlock_irq(&current->sighand->siglock);
130 regs->rax = -EINTR;
131 while (1) {
132 current->state = TASK_INTERRUPTIBLE;
133 schedule();
134 if (do_signal(regs, &saveset))
135 return -EINTR;
139 asmlinkage long
140 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;
147 if (uss_ptr) {
148 u32 ptr;
149 memset(&uss,0,sizeof(stack_t));
150 if (!access_ok(VERIFY_READ,uss_ptr,sizeof(stack_ia32_t)) ||
151 __get_user(ptr, &uss_ptr->ss_sp) ||
152 __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
153 __get_user(uss.ss_size, &uss_ptr->ss_size))
154 return -EFAULT;
155 uss.ss_sp = compat_ptr(ptr);
157 seg = get_fs();
158 set_fs(KERNEL_DS);
159 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->rsp);
160 set_fs(seg);
161 if (ret >= 0 && uoss_ptr) {
162 if (!access_ok(VERIFY_WRITE,uoss_ptr,sizeof(stack_ia32_t)) ||
163 __put_user((u32)(u64)uoss.ss_sp, &uoss_ptr->ss_sp) ||
164 __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
165 __put_user(uoss.ss_size, &uoss_ptr->ss_size))
166 ret = -EFAULT;
168 return ret;
172 * Do a signal return; undo the signal stack.
175 struct sigframe
177 u32 pretcode;
178 int sig;
179 struct sigcontext_ia32 sc;
180 struct _fpstate_ia32 fpstate;
181 unsigned int extramask[_COMPAT_NSIG_WORDS-1];
182 char retcode[8];
185 struct rt_sigframe
187 u32 pretcode;
188 int sig;
189 u32 pinfo;
190 u32 puc;
191 struct siginfo32 info;
192 struct ucontext_ia32 uc;
193 struct _fpstate_ia32 fpstate;
194 char retcode[8];
197 static int
198 ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 __user *sc, unsigned int *peax)
200 unsigned int err = 0;
202 /* Always make any pending restarted system calls return -EINTR */
203 current_thread_info()->restart_block.fn = do_no_restart_syscall;
205 #if DEBUG_SIG
206 printk("SIG restore_sigcontext: sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
207 sc, sc->err, sc->eip, sc->cs, sc->eflags);
208 #endif
209 #define COPY(x) { \
210 unsigned int reg; \
211 err |= __get_user(reg, &sc->e ##x); \
212 regs->r ## x = reg; \
215 #define RELOAD_SEG(seg,mask) \
216 { unsigned int cur; \
217 unsigned short pre; \
218 err |= __get_user(pre, &sc->seg); \
219 asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \
220 pre |= mask; \
221 if (pre != cur) loadsegment(seg,pre); }
223 /* Reload fs and gs if they have changed in the signal handler.
224 This does not handle long fs/gs base changes in the handler, but
225 does not clobber them at least in the normal case. */
228 unsigned gs, oldgs;
229 err |= __get_user(gs, &sc->gs);
230 gs |= 3;
231 asm("movl %%gs,%0" : "=r" (oldgs));
232 if (gs != oldgs)
233 load_gs_index(gs);
235 RELOAD_SEG(fs,3);
236 RELOAD_SEG(ds,3);
237 RELOAD_SEG(es,3);
239 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
240 COPY(dx); COPY(cx); COPY(ip);
241 /* Don't touch extended registers */
243 err |= __get_user(regs->cs, &sc->cs);
244 regs->cs |= 3;
245 err |= __get_user(regs->ss, &sc->ss);
246 regs->ss |= 3;
249 unsigned int tmpflags;
250 err |= __get_user(tmpflags, &sc->eflags);
251 regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);
252 regs->orig_rax = -1; /* disable syscall checks */
256 u32 tmp;
257 struct _fpstate_ia32 __user * buf;
258 err |= __get_user(tmp, &sc->fpstate);
259 buf = compat_ptr(tmp);
260 if (buf) {
261 if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
262 goto badframe;
263 err |= restore_i387_ia32(current, buf, 0);
268 u32 tmp;
269 err |= __get_user(tmp, &sc->eax);
270 *peax = tmp;
272 return err;
274 badframe:
275 return 1;
278 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
280 struct sigframe __user *frame = (struct sigframe __user *)(regs->rsp-8);
281 sigset_t set;
282 unsigned int eax;
284 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
285 goto badframe;
286 if (__get_user(set.sig[0], &frame->sc.oldmask)
287 || (_COMPAT_NSIG_WORDS > 1
288 && __copy_from_user((((char *) &set.sig) + 4), &frame->extramask,
289 sizeof(frame->extramask))))
290 goto badframe;
292 sigdelsetmask(&set, ~_BLOCKABLE);
293 spin_lock_irq(&current->sighand->siglock);
294 current->blocked = set;
295 recalc_sigpending();
296 spin_unlock_irq(&current->sighand->siglock);
298 if (ia32_restore_sigcontext(regs, &frame->sc, &eax))
299 goto badframe;
300 return eax;
302 badframe:
303 signal_fault(regs, frame, "32bit sigreturn");
304 return 0;
307 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
309 struct rt_sigframe __user *frame;
310 sigset_t set;
311 unsigned int eax;
312 struct pt_regs tregs;
314 frame = (struct rt_sigframe __user *)(regs->rsp - 4);
316 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
317 goto badframe;
318 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
319 goto badframe;
321 sigdelsetmask(&set, ~_BLOCKABLE);
322 spin_lock_irq(&current->sighand->siglock);
323 current->blocked = set;
324 recalc_sigpending();
325 spin_unlock_irq(&current->sighand->siglock);
327 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax))
328 goto badframe;
330 tregs = *regs;
331 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
332 goto badframe;
334 return eax;
336 badframe:
337 signal_fault(regs,frame,"32bit rt sigreturn");
338 return 0;
342 * Set up a signal frame.
345 static int
346 ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate,
347 struct pt_regs *regs, unsigned int mask)
349 int tmp, err = 0;
350 u32 eflags;
352 tmp = 0;
353 __asm__("movl %%gs,%0" : "=r"(tmp): "0"(tmp));
354 err |= __put_user(tmp, (unsigned int __user *)&sc->gs);
355 __asm__("movl %%fs,%0" : "=r"(tmp): "0"(tmp));
356 err |= __put_user(tmp, (unsigned int __user *)&sc->fs);
357 __asm__("movl %%ds,%0" : "=r"(tmp): "0"(tmp));
358 err |= __put_user(tmp, (unsigned int __user *)&sc->ds);
359 __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
360 err |= __put_user(tmp, (unsigned int __user *)&sc->es);
362 err |= __put_user((u32)regs->rdi, &sc->edi);
363 err |= __put_user((u32)regs->rsi, &sc->esi);
364 err |= __put_user((u32)regs->rbp, &sc->ebp);
365 err |= __put_user((u32)regs->rsp, &sc->esp);
366 err |= __put_user((u32)regs->rbx, &sc->ebx);
367 err |= __put_user((u32)regs->rdx, &sc->edx);
368 err |= __put_user((u32)regs->rcx, &sc->ecx);
369 err |= __put_user((u32)regs->rax, &sc->eax);
370 err |= __put_user((u32)regs->cs, &sc->cs);
371 err |= __put_user((u32)regs->ss, &sc->ss);
372 err |= __put_user(current->thread.trap_no, &sc->trapno);
373 err |= __put_user(current->thread.error_code, &sc->err);
374 err |= __put_user((u32)regs->rip, &sc->eip);
375 eflags = regs->eflags;
376 if (current->ptrace & PT_PTRACED) {
377 eflags &= ~TF_MASK;
379 err |= __put_user((u32)eflags, &sc->eflags);
380 err |= __put_user((u32)regs->rsp, &sc->esp_at_signal);
382 tmp = save_i387_ia32(current, fpstate, regs, 0);
383 if (tmp < 0)
384 err = -EFAULT;
385 else {
386 current->used_math = 0;
387 stts();
388 err |= __put_user((u32)(u64)(tmp ? fpstate : NULL), &sc->fpstate);
391 /* non-iBCS2 extensions.. */
392 err |= __put_user(mask, &sc->oldmask);
393 err |= __put_user(current->thread.cr2, &sc->cr2);
395 return err;
399 * Determine which stack to use..
401 static void __user *
402 get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
404 unsigned long rsp;
406 /* Default to using normal stack */
407 rsp = regs->rsp;
409 /* This is the X/Open sanctioned signal stack switching. */
410 if (ka->sa.sa_flags & SA_ONSTACK) {
411 if (sas_ss_flags(rsp) == 0)
412 rsp = current->sas_ss_sp + current->sas_ss_size;
415 /* This is the legacy signal stack switching. */
416 else if ((regs->ss & 0xffff) != __USER_DS &&
417 !(ka->sa.sa_flags & SA_RESTORER) &&
418 ka->sa.sa_restorer) {
419 rsp = (unsigned long) ka->sa.sa_restorer;
422 return (void __user *)((rsp - frame_size) & -8UL);
425 void ia32_setup_frame(int sig, struct k_sigaction *ka,
426 compat_sigset_t *set, struct pt_regs * regs)
428 struct sigframe __user *frame;
429 int err = 0;
431 frame = get_sigframe(ka, regs, sizeof(*frame));
433 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
434 goto give_sigsegv;
437 struct exec_domain *ed = current_thread_info()->exec_domain;
438 err |= __put_user((ed
439 && ed->signal_invmap
440 && sig < 32
441 ? ed->signal_invmap[sig]
442 : sig),
443 &frame->sig);
445 if (err)
446 goto give_sigsegv;
448 err |= ia32_setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
449 if (err)
450 goto give_sigsegv;
452 if (_COMPAT_NSIG_WORDS > 1) {
453 err |= __copy_to_user(frame->extramask, &set->sig[1],
454 sizeof(frame->extramask));
456 if (err)
457 goto give_sigsegv;
459 /* Return stub is in 32bit vsyscall page */
461 void __user *restorer = VSYSCALL32_SIGRETURN;
462 if (ka->sa.sa_flags & SA_RESTORER)
463 restorer = ka->sa.sa_restorer;
464 err |= __put_user(ptr_to_u32(restorer), &frame->pretcode);
466 /* These are actually not used anymore, but left because some
467 gdb versions depend on them as a marker. */
469 /* copy_to_user optimizes that into a single 8 byte store */
470 static const struct {
471 u16 poplmovl;
472 u32 val;
473 u16 int80;
474 u16 pad;
475 } __attribute__((packed)) code = {
476 0xb858, /* popl %eax ; movl $...,%eax */
477 __NR_ia32_sigreturn,
478 0x80cd, /* int $0x80 */
481 err |= __copy_to_user(frame->retcode, &code, 8);
483 if (err)
484 goto give_sigsegv;
486 /* Set up registers for signal handler */
487 regs->rsp = (unsigned long) frame;
488 regs->rip = (unsigned long) ka->sa.sa_handler;
490 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
491 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
493 regs->cs = __USER32_CS;
494 regs->ss = __USER32_DS;
496 set_fs(USER_DS);
497 if (regs->eflags & TF_MASK) {
498 if (current->ptrace & PT_PTRACED) {
499 ptrace_notify(SIGTRAP);
500 } else {
501 regs->eflags &= ~TF_MASK;
505 #if DEBUG_SIG
506 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
507 current->comm, current->pid, frame, regs->rip, frame->pretcode);
508 #endif
510 return;
512 give_sigsegv:
513 force_sigsegv(sig, current);
516 void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
517 compat_sigset_t *set, struct pt_regs * regs)
519 struct rt_sigframe __user *frame;
520 int err = 0;
522 frame = get_sigframe(ka, regs, sizeof(*frame));
524 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
525 goto give_sigsegv;
529 struct exec_domain *ed = current_thread_info()->exec_domain;
530 err |= __put_user((ed
531 && ed->signal_invmap
532 && sig < 32
533 ? ed->signal_invmap[sig]
534 : sig),
535 &frame->sig);
537 err |= __put_user((u32)(u64)&frame->info, &frame->pinfo);
538 err |= __put_user((u32)(u64)&frame->uc, &frame->puc);
539 err |= ia32_copy_siginfo_to_user(&frame->info, info);
540 if (err)
541 goto give_sigsegv;
543 /* Create the ucontext. */
544 err |= __put_user(0, &frame->uc.uc_flags);
545 err |= __put_user(0, &frame->uc.uc_link);
546 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
547 err |= __put_user(sas_ss_flags(regs->rsp),
548 &frame->uc.uc_stack.ss_flags);
549 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
550 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
551 regs, set->sig[0]);
552 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
553 if (err)
554 goto give_sigsegv;
558 void __user *restorer = VSYSCALL32_RTSIGRETURN;
559 if (ka->sa.sa_flags & SA_RESTORER)
560 restorer = ka->sa.sa_restorer;
561 err |= __put_user(ptr_to_u32(restorer), &frame->pretcode);
564 /* This is movl $,%eax ; int $0x80 */
565 /* Not actually used anymore, but left because some gdb versions
566 need it. */
568 /* __copy_to_user optimizes that into a single 8 byte store */
569 static const struct {
570 u8 movl;
571 u32 val;
572 u16 int80;
573 u16 pad;
574 u8 pad2;
575 } __attribute__((packed)) code = {
576 0xb8,
577 __NR_ia32_rt_sigreturn,
578 0x80cd,
581 err |= __copy_to_user(frame->retcode, &code, 8);
583 if (err)
584 goto give_sigsegv;
586 /* Set up registers for signal handler */
587 regs->rsp = (unsigned long) frame;
588 regs->rip = (unsigned long) ka->sa.sa_handler;
590 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
591 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
593 regs->cs = __USER32_CS;
594 regs->ss = __USER32_DS;
596 set_fs(USER_DS);
597 if (regs->eflags & TF_MASK) {
598 if (current->ptrace & PT_PTRACED) {
599 ptrace_notify(SIGTRAP);
600 } else {
601 regs->eflags &= ~TF_MASK;
605 #if DEBUG_SIG
606 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
607 current->comm, current->pid, frame, regs->rip, frame->pretcode);
608 #endif
610 return;
612 give_sigsegv:
613 force_sigsegv(sig, current);