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/fpu-internal.h>
26 #include <asm/ptrace.h>
27 #include <asm/ia32_unistd.h>
28 #include <asm/user32.h>
29 #include <asm/sigcontext32.h>
30 #include <asm/proto.h>
32 #include <asm/sigframe.h>
33 #include <asm/sighandling.h>
34 #include <asm/sys_ia32.h>
36 #define FIX_EFLAGS __FIX_EFLAGS
38 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
41 bool ia32 = is_ia32_task();
43 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
47 /* If you change siginfo_t structure, please make sure that
48 this code is fixed accordingly.
49 It should never copy any pad contained in the structure
50 to avoid security leaks, but must copy the generic
51 3 ints plus the relevant union member. */
52 put_user_ex(from->si_signo, &to->si_signo);
53 put_user_ex(from->si_errno, &to->si_errno);
54 put_user_ex((short)from->si_code, &to->si_code);
56 if (from->si_code < 0) {
57 put_user_ex(from->si_pid, &to->si_pid);
58 put_user_ex(from->si_uid, &to->si_uid);
59 put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
62 * First 32bits of unions are always present:
63 * si_pid === si_band === si_tid === si_addr(LS half)
65 put_user_ex(from->_sifields._pad[0],
66 &to->_sifields._pad[0]);
67 switch (from->si_code >> 16) {
68 case __SI_FAULT >> 16:
72 put_user_ex(from->si_utime, &to->si_utime);
73 put_user_ex(from->si_stime, &to->si_stime);
75 put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
76 put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
78 put_user_ex(from->si_status, &to->si_status);
82 put_user_ex(from->si_uid, &to->si_uid);
85 put_user_ex(from->si_fd, &to->si_fd);
87 case __SI_TIMER >> 16:
88 put_user_ex(from->si_overrun, &to->si_overrun);
89 put_user_ex(ptr_to_compat(from->si_ptr),
92 /* This is not generated by the kernel as of now. */
94 case __SI_MESGQ >> 16:
95 put_user_ex(from->si_uid, &to->si_uid);
96 put_user_ex(from->si_int, &to->si_int);
100 } put_user_catch(err);
105 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
110 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
114 get_user_ex(to->si_signo, &from->si_signo);
115 get_user_ex(to->si_errno, &from->si_errno);
116 get_user_ex(to->si_code, &from->si_code);
118 get_user_ex(to->si_pid, &from->si_pid);
119 get_user_ex(to->si_uid, &from->si_uid);
120 get_user_ex(ptr32, &from->si_ptr);
121 to->si_ptr = compat_ptr(ptr32);
122 } get_user_catch(err);
127 asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
131 current->saved_sigmask = current->blocked;
134 siginitset(&blocked, mask);
135 set_current_blocked(&blocked);
137 current->state = TASK_INTERRUPTIBLE;
140 set_restore_sigmask();
141 return -ERESTARTNOHAND;
144 asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
145 stack_ia32_t __user *uoss_ptr,
146 struct pt_regs *regs)
155 memset(&uss, 0, sizeof(stack_t));
156 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)))
160 get_user_ex(ptr, &uss_ptr->ss_sp);
161 get_user_ex(uss.ss_flags, &uss_ptr->ss_flags);
162 get_user_ex(uss.ss_size, &uss_ptr->ss_size);
163 } get_user_catch(err);
167 uss.ss_sp = compat_ptr(ptr);
171 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
173 if (ret >= 0 && uoss_ptr) {
174 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
178 put_user_ex(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp);
179 put_user_ex(uoss.ss_flags, &uoss_ptr->ss_flags);
180 put_user_ex(uoss.ss_size, &uoss_ptr->ss_size);
181 } put_user_catch(err);
190 * Do a signal return; undo the signal stack.
192 #define loadsegment_gs(v) load_gs_index(v)
193 #define loadsegment_fs(v) loadsegment(fs, v)
194 #define loadsegment_ds(v) loadsegment(ds, v)
195 #define loadsegment_es(v) loadsegment(es, v)
197 #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
198 #define set_user_seg(seg, v) loadsegment_##seg(v)
201 get_user_ex(regs->x, &sc->x); \
204 #define GET_SEG(seg) ({ \
205 unsigned short tmp; \
206 get_user_ex(tmp, &sc->seg); \
210 #define COPY_SEG_CPL3(seg) do { \
211 regs->seg = GET_SEG(seg) | 3; \
214 #define RELOAD_SEG(seg) { \
215 unsigned int pre = GET_SEG(seg); \
216 unsigned int cur = get_user_seg(seg); \
219 set_user_seg(seg, pre); \
222 static int ia32_restore_sigcontext(struct pt_regs *regs,
223 struct sigcontext_ia32 __user *sc,
226 unsigned int tmpflags, err = 0;
230 /* Always make any pending restarted system calls return -EINTR */
231 current_thread_info()->restart_block.fn = do_no_restart_syscall;
235 * Reload fs and gs if they have changed in the signal
236 * handler. This does not handle long fs/gs base changes in
237 * the handler, but does not clobber them at least in the
245 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
246 COPY(dx); COPY(cx); COPY(ip);
247 /* Don't touch extended registers */
252 get_user_ex(tmpflags, &sc->flags);
253 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
254 /* disable syscall checks */
257 get_user_ex(tmp, &sc->fpstate);
258 buf = compat_ptr(tmp);
259 err |= restore_i387_xstate_ia32(buf);
261 get_user_ex(*pax, &sc->ax);
262 } get_user_catch(err);
267 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
269 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
273 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
275 if (__get_user(set.sig[0], &frame->sc.oldmask)
276 || (_COMPAT_NSIG_WORDS > 1
277 && __copy_from_user((((char *) &set.sig) + 4),
279 sizeof(frame->extramask))))
282 sigdelsetmask(&set, ~_BLOCKABLE);
283 set_current_blocked(&set);
285 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
290 signal_fault(regs, frame, "32bit sigreturn");
294 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
296 struct rt_sigframe_ia32 __user *frame;
299 struct pt_regs tregs;
301 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
303 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
305 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
308 sigdelsetmask(&set, ~_BLOCKABLE);
309 set_current_blocked(&set);
311 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
315 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
321 signal_fault(regs, frame, "32bit rt sigreturn");
326 * Set up a signal frame.
329 static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
330 void __user *fpstate,
331 struct pt_regs *regs, unsigned int mask)
336 put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
337 put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
338 put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
339 put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
341 put_user_ex(regs->di, &sc->di);
342 put_user_ex(regs->si, &sc->si);
343 put_user_ex(regs->bp, &sc->bp);
344 put_user_ex(regs->sp, &sc->sp);
345 put_user_ex(regs->bx, &sc->bx);
346 put_user_ex(regs->dx, &sc->dx);
347 put_user_ex(regs->cx, &sc->cx);
348 put_user_ex(regs->ax, &sc->ax);
349 put_user_ex(current->thread.trap_nr, &sc->trapno);
350 put_user_ex(current->thread.error_code, &sc->err);
351 put_user_ex(regs->ip, &sc->ip);
352 put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
353 put_user_ex(regs->flags, &sc->flags);
354 put_user_ex(regs->sp, &sc->sp_at_signal);
355 put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
357 put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
359 /* non-iBCS2 extensions.. */
360 put_user_ex(mask, &sc->oldmask);
361 put_user_ex(current->thread.cr2, &sc->cr2);
362 } put_user_catch(err);
368 * Determine which stack to use..
370 static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
376 /* Default to using normal stack */
379 /* This is the X/Open sanctioned signal stack switching. */
380 if (ka->sa.sa_flags & SA_ONSTACK) {
381 if (sas_ss_flags(sp) == 0)
382 sp = current->sas_ss_sp + current->sas_ss_size;
385 /* This is the legacy signal stack switching. */
386 else if ((regs->ss & 0xffff) != __USER32_DS &&
387 !(ka->sa.sa_flags & SA_RESTORER) &&
389 sp = (unsigned long) ka->sa.sa_restorer;
392 sp = sp - sig_xstate_ia32_size;
393 *fpstate = (struct _fpstate_ia32 *) sp;
394 if (save_i387_xstate_ia32(*fpstate) < 0)
395 return (void __user *) -1L;
399 /* Align the stack pointer according to the i386 ABI,
400 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
401 sp = ((sp + 4) & -16ul) - 4;
402 return (void __user *) sp;
405 int ia32_setup_frame(int sig, struct k_sigaction *ka,
406 compat_sigset_t *set, struct pt_regs *regs)
408 struct sigframe_ia32 __user *frame;
409 void __user *restorer;
411 void __user *fpstate = NULL;
413 /* copy_to_user optimizes that into a single 8 byte store */
414 static const struct {
418 } __attribute__((packed)) code = {
419 0xb858, /* popl %eax ; movl $...,%eax */
421 0x80cd, /* int $0x80 */
424 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
426 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
429 if (__put_user(sig, &frame->sig))
432 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
435 if (_COMPAT_NSIG_WORDS > 1) {
436 if (__copy_to_user(frame->extramask, &set->sig[1],
437 sizeof(frame->extramask)))
441 if (ka->sa.sa_flags & SA_RESTORER) {
442 restorer = ka->sa.sa_restorer;
444 /* Return stub is in 32bit vsyscall page */
445 if (current->mm->context.vdso)
446 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
449 restorer = &frame->retcode;
453 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
456 * These are actually not used anymore, but left because some
457 * gdb versions depend on them as a marker.
459 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
460 } put_user_catch(err);
465 /* Set up registers for signal handler */
466 regs->sp = (unsigned long) frame;
467 regs->ip = (unsigned long) ka->sa.sa_handler;
469 /* Make -mregparm=3 work */
474 loadsegment(ds, __USER32_DS);
475 loadsegment(es, __USER32_DS);
477 regs->cs = __USER32_CS;
478 regs->ss = __USER32_DS;
483 int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
484 compat_sigset_t *set, struct pt_regs *regs)
486 struct rt_sigframe_ia32 __user *frame;
487 void __user *restorer;
489 void __user *fpstate = NULL;
491 /* __copy_to_user optimizes that into a single 8 byte store */
492 static const struct {
497 } __attribute__((packed)) code = {
499 __NR_ia32_rt_sigreturn,
504 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
506 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
510 put_user_ex(sig, &frame->sig);
511 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
512 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
513 err |= copy_siginfo_to_user32(&frame->info, info);
515 /* Create the ucontext. */
517 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
519 put_user_ex(0, &frame->uc.uc_flags);
520 put_user_ex(0, &frame->uc.uc_link);
521 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
522 put_user_ex(sas_ss_flags(regs->sp),
523 &frame->uc.uc_stack.ss_flags);
524 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
525 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
527 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
529 if (ka->sa.sa_flags & SA_RESTORER)
530 restorer = ka->sa.sa_restorer;
532 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
534 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
537 * Not actually used anymore, but left because some gdb
540 put_user_ex(*((u64 *)&code), (u64 *)frame->retcode);
541 } put_user_catch(err);
546 /* Set up registers for signal handler */
547 regs->sp = (unsigned long) frame;
548 regs->ip = (unsigned long) ka->sa.sa_handler;
550 /* Make -mregparm=3 work */
552 regs->dx = (unsigned long) &frame->info;
553 regs->cx = (unsigned long) &frame->uc;
555 loadsegment(ds, __USER32_DS);
556 loadsegment(es, __USER32_DS);
558 regs->cs = __USER32_CS;
559 regs->ss = __USER32_DS;