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
11 #include <linux/sched.h>
13 #include <linux/smp.h>
14 #include <linux/kernel.h>
15 #include <linux/errno.h>
16 #include <linux/wait.h>
17 #include <linux/unistd.h>
18 #include <linux/stddef.h>
19 #include <linux/personality.h>
20 #include <linux/compat.h>
21 #include <linux/binfmts.h>
22 #include <asm/ucontext.h>
23 #include <asm/uaccess.h>
25 #include <asm/ptrace.h>
26 #include <asm/ia32_unistd.h>
27 #include <asm/user32.h>
28 #include <asm/sigcontext32.h>
29 #include <asm/proto.h>
31 #include <asm/sigframe.h>
32 #include <asm/sighandling.h>
33 #include <asm/sys_ia32.h>
35 #define FIX_EFLAGS __FIX_EFLAGS
37 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
40 bool ia32 = !is_ia32_task();
42 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
46 /* If you change siginfo_t structure, please make sure that
47 this code is fixed accordingly.
48 It should never copy any pad contained in the structure
49 to avoid security leaks, but must copy the generic
50 3 ints plus the relevant union member. */
51 put_user_ex(from->si_signo, &to->si_signo);
52 put_user_ex(from->si_errno, &to->si_errno);
53 put_user_ex((short)from->si_code, &to->si_code);
55 if (from->si_code < 0) {
56 put_user_ex(from->si_pid, &to->si_pid);
57 put_user_ex(from->si_uid, &to->si_uid);
58 put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
61 * First 32bits of unions are always present:
62 * si_pid === si_band === si_tid === si_addr(LS half)
64 put_user_ex(from->_sifields._pad[0],
65 &to->_sifields._pad[0]);
66 switch (from->si_code >> 16) {
67 case __SI_FAULT >> 16:
71 put_user_ex(from->si_utime, &to->si_utime);
72 put_user_ex(from->si_stime, &to->si_stime);
74 put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
75 put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
77 put_user_ex(from->si_status, &to->si_status);
81 put_user_ex(from->si_uid, &to->si_uid);
84 put_user_ex(from->si_fd, &to->si_fd);
86 case __SI_TIMER >> 16:
87 put_user_ex(from->si_overrun, &to->si_overrun);
88 put_user_ex(ptr_to_compat(from->si_ptr),
91 /* This is not generated by the kernel as of now. */
93 case __SI_MESGQ >> 16:
94 put_user_ex(from->si_uid, &to->si_uid);
95 put_user_ex(from->si_int, &to->si_int);
99 } put_user_catch(err);
104 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
109 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
113 get_user_ex(to->si_signo, &from->si_signo);
114 get_user_ex(to->si_errno, &from->si_errno);
115 get_user_ex(to->si_code, &from->si_code);
117 get_user_ex(to->si_pid, &from->si_pid);
118 get_user_ex(to->si_uid, &from->si_uid);
119 get_user_ex(ptr32, &from->si_ptr);
120 to->si_ptr = compat_ptr(ptr32);
121 } get_user_catch(err);
126 asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
130 current->saved_sigmask = current->blocked;
133 siginitset(&blocked, mask);
134 set_current_blocked(&blocked);
136 current->state = TASK_INTERRUPTIBLE;
139 set_restore_sigmask();
140 return -ERESTARTNOHAND;
143 asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
144 stack_ia32_t __user *uoss_ptr,
145 struct pt_regs *regs)
154 memset(&uss, 0, sizeof(stack_t));
155 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)))
159 get_user_ex(ptr, &uss_ptr->ss_sp);
160 get_user_ex(uss.ss_flags, &uss_ptr->ss_flags);
161 get_user_ex(uss.ss_size, &uss_ptr->ss_size);
162 } get_user_catch(err);
166 uss.ss_sp = compat_ptr(ptr);
170 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
172 if (ret >= 0 && uoss_ptr) {
173 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
177 put_user_ex(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp);
178 put_user_ex(uoss.ss_flags, &uoss_ptr->ss_flags);
179 put_user_ex(uoss.ss_size, &uoss_ptr->ss_size);
180 } put_user_catch(err);
189 * Do a signal return; undo the signal stack.
191 #define loadsegment_gs(v) load_gs_index(v)
192 #define loadsegment_fs(v) loadsegment(fs, v)
193 #define loadsegment_ds(v) loadsegment(ds, v)
194 #define loadsegment_es(v) loadsegment(es, v)
196 #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
197 #define set_user_seg(seg, v) loadsegment_##seg(v)
200 get_user_ex(regs->x, &sc->x); \
203 #define GET_SEG(seg) ({ \
204 unsigned short tmp; \
205 get_user_ex(tmp, &sc->seg); \
209 #define COPY_SEG_CPL3(seg) do { \
210 regs->seg = GET_SEG(seg) | 3; \
213 #define RELOAD_SEG(seg) { \
214 unsigned int pre = GET_SEG(seg); \
215 unsigned int cur = get_user_seg(seg); \
218 set_user_seg(seg, pre); \
221 static int ia32_restore_sigcontext(struct pt_regs *regs,
222 struct sigcontext_ia32 __user *sc,
225 unsigned int tmpflags, err = 0;
229 /* Always make any pending restarted system calls return -EINTR */
230 current_thread_info()->restart_block.fn = do_no_restart_syscall;
234 * Reload fs and gs if they have changed in the signal
235 * handler. This does not handle long fs/gs base changes in
236 * the handler, but does not clobber them at least in the
244 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
245 COPY(dx); COPY(cx); COPY(ip);
246 /* Don't touch extended registers */
251 get_user_ex(tmpflags, &sc->flags);
252 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
253 /* disable syscall checks */
256 get_user_ex(tmp, &sc->fpstate);
257 buf = compat_ptr(tmp);
258 err |= restore_i387_xstate_ia32(buf);
260 get_user_ex(*pax, &sc->ax);
261 } get_user_catch(err);
266 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
268 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
272 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
274 if (__get_user(set.sig[0], &frame->sc.oldmask)
275 || (_COMPAT_NSIG_WORDS > 1
276 && __copy_from_user((((char *) &set.sig) + 4),
278 sizeof(frame->extramask))))
281 sigdelsetmask(&set, ~_BLOCKABLE);
282 set_current_blocked(&set);
284 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
289 signal_fault(regs, frame, "32bit sigreturn");
293 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
295 struct rt_sigframe_ia32 __user *frame;
298 struct pt_regs tregs;
300 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
302 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
304 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
307 sigdelsetmask(&set, ~_BLOCKABLE);
308 set_current_blocked(&set);
310 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
314 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
320 signal_fault(regs, frame, "32bit rt sigreturn");
325 * Set up a signal frame.
328 static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
329 void __user *fpstate,
330 struct pt_regs *regs, unsigned int mask)
335 put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
336 put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
337 put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
338 put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
340 put_user_ex(regs->di, &sc->di);
341 put_user_ex(regs->si, &sc->si);
342 put_user_ex(regs->bp, &sc->bp);
343 put_user_ex(regs->sp, &sc->sp);
344 put_user_ex(regs->bx, &sc->bx);
345 put_user_ex(regs->dx, &sc->dx);
346 put_user_ex(regs->cx, &sc->cx);
347 put_user_ex(regs->ax, &sc->ax);
348 put_user_ex(current->thread.trap_no, &sc->trapno);
349 put_user_ex(current->thread.error_code, &sc->err);
350 put_user_ex(regs->ip, &sc->ip);
351 put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
352 put_user_ex(regs->flags, &sc->flags);
353 put_user_ex(regs->sp, &sc->sp_at_signal);
354 put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
356 put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
358 /* non-iBCS2 extensions.. */
359 put_user_ex(mask, &sc->oldmask);
360 put_user_ex(current->thread.cr2, &sc->cr2);
361 } put_user_catch(err);
367 * Determine which stack to use..
369 static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
375 /* Default to using normal stack */
378 /* This is the X/Open sanctioned signal stack switching. */
379 if (ka->sa.sa_flags & SA_ONSTACK) {
380 if (sas_ss_flags(sp) == 0)
381 sp = current->sas_ss_sp + current->sas_ss_size;
384 /* This is the legacy signal stack switching. */
385 else if ((regs->ss & 0xffff) != __USER32_DS &&
386 !(ka->sa.sa_flags & SA_RESTORER) &&
388 sp = (unsigned long) ka->sa.sa_restorer;
391 sp = sp - sig_xstate_ia32_size;
392 *fpstate = (struct _fpstate_ia32 *) sp;
393 if (save_i387_xstate_ia32(*fpstate) < 0)
394 return (void __user *) -1L;
398 /* Align the stack pointer according to the i386 ABI,
399 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
400 sp = ((sp + 4) & -16ul) - 4;
401 return (void __user *) sp;
404 int ia32_setup_frame(int sig, struct k_sigaction *ka,
405 compat_sigset_t *set, struct pt_regs *regs)
407 struct sigframe_ia32 __user *frame;
408 void __user *restorer;
410 void __user *fpstate = NULL;
412 /* copy_to_user optimizes that into a single 8 byte store */
413 static const struct {
417 } __attribute__((packed)) code = {
418 0xb858, /* popl %eax ; movl $...,%eax */
420 0x80cd, /* int $0x80 */
423 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
425 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
428 if (__put_user(sig, &frame->sig))
431 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
434 if (_COMPAT_NSIG_WORDS > 1) {
435 if (__copy_to_user(frame->extramask, &set->sig[1],
436 sizeof(frame->extramask)))
440 if (ka->sa.sa_flags & SA_RESTORER) {
441 restorer = ka->sa.sa_restorer;
443 /* Return stub is in 32bit vsyscall page */
444 if (current->mm->context.vdso)
445 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
448 restorer = &frame->retcode;
452 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
455 * These are actually not used anymore, but left because some
456 * gdb versions depend on them as a marker.
458 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
459 } put_user_catch(err);
464 /* Set up registers for signal handler */
465 regs->sp = (unsigned long) frame;
466 regs->ip = (unsigned long) ka->sa.sa_handler;
468 /* Make -mregparm=3 work */
473 loadsegment(ds, __USER32_DS);
474 loadsegment(es, __USER32_DS);
476 regs->cs = __USER32_CS;
477 regs->ss = __USER32_DS;
482 int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
483 compat_sigset_t *set, struct pt_regs *regs)
485 struct rt_sigframe_ia32 __user *frame;
486 void __user *restorer;
488 void __user *fpstate = NULL;
490 /* __copy_to_user optimizes that into a single 8 byte store */
491 static const struct {
496 } __attribute__((packed)) code = {
498 __NR_ia32_rt_sigreturn,
503 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
505 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
509 put_user_ex(sig, &frame->sig);
510 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
511 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
512 err |= copy_siginfo_to_user32(&frame->info, info);
514 /* Create the ucontext. */
516 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
518 put_user_ex(0, &frame->uc.uc_flags);
519 put_user_ex(0, &frame->uc.uc_link);
520 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
521 put_user_ex(sas_ss_flags(regs->sp),
522 &frame->uc.uc_stack.ss_flags);
523 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
524 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
526 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
528 if (ka->sa.sa_flags & SA_RESTORER)
529 restorer = ka->sa.sa_restorer;
531 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
533 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
536 * Not actually used anymore, but left because some gdb
539 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
540 } put_user_catch(err);
545 /* Set up registers for signal handler */
546 regs->sp = (unsigned long) frame;
547 regs->ip = (unsigned long) ka->sa.sa_handler;
549 /* Make -mregparm=3 work */
551 regs->dx = (unsigned long) &frame->info;
552 regs->cx = (unsigned long) &frame->uc;
554 loadsegment(ds, __USER32_DS);
555 loadsegment(es, __USER32_DS);
557 regs->cs = __USER32_CS;
558 regs->ss = __USER32_DS;