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.32 2003/09/06 18:10:44 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 <asm/ucontext.h>
26 #include <asm/uaccess.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>
35 #define ptr_to_u32(x) ((u32)(u64)(x)) /* avoid gcc warning */
36 #define u32_to_ptr(x) ((void *)(u64)(x))
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 *frame, char *where);
45 static int ia32_copy_siginfo_to_user(siginfo_t32 *to, siginfo_t *from)
47 if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t)))
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
53 memmove(&((siginfo_t32 *)&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));
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:
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);
79 err |= __put_user(from->si_uid, &to->si_uid);
82 err |= __put_user(from->si_band, &to->si_band);
83 err |= __put_user(from->si_fd, &to->si_fd);
85 /* case __SI_RT: This is not generated by the kernel as of now. */
92 sys32_sigsuspend(int history0, int history1, old_sigset_t mask, struct pt_regs regs)
97 spin_lock_irq(¤t->sigmask_lock);
98 saveset = current->blocked;
99 siginitset(¤t->blocked, mask);
100 recalc_sigpending(current);
101 spin_unlock_irq(¤t->sigmask_lock);
105 current->state = TASK_INTERRUPTIBLE;
107 if (do_signal(®s, &saveset))
113 sys32_sigaltstack(const stack_ia32_t *uss_ptr, stack_ia32_t *uoss_ptr,
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))
127 uss.ss_sp = u32_to_ptr(val32);
131 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs.rsp);
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))
144 * Do a signal return; undo the signal stack.
151 struct sigcontext_ia32 sc;
152 struct _fpstate_ia32 fpstate;
153 unsigned int extramask[_IA32_NSIG_WORDS-1];
163 struct siginfo32 info;
164 struct ucontext_ia32 uc;
165 struct _fpstate_ia32 fpstate;
170 ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 *sc, unsigned int *peax)
172 unsigned int err = 0;
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);
180 err |= __get_user(reg, &sc->e ##x); \
181 regs->r ## x = reg; \
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)); \
190 if (pre != cur) loadsegment(seg,pre); }
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. */
199 err |= __get_user(gs, &sc->gs);
200 asm volatile("movl %%gs,%0" : "=r" (curgs));
202 load_gs_index(gs | 3);
208 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
209 COPY(dx); COPY(cx); COPY(ip);
210 /* Don't touch extended registers */
212 err |= __get_user(regs->cs, &sc->cs);
214 err |= __get_user(regs->ss, &sc->ss);
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 */
226 struct _fpstate_ia32 * buf;
227 err |= __get_user(tmp, &sc->fpstate);
228 buf = (struct _fpstate_ia32 *) (u64)tmp;
230 if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
232 err |= restore_i387_ia32(current, buf, 0);
238 err |= __get_user(tmp, &sc->eax);
244 asmlinkage long sys32_sigreturn(struct pt_regs regs)
246 struct sigframe *frame = (struct sigframe *)(regs.rsp - 8);
250 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
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))))
258 sigdelsetmask(&set, ~_BLOCKABLE);
259 spin_lock_irq(¤t->sigmask_lock);
260 current->blocked = set;
261 recalc_sigpending(current);
262 spin_unlock_irq(¤t->sigmask_lock);
264 if (ia32_restore_sigcontext(®s, &frame->sc, &eax))
269 signal_fault(®s,frame,"32bit sigreturn");
273 asmlinkage long sys32_rt_sigreturn(struct pt_regs regs)
275 struct rt_sigframe *frame = (struct rt_sigframe *)(regs.rsp - 4);
280 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
282 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
285 sigdelsetmask(&set, ~_BLOCKABLE);
286 spin_lock_irq(¤t->sigmask_lock);
287 current->blocked = set;
288 recalc_sigpending(current);
289 spin_unlock_irq(¤t->sigmask_lock);
291 if (ia32_restore_sigcontext(®s, &frame->uc.uc_mcontext, &eax))
294 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
296 /* It is more difficult to avoid calling this function than to
297 call it and ignore errors. */
299 mm_segment_t oldds = get_fs();
301 do_sigaltstack(&st, NULL, regs.rsp);
308 signal_fault(®s,frame,"32bit rt sigreturn");
313 * Set up a signal frame.
317 ia32_setup_sigcontext(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
318 struct pt_regs *regs, unsigned int mask)
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);
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);
348 tmp = save_i387_ia32(current, fpstate, regs, 0);
352 /* trigger finit in signal handler */
353 current->used_math = 0;
355 err |= __put_user((u32)(u64)(tmp ? fpstate : NULL), &sc->fpstate);
358 /* non-iBCS2 extensions.. */
359 err |= __put_user(mask, &sc->oldmask);
360 err |= __put_user(current->thread.cr2, &sc->cr2);
366 * Determine which stack to use..
369 get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
373 /* Default to using normal stack */
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;
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;
389 return (void *)((rsp - frame_size) & -8UL);
392 void ia32_setup_frame(int sig, struct k_sigaction *ka,
393 sigset32_t *set, struct pt_regs * regs)
395 struct sigframe *frame;
398 frame = get_sigframe(ka, regs, sizeof(*frame));
400 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
403 err |= __put_user((current->exec_domain
404 && current->exec_domain->signal_invmap
406 ? current->exec_domain->signal_invmap[sig]
412 err |= ia32_setup_sigcontext(&frame->sc, &frame->fpstate, regs, set->sig[0]);
416 if (_IA32_NSIG_WORDS > 1) {
417 err |= __copy_to_user(frame->extramask, &set->sig[1],
418 sizeof(frame->extramask));
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);
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));
438 /* Set up registers for signal handler */
439 regs->rsp = (unsigned long) frame;
440 regs->rip = (unsigned long) ka->sa.sa_handler;
442 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
443 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
445 regs->cs = __USER32_CS;
446 regs->ss = __USER32_DS;
449 regs->eflags &= ~TF_MASK;
452 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
453 current->comm, current->pid, frame, regs->rip, frame->pretcode);
460 ka->sa.sa_handler = SIG_DFL;
461 signal_fault(regs,frame,"32bit signal deliver");
464 void ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
465 sigset32_t *set, struct pt_regs * regs)
467 struct rt_sigframe *frame;
470 frame = get_sigframe(ka, regs, sizeof(*frame));
472 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
475 err |= __put_user((current->exec_domain
476 && current->exec_domain->signal_invmap
478 ? current->exec_domain->signal_invmap[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);
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,
496 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
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);
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));
515 /* Set up registers for signal handler */
516 regs->rsp = (unsigned long) frame;
517 regs->rip = (unsigned long) ka->sa.sa_handler;
519 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
520 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
522 regs->cs = __USER32_CS;
523 regs->ss = __USER32_DS;
526 regs->eflags &= ~TF_MASK;
529 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
530 current->comm, current->pid, frame, regs->rip, frame->pretcode);
537 ka->sa.sa_handler = SIG_DFL;
538 signal_fault(regs,frame,"32bit rt signal deliver");