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
10 * $Id: ia32_signal.c,v 1.22 2002/07/29 10:34:03 ak Exp $
13 #include <linux/sched.h>
15 #include <linux/smp.h>
16 #include <linux/smp_lock.h>
17 #include <linux/kernel.h>
18 #include <linux/signal.h>
19 #include <linux/errno.h>
20 #include <linux/wait.h>
21 #include <linux/ptrace.h>
22 #include <linux/unistd.h>
23 #include <linux/stddef.h>
24 #include <linux/personality.h>
25 #include <linux/compat.h>
26 #include <asm/ucontext.h>
27 #include <asm/uaccess.h>
30 #include <asm/ptrace.h>
31 #include <asm/ia32_unistd.h>
32 #include <asm/user32.h>
33 #include <asm/sigcontext32.h>
34 #include <asm/fpu32.h>
35 #include <asm/proto.h>
36 #include <asm/vsyscall32.h>
38 #define ptr_to_u32(x) ((u32)(u64)(x)) /* avoid gcc warning */
42 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
44 asmlinkage
int do_signal(struct pt_regs
*regs
, sigset_t
*oldset
);
45 void signal_fault(struct pt_regs
*regs
, void __user
*frame
, char *where
);
47 int ia32_copy_siginfo_to_user(siginfo_t32 __user
*to
, siginfo_t
*from
)
50 if (!access_ok (VERIFY_WRITE
, to
, sizeof(siginfo_t32
)))
53 /* If you change siginfo_t structure, please make sure that
54 this code is fixed accordingly.
55 It should never copy any pad contained in the structure
56 to avoid security leaks, but must copy the generic
57 3 ints plus the relevant union member. */
58 err
= __put_user(from
->si_signo
, &to
->si_signo
);
59 err
|= __put_user(from
->si_errno
, &to
->si_errno
);
60 err
|= __put_user((short)from
->si_code
, &to
->si_code
);
62 if (from
->si_code
< 0) {
63 err
|= __put_user(from
->si_pid
, &to
->si_pid
);
64 err
|= __put_user(from
->si_uid
, &to
->si_uid
);
65 err
|= __put_user((u32
)(u64
)from
->si_ptr
, &to
->si_ptr
);
67 /* First 32bits of unions are always present:
68 * si_pid === si_band === si_tid === si_addr(LS half) */
69 err
|= __put_user(from
->_sifields
._pad
[0], &to
->_sifields
._pad
[0]);
70 switch (from
->si_code
>> 16) {
71 case __SI_FAULT
>> 16:
74 err
|= __put_user(from
->si_utime
, &to
->si_utime
);
75 err
|= __put_user(from
->si_stime
, &to
->si_stime
);
76 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((u32
)(u64
)from
->si_ptr
, &to
->si_ptr
);
88 case __SI_RT
>> 16: /* This is not generated by the kernel as of now. */
89 case __SI_MESGQ
>> 16:
90 err
|= __put_user(from
->si_uid
, &to
->si_uid
);
91 err
|= __put_user(from
->si_int
, &to
->si_int
);
98 int ia32_copy_siginfo_from_user(siginfo_t
*to
, siginfo_t32 __user
*from
)
102 if (!access_ok (VERIFY_READ
, from
, sizeof(siginfo_t32
)))
105 err
= __get_user(to
->si_signo
, &from
->si_signo
);
106 err
|= __get_user(to
->si_errno
, &from
->si_errno
);
107 err
|= __get_user(to
->si_code
, &from
->si_code
);
109 err
|= __get_user(to
->si_pid
, &from
->si_pid
);
110 err
|= __get_user(to
->si_uid
, &from
->si_uid
);
111 err
|= __get_user(ptr32
, &from
->si_ptr
);
112 to
->si_ptr
= compat_ptr(ptr32
);
118 sys32_sigsuspend(int history0
, int history1
, old_sigset_t mask
,
119 struct pt_regs
*regs
)
124 spin_lock_irq(¤t
->sighand
->siglock
);
125 saveset
= current
->blocked
;
126 siginitset(¤t
->blocked
, mask
);
128 spin_unlock_irq(¤t
->sighand
->siglock
);
132 current
->state
= TASK_INTERRUPTIBLE
;
134 if (do_signal(regs
, &saveset
))
140 sys32_sigaltstack(const stack_ia32_t __user
*uss_ptr
,
141 stack_ia32_t __user
*uoss_ptr
,
142 struct pt_regs
*regs
)
149 memset(&uss
,0,sizeof(stack_t
));
150 if (!access_ok(VERIFY_READ
,uss_ptr
,sizeof(stack_ia32_t
)) ||
151 __get_user(ptr
, &uss_ptr
->ss_sp
) ||
152 __get_user(uss
.ss_flags
, &uss_ptr
->ss_flags
) ||
153 __get_user(uss
.ss_size
, &uss_ptr
->ss_size
))
155 uss
.ss_sp
= compat_ptr(ptr
);
159 ret
= do_sigaltstack(uss_ptr
? &uss
: NULL
, &uoss
, regs
->rsp
);
161 if (ret
>= 0 && uoss_ptr
) {
162 if (!access_ok(VERIFY_WRITE
,uoss_ptr
,sizeof(stack_ia32_t
)) ||
163 __put_user((u32
)(u64
)uoss
.ss_sp
, &uoss_ptr
->ss_sp
) ||
164 __put_user(uoss
.ss_flags
, &uoss_ptr
->ss_flags
) ||
165 __put_user(uoss
.ss_size
, &uoss_ptr
->ss_size
))
172 * Do a signal return; undo the signal stack.
179 struct sigcontext_ia32 sc
;
180 struct _fpstate_ia32 fpstate
;
181 unsigned int extramask
[_COMPAT_NSIG_WORDS
-1];
191 struct siginfo32 info
;
192 struct ucontext_ia32 uc
;
193 struct _fpstate_ia32 fpstate
;
198 ia32_restore_sigcontext(struct pt_regs
*regs
, struct sigcontext_ia32 __user
*sc
, unsigned int *peax
)
200 unsigned int err
= 0;
202 /* Always make any pending restarted system calls return -EINTR */
203 current_thread_info()->restart_block
.fn
= do_no_restart_syscall
;
206 printk("SIG restore_sigcontext: sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
207 sc
, sc
->err
, sc
->eip
, sc
->cs
, sc
->eflags
);
211 err |= __get_user(reg, &sc->e ##x); \
212 regs->r ## x = reg; \
215 #define RELOAD_SEG(seg,mask) \
216 { unsigned int cur; \
217 unsigned short pre; \
218 err |= __get_user(pre, &sc->seg); \
219 asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \
221 if (pre != cur) loadsegment(seg,pre); }
223 /* Reload fs and gs if they have changed in the signal handler.
224 This does not handle long fs/gs base changes in the handler, but
225 does not clobber them at least in the normal case. */
229 err
|= __get_user(gs
, &sc
->gs
);
231 asm("movl %%gs,%0" : "=r" (oldgs
));
239 COPY(di
); COPY(si
); COPY(bp
); COPY(sp
); COPY(bx
);
240 COPY(dx
); COPY(cx
); COPY(ip
);
241 /* Don't touch extended registers */
243 err
|= __get_user(regs
->cs
, &sc
->cs
);
245 err
|= __get_user(regs
->ss
, &sc
->ss
);
249 unsigned int tmpflags
;
250 err
|= __get_user(tmpflags
, &sc
->eflags
);
251 regs
->eflags
= (regs
->eflags
& ~0x40DD5) | (tmpflags
& 0x40DD5);
252 regs
->orig_rax
= -1; /* disable syscall checks */
257 struct _fpstate_ia32 __user
* buf
;
258 err
|= __get_user(tmp
, &sc
->fpstate
);
259 buf
= compat_ptr(tmp
);
261 if (verify_area(VERIFY_READ
, buf
, sizeof(*buf
)))
263 err
|= restore_i387_ia32(current
, buf
, 0);
269 err
|= __get_user(tmp
, &sc
->eax
);
278 asmlinkage
long sys32_sigreturn(struct pt_regs
*regs
)
280 struct sigframe __user
*frame
= (struct sigframe __user
*)(regs
->rsp
-8);
284 if (verify_area(VERIFY_READ
, frame
, sizeof(*frame
)))
286 if (__get_user(set
.sig
[0], &frame
->sc
.oldmask
)
287 || (_COMPAT_NSIG_WORDS
> 1
288 && __copy_from_user((((char *) &set
.sig
) + 4), &frame
->extramask
,
289 sizeof(frame
->extramask
))))
292 sigdelsetmask(&set
, ~_BLOCKABLE
);
293 spin_lock_irq(¤t
->sighand
->siglock
);
294 current
->blocked
= set
;
296 spin_unlock_irq(¤t
->sighand
->siglock
);
298 if (ia32_restore_sigcontext(regs
, &frame
->sc
, &eax
))
303 signal_fault(regs
, frame
, "32bit sigreturn");
307 asmlinkage
long sys32_rt_sigreturn(struct pt_regs
*regs
)
309 struct rt_sigframe __user
*frame
;
312 struct pt_regs tregs
;
314 frame
= (struct rt_sigframe __user
*)(regs
->rsp
- 4);
316 if (verify_area(VERIFY_READ
, frame
, sizeof(*frame
)))
318 if (__copy_from_user(&set
, &frame
->uc
.uc_sigmask
, sizeof(set
)))
321 sigdelsetmask(&set
, ~_BLOCKABLE
);
322 spin_lock_irq(¤t
->sighand
->siglock
);
323 current
->blocked
= set
;
325 spin_unlock_irq(¤t
->sighand
->siglock
);
327 if (ia32_restore_sigcontext(regs
, &frame
->uc
.uc_mcontext
, &eax
))
331 if (sys32_sigaltstack(&frame
->uc
.uc_stack
, NULL
, &tregs
) == -EFAULT
)
337 signal_fault(regs
,frame
,"32bit rt sigreturn");
342 * Set up a signal frame.
346 ia32_setup_sigcontext(struct sigcontext_ia32 __user
*sc
, struct _fpstate_ia32 __user
*fpstate
,
347 struct pt_regs
*regs
, unsigned int mask
)
353 __asm__("movl %%gs,%0" : "=r"(tmp
): "0"(tmp
));
354 err
|= __put_user(tmp
, (unsigned int __user
*)&sc
->gs
);
355 __asm__("movl %%fs,%0" : "=r"(tmp
): "0"(tmp
));
356 err
|= __put_user(tmp
, (unsigned int __user
*)&sc
->fs
);
357 __asm__("movl %%ds,%0" : "=r"(tmp
): "0"(tmp
));
358 err
|= __put_user(tmp
, (unsigned int __user
*)&sc
->ds
);
359 __asm__("movl %%es,%0" : "=r"(tmp
): "0"(tmp
));
360 err
|= __put_user(tmp
, (unsigned int __user
*)&sc
->es
);
362 err
|= __put_user((u32
)regs
->rdi
, &sc
->edi
);
363 err
|= __put_user((u32
)regs
->rsi
, &sc
->esi
);
364 err
|= __put_user((u32
)regs
->rbp
, &sc
->ebp
);
365 err
|= __put_user((u32
)regs
->rsp
, &sc
->esp
);
366 err
|= __put_user((u32
)regs
->rbx
, &sc
->ebx
);
367 err
|= __put_user((u32
)regs
->rdx
, &sc
->edx
);
368 err
|= __put_user((u32
)regs
->rcx
, &sc
->ecx
);
369 err
|= __put_user((u32
)regs
->rax
, &sc
->eax
);
370 err
|= __put_user((u32
)regs
->cs
, &sc
->cs
);
371 err
|= __put_user((u32
)regs
->ss
, &sc
->ss
);
372 err
|= __put_user(current
->thread
.trap_no
, &sc
->trapno
);
373 err
|= __put_user(current
->thread
.error_code
, &sc
->err
);
374 err
|= __put_user((u32
)regs
->rip
, &sc
->eip
);
375 eflags
= regs
->eflags
;
376 if (current
->ptrace
& PT_PTRACED
) {
379 err
|= __put_user((u32
)eflags
, &sc
->eflags
);
380 err
|= __put_user((u32
)regs
->rsp
, &sc
->esp_at_signal
);
382 tmp
= save_i387_ia32(current
, fpstate
, regs
, 0);
386 current
->used_math
= 0;
388 err
|= __put_user((u32
)(u64
)(tmp
? fpstate
: NULL
), &sc
->fpstate
);
391 /* non-iBCS2 extensions.. */
392 err
|= __put_user(mask
, &sc
->oldmask
);
393 err
|= __put_user(current
->thread
.cr2
, &sc
->cr2
);
399 * Determine which stack to use..
402 get_sigframe(struct k_sigaction
*ka
, struct pt_regs
* regs
, size_t frame_size
)
406 /* Default to using normal stack */
409 /* This is the X/Open sanctioned signal stack switching. */
410 if (ka
->sa
.sa_flags
& SA_ONSTACK
) {
411 if (sas_ss_flags(rsp
) == 0)
412 rsp
= current
->sas_ss_sp
+ current
->sas_ss_size
;
415 /* This is the legacy signal stack switching. */
416 else if ((regs
->ss
& 0xffff) != __USER_DS
&&
417 !(ka
->sa
.sa_flags
& SA_RESTORER
) &&
418 ka
->sa
.sa_restorer
) {
419 rsp
= (unsigned long) ka
->sa
.sa_restorer
;
422 return (void __user
*)((rsp
- frame_size
) & -8UL);
425 void ia32_setup_frame(int sig
, struct k_sigaction
*ka
,
426 compat_sigset_t
*set
, struct pt_regs
* regs
)
428 struct sigframe __user
*frame
;
431 frame
= get_sigframe(ka
, regs
, sizeof(*frame
));
433 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
437 struct exec_domain
*ed
= current_thread_info()->exec_domain
;
438 err
|= __put_user((ed
441 ? ed
->signal_invmap
[sig
]
448 err
|= ia32_setup_sigcontext(&frame
->sc
, &frame
->fpstate
, regs
, set
->sig
[0]);
452 if (_COMPAT_NSIG_WORDS
> 1) {
453 err
|= __copy_to_user(frame
->extramask
, &set
->sig
[1],
454 sizeof(frame
->extramask
));
459 /* Return stub is in 32bit vsyscall page */
461 void __user
*restorer
= VSYSCALL32_SIGRETURN
;
462 if (ka
->sa
.sa_flags
& SA_RESTORER
)
463 restorer
= ka
->sa
.sa_restorer
;
464 err
|= __put_user(ptr_to_u32(restorer
), &frame
->pretcode
);
466 /* These are actually not used anymore, but left because some
467 gdb versions depend on them as a marker. */
469 /* copy_to_user optimizes that into a single 8 byte store */
470 static const struct {
475 } __attribute__((packed
)) code
= {
476 0xb858, /* popl %eax ; movl $...,%eax */
478 0x80cd, /* int $0x80 */
481 err
|= __copy_to_user(frame
->retcode
, &code
, 8);
486 /* Set up registers for signal handler */
487 regs
->rsp
= (unsigned long) frame
;
488 regs
->rip
= (unsigned long) ka
->sa
.sa_handler
;
490 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS
));
491 asm volatile("movl %0,%%es" :: "r" (__USER32_DS
));
493 regs
->cs
= __USER32_CS
;
494 regs
->ss
= __USER32_DS
;
497 if (regs
->eflags
& TF_MASK
) {
498 if (current
->ptrace
& PT_PTRACED
) {
499 ptrace_notify(SIGTRAP
);
501 regs
->eflags
&= ~TF_MASK
;
506 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
507 current
->comm
, current
->pid
, frame
, regs
->rip
, frame
->pretcode
);
513 force_sigsegv(sig
, current
);
516 void ia32_setup_rt_frame(int sig
, struct k_sigaction
*ka
, siginfo_t
*info
,
517 compat_sigset_t
*set
, struct pt_regs
* regs
)
519 struct rt_sigframe __user
*frame
;
522 frame
= get_sigframe(ka
, regs
, sizeof(*frame
));
524 if (!access_ok(VERIFY_WRITE
, frame
, sizeof(*frame
)))
529 struct exec_domain
*ed
= current_thread_info()->exec_domain
;
530 err
|= __put_user((ed
533 ? ed
->signal_invmap
[sig
]
537 err
|= __put_user((u32
)(u64
)&frame
->info
, &frame
->pinfo
);
538 err
|= __put_user((u32
)(u64
)&frame
->uc
, &frame
->puc
);
539 err
|= ia32_copy_siginfo_to_user(&frame
->info
, info
);
543 /* Create the ucontext. */
544 err
|= __put_user(0, &frame
->uc
.uc_flags
);
545 err
|= __put_user(0, &frame
->uc
.uc_link
);
546 err
|= __put_user(current
->sas_ss_sp
, &frame
->uc
.uc_stack
.ss_sp
);
547 err
|= __put_user(sas_ss_flags(regs
->rsp
),
548 &frame
->uc
.uc_stack
.ss_flags
);
549 err
|= __put_user(current
->sas_ss_size
, &frame
->uc
.uc_stack
.ss_size
);
550 err
|= ia32_setup_sigcontext(&frame
->uc
.uc_mcontext
, &frame
->fpstate
,
552 err
|= __copy_to_user(&frame
->uc
.uc_sigmask
, set
, sizeof(*set
));
558 void __user
*restorer
= VSYSCALL32_RTSIGRETURN
;
559 if (ka
->sa
.sa_flags
& SA_RESTORER
)
560 restorer
= ka
->sa
.sa_restorer
;
561 err
|= __put_user(ptr_to_u32(restorer
), &frame
->pretcode
);
564 /* This is movl $,%eax ; int $0x80 */
565 /* Not actually used anymore, but left because some gdb versions
568 /* __copy_to_user optimizes that into a single 8 byte store */
569 static const struct {
575 } __attribute__((packed
)) code
= {
577 __NR_ia32_rt_sigreturn
,
581 err
|= __copy_to_user(frame
->retcode
, &code
, 8);
586 /* Set up registers for signal handler */
587 regs
->rsp
= (unsigned long) frame
;
588 regs
->rip
= (unsigned long) ka
->sa
.sa_handler
;
590 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS
));
591 asm volatile("movl %0,%%es" :: "r" (__USER32_DS
));
593 regs
->cs
= __USER32_CS
;
594 regs
->ss
= __USER32_DS
;
597 if (regs
->eflags
& TF_MASK
) {
598 if (current
->ptrace
& PT_PTRACED
) {
599 ptrace_notify(SIGTRAP
);
601 regs
->eflags
&= ~TF_MASK
;
606 printk("SIG deliver (%s:%d): sp=%p pc=%p ra=%p\n",
607 current
->comm
, current
->pid
, frame
, regs
->rip
, frame
->pretcode
);
613 force_sigsegv(sig
, current
);