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
= test_thread_flag(TIF_IA32
);
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:
71 put_user_ex(from
->si_syscall
, &to
->si_syscall
);
72 put_user_ex(from
->si_arch
, &to
->si_arch
);
76 put_user_ex(from
->si_utime
, &to
->si_utime
);
77 put_user_ex(from
->si_stime
, &to
->si_stime
);
79 put_user_ex(from
->si_utime
, &to
->_sifields
._sigchld_x32
._utime
);
80 put_user_ex(from
->si_stime
, &to
->_sifields
._sigchld_x32
._stime
);
82 put_user_ex(from
->si_status
, &to
->si_status
);
86 put_user_ex(from
->si_uid
, &to
->si_uid
);
89 put_user_ex(from
->si_fd
, &to
->si_fd
);
91 case __SI_TIMER
>> 16:
92 put_user_ex(from
->si_overrun
, &to
->si_overrun
);
93 put_user_ex(ptr_to_compat(from
->si_ptr
),
96 /* This is not generated by the kernel as of now. */
98 case __SI_MESGQ
>> 16:
99 put_user_ex(from
->si_uid
, &to
->si_uid
);
100 put_user_ex(from
->si_int
, &to
->si_int
);
104 } put_user_catch(err
);
109 int copy_siginfo_from_user32(siginfo_t
*to
, compat_siginfo_t __user
*from
)
114 if (!access_ok(VERIFY_READ
, from
, sizeof(compat_siginfo_t
)))
118 get_user_ex(to
->si_signo
, &from
->si_signo
);
119 get_user_ex(to
->si_errno
, &from
->si_errno
);
120 get_user_ex(to
->si_code
, &from
->si_code
);
122 get_user_ex(to
->si_pid
, &from
->si_pid
);
123 get_user_ex(to
->si_uid
, &from
->si_uid
);
124 get_user_ex(ptr32
, &from
->si_ptr
);
125 to
->si_ptr
= compat_ptr(ptr32
);
126 } get_user_catch(err
);
131 asmlinkage
long sys32_sigsuspend(int history0
, int history1
, old_sigset_t mask
)
134 siginitset(&blocked
, mask
);
135 return sigsuspend(&blocked
);
138 asmlinkage
long sys32_sigaltstack(const stack_ia32_t __user
*uss_ptr
,
139 stack_ia32_t __user
*uoss_ptr
,
140 struct pt_regs
*regs
)
149 memset(&uss
, 0, sizeof(stack_t
));
150 if (!access_ok(VERIFY_READ
, uss_ptr
, sizeof(stack_ia32_t
)))
154 get_user_ex(ptr
, &uss_ptr
->ss_sp
);
155 get_user_ex(uss
.ss_flags
, &uss_ptr
->ss_flags
);
156 get_user_ex(uss
.ss_size
, &uss_ptr
->ss_size
);
157 } get_user_catch(err
);
161 uss
.ss_sp
= compat_ptr(ptr
);
165 ret
= do_sigaltstack(uss_ptr
? &uss
: NULL
, &uoss
, regs
->sp
);
167 if (ret
>= 0 && uoss_ptr
) {
168 if (!access_ok(VERIFY_WRITE
, uoss_ptr
, sizeof(stack_ia32_t
)))
172 put_user_ex(ptr_to_compat(uoss
.ss_sp
), &uoss_ptr
->ss_sp
);
173 put_user_ex(uoss
.ss_flags
, &uoss_ptr
->ss_flags
);
174 put_user_ex(uoss
.ss_size
, &uoss_ptr
->ss_size
);
175 } put_user_catch(err
);
184 * Do a signal return; undo the signal stack.
186 #define loadsegment_gs(v) load_gs_index(v)
187 #define loadsegment_fs(v) loadsegment(fs, v)
188 #define loadsegment_ds(v) loadsegment(ds, v)
189 #define loadsegment_es(v) loadsegment(es, v)
191 #define get_user_seg(seg) ({ unsigned int v; savesegment(seg, v); v; })
192 #define set_user_seg(seg, v) loadsegment_##seg(v)
195 get_user_ex(regs->x, &sc->x); \
198 #define GET_SEG(seg) ({ \
199 unsigned short tmp; \
200 get_user_ex(tmp, &sc->seg); \
204 #define COPY_SEG_CPL3(seg) do { \
205 regs->seg = GET_SEG(seg) | 3; \
208 #define RELOAD_SEG(seg) { \
209 unsigned int pre = GET_SEG(seg); \
210 unsigned int cur = get_user_seg(seg); \
213 set_user_seg(seg, pre); \
216 static int ia32_restore_sigcontext(struct pt_regs
*regs
,
217 struct sigcontext_ia32 __user
*sc
,
220 unsigned int tmpflags
, err
= 0;
224 /* Always make any pending restarted system calls return -EINTR */
225 current_thread_info()->restart_block
.fn
= do_no_restart_syscall
;
229 * Reload fs and gs if they have changed in the signal
230 * handler. This does not handle long fs/gs base changes in
231 * the handler, but does not clobber them at least in the
239 COPY(di
); COPY(si
); COPY(bp
); COPY(sp
); COPY(bx
);
240 COPY(dx
); COPY(cx
); COPY(ip
);
241 /* Don't touch extended registers */
246 get_user_ex(tmpflags
, &sc
->flags
);
247 regs
->flags
= (regs
->flags
& ~FIX_EFLAGS
) | (tmpflags
& FIX_EFLAGS
);
248 /* disable syscall checks */
251 get_user_ex(tmp
, &sc
->fpstate
);
252 buf
= compat_ptr(tmp
);
253 err
|= restore_i387_xstate_ia32(buf
);
255 get_user_ex(*pax
, &sc
->ax
);
256 } get_user_catch(err
);
261 asmlinkage
long sys32_sigreturn(struct pt_regs
*regs
)
263 struct sigframe_ia32 __user
*frame
= (struct sigframe_ia32 __user
*)(regs
->sp
-8);
267 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
269 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
)
270 || (_COMPAT_NSIG_WORDS
> 1
271 && __copy_from_user((((char *) &set
.sig
) + 4),
273 sizeof(frame
->extramask
))))
276 set_current_blocked(&set
);
278 if (ia32_restore_sigcontext(regs
, &frame
->sc
, &ax
))
283 signal_fault(regs
, frame
, "32bit sigreturn");
287 asmlinkage
long sys32_rt_sigreturn(struct pt_regs
*regs
)
289 struct rt_sigframe_ia32 __user
*frame
;
292 struct pt_regs tregs
;
294 frame
= (struct rt_sigframe_ia32 __user
*)(regs
->sp
- 4);
296 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
298 if (__copy_from_user(&set
, &frame
->uc
.uc_sigmask
, sizeof(set
)))
301 set_current_blocked(&set
);
303 if (ia32_restore_sigcontext(regs
, &frame
->uc
.uc_mcontext
, &ax
))
307 if (sys32_sigaltstack(&frame
->uc
.uc_stack
, NULL
, &tregs
) == -EFAULT
)
313 signal_fault(regs
, frame
, "32bit rt sigreturn");
318 * Set up a signal frame.
321 static int ia32_setup_sigcontext(struct sigcontext_ia32 __user
*sc
,
322 void __user
*fpstate
,
323 struct pt_regs
*regs
, unsigned int mask
)
328 put_user_ex(get_user_seg(gs
), (unsigned int __user
*)&sc
->gs
);
329 put_user_ex(get_user_seg(fs
), (unsigned int __user
*)&sc
->fs
);
330 put_user_ex(get_user_seg(ds
), (unsigned int __user
*)&sc
->ds
);
331 put_user_ex(get_user_seg(es
), (unsigned int __user
*)&sc
->es
);
333 put_user_ex(regs
->di
, &sc
->di
);
334 put_user_ex(regs
->si
, &sc
->si
);
335 put_user_ex(regs
->bp
, &sc
->bp
);
336 put_user_ex(regs
->sp
, &sc
->sp
);
337 put_user_ex(regs
->bx
, &sc
->bx
);
338 put_user_ex(regs
->dx
, &sc
->dx
);
339 put_user_ex(regs
->cx
, &sc
->cx
);
340 put_user_ex(regs
->ax
, &sc
->ax
);
341 put_user_ex(current
->thread
.trap_nr
, &sc
->trapno
);
342 put_user_ex(current
->thread
.error_code
, &sc
->err
);
343 put_user_ex(regs
->ip
, &sc
->ip
);
344 put_user_ex(regs
->cs
, (unsigned int __user
*)&sc
->cs
);
345 put_user_ex(regs
->flags
, &sc
->flags
);
346 put_user_ex(regs
->sp
, &sc
->sp_at_signal
);
347 put_user_ex(regs
->ss
, (unsigned int __user
*)&sc
->ss
);
349 put_user_ex(ptr_to_compat(fpstate
), &sc
->fpstate
);
351 /* non-iBCS2 extensions.. */
352 put_user_ex(mask
, &sc
->oldmask
);
353 put_user_ex(current
->thread
.cr2
, &sc
->cr2
);
354 } put_user_catch(err
);
360 * Determine which stack to use..
362 static void __user
*get_sigframe(struct k_sigaction
*ka
, struct pt_regs
*regs
,
368 /* Default to using normal stack */
371 /* This is the X/Open sanctioned signal stack switching. */
372 if (ka
->sa
.sa_flags
& SA_ONSTACK
) {
373 if (sas_ss_flags(sp
) == 0)
374 sp
= current
->sas_ss_sp
+ current
->sas_ss_size
;
377 /* This is the legacy signal stack switching. */
378 else if ((regs
->ss
& 0xffff) != __USER32_DS
&&
379 !(ka
->sa
.sa_flags
& SA_RESTORER
) &&
381 sp
= (unsigned long) ka
->sa
.sa_restorer
;
384 sp
= sp
- sig_xstate_ia32_size
;
385 *fpstate
= (struct _fpstate_ia32
*) sp
;
386 if (save_i387_xstate_ia32(*fpstate
) < 0)
387 return (void __user
*) -1L;
391 /* Align the stack pointer according to the i386 ABI,
392 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
393 sp
= ((sp
+ 4) & -16ul) - 4;
394 return (void __user
*) sp
;
397 int ia32_setup_frame(int sig
, struct k_sigaction
*ka
,
398 compat_sigset_t
*set
, struct pt_regs
*regs
)
400 struct sigframe_ia32 __user
*frame
;
401 void __user
*restorer
;
403 void __user
*fpstate
= NULL
;
405 /* copy_to_user optimizes that into a single 8 byte store */
406 static const struct {
410 } __attribute__((packed
)) code
= {
411 0xb858, /* popl %eax ; movl $...,%eax */
413 0x80cd, /* int $0x80 */
416 frame
= get_sigframe(ka
, regs
, sizeof(*frame
), &fpstate
);
418 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
421 if (__put_user(sig
, &frame
->sig
))
424 if (ia32_setup_sigcontext(&frame
->sc
, fpstate
, regs
, set
->sig
[0]))
427 if (_COMPAT_NSIG_WORDS
> 1) {
428 if (__copy_to_user(frame
->extramask
, &set
->sig
[1],
429 sizeof(frame
->extramask
)))
433 if (ka
->sa
.sa_flags
& SA_RESTORER
) {
434 restorer
= ka
->sa
.sa_restorer
;
436 /* Return stub is in 32bit vsyscall page */
437 if (current
->mm
->context
.vdso
)
438 restorer
= VDSO32_SYMBOL(current
->mm
->context
.vdso
,
441 restorer
= &frame
->retcode
;
445 put_user_ex(ptr_to_compat(restorer
), &frame
->pretcode
);
448 * These are actually not used anymore, but left because some
449 * gdb versions depend on them as a marker.
451 put_user_ex(*((u64
*)&code
), (u64
*)frame
->retcode
);
452 } put_user_catch(err
);
457 /* Set up registers for signal handler */
458 regs
->sp
= (unsigned long) frame
;
459 regs
->ip
= (unsigned long) ka
->sa
.sa_handler
;
461 /* Make -mregparm=3 work */
466 loadsegment(ds
, __USER32_DS
);
467 loadsegment(es
, __USER32_DS
);
469 regs
->cs
= __USER32_CS
;
470 regs
->ss
= __USER32_DS
;
475 int ia32_setup_rt_frame(int sig
, struct k_sigaction
*ka
, siginfo_t
*info
,
476 compat_sigset_t
*set
, struct pt_regs
*regs
)
478 struct rt_sigframe_ia32 __user
*frame
;
479 void __user
*restorer
;
481 void __user
*fpstate
= NULL
;
483 /* __copy_to_user optimizes that into a single 8 byte store */
484 static const struct {
489 } __attribute__((packed
)) code
= {
491 __NR_ia32_rt_sigreturn
,
496 frame
= get_sigframe(ka
, regs
, sizeof(*frame
), &fpstate
);
498 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
502 put_user_ex(sig
, &frame
->sig
);
503 put_user_ex(ptr_to_compat(&frame
->info
), &frame
->pinfo
);
504 put_user_ex(ptr_to_compat(&frame
->uc
), &frame
->puc
);
505 err
|= copy_siginfo_to_user32(&frame
->info
, info
);
507 /* Create the ucontext. */
509 put_user_ex(UC_FP_XSTATE
, &frame
->uc
.uc_flags
);
511 put_user_ex(0, &frame
->uc
.uc_flags
);
512 put_user_ex(0, &frame
->uc
.uc_link
);
513 put_user_ex(current
->sas_ss_sp
, &frame
->uc
.uc_stack
.ss_sp
);
514 put_user_ex(sas_ss_flags(regs
->sp
),
515 &frame
->uc
.uc_stack
.ss_flags
);
516 put_user_ex(current
->sas_ss_size
, &frame
->uc
.uc_stack
.ss_size
);
517 err
|= ia32_setup_sigcontext(&frame
->uc
.uc_mcontext
, fpstate
,
519 err
|= __copy_to_user(&frame
->uc
.uc_sigmask
, set
, sizeof(*set
));
521 if (ka
->sa
.sa_flags
& SA_RESTORER
)
522 restorer
= ka
->sa
.sa_restorer
;
524 restorer
= VDSO32_SYMBOL(current
->mm
->context
.vdso
,
526 put_user_ex(ptr_to_compat(restorer
), &frame
->pretcode
);
529 * Not actually used anymore, but left because some gdb
532 put_user_ex(*((u64
*)&code
), (u64
*)frame
->retcode
);
533 } put_user_catch(err
);
538 /* Set up registers for signal handler */
539 regs
->sp
= (unsigned long) frame
;
540 regs
->ip
= (unsigned long) ka
->sa
.sa_handler
;
542 /* Make -mregparm=3 work */
544 regs
->dx
= (unsigned long) &frame
->info
;
545 regs
->cx
= (unsigned long) &frame
->uc
;
547 loadsegment(ds
, __USER32_DS
);
548 loadsegment(es
, __USER32_DS
);
550 regs
->cs
= __USER32_CS
;
551 regs
->ss
= __USER32_DS
;