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);
140 * Do a signal return; undo the signal stack.
142 #define loadsegment_gs(v) load_gs_index(v)
143 #define loadsegment_fs(v) loadsegment(fs, v)
144 #define loadsegment_ds(v) loadsegment(ds, v)
145 #define loadsegment_es(v) loadsegment(es, v)
147 #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
148 #define set_user_seg(seg, v) loadsegment_##seg(v)
151 get_user_ex(regs->x, &sc->x); \
154 #define GET_SEG(seg) ({ \
155 unsigned short tmp; \
156 get_user_ex(tmp, &sc->seg); \
160 #define COPY_SEG_CPL3(seg) do { \
161 regs->seg = GET_SEG(seg) | 3; \
164 #define RELOAD_SEG(seg) { \
165 unsigned int pre = GET_SEG(seg); \
166 unsigned int cur = get_user_seg(seg); \
169 set_user_seg(seg, pre); \
172 static int ia32_restore_sigcontext(struct pt_regs *regs,
173 struct sigcontext_ia32 __user *sc,
176 unsigned int tmpflags, err = 0;
180 /* Always make any pending restarted system calls return -EINTR */
181 current_thread_info()->restart_block.fn = do_no_restart_syscall;
185 * Reload fs and gs if they have changed in the signal
186 * handler. This does not handle long fs/gs base changes in
187 * the handler, but does not clobber them at least in the
195 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
196 COPY(dx); COPY(cx); COPY(ip);
197 /* Don't touch extended registers */
202 get_user_ex(tmpflags, &sc->flags);
203 regs->flags = (regs->flags & ~FIX_EFLAGS) | (tmpflags & FIX_EFLAGS);
204 /* disable syscall checks */
207 get_user_ex(tmp, &sc->fpstate);
208 buf = compat_ptr(tmp);
210 get_user_ex(*pax, &sc->ax);
211 } get_user_catch(err);
213 err |= restore_xstate_sig(buf, 1);
218 asmlinkage long sys32_sigreturn(struct pt_regs *regs)
220 struct sigframe_ia32 __user *frame = (struct sigframe_ia32 __user *)(regs->sp-8);
224 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
226 if (__get_user(set.sig[0], &frame->sc.oldmask)
227 || (_COMPAT_NSIG_WORDS > 1
228 && __copy_from_user((((char *) &set.sig) + 4),
230 sizeof(frame->extramask))))
233 set_current_blocked(&set);
235 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
240 signal_fault(regs, frame, "32bit sigreturn");
244 asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
246 struct rt_sigframe_ia32 __user *frame;
250 frame = (struct rt_sigframe_ia32 __user *)(regs->sp - 4);
252 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
254 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
257 set_current_blocked(&set);
259 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
262 if (compat_restore_altstack(&frame->uc.uc_stack))
268 signal_fault(regs, frame, "32bit rt sigreturn");
273 * Set up a signal frame.
276 static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
277 void __user *fpstate,
278 struct pt_regs *regs, unsigned int mask)
283 put_user_ex(get_user_seg(gs), (unsigned int __user *)&sc->gs);
284 put_user_ex(get_user_seg(fs), (unsigned int __user *)&sc->fs);
285 put_user_ex(get_user_seg(ds), (unsigned int __user *)&sc->ds);
286 put_user_ex(get_user_seg(es), (unsigned int __user *)&sc->es);
288 put_user_ex(regs->di, &sc->di);
289 put_user_ex(regs->si, &sc->si);
290 put_user_ex(regs->bp, &sc->bp);
291 put_user_ex(regs->sp, &sc->sp);
292 put_user_ex(regs->bx, &sc->bx);
293 put_user_ex(regs->dx, &sc->dx);
294 put_user_ex(regs->cx, &sc->cx);
295 put_user_ex(regs->ax, &sc->ax);
296 put_user_ex(current->thread.trap_nr, &sc->trapno);
297 put_user_ex(current->thread.error_code, &sc->err);
298 put_user_ex(regs->ip, &sc->ip);
299 put_user_ex(regs->cs, (unsigned int __user *)&sc->cs);
300 put_user_ex(regs->flags, &sc->flags);
301 put_user_ex(regs->sp, &sc->sp_at_signal);
302 put_user_ex(regs->ss, (unsigned int __user *)&sc->ss);
304 put_user_ex(ptr_to_compat(fpstate), &sc->fpstate);
306 /* non-iBCS2 extensions.. */
307 put_user_ex(mask, &sc->oldmask);
308 put_user_ex(current->thread.cr2, &sc->cr2);
309 } put_user_catch(err);
315 * Determine which stack to use..
317 static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
319 void __user **fpstate)
323 /* Default to using normal stack */
326 /* This is the X/Open sanctioned signal stack switching. */
327 if (ka->sa.sa_flags & SA_ONSTACK) {
328 if (sas_ss_flags(sp) == 0)
329 sp = current->sas_ss_sp + current->sas_ss_size;
332 /* This is the legacy signal stack switching. */
333 else if ((regs->ss & 0xffff) != __USER32_DS &&
334 !(ka->sa.sa_flags & SA_RESTORER) &&
336 sp = (unsigned long) ka->sa.sa_restorer;
339 unsigned long fx_aligned, math_size;
341 sp = alloc_mathframe(sp, 1, &fx_aligned, &math_size);
342 *fpstate = (struct _fpstate_ia32 __user *) sp;
343 if (save_xstate_sig(*fpstate, (void __user *)fx_aligned,
345 return (void __user *) -1L;
349 /* Align the stack pointer according to the i386 ABI,
350 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
351 sp = ((sp + 4) & -16ul) - 4;
352 return (void __user *) sp;
355 int ia32_setup_frame(int sig, struct k_sigaction *ka,
356 compat_sigset_t *set, struct pt_regs *regs)
358 struct sigframe_ia32 __user *frame;
359 void __user *restorer;
361 void __user *fpstate = NULL;
363 /* copy_to_user optimizes that into a single 8 byte store */
364 static const struct {
368 } __attribute__((packed)) code = {
369 0xb858, /* popl %eax ; movl $...,%eax */
371 0x80cd, /* int $0x80 */
374 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
376 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
379 if (__put_user(sig, &frame->sig))
382 if (ia32_setup_sigcontext(&frame->sc, fpstate, regs, set->sig[0]))
385 if (_COMPAT_NSIG_WORDS > 1) {
386 if (__copy_to_user(frame->extramask, &set->sig[1],
387 sizeof(frame->extramask)))
391 if (ka->sa.sa_flags & SA_RESTORER) {
392 restorer = ka->sa.sa_restorer;
394 /* Return stub is in 32bit vsyscall page */
395 if (current->mm->context.vdso)
396 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
399 restorer = &frame->retcode;
403 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
406 * These are actually not used anymore, but left because some
407 * gdb versions depend on them as a marker.
409 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
410 } put_user_catch(err);
415 /* Set up registers for signal handler */
416 regs->sp = (unsigned long) frame;
417 regs->ip = (unsigned long) ka->sa.sa_handler;
419 /* Make -mregparm=3 work */
424 loadsegment(ds, __USER32_DS);
425 loadsegment(es, __USER32_DS);
427 regs->cs = __USER32_CS;
428 regs->ss = __USER32_DS;
433 int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
434 compat_sigset_t *set, struct pt_regs *regs)
436 struct rt_sigframe_ia32 __user *frame;
437 void __user *restorer;
439 void __user *fpstate = NULL;
441 /* __copy_to_user optimizes that into a single 8 byte store */
442 static const struct {
447 } __attribute__((packed)) code = {
449 __NR_ia32_rt_sigreturn,
454 frame = get_sigframe(ka, regs, sizeof(*frame), &fpstate);
456 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
460 put_user_ex(sig, &frame->sig);
461 put_user_ex(ptr_to_compat(&frame->info), &frame->pinfo);
462 put_user_ex(ptr_to_compat(&frame->uc), &frame->puc);
464 /* Create the ucontext. */
466 put_user_ex(UC_FP_XSTATE, &frame->uc.uc_flags);
468 put_user_ex(0, &frame->uc.uc_flags);
469 put_user_ex(0, &frame->uc.uc_link);
470 err |= __compat_save_altstack(&frame->uc.uc_stack, regs->sp);
472 if (ka->sa.sa_flags & SA_RESTORER)
473 restorer = ka->sa.sa_restorer;
475 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
477 put_user_ex(ptr_to_compat(restorer), &frame->pretcode);
480 * Not actually used anymore, but left because some gdb
483 put_user_ex(*((u64 *)&code), (u64 __user *)frame->retcode);
484 } put_user_catch(err);
486 err |= copy_siginfo_to_user32(&frame->info, info);
487 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, fpstate,
489 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
494 /* Set up registers for signal handler */
495 regs->sp = (unsigned long) frame;
496 regs->ip = (unsigned long) ka->sa.sa_handler;
498 /* Make -mregparm=3 work */
500 regs->dx = (unsigned long) &frame->info;
501 regs->cx = (unsigned long) &frame->uc;
503 loadsegment(ds, __USER32_DS);
504 loadsegment(es, __USER32_DS);
506 regs->cs = __USER32_CS;
507 regs->ss = __USER32_DS;