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>
37 #define FIX_EFLAGS __FIX_EFLAGS
39 int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
42 bool ia32 = test_thread_flag(TIF_IA32);
44 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
48 /* If you change siginfo_t structure, please make sure that
49 this code is fixed accordingly.
50 It should never copy any pad contained in the structure
51 to avoid security leaks, but must copy the generic
52 3 ints plus the relevant union member. */
53 put_user_ex(from->si_signo, &to->si_signo);
54 put_user_ex(from->si_errno, &to->si_errno);
55 put_user_ex((short)from->si_code, &to->si_code);
57 if (from->si_code < 0) {
58 put_user_ex(from->si_pid, &to->si_pid);
59 put_user_ex(from->si_uid, &to->si_uid);
60 put_user_ex(ptr_to_compat(from->si_ptr), &to->si_ptr);
63 * First 32bits of unions are always present:
64 * si_pid === si_band === si_tid === si_addr(LS half)
66 put_user_ex(from->_sifields._pad[0],
67 &to->_sifields._pad[0]);
68 switch (from->si_code >> 16) {
69 case __SI_FAULT >> 16:
72 put_user_ex(from->si_syscall, &to->si_syscall);
73 put_user_ex(from->si_arch, &to->si_arch);
77 put_user_ex(from->si_utime, &to->si_utime);
78 put_user_ex(from->si_stime, &to->si_stime);
80 put_user_ex(from->si_utime, &to->_sifields._sigchld_x32._utime);
81 put_user_ex(from->si_stime, &to->_sifields._sigchld_x32._stime);
83 put_user_ex(from->si_status, &to->si_status);
87 put_user_ex(from->si_uid, &to->si_uid);
90 put_user_ex(from->si_fd, &to->si_fd);
92 case __SI_TIMER >> 16:
93 put_user_ex(from->si_overrun, &to->si_overrun);
94 put_user_ex(ptr_to_compat(from->si_ptr),
97 /* This is not generated by the kernel as of now. */
99 case __SI_MESGQ >> 16:
100 put_user_ex(from->si_uid, &to->si_uid);
101 put_user_ex(from->si_int, &to->si_int);
105 } put_user_catch(err);
110 int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
115 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
119 get_user_ex(to->si_signo, &from->si_signo);
120 get_user_ex(to->si_errno, &from->si_errno);
121 get_user_ex(to->si_code, &from->si_code);
123 get_user_ex(to->si_pid, &from->si_pid);
124 get_user_ex(to->si_uid, &from->si_uid);
125 get_user_ex(ptr32, &from->si_ptr);
126 to->si_ptr = compat_ptr(ptr32);
127 } get_user_catch(err);
132 asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
135 siginitset(&blocked, mask);
136 return sigsuspend(&blocked);
139 asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
140 stack_ia32_t __user *uoss_ptr,
141 struct pt_regs *regs)
150 memset(&uss, 0, sizeof(stack_t));
151 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)))
155 get_user_ex(ptr, &uss_ptr->ss_sp);
156 get_user_ex(uss.ss_flags, &uss_ptr->ss_flags);
157 get_user_ex(uss.ss_size, &uss_ptr->ss_size);
158 } get_user_catch(err);
162 uss.ss_sp = compat_ptr(ptr);
166 ret = do_sigaltstack((stack_t __force __user *) (uss_ptr ? &uss : NULL),
167 (stack_t __force __user *) &uoss, regs->sp);
169 if (ret >= 0 && uoss_ptr) {
170 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)))
174 put_user_ex(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp);
175 put_user_ex(uoss.ss_flags, &uoss_ptr->ss_flags);
176 put_user_ex(uoss.ss_size, &uoss_ptr->ss_size);
177 } put_user_catch(err);
186 * Do a signal return; undo the signal stack.
188 #define loadsegment_gs(v) load_gs_index(v)
189 #define loadsegment_fs(v) loadsegment(fs, v)
190 #define loadsegment_ds(v) loadsegment(ds, v)
191 #define loadsegment_es(v) loadsegment(es, v)
193 #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
194 #define set_user_seg(seg, v) loadsegment_##seg(v)
197 get_user_ex(regs->x, &sc->x); \
200 #define GET_SEG(seg) ({ \
201 unsigned short tmp; \
202 get_user_ex(tmp, &sc->seg); \
206 #define COPY_SEG_CPL3(seg) do { \
207 regs->seg = GET_SEG(seg) | 3; \
210 #define RELOAD_SEG(seg) { \
211 unsigned int pre = GET_SEG(seg); \
212 unsigned int cur = get_user_seg(seg); \
215 set_user_seg(seg, pre); \
218 static int ia32_restore_sigcontext(struct pt_regs *regs,
219 struct sigcontext_ia32 __user *sc,
222 unsigned int tmpflags, err = 0;
226 /* Always make any pending restarted system calls return -EINTR */
227 current_thread_info()->restart_block.fn = do_no_restart_syscall;
231 * Reload fs and gs if they have changed in the signal
232 * handler. This does not handle long fs/gs base changes in
233 * the handler, but does not clobber them at least in the
241 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
242 COPY(dx); COPY(cx); COPY(ip);
243 /* Don't touch extended registers */
248 get_user_ex(tmpflags, &sc->flags);
249 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
250 /* disable syscall checks */
253 get_user_ex(tmp, &sc->fpstate);
254 buf = compat_ptr(tmp);
256 get_user_ex(*pax, &sc->ax);
257 } get_user_catch(err);
259 err |= restore_xstate_sig(buf, 1);
264 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
266 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
270 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
272 if (__get_user(set.sig[0], &frame->sc.oldmask)
273 || (_COMPAT_NSIG_WORDS > 1
274 && __copy_from_user((((char *) &set.sig) + 4),
276 sizeof(frame->extramask))))
279 set_current_blocked(&set);
281 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
286 signal_fault(regs, frame, "32bit sigreturn");
290 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
292 struct rt_sigframe_ia32 __user *frame;
295 struct pt_regs tregs;
297 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
299 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
301 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
304 set_current_blocked(&set);
306 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
310 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
316 signal_fault(regs, frame, "32bit rt sigreturn");
321 * Set up a signal frame.
324 static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
325 void __user *fpstate,
326 struct pt_regs *regs, unsigned int mask)
331 put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
332 put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
333 put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
334 put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
336 put_user_ex(regs->di, &sc->di);
337 put_user_ex(regs->si, &sc->si);
338 put_user_ex(regs->bp, &sc->bp);
339 put_user_ex(regs->sp, &sc->sp);
340 put_user_ex(regs->bx, &sc->bx);
341 put_user_ex(regs->dx, &sc->dx);
342 put_user_ex(regs->cx, &sc->cx);
343 put_user_ex(regs->ax, &sc->ax);
344 put_user_ex(current->thread.trap_nr, &sc->trapno);
345 put_user_ex(current->thread.error_code, &sc->err);
346 put_user_ex(regs->ip, &sc->ip);
347 put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
348 put_user_ex(regs->flags, &sc->flags);
349 put_user_ex(regs->sp, &sc->sp_at_signal);
350 put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
352 put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
354 /* non-iBCS2 extensions.. */
355 put_user_ex(mask, &sc->oldmask);
356 put_user_ex(current->thread.cr2, &sc->cr2);
357 } put_user_catch(err);
363 * Determine which stack to use..
365 static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
367 void __user **fpstate)
371 /* Default to using normal stack */
374 /* This is the X/Open sanctioned signal stack switching. */
375 if (ka->sa.sa_flags & SA_ONSTACK) {
376 if (sas_ss_flags(sp) == 0)
377 sp = current->sas_ss_sp + current->sas_ss_size;
380 /* This is the legacy signal stack switching. */
381 else if ((regs->ss & 0xffff) != __USER32_DS &&
382 !(ka->sa.sa_flags & SA_RESTORER) &&
384 sp = (unsigned long) ka->sa.sa_restorer;
387 unsigned long fx_aligned, math_size;
389 sp = alloc_mathframe(sp, 1, &fx_aligned, &math_size);
390 *fpstate = (struct _fpstate_ia32 __user *) sp;
391 if (save_xstate_sig(*fpstate, (void __user *)fx_aligned,
393 return (void __user *) -1L;
397 /* Align the stack pointer according to the i386 ABI,
398 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
399 sp = ((sp + 4) & -16ul) - 4;
400 return (void __user *) sp;
403 int ia32_setup_frame(int sig, struct k_sigaction *ka,
404 compat_sigset_t *set, struct pt_regs *regs)
406 struct sigframe_ia32 __user *frame;
407 void __user *restorer;
409 void __user *fpstate = NULL;
411 /* copy_to_user optimizes that into a single 8 byte store */
412 static const struct {
416 } __attribute__((packed)) code = {
417 0xb858, /* popl %eax ; movl $...,%eax */
419 0x80cd, /* int $0x80 */
422 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
424 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
427 if (__put_user(sig, &frame->sig))
430 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
433 if (_COMPAT_NSIG_WORDS > 1) {
434 if (__copy_to_user(frame->extramask, &set->sig[1],
435 sizeof(frame->extramask)))
439 if (ka->sa.sa_flags & SA_RESTORER) {
440 restorer = ka->sa.sa_restorer;
442 /* Return stub is in 32bit vsyscall page */
443 if (current->mm->context.vdso)
444 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
447 restorer = &frame->retcode;
451 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
454 * These are actually not used anymore, but left because some
455 * gdb versions depend on them as a marker.
457 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
458 } put_user_catch(err);
463 /* Set up registers for signal handler */
464 regs->sp = (unsigned long) frame;
465 regs->ip = (unsigned long) ka->sa.sa_handler;
467 /* Make -mregparm=3 work */
472 loadsegment(ds, __USER32_DS);
473 loadsegment(es, __USER32_DS);
475 regs->cs = __USER32_CS;
476 regs->ss = __USER32_DS;
481 int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
482 compat_sigset_t *set, struct pt_regs *regs)
484 struct rt_sigframe_ia32 __user *frame;
485 void __user *restorer;
487 void __user *fpstate = NULL;
489 /* __copy_to_user optimizes that into a single 8 byte store */
490 static const struct {
495 } __attribute__((packed)) code = {
497 __NR_ia32_rt_sigreturn,
502 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
504 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
508 put_user_ex(sig, &frame->sig);
509 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
510 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
512 /* Create the ucontext. */
514 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
516 put_user_ex(0, &frame->uc.uc_flags);
517 put_user_ex(0, &frame->uc.uc_link);
518 put_user_ex(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
519 put_user_ex(sas_ss_flags(regs->sp),
520 &frame->uc.uc_stack.ss_flags);
521 put_user_ex(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
523 if (ka->sa.sa_flags & SA_RESTORER)
524 restorer = ka->sa.sa_restorer;
526 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
528 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
531 * Not actually used anymore, but left because some gdb
534 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
535 } put_user_catch(err);
537 err |= copy_siginfo_to_user32(&frame->info, info);
538 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
540 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
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;