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
10 * $Id: ia32_signal.c,v 1.22 2002/07/29 10:34:03 ak Exp $
13 #include <linux/sched.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>
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>
40 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
42 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
43 void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
45 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
48 if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
51 /* If you change siginfo_t structure, please make sure that
52 this code is fixed accordingly.
53 It should never copy any pad contained in the structure
54 to avoid security leaks, but must copy the generic
55 3 ints plus the relevant union member. */
56 err = __put_user(from->si_signo, &to->si_signo);
57 err |= __put_user(from->si_errno, &to->si_errno);
58 err |= __put_user((short)from->si_code, &to->si_code);
60 if (from->si_code < 0) {
61 err |= __put_user(from->si_pid, &to->si_pid);
62 err |= __put_user(from->si_uid, &to->si_uid);
63 err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
65 /* First 32bits of unions are always present:
66 * si_pid === si_band === si_tid === si_addr(LS half) */
67 err |= __put_user(from->_sifields._pad[0], &to->_sifields._pad[0]);
68 switch (from->si_code >> 16) {
69 case __SI_FAULT >> 16:
72 err |= __put_user(from->si_utime, &to->si_utime);
73 err |= __put_user(from->si_stime, &to->si_stime);
74 err |= __put_user(from->si_status, &to->si_status);
78 err |= __put_user(from->si_uid, &to->si_uid);
81 err |= __put_user(from->si_fd, &to->si_fd);
83 case __SI_TIMER >> 16:
84 err |= __put_user(from->si_overrun, &to->si_overrun);
85 err |= __put_user(ptr_to_compat(from->si_ptr),
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);
98 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
102 if (!access_ok (VERIFY_READ, from, sizeof(compat_siginfo_t)))
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);
118 sys32_sigsuspend(int history0, int history1, old_sigset_t mask,
119 struct pt_regs *regs)
124 spin_lock_irq(¤t->sighand->siglock);
125 saveset = current->blocked;
126 siginitset(¤t->blocked, mask);
128 spin_unlock_irq(¤t->sighand->siglock);
132 current->state = TASK_INTERRUPTIBLE;
134 if (do_signal(regs, &saveset))
140 sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
141 stack_ia32_t __user *uoss_ptr,
142 struct pt_regs *regs)
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))
155 uss.ss_sp = compat_ptr(ptr);
159 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->rsp);
161 if (ret >= 0 && uoss_ptr) {
162 if (!access_ok(VERIFY_WRITE,uoss_ptr,sizeof(stack_ia32_t)) ||
163 __put_user(ptr_to_compat(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))
172 * Do a signal return; undo the signal stack.
179 struct sigcontext_ia32 sc;
180 struct _fpstate_ia32 fpstate;
181 unsigned int extramask[_COMPAT_NSIG_WORDS-1];
191 compat_siginfo_t info;
192 struct ucontext_ia32 uc;
193 struct _fpstate_ia32 fpstate;
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;
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);
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)); \
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. */
229 err |= __get_user(gs, &sc->gs);
231 asm("movl %%gs,%0" : "=r" (oldgs));
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);
245 err |= __get_user(regs->ss, &sc->ss);
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 */
257 struct _fpstate_ia32 __user * buf;
258 err |= __get_user(tmp, &sc->fpstate);
259 buf = compat_ptr(tmp);
261 if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
263 err |= restore_i387_ia32(current, buf, 0);
265 struct task_struct *me = current;
275 err |= __get_user(tmp, &sc->eax);
284 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
286 struct sigframe __user *frame = (struct sigframe __user *)(regs->rsp-8);
290 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
292 if (__get_user(set.sig[0], &frame->sc.oldmask)
293 || (_COMPAT_NSIG_WORDS > 1
294 && __copy_from_user((((char *) &set.sig) + 4), &frame->extramask,
295 sizeof(frame->extramask))))
298 sigdelsetmask(&set, ~_BLOCKABLE);
299 spin_lock_irq(¤t->sighand->siglock);
300 current->blocked = set;
302 spin_unlock_irq(¤t->sighand->siglock);
304 if (ia32_restore_sigcontext(regs, &frame->sc, &eax))
309 signal_fault(regs, frame, "32bit sigreturn");
313 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
315 struct rt_sigframe __user *frame;
318 struct pt_regs tregs;
320 frame = (struct rt_sigframe __user *)(regs->rsp - 4);
322 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
324 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
327 sigdelsetmask(&set, ~_BLOCKABLE);
328 spin_lock_irq(¤t->sighand->siglock);
329 current->blocked = set;
331 spin_unlock_irq(¤t->sighand->siglock);
333 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax))
337 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
343 signal_fault(regs,frame,"32bit rt sigreturn");
348 * Set up a signal frame.
352 ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate,
353 struct pt_regs *regs, unsigned int mask)
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);
368 err |= __put_user((u32)regs->rdi, &sc->edi);
369 err |= __put_user((u32)regs->rsi, &sc->esi);
370 err |= __put_user((u32)regs->rbp, &sc->ebp);
371 err |= __put_user((u32)regs->rsp, &sc->esp);
372 err |= __put_user((u32)regs->rbx, &sc->ebx);
373 err |= __put_user((u32)regs->rdx, &sc->edx);
374 err |= __put_user((u32)regs->rcx, &sc->ecx);
375 err |= __put_user((u32)regs->rax, &sc->eax);
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->rip, &sc->eip);
381 eflags = regs->eflags;
382 if (current->ptrace & PT_PTRACED)
384 err |= __put_user((u32)eflags, &sc->eflags);
385 err |= __put_user((u32)regs->rsp, &sc->esp_at_signal);
387 tmp = save_i387_ia32(current, fpstate, regs, 0);
393 err |= __put_user(ptr_to_compat(tmp ? fpstate : NULL),
397 /* non-iBCS2 extensions.. */
398 err |= __put_user(mask, &sc->oldmask);
399 err |= __put_user(current->thread.cr2, &sc->cr2);
405 * Determine which stack to use..
408 get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
412 /* Default to using normal stack */
415 /* This is the X/Open sanctioned signal stack switching. */
416 if (ka->sa.sa_flags & SA_ONSTACK) {
417 if (sas_ss_flags(rsp) == 0)
418 rsp = current->sas_ss_sp + current->sas_ss_size;
421 /* This is the legacy signal stack switching. */
422 else if ((regs->ss & 0xffff) != __USER_DS &&
423 !(ka->sa.sa_flags & SA_RESTORER) &&
424 ka->sa.sa_restorer) {
425 rsp = (unsigned long) ka->sa.sa_restorer;
429 /* Align the stack pointer according to the i386 ABI,
430 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
431 rsp = ((rsp + 4) & -16ul) - 4;
432 return (void __user *) rsp;
435 int ia32_setup_frame(int sig, struct k_sigaction *ka,
436 compat_sigset_t *set, struct pt_regs * regs)
438 struct sigframe __user *frame;
441 frame = get_sigframe(ka, regs, sizeof(*frame));
443 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
447 struct exec_domain *ed = current_thread_info()->exec_domain;
448 err |= __put_user((ed
451 ? ed->signal_invmap[sig]
458 err |= ia32_setup_sigcontext(&frame->sc, &frame->fpstate, regs,
463 if (_COMPAT_NSIG_WORDS > 1) {
464 err |= __copy_to_user(frame->extramask, &set->sig[1],
465 sizeof(frame->extramask));
470 /* Return stub is in 32bit vsyscall page */
472 void __user *restorer = VSYSCALL32_SIGRETURN;
473 if (ka->sa.sa_flags & SA_RESTORER)
474 restorer = ka->sa.sa_restorer;
475 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
477 /* These are actually not used anymore, but left because some
478 gdb versions depend on them as a marker. */
480 /* copy_to_user optimizes that into a single 8 byte store */
481 static const struct {
486 } __attribute__((packed)) code = {
487 0xb858, /* popl %eax ; movl $...,%eax */
489 0x80cd, /* int $0x80 */
492 err |= __copy_to_user(frame->retcode, &code, 8);
497 /* Set up registers for signal handler */
498 regs->rsp = (unsigned long) frame;
499 regs->rip = (unsigned long) ka->sa.sa_handler;
501 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
502 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
504 regs->cs = __USER32_CS;
505 regs->ss = __USER32_DS;
508 if (regs->eflags & TF_MASK) {
509 if (current->ptrace & PT_PTRACED) {
510 ptrace_notify(SIGTRAP);
512 regs->eflags &= ~TF_MASK;
517 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
518 current->comm, current->pid, frame, regs->rip, frame->pretcode);
524 force_sigsegv(sig, current);
528 int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
529 compat_sigset_t *set, struct pt_regs * regs)
531 struct rt_sigframe __user *frame;
534 frame = get_sigframe(ka, regs, sizeof(*frame));
536 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
540 struct exec_domain *ed = current_thread_info()->exec_domain;
541 err |= __put_user((ed
544 ? ed->signal_invmap[sig]
548 err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
549 err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
550 err |= copy_siginfo_to_user32(&frame->info, info);
554 /* Create the ucontext. */
555 err |= __put_user(0, &frame->uc.uc_flags);
556 err |= __put_user(0, &frame->uc.uc_link);
557 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
558 err |= __put_user(sas_ss_flags(regs->rsp),
559 &frame->uc.uc_stack.ss_flags);
560 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
561 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
563 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
569 void __user *restorer = VSYSCALL32_RTSIGRETURN;
570 if (ka->sa.sa_flags & SA_RESTORER)
571 restorer = ka->sa.sa_restorer;
572 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
575 /* This is movl $,%eax ; int $0x80 */
576 /* Not actually used anymore, but left because some gdb versions
579 /* __copy_to_user optimizes that into a single 8 byte store */
580 static const struct {
586 } __attribute__((packed)) code = {
588 __NR_ia32_rt_sigreturn,
592 err |= __copy_to_user(frame->retcode, &code, 8);
597 /* Set up registers for signal handler */
598 regs->rsp = (unsigned long) frame;
599 regs->rip = (unsigned long) ka->sa.sa_handler;
601 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
602 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
604 regs->cs = __USER32_CS;
605 regs->ss = __USER32_DS;
608 if (regs->eflags & TF_MASK) {
609 if (current->ptrace & PT_PTRACED) {
610 ptrace_notify(SIGTRAP);
612 regs->eflags &= ~TF_MASK;
617 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
618 current->comm, current->pid, frame, regs->rip, frame->pretcode);
624 force_sigsegv(sig, current);