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/signal.h>
16 #include <linux/errno.h>
17 #include <linux/wait.h>
18 #include <linux/ptrace.h>
19 #include <linux/unistd.h>
20 #include <linux/stddef.h>
21 #include <linux/personality.h>
22 #include <linux/compat.h>
23 #include <linux/binfmts.h>
24 #include <asm/ucontext.h>
25 #include <asm/uaccess.h>
28 #include <asm/ptrace.h>
29 #include <asm/ia32_unistd.h>
30 #include <asm/user32.h>
31 #include <asm/sigcontext32.h>
32 #include <asm/proto.h>
37 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
39 asmlinkage
int do_signal(struct pt_regs
*regs
, sigset_t
*oldset
);
40 void signal_fault(struct pt_regs
*regs
, void __user
*frame
, char *where
);
42 int copy_siginfo_to_user32(compat_siginfo_t __user
*to
, siginfo_t
*from
)
46 if (!access_ok(VERIFY_WRITE
, to
, sizeof(compat_siginfo_t
)))
49 /* If you change siginfo_t structure, please make sure that
50 this code is fixed accordingly.
51 It should never copy any pad contained in the structure
52 to avoid security leaks, but must copy the generic
53 3 ints plus the relevant union member. */
54 err
= __put_user(from
->si_signo
, &to
->si_signo
);
55 err
|= __put_user(from
->si_errno
, &to
->si_errno
);
56 err
|= __put_user((short)from
->si_code
, &to
->si_code
);
58 if (from
->si_code
< 0) {
59 err
|= __put_user(from
->si_pid
, &to
->si_pid
);
60 err
|= __put_user(from
->si_uid
, &to
->si_uid
);
61 err
|= __put_user(ptr_to_compat(from
->si_ptr
), &to
->si_ptr
);
64 * First 32bits of unions are always present:
65 * si_pid === si_band === si_tid === si_addr(LS half)
67 err
|= __put_user(from
->_sifields
._pad
[0],
68 &to
->_sifields
._pad
[0]);
69 switch (from
->si_code
>> 16) {
70 case __SI_FAULT
>> 16:
73 err
|= __put_user(from
->si_utime
, &to
->si_utime
);
74 err
|= __put_user(from
->si_stime
, &to
->si_stime
);
75 err
|= __put_user(from
->si_status
, &to
->si_status
);
79 err
|= __put_user(from
->si_uid
, &to
->si_uid
);
82 err
|= __put_user(from
->si_fd
, &to
->si_fd
);
84 case __SI_TIMER
>> 16:
85 err
|= __put_user(from
->si_overrun
, &to
->si_overrun
);
86 err
|= __put_user(ptr_to_compat(from
->si_ptr
),
89 /* This is not generated by the kernel as of now. */
91 case __SI_MESGQ
>> 16:
92 err
|= __put_user(from
->si_uid
, &to
->si_uid
);
93 err
|= __put_user(from
->si_int
, &to
->si_int
);
100 int copy_siginfo_from_user32(siginfo_t
*to
, compat_siginfo_t __user
*from
)
105 if (!access_ok(VERIFY_READ
, from
, sizeof(compat_siginfo_t
)))
108 err
= __get_user(to
->si_signo
, &from
->si_signo
);
109 err
|= __get_user(to
->si_errno
, &from
->si_errno
);
110 err
|= __get_user(to
->si_code
, &from
->si_code
);
112 err
|= __get_user(to
->si_pid
, &from
->si_pid
);
113 err
|= __get_user(to
->si_uid
, &from
->si_uid
);
114 err
|= __get_user(ptr32
, &from
->si_ptr
);
115 to
->si_ptr
= compat_ptr(ptr32
);
120 asmlinkage
long sys32_sigsuspend(int history0
, int history1
, old_sigset_t mask
)
123 spin_lock_irq(¤t
->sighand
->siglock
);
124 current
->saved_sigmask
= current
->blocked
;
125 siginitset(¤t
->blocked
, mask
);
127 spin_unlock_irq(¤t
->sighand
->siglock
);
129 current
->state
= TASK_INTERRUPTIBLE
;
131 set_thread_flag(TIF_RESTORE_SIGMASK
);
132 return -ERESTARTNOHAND
;
135 asmlinkage
long sys32_sigaltstack(const stack_ia32_t __user
*uss_ptr
,
136 stack_ia32_t __user
*uoss_ptr
,
137 struct pt_regs
*regs
)
146 memset(&uss
, 0, sizeof(stack_t
));
147 if (!access_ok(VERIFY_READ
, uss_ptr
, sizeof(stack_ia32_t
)) ||
148 __get_user(ptr
, &uss_ptr
->ss_sp
) ||
149 __get_user(uss
.ss_flags
, &uss_ptr
->ss_flags
) ||
150 __get_user(uss
.ss_size
, &uss_ptr
->ss_size
))
152 uss
.ss_sp
= compat_ptr(ptr
);
156 ret
= do_sigaltstack(uss_ptr
? &uss
: NULL
, &uoss
, regs
->sp
);
158 if (ret
>= 0 && uoss_ptr
) {
159 if (!access_ok(VERIFY_WRITE
, uoss_ptr
, sizeof(stack_ia32_t
)) ||
160 __put_user(ptr_to_compat(uoss
.ss_sp
), &uoss_ptr
->ss_sp
) ||
161 __put_user(uoss
.ss_flags
, &uoss_ptr
->ss_flags
) ||
162 __put_user(uoss
.ss_size
, &uoss_ptr
->ss_size
))
169 * Do a signal return; undo the signal stack.
176 struct sigcontext_ia32 sc
;
177 struct _fpstate_ia32 fpstate
;
178 unsigned int extramask
[_COMPAT_NSIG_WORDS
-1];
188 compat_siginfo_t info
;
189 struct ucontext_ia32 uc
;
190 struct _fpstate_ia32 fpstate
;
196 err |= __get_user(reg, &sc->x); \
200 #define RELOAD_SEG(seg,mask) \
201 { unsigned int cur; \
202 unsigned short pre; \
203 err |= __get_user(pre, &sc->seg); \
204 asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \
206 if (pre != cur) loadsegment(seg, pre); }
208 static int ia32_restore_sigcontext(struct pt_regs
*regs
,
209 struct sigcontext_ia32 __user
*sc
,
212 unsigned int tmpflags
, gs
, oldgs
, err
= 0;
213 struct _fpstate_ia32 __user
*buf
;
216 /* Always make any pending restarted system calls return -EINTR */
217 current_thread_info()->restart_block
.fn
= do_no_restart_syscall
;
220 printk(KERN_DEBUG
"SIG restore_sigcontext: "
221 "sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
222 sc
, sc
->err
, sc
->ip
, sc
->cs
, sc
->flags
);
226 * Reload fs and gs if they have changed in the signal
227 * handler. This does not handle long fs/gs base changes in
228 * the handler, but does not clobber them at least in the
231 err
|= __get_user(gs
, &sc
->gs
);
233 asm("movl %%gs,%0" : "=r" (oldgs
));
241 COPY(di
); COPY(si
); COPY(bp
); COPY(sp
); COPY(bx
);
242 COPY(dx
); COPY(cx
); COPY(ip
);
243 /* Don't touch extended registers */
245 err
|= __get_user(regs
->cs
, &sc
->cs
);
247 err
|= __get_user(regs
->ss
, &sc
->ss
);
250 err
|= __get_user(tmpflags
, &sc
->flags
);
251 regs
->flags
= (regs
->flags
& ~0x40DD5) | (tmpflags
& 0x40DD5);
252 /* disable syscall checks */
255 err
|= __get_user(tmp
, &sc
->fpstate
);
256 buf
= compat_ptr(tmp
);
258 if (!access_ok(VERIFY_READ
, buf
, sizeof(*buf
)))
260 err
|= restore_i387_ia32(buf
);
262 struct task_struct
*me
= current
;
270 err
|= __get_user(tmp
, &sc
->ax
);
279 asmlinkage
long sys32_sigreturn(struct pt_regs
*regs
)
281 struct sigframe __user
*frame
= (struct sigframe __user
*)(regs
->sp
-8);
285 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
287 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
)
288 || (_COMPAT_NSIG_WORDS
> 1
289 && __copy_from_user((((char *) &set
.sig
) + 4),
291 sizeof(frame
->extramask
))))
294 sigdelsetmask(&set
, ~_BLOCKABLE
);
295 spin_lock_irq(¤t
->sighand
->siglock
);
296 current
->blocked
= set
;
298 spin_unlock_irq(¤t
->sighand
->siglock
);
300 if (ia32_restore_sigcontext(regs
, &frame
->sc
, &ax
))
305 signal_fault(regs
, frame
, "32bit sigreturn");
309 asmlinkage
long sys32_rt_sigreturn(struct pt_regs
*regs
)
311 struct rt_sigframe __user
*frame
;
314 struct pt_regs tregs
;
316 frame
= (struct rt_sigframe __user
*)(regs
->sp
- 4);
318 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
320 if (__copy_from_user(&set
, &frame
->uc
.uc_sigmask
, sizeof(set
)))
323 sigdelsetmask(&set
, ~_BLOCKABLE
);
324 spin_lock_irq(¤t
->sighand
->siglock
);
325 current
->blocked
= set
;
327 spin_unlock_irq(¤t
->sighand
->siglock
);
329 if (ia32_restore_sigcontext(regs
, &frame
->uc
.uc_mcontext
, &ax
))
333 if (sys32_sigaltstack(&frame
->uc
.uc_stack
, NULL
, &tregs
) == -EFAULT
)
339 signal_fault(regs
, frame
, "32bit rt sigreturn");
344 * Set up a signal frame.
347 static int ia32_setup_sigcontext(struct sigcontext_ia32 __user
*sc
,
348 struct _fpstate_ia32 __user
*fpstate
,
349 struct pt_regs
*regs
, unsigned int mask
)
354 __asm__("movl %%gs,%0" : "=r"(tmp
): "0"(tmp
));
355 err
|= __put_user(tmp
, (unsigned int __user
*)&sc
->gs
);
356 __asm__("movl %%fs,%0" : "=r"(tmp
): "0"(tmp
));
357 err
|= __put_user(tmp
, (unsigned int __user
*)&sc
->fs
);
358 __asm__("movl %%ds,%0" : "=r"(tmp
): "0"(tmp
));
359 err
|= __put_user(tmp
, (unsigned int __user
*)&sc
->ds
);
360 __asm__("movl %%es,%0" : "=r"(tmp
): "0"(tmp
));
361 err
|= __put_user(tmp
, (unsigned int __user
*)&sc
->es
);
363 err
|= __put_user((u32
)regs
->di
, &sc
->di
);
364 err
|= __put_user((u32
)regs
->si
, &sc
->si
);
365 err
|= __put_user((u32
)regs
->bp
, &sc
->bp
);
366 err
|= __put_user((u32
)regs
->sp
, &sc
->sp
);
367 err
|= __put_user((u32
)regs
->bx
, &sc
->bx
);
368 err
|= __put_user((u32
)regs
->dx
, &sc
->dx
);
369 err
|= __put_user((u32
)regs
->cx
, &sc
->cx
);
370 err
|= __put_user((u32
)regs
->ax
, &sc
->ax
);
371 err
|= __put_user((u32
)regs
->cs
, &sc
->cs
);
372 err
|= __put_user((u32
)regs
->ss
, &sc
->ss
);
373 err
|= __put_user(current
->thread
.trap_no
, &sc
->trapno
);
374 err
|= __put_user(current
->thread
.error_code
, &sc
->err
);
375 err
|= __put_user((u32
)regs
->ip
, &sc
->ip
);
376 err
|= __put_user((u32
)regs
->flags
, &sc
->flags
);
377 err
|= __put_user((u32
)regs
->sp
, &sc
->sp_at_signal
);
379 tmp
= save_i387_ia32(fpstate
);
385 err
|= __put_user(ptr_to_compat(tmp
? fpstate
: NULL
),
389 /* non-iBCS2 extensions.. */
390 err
|= __put_user(mask
, &sc
->oldmask
);
391 err
|= __put_user(current
->thread
.cr2
, &sc
->cr2
);
397 * Determine which stack to use..
399 static void __user
*get_sigframe(struct k_sigaction
*ka
, struct pt_regs
*regs
,
404 /* Default to using normal stack */
407 /* This is the X/Open sanctioned signal stack switching. */
408 if (ka
->sa
.sa_flags
& SA_ONSTACK
) {
409 if (sas_ss_flags(sp
) == 0)
410 sp
= current
->sas_ss_sp
+ current
->sas_ss_size
;
413 /* This is the legacy signal stack switching. */
414 else if ((regs
->ss
& 0xffff) != __USER_DS
&&
415 !(ka
->sa
.sa_flags
& SA_RESTORER
) &&
417 sp
= (unsigned long) ka
->sa
.sa_restorer
;
420 /* Align the stack pointer according to the i386 ABI,
421 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
422 sp
= ((sp
+ 4) & -16ul) - 4;
423 return (void __user
*) sp
;
426 int ia32_setup_frame(int sig
, struct k_sigaction
*ka
,
427 compat_sigset_t
*set
, struct pt_regs
*regs
)
429 struct sigframe __user
*frame
;
430 void __user
*restorer
;
433 /* copy_to_user optimizes that into a single 8 byte store */
434 static const struct {
439 } __attribute__((packed
)) code
= {
440 0xb858, /* popl %eax ; movl $...,%eax */
442 0x80cd, /* int $0x80 */
446 frame
= get_sigframe(ka
, regs
, sizeof(*frame
));
448 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
451 err
|= __put_user(sig
, &frame
->sig
);
455 err
|= ia32_setup_sigcontext(&frame
->sc
, &frame
->fpstate
, regs
,
460 if (_COMPAT_NSIG_WORDS
> 1) {
461 err
|= __copy_to_user(frame
->extramask
, &set
->sig
[1],
462 sizeof(frame
->extramask
));
467 if (ka
->sa
.sa_flags
& SA_RESTORER
) {
468 restorer
= ka
->sa
.sa_restorer
;
470 /* Return stub is in 32bit vsyscall page */
471 if (current
->binfmt
->hasvdso
)
472 restorer
= VDSO32_SYMBOL(current
->mm
->context
.vdso
,
475 restorer
= &frame
->retcode
;
477 err
|= __put_user(ptr_to_compat(restorer
), &frame
->pretcode
);
480 * These are actually not used anymore, but left because some
481 * gdb versions depend on them as a marker.
483 err
|= __copy_to_user(frame
->retcode
, &code
, 8);
487 /* Set up registers for signal handler */
488 regs
->sp
= (unsigned long) frame
;
489 regs
->ip
= (unsigned long) ka
->sa
.sa_handler
;
491 /* Make -mregparm=3 work */
496 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS
));
497 asm volatile("movl %0,%%es" :: "r" (__USER32_DS
));
499 regs
->cs
= __USER32_CS
;
500 regs
->ss
= __USER32_DS
;
503 regs
->flags
&= ~X86_EFLAGS_TF
;
504 if (test_thread_flag(TIF_SINGLESTEP
))
505 ptrace_notify(SIGTRAP
);
508 printk(KERN_DEBUG
"SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
509 current
->comm
, current
->pid
, frame
, regs
->ip
, frame
->pretcode
);
515 force_sigsegv(sig
, current
);
519 int ia32_setup_rt_frame(int sig
, struct k_sigaction
*ka
, siginfo_t
*info
,
520 compat_sigset_t
*set
, struct pt_regs
*regs
)
522 struct rt_sigframe __user
*frame
;
523 struct exec_domain
*ed
= current_thread_info()->exec_domain
;
524 void __user
*restorer
;
527 /* __copy_to_user optimizes that into a single 8 byte store */
528 static const struct {
534 } __attribute__((packed
)) code
= {
536 __NR_ia32_rt_sigreturn
,
541 frame
= get_sigframe(ka
, regs
, sizeof(*frame
));
543 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
546 err
|= __put_user((ed
&& ed
->signal_invmap
&& sig
< 32
547 ? ed
->signal_invmap
[sig
] : sig
), &frame
->sig
);
548 err
|= __put_user(ptr_to_compat(&frame
->info
), &frame
->pinfo
);
549 err
|= __put_user(ptr_to_compat(&frame
->uc
), &frame
->puc
);
550 err
|= copy_siginfo_to_user32(&frame
->info
, info
);
554 /* Create the ucontext. */
555 err
|= __put_user(0, &frame
->uc
.uc_flags
);
556 err
|= __put_user(0, &frame
->uc
.uc_link
);
557 err
|= __put_user(current
->sas_ss_sp
, &frame
->uc
.uc_stack
.ss_sp
);
558 err
|= __put_user(sas_ss_flags(regs
->sp
),
559 &frame
->uc
.uc_stack
.ss_flags
);
560 err
|= __put_user(current
->sas_ss_size
, &frame
->uc
.uc_stack
.ss_size
);
561 err
|= ia32_setup_sigcontext(&frame
->uc
.uc_mcontext
, &frame
->fpstate
,
563 err
|= __copy_to_user(&frame
->uc
.uc_sigmask
, set
, sizeof(*set
));
567 if (ka
->sa
.sa_flags
& SA_RESTORER
)
568 restorer
= ka
->sa
.sa_restorer
;
570 restorer
= VDSO32_SYMBOL(current
->mm
->context
.vdso
,
572 err
|= __put_user(ptr_to_compat(restorer
), &frame
->pretcode
);
575 * Not actually used anymore, but left because some gdb
578 err
|= __copy_to_user(frame
->retcode
, &code
, 8);
582 /* Set up registers for signal handler */
583 regs
->sp
= (unsigned long) frame
;
584 regs
->ip
= (unsigned long) ka
->sa
.sa_handler
;
586 /* Make -mregparm=3 work */
588 regs
->dx
= (unsigned long) &frame
->info
;
589 regs
->cx
= (unsigned long) &frame
->uc
;
591 /* Make -mregparm=3 work */
593 regs
->dx
= (unsigned long) &frame
->info
;
594 regs
->cx
= (unsigned long) &frame
->uc
;
596 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS
));
597 asm volatile("movl %0,%%es" :: "r" (__USER32_DS
));
599 regs
->cs
= __USER32_CS
;
600 regs
->ss
= __USER32_DS
;
603 regs
->flags
&= ~X86_EFLAGS_TF
;
604 if (test_thread_flag(TIF_SINGLESTEP
))
605 ptrace_notify(SIGTRAP
);
608 printk(KERN_DEBUG
"SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
609 current
->comm
, current
->pid
, frame
, regs
->ip
, frame
->pretcode
);
615 force_sigsegv(sig
, current
);