2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (C) 1991, 1992 Linus Torvalds
7 * Copyright (C) 1994 - 2000 Ralf Baechle
8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
10 #include <linux/sched.h>
12 #include <linux/smp.h>
13 #include <linux/smp_lock.h>
14 #include <linux/kernel.h>
15 #include <linux/signal.h>
16 #include <linux/syscalls.h>
17 #include <linux/errno.h>
18 #include <linux/wait.h>
19 #include <linux/ptrace.h>
20 #include <linux/compat.h>
21 #include <linux/suspend.h>
22 #include <linux/compiler.h>
25 #include <linux/bitops.h>
26 #include <asm/cacheflush.h>
28 #include <asm/uaccess.h>
29 #include <asm/ucontext.h>
30 #include <asm/system.h>
33 #define SI_PAD_SIZE32 ((SI_MAX_SIZE/sizeof(int)) - 3)
35 typedef struct compat_siginfo
{
41 int _pad
[SI_PAD_SIZE32
];
45 compat_pid_t _pid
; /* sender's pid */
46 compat_uid_t _uid
; /* sender's uid */
51 compat_pid_t _pid
; /* which child */
52 compat_uid_t _uid
; /* sender's uid */
53 int _status
; /* exit code */
54 compat_clock_t _utime
;
55 compat_clock_t _stime
;
60 compat_pid_t _pid
; /* which child */
61 compat_clock_t _utime
;
62 int _status
; /* exit code */
63 compat_clock_t _stime
;
66 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
68 s32 _addr
; /* faulting insn/memory ref. */
71 /* SIGPOLL, SIGXFSZ (To do ...) */
73 int _band
; /* POLL_IN, POLL_OUT, POLL_MSG */
83 /* POSIX.1b signals */
85 compat_pid_t _pid
; /* sender's pid */
86 compat_uid_t _uid
; /* sender's uid */
87 compat_sigval_t _sigval
;
94 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
96 #define __NR_O32_sigreturn 4119
97 #define __NR_O32_rt_sigreturn 4193
98 #define __NR_O32_restart_syscall 4253
102 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
104 extern int do_signal32(sigset_t
*oldset
, struct pt_regs
*regs
);
106 /* 32-bit compatibility types */
108 #define _NSIG_BPW32 32
109 #define _NSIG_WORDS32 (_NSIG / _NSIG_BPW32)
112 unsigned int sig
[_NSIG_WORDS32
];
115 typedef unsigned int __sighandler32_t
;
116 typedef void (*vfptr_t
)(void);
119 unsigned int sa_flags
;
120 __sighandler32_t sa_handler
;
121 compat_sigset_t sa_mask
;
124 /* IRIX compatible stack_t */
125 typedef struct sigaltstack32
{
127 compat_size_t ss_size
;
135 struct sigcontext32 uc_mcontext
;
136 sigset_t32 uc_sigmask
; /* mask last for extensibility */
139 extern void __put_sigset_unknown_nsig(void);
140 extern void __get_sigset_unknown_nsig(void);
142 static inline int put_sigset(const sigset_t
*kbuf
, compat_sigset_t
*ubuf
)
146 if (!access_ok(VERIFY_WRITE
, ubuf
, sizeof(*ubuf
)))
149 switch (_NSIG_WORDS
) {
151 __put_sigset_unknown_nsig();
153 err
|= __put_user (kbuf
->sig
[1] >> 32, &ubuf
->sig
[3]);
154 err
|= __put_user (kbuf
->sig
[1] & 0xffffffff, &ubuf
->sig
[2]);
156 err
|= __put_user (kbuf
->sig
[0] >> 32, &ubuf
->sig
[1]);
157 err
|= __put_user (kbuf
->sig
[0] & 0xffffffff, &ubuf
->sig
[0]);
163 static inline int get_sigset(sigset_t
*kbuf
, const compat_sigset_t
*ubuf
)
166 unsigned long sig
[4];
168 if (!access_ok(VERIFY_READ
, ubuf
, sizeof(*ubuf
)))
171 switch (_NSIG_WORDS
) {
173 __get_sigset_unknown_nsig();
175 err
|= __get_user (sig
[3], &ubuf
->sig
[3]);
176 err
|= __get_user (sig
[2], &ubuf
->sig
[2]);
177 kbuf
->sig
[1] = sig
[2] | (sig
[3] << 32);
179 err
|= __get_user (sig
[1], &ubuf
->sig
[1]);
180 err
|= __get_user (sig
[0], &ubuf
->sig
[0]);
181 kbuf
->sig
[0] = sig
[0] | (sig
[1] << 32);
188 * Atomically swap in the new signal mask, and wait for a signal.
191 save_static_function(sys32_sigsuspend
);
192 __attribute_used__ noinline
static int
193 _sys32_sigsuspend(nabi_no_regargs
struct pt_regs regs
)
195 compat_sigset_t
*uset
;
196 sigset_t newset
, saveset
;
198 uset
= (compat_sigset_t
*) regs
.regs
[4];
199 if (get_sigset(&newset
, uset
))
201 sigdelsetmask(&newset
, ~_BLOCKABLE
);
203 spin_lock_irq(¤t
->sighand
->siglock
);
204 saveset
= current
->blocked
;
205 current
->blocked
= newset
;
207 spin_unlock_irq(¤t
->sighand
->siglock
);
209 regs
.regs
[2] = EINTR
;
212 current
->state
= TASK_INTERRUPTIBLE
;
214 if (do_signal32(&saveset
, ®s
))
219 save_static_function(sys32_rt_sigsuspend
);
220 __attribute_used__ noinline
static int
221 _sys32_rt_sigsuspend(nabi_no_regargs
struct pt_regs regs
)
223 compat_sigset_t
*uset
;
224 sigset_t newset
, saveset
;
227 /* XXX Don't preclude handling different sized sigset_t's. */
228 sigsetsize
= regs
.regs
[5];
229 if (sigsetsize
!= sizeof(compat_sigset_t
))
232 uset
= (compat_sigset_t
*) regs
.regs
[4];
233 if (get_sigset(&newset
, uset
))
235 sigdelsetmask(&newset
, ~_BLOCKABLE
);
237 spin_lock_irq(¤t
->sighand
->siglock
);
238 saveset
= current
->blocked
;
239 current
->blocked
= newset
;
241 spin_unlock_irq(¤t
->sighand
->siglock
);
243 regs
.regs
[2] = EINTR
;
246 current
->state
= TASK_INTERRUPTIBLE
;
248 if (do_signal32(&saveset
, ®s
))
253 asmlinkage
int sys32_sigaction(int sig
, const struct sigaction32
*act
,
254 struct sigaction32
*oact
)
256 struct k_sigaction new_ka
, old_ka
;
263 if (!access_ok(VERIFY_READ
, act
, sizeof(*act
)))
265 err
|= __get_user((u32
)(u64
)new_ka
.sa
.sa_handler
,
267 err
|= __get_user(new_ka
.sa
.sa_flags
, &act
->sa_flags
);
268 err
|= __get_user(mask
, &act
->sa_mask
.sig
[0]);
272 siginitset(&new_ka
.sa
.sa_mask
, mask
);
275 ret
= do_sigaction(sig
, act
? &new_ka
: NULL
, oact
? &old_ka
: NULL
);
278 if (!access_ok(VERIFY_WRITE
, oact
, sizeof(*oact
)))
280 err
|= __put_user(old_ka
.sa
.sa_flags
, &oact
->sa_flags
);
281 err
|= __put_user((u32
)(u64
)old_ka
.sa
.sa_handler
,
283 err
|= __put_user(old_ka
.sa
.sa_mask
.sig
[0], oact
->sa_mask
.sig
);
284 err
|= __put_user(0, &oact
->sa_mask
.sig
[1]);
285 err
|= __put_user(0, &oact
->sa_mask
.sig
[2]);
286 err
|= __put_user(0, &oact
->sa_mask
.sig
[3]);
294 asmlinkage
int sys32_sigaltstack(nabi_no_regargs
struct pt_regs regs
)
296 const stack32_t
*uss
= (const stack32_t
*) regs
.regs
[4];
297 stack32_t
*uoss
= (stack32_t
*) regs
.regs
[5];
298 unsigned long usp
= regs
.regs
[29];
301 mm_segment_t old_fs
= get_fs();
305 if (!access_ok(VERIFY_READ
, uss
, sizeof(*uss
)))
307 err
|= __get_user(sp
, &uss
->ss_sp
);
308 kss
.ss_sp
= (void *) (long) sp
;
309 err
|= __get_user(kss
.ss_size
, &uss
->ss_size
);
310 err
|= __get_user(kss
.ss_flags
, &uss
->ss_flags
);
316 ret
= do_sigaltstack(uss
? &kss
: NULL
, uoss
? &koss
: NULL
, usp
);
320 if (!access_ok(VERIFY_WRITE
, uoss
, sizeof(*uoss
)))
322 sp
= (int) (long) koss
.ss_sp
;
323 err
|= __put_user(sp
, &uoss
->ss_sp
);
324 err
|= __put_user(koss
.ss_size
, &uoss
->ss_size
);
325 err
|= __put_user(koss
.ss_flags
, &uoss
->ss_flags
);
332 static int restore_sigcontext32(struct pt_regs
*regs
, struct sigcontext32
*sc
)
337 /* Always make any pending restarted system calls return -EINTR */
338 current_thread_info()->restart_block
.fn
= do_no_restart_syscall
;
340 err
|= __get_user(regs
->cp0_epc
, &sc
->sc_pc
);
341 err
|= __get_user(regs
->hi
, &sc
->sc_mdhi
);
342 err
|= __get_user(regs
->lo
, &sc
->sc_mdlo
);
344 #define restore_gp_reg(i) do { \
345 err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \
347 restore_gp_reg( 1); restore_gp_reg( 2); restore_gp_reg( 3);
348 restore_gp_reg( 4); restore_gp_reg( 5); restore_gp_reg( 6);
349 restore_gp_reg( 7); restore_gp_reg( 8); restore_gp_reg( 9);
350 restore_gp_reg(10); restore_gp_reg(11); restore_gp_reg(12);
351 restore_gp_reg(13); restore_gp_reg(14); restore_gp_reg(15);
352 restore_gp_reg(16); restore_gp_reg(17); restore_gp_reg(18);
353 restore_gp_reg(19); restore_gp_reg(20); restore_gp_reg(21);
354 restore_gp_reg(22); restore_gp_reg(23); restore_gp_reg(24);
355 restore_gp_reg(25); restore_gp_reg(26); restore_gp_reg(27);
356 restore_gp_reg(28); restore_gp_reg(29); restore_gp_reg(30);
358 #undef restore_gp_reg
360 err
|= __get_user(used_math
, &sc
->sc_used_math
);
361 conditional_used_math(used_math
);
366 /* restore fpu context if we have used it before */
368 err
|= restore_fp_context32(sc
);
370 /* signal handler may have used FPU. Give it up. */
380 u32 sf_ass
[4]; /* argument save space for o32 */
381 u32 sf_code
[2]; /* signal trampoline */
382 struct sigcontext32 sf_sc
;
386 struct rt_sigframe32
{
387 u32 rs_ass
[4]; /* argument save space for o32 */
388 u32 rs_code
[2]; /* signal trampoline */
389 compat_siginfo_t rs_info
;
390 struct ucontext32 rs_uc
;
393 int copy_siginfo_to_user32(compat_siginfo_t
*to
, siginfo_t
*from
)
397 if (!access_ok (VERIFY_WRITE
, to
, sizeof(compat_siginfo_t
)))
400 /* If you change siginfo_t structure, please be sure
401 this code is fixed accordingly.
402 It should never copy any pad contained in the structure
403 to avoid security leaks, but must copy the generic
404 3 ints plus the relevant union member.
405 This routine must convert siginfo from 64bit to 32bit as well
407 err
= __put_user(from
->si_signo
, &to
->si_signo
);
408 err
|= __put_user(from
->si_errno
, &to
->si_errno
);
409 err
|= __put_user((short)from
->si_code
, &to
->si_code
);
410 if (from
->si_code
< 0)
411 err
|= __copy_to_user(&to
->_sifields
._pad
, &from
->_sifields
._pad
, SI_PAD_SIZE
);
413 switch (from
->si_code
>> 16) {
414 case __SI_CHLD
>> 16:
415 err
|= __put_user(from
->si_utime
, &to
->si_utime
);
416 err
|= __put_user(from
->si_stime
, &to
->si_stime
);
417 err
|= __put_user(from
->si_status
, &to
->si_status
);
419 err
|= __put_user(from
->si_pid
, &to
->si_pid
);
420 err
|= __put_user(from
->si_uid
, &to
->si_uid
);
422 case __SI_FAULT
>> 16:
423 err
|= __put_user((long)from
->si_addr
, &to
->si_addr
);
425 case __SI_POLL
>> 16:
426 err
|= __put_user(from
->si_band
, &to
->si_band
);
427 err
|= __put_user(from
->si_fd
, &to
->si_fd
);
429 case __SI_RT
>> 16: /* This is not generated by the kernel as of now. */
430 case __SI_MESGQ
>> 16:
431 err
|= __put_user(from
->si_pid
, &to
->si_pid
);
432 err
|= __put_user(from
->si_uid
, &to
->si_uid
);
433 err
|= __put_user(from
->si_int
, &to
->si_int
);
440 save_static_function(sys32_sigreturn
);
441 __attribute_used__ noinline
static void
442 _sys32_sigreturn(nabi_no_regargs
struct pt_regs regs
)
444 struct sigframe
*frame
;
447 frame
= (struct sigframe
*) regs
.regs
[29];
448 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
450 if (__copy_from_user(&blocked
, &frame
->sf_mask
, sizeof(blocked
)))
453 sigdelsetmask(&blocked
, ~_BLOCKABLE
);
454 spin_lock_irq(¤t
->sighand
->siglock
);
455 current
->blocked
= blocked
;
457 spin_unlock_irq(¤t
->sighand
->siglock
);
459 if (restore_sigcontext32(®s
, &frame
->sf_sc
))
463 * Don't let your children do this ...
465 if (current_thread_info()->flags
& TIF_SYSCALL_TRACE
)
466 do_syscall_trace(®s
, 1);
467 __asm__
__volatile__(
475 force_sig(SIGSEGV
, current
);
478 save_static_function(sys32_rt_sigreturn
);
479 __attribute_used__ noinline
static void
480 _sys32_rt_sigreturn(nabi_no_regargs
struct pt_regs regs
)
482 struct rt_sigframe32
*frame
;
487 frame
= (struct rt_sigframe32
*) regs
.regs
[29];
488 if (!access_ok(VERIFY_READ
, frame
, sizeof(*frame
)))
490 if (__copy_from_user(&set
, &frame
->rs_uc
.uc_sigmask
, sizeof(set
)))
493 sigdelsetmask(&set
, ~_BLOCKABLE
);
494 spin_lock_irq(¤t
->sighand
->siglock
);
495 current
->blocked
= set
;
497 spin_unlock_irq(¤t
->sighand
->siglock
);
499 if (restore_sigcontext32(®s
, &frame
->rs_uc
.uc_mcontext
))
502 /* The ucontext contains a stack32_t, so we must convert! */
503 if (__get_user(sp
, &frame
->rs_uc
.uc_stack
.ss_sp
))
505 st
.ss_size
= (long) sp
;
506 if (__get_user(st
.ss_size
, &frame
->rs_uc
.uc_stack
.ss_size
))
508 if (__get_user(st
.ss_flags
, &frame
->rs_uc
.uc_stack
.ss_flags
))
511 /* It is more difficult to avoid calling this function than to
512 call it and ignore errors. */
513 do_sigaltstack(&st
, NULL
, regs
.regs
[29]);
516 * Don't let your children do this ...
518 __asm__
__volatile__(
526 force_sig(SIGSEGV
, current
);
529 static inline int setup_sigcontext32(struct pt_regs
*regs
,
530 struct sigcontext32
*sc
)
534 err
|= __put_user(regs
->cp0_epc
, &sc
->sc_pc
);
535 err
|= __put_user(regs
->cp0_status
, &sc
->sc_status
);
537 #define save_gp_reg(i) { \
538 err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \
540 __put_user(0, &sc
->sc_regs
[0]); save_gp_reg(1); save_gp_reg(2);
541 save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6);
542 save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10);
543 save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14);
544 save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18);
545 save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22);
546 save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26);
547 save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30);
551 err
|= __put_user(regs
->hi
, &sc
->sc_mdhi
);
552 err
|= __put_user(regs
->lo
, &sc
->sc_mdlo
);
553 err
|= __put_user(regs
->cp0_cause
, &sc
->sc_cause
);
554 err
|= __put_user(regs
->cp0_badvaddr
, &sc
->sc_badvaddr
);
556 err
|= __put_user(!!used_math(), &sc
->sc_used_math
);
562 * Save FPU state to signal context. Signal handler will "inherit"
567 if (!is_fpu_owner()) {
571 err
|= save_fp_context32(sc
);
580 * Determine which stack to use..
582 static inline void *get_sigframe(struct k_sigaction
*ka
, struct pt_regs
*regs
,
587 /* Default to using normal stack */
591 * FPU emulator may have it's own trampoline active just
592 * above the user stack, 16-bytes before the next lowest
593 * 16 byte boundary. Try to avoid trashing it.
597 /* This is the X/Open sanctioned signal stack switching. */
598 if ((ka
->sa
.sa_flags
& SA_ONSTACK
) && (sas_ss_flags (sp
) == 0))
599 sp
= current
->sas_ss_sp
+ current
->sas_ss_size
;
601 return (void *)((sp
- frame_size
) & ALMASK
);
604 static inline void setup_frame(struct k_sigaction
* ka
, struct pt_regs
*regs
,
605 int signr
, sigset_t
*set
)
607 struct sigframe
*frame
;
610 frame
= get_sigframe(ka
, regs
, sizeof(*frame
));
611 if (!access_ok(VERIFY_WRITE
, frame
, sizeof (*frame
)))
615 * Set up the return code ...
617 * li v0, __NR_O32_sigreturn
620 err
|= __put_user(0x24020000 + __NR_O32_sigreturn
, frame
->sf_code
+ 0);
621 err
|= __put_user(0x0000000c , frame
->sf_code
+ 1);
622 flush_cache_sigtramp((unsigned long) frame
->sf_code
);
624 err
|= setup_sigcontext32(regs
, &frame
->sf_sc
);
625 err
|= __copy_to_user(&frame
->sf_mask
, set
, sizeof(*set
));
630 * Arguments to signal handler:
633 * a1 = 0 (should be cause)
634 * a2 = pointer to struct sigcontext
636 * $25 and c0_epc point to the signal handler, $29 points to the
639 regs
->regs
[ 4] = signr
;
641 regs
->regs
[ 6] = (unsigned long) &frame
->sf_sc
;
642 regs
->regs
[29] = (unsigned long) frame
;
643 regs
->regs
[31] = (unsigned long) frame
->sf_code
;
644 regs
->cp0_epc
= regs
->regs
[25] = (unsigned long) ka
->sa
.sa_handler
;
647 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
648 current
->comm
, current
->pid
,
649 frame
, regs
->cp0_epc
, frame
->sf_code
);
654 force_sigsegv(signr
, current
);
657 static inline void setup_rt_frame(struct k_sigaction
* ka
,
658 struct pt_regs
*regs
, int signr
,
659 sigset_t
*set
, siginfo_t
*info
)
661 struct rt_sigframe32
*frame
;
665 frame
= get_sigframe(ka
, regs
, sizeof(*frame
));
666 if (!access_ok(VERIFY_WRITE
, frame
, sizeof (*frame
)))
669 /* Set up to return from userspace. If provided, use a stub already
672 * Set up the return code ...
674 * li v0, __NR_O32_rt_sigreturn
677 err
|= __put_user(0x24020000 + __NR_O32_rt_sigreturn
, frame
->rs_code
+ 0);
678 err
|= __put_user(0x0000000c , frame
->rs_code
+ 1);
679 flush_cache_sigtramp((unsigned long) frame
->rs_code
);
681 /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
682 err
|= copy_siginfo_to_user32(&frame
->rs_info
, info
);
684 /* Create the ucontext. */
685 err
|= __put_user(0, &frame
->rs_uc
.uc_flags
);
686 err
|= __put_user(0, &frame
->rs_uc
.uc_link
);
687 sp
= (int) (long) current
->sas_ss_sp
;
688 err
|= __put_user(sp
,
689 &frame
->rs_uc
.uc_stack
.ss_sp
);
690 err
|= __put_user(sas_ss_flags(regs
->regs
[29]),
691 &frame
->rs_uc
.uc_stack
.ss_flags
);
692 err
|= __put_user(current
->sas_ss_size
,
693 &frame
->rs_uc
.uc_stack
.ss_size
);
694 err
|= setup_sigcontext32(regs
, &frame
->rs_uc
.uc_mcontext
);
695 err
|= __copy_to_user(&frame
->rs_uc
.uc_sigmask
, set
, sizeof(*set
));
701 * Arguments to signal handler:
704 * a1 = 0 (should be cause)
705 * a2 = pointer to ucontext
707 * $25 and c0_epc point to the signal handler, $29 points to
708 * the struct rt_sigframe32.
710 regs
->regs
[ 4] = signr
;
711 regs
->regs
[ 5] = (unsigned long) &frame
->rs_info
;
712 regs
->regs
[ 6] = (unsigned long) &frame
->rs_uc
;
713 regs
->regs
[29] = (unsigned long) frame
;
714 regs
->regs
[31] = (unsigned long) frame
->rs_code
;
715 regs
->cp0_epc
= regs
->regs
[25] = (unsigned long) ka
->sa
.sa_handler
;
718 printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n",
719 current
->comm
, current
->pid
,
720 frame
, regs
->cp0_epc
, frame
->rs_code
);
725 force_sigsegv(signr
, current
);
728 static inline void handle_signal(unsigned long sig
, siginfo_t
*info
,
729 struct k_sigaction
*ka
, sigset_t
*oldset
, struct pt_regs
* regs
)
731 switch (regs
->regs
[0]) {
732 case ERESTART_RESTARTBLOCK
:
734 regs
->regs
[2] = EINTR
;
737 if(!(ka
->sa
.sa_flags
& SA_RESTART
)) {
738 regs
->regs
[2] = EINTR
;
742 case ERESTARTNOINTR
: /* Userland will reload $v0. */
743 regs
->regs
[7] = regs
->regs
[26];
747 regs
->regs
[0] = 0; /* Don't deal with this again. */
749 if (ka
->sa
.sa_flags
& SA_SIGINFO
)
750 setup_rt_frame(ka
, regs
, sig
, oldset
, info
);
752 setup_frame(ka
, regs
, sig
, oldset
);
754 if (!(ka
->sa
.sa_flags
& SA_NODEFER
)) {
755 spin_lock_irq(¤t
->sighand
->siglock
);
756 sigorsets(¤t
->blocked
,¤t
->blocked
,&ka
->sa
.sa_mask
);
757 sigaddset(¤t
->blocked
,sig
);
759 spin_unlock_irq(¤t
->sighand
->siglock
);
763 int do_signal32(sigset_t
*oldset
, struct pt_regs
*regs
)
765 struct k_sigaction ka
;
770 * We want the common case to go fast, which is why we may in certain
771 * cases get here from kernel mode. Just return without doing anything
774 if (!user_mode(regs
))
777 if (try_to_freeze(0))
781 oldset
= ¤t
->blocked
;
783 signr
= get_signal_to_deliver(&info
, &ka
, regs
, NULL
);
785 handle_signal(signr
, &info
, &ka
, oldset
, regs
);
791 * Who's code doesn't conform to the restartable syscall convention
792 * dies here!!! The li instruction, a single machine instruction,
793 * must directly be followed by the syscall instruction.
796 if (regs
->regs
[2] == ERESTARTNOHAND
||
797 regs
->regs
[2] == ERESTARTSYS
||
798 regs
->regs
[2] == ERESTARTNOINTR
) {
799 regs
->regs
[7] = regs
->regs
[26];
802 if (regs
->regs
[2] == ERESTART_RESTARTBLOCK
) {
803 regs
->regs
[2] = __NR_O32_restart_syscall
;
804 regs
->regs
[7] = regs
->regs
[26];
811 asmlinkage
int sys32_rt_sigaction(int sig
, const struct sigaction32
*act
,
812 struct sigaction32
*oact
,
813 unsigned int sigsetsize
)
815 struct k_sigaction new_sa
, old_sa
;
818 /* XXX: Don't preclude handling different sized sigset_t's. */
819 if (sigsetsize
!= sizeof(sigset_t
))
825 if (!access_ok(VERIFY_READ
, act
, sizeof(*act
)))
827 err
|= __get_user((u32
)(u64
)new_sa
.sa
.sa_handler
,
829 err
|= __get_user(new_sa
.sa
.sa_flags
, &act
->sa_flags
);
830 err
|= get_sigset(&new_sa
.sa
.sa_mask
, &act
->sa_mask
);
835 ret
= do_sigaction(sig
, act
? &new_sa
: NULL
, oact
? &old_sa
: NULL
);
840 if (!access_ok(VERIFY_WRITE
, oact
, sizeof(*oact
)))
843 err
|= __put_user((u32
)(u64
)old_sa
.sa
.sa_handler
,
845 err
|= __put_user(old_sa
.sa
.sa_flags
, &oact
->sa_flags
);
846 err
|= put_sigset(&old_sa
.sa
.sa_mask
, &oact
->sa_mask
);
854 asmlinkage
int sys32_rt_sigprocmask(int how
, compat_sigset_t
*set
,
855 compat_sigset_t
*oset
, unsigned int sigsetsize
)
857 sigset_t old_set
, new_set
;
859 mm_segment_t old_fs
= get_fs();
861 if (set
&& get_sigset(&new_set
, set
))
865 ret
= sys_rt_sigprocmask(how
, set
? &new_set
: NULL
,
866 oset
? &old_set
: NULL
, sigsetsize
);
869 if (!ret
&& oset
&& put_sigset(&old_set
, oset
))
875 asmlinkage
int sys32_rt_sigpending(compat_sigset_t
*uset
,
876 unsigned int sigsetsize
)
880 mm_segment_t old_fs
= get_fs();
883 ret
= sys_rt_sigpending(&set
, sigsetsize
);
886 if (!ret
&& put_sigset(&set
, uset
))
892 asmlinkage
int sys32_rt_sigqueueinfo(int pid
, int sig
, compat_siginfo_t
*uinfo
)
896 mm_segment_t old_fs
= get_fs();
898 if (copy_from_user (&info
, uinfo
, 3*sizeof(int)) ||
899 copy_from_user (info
._sifields
._pad
, uinfo
->_sifields
._pad
, SI_PAD_SIZE
))
902 ret
= sys_rt_sigqueueinfo(pid
, sig
, &info
);