Root/arch/s390/kernel/compat_signal.c

1/*
2 * arch/s390/kernel/compat_signal.c
3 *
4 * Copyright (C) IBM Corp. 2000,2006
5 * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
6 * Gerhard Tonn (ton@de.ibm.com)
7 *
8 * Copyright (C) 1991, 1992 Linus Torvalds
9 *
10 * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson
11 */
12
13#include <linux/compat.h>
14#include <linux/sched.h>
15#include <linux/mm.h>
16#include <linux/smp.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/tty.h>
25#include <linux/personality.h>
26#include <linux/binfmts.h>
27#include <asm/ucontext.h>
28#include <asm/uaccess.h>
29#include <asm/lowcore.h>
30#include "compat_linux.h"
31#include "compat_ptrace.h"
32#include "entry.h"
33
34#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
35
36typedef struct
37{
38    __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
39    struct sigcontext32 sc;
40    _sigregs32 sregs;
41    int signo;
42    __u32 gprs_high[NUM_GPRS];
43    __u8 retcode[S390_SYSCALL_SIZE];
44} sigframe32;
45
46typedef struct
47{
48    __u8 callee_used_stack[__SIGNAL_FRAMESIZE32];
49    __u8 retcode[S390_SYSCALL_SIZE];
50    compat_siginfo_t info;
51    struct ucontext32 uc;
52    __u32 gprs_high[NUM_GPRS];
53} rt_sigframe32;
54
55int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
56{
57    int err;
58
59    if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
60        return -EFAULT;
61
62    /* If you change siginfo_t structure, please be sure
63       this code is fixed accordingly.
64       It should never copy any pad contained in the structure
65       to avoid security leaks, but must copy the generic
66       3 ints plus the relevant union member.
67       This routine must convert siginfo from 64bit to 32bit as well
68       at the same time. */
69    err = __put_user(from->si_signo, &to->si_signo);
70    err |= __put_user(from->si_errno, &to->si_errno);
71    err |= __put_user((short)from->si_code, &to->si_code);
72    if (from->si_code < 0)
73        err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
74    else {
75        switch (from->si_code >> 16) {
76        case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
77        case __SI_MESGQ >> 16:
78            err |= __put_user(from->si_int, &to->si_int);
79            /* fallthrough */
80        case __SI_KILL >> 16:
81            err |= __put_user(from->si_pid, &to->si_pid);
82            err |= __put_user(from->si_uid, &to->si_uid);
83            break;
84        case __SI_CHLD >> 16:
85            err |= __put_user(from->si_pid, &to->si_pid);
86            err |= __put_user(from->si_uid, &to->si_uid);
87            err |= __put_user(from->si_utime, &to->si_utime);
88            err |= __put_user(from->si_stime, &to->si_stime);
89            err |= __put_user(from->si_status, &to->si_status);
90            break;
91        case __SI_FAULT >> 16:
92            err |= __put_user((unsigned long) from->si_addr,
93                      &to->si_addr);
94            break;
95        case __SI_POLL >> 16:
96            err |= __put_user(from->si_band, &to->si_band);
97            err |= __put_user(from->si_fd, &to->si_fd);
98            break;
99        case __SI_TIMER >> 16:
100            err |= __put_user(from->si_tid, &to->si_tid);
101            err |= __put_user(from->si_overrun, &to->si_overrun);
102            err |= __put_user(from->si_int, &to->si_int);
103            break;
104        default:
105            break;
106        }
107    }
108    return err;
109}
110
111int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
112{
113    int err;
114    u32 tmp;
115
116    if (!access_ok (VERIFY_READ, from, sizeof(compat_siginfo_t)))
117        return -EFAULT;
118
119    err = __get_user(to->si_signo, &from->si_signo);
120    err |= __get_user(to->si_errno, &from->si_errno);
121    err |= __get_user(to->si_code, &from->si_code);
122
123    if (to->si_code < 0)
124        err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
125    else {
126        switch (to->si_code >> 16) {
127        case __SI_RT >> 16: /* This is not generated by the kernel as of now. */
128        case __SI_MESGQ >> 16:
129            err |= __get_user(to->si_int, &from->si_int);
130            /* fallthrough */
131        case __SI_KILL >> 16:
132            err |= __get_user(to->si_pid, &from->si_pid);
133            err |= __get_user(to->si_uid, &from->si_uid);
134            break;
135        case __SI_CHLD >> 16:
136            err |= __get_user(to->si_pid, &from->si_pid);
137            err |= __get_user(to->si_uid, &from->si_uid);
138            err |= __get_user(to->si_utime, &from->si_utime);
139            err |= __get_user(to->si_stime, &from->si_stime);
140            err |= __get_user(to->si_status, &from->si_status);
141            break;
142        case __SI_FAULT >> 16:
143            err |= __get_user(tmp, &from->si_addr);
144            to->si_addr = (void __user *)(u64) (tmp & PSW32_ADDR_INSN);
145            break;
146        case __SI_POLL >> 16:
147            err |= __get_user(to->si_band, &from->si_band);
148            err |= __get_user(to->si_fd, &from->si_fd);
149            break;
150        case __SI_TIMER >> 16:
151            err |= __get_user(to->si_tid, &from->si_tid);
152            err |= __get_user(to->si_overrun, &from->si_overrun);
153            err |= __get_user(to->si_int, &from->si_int);
154            break;
155        default:
156            break;
157        }
158    }
159    return err;
160}
161
162asmlinkage long
163sys32_sigaction(int sig, const struct old_sigaction32 __user *act,
164         struct old_sigaction32 __user *oact)
165{
166        struct k_sigaction new_ka, old_ka;
167    unsigned long sa_handler, sa_restorer;
168        int ret;
169
170        if (act) {
171        compat_old_sigset_t mask;
172        if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
173            __get_user(sa_handler, &act->sa_handler) ||
174            __get_user(sa_restorer, &act->sa_restorer) ||
175            __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
176            __get_user(mask, &act->sa_mask))
177            return -EFAULT;
178        new_ka.sa.sa_handler = (__sighandler_t) sa_handler;
179        new_ka.sa.sa_restorer = (void (*)(void)) sa_restorer;
180        siginitset(&new_ka.sa.sa_mask, mask);
181        }
182
183        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
184
185    if (!ret && oact) {
186        sa_handler = (unsigned long) old_ka.sa.sa_handler;
187        sa_restorer = (unsigned long) old_ka.sa.sa_restorer;
188        if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
189            __put_user(sa_handler, &oact->sa_handler) ||
190            __put_user(sa_restorer, &oact->sa_restorer) ||
191            __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
192            __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
193            return -EFAULT;
194        }
195
196    return ret;
197}
198
199asmlinkage long
200sys32_rt_sigaction(int sig, const struct sigaction32 __user *act,
201       struct sigaction32 __user *oact, size_t sigsetsize)
202{
203    struct k_sigaction new_ka, old_ka;
204    unsigned long sa_handler;
205    int ret;
206    compat_sigset_t set32;
207
208    /* XXX: Don't preclude handling different sized sigset_t's. */
209    if (sigsetsize != sizeof(compat_sigset_t))
210        return -EINVAL;
211
212    if (act) {
213        ret = get_user(sa_handler, &act->sa_handler);
214        ret |= __copy_from_user(&set32, &act->sa_mask,
215                    sizeof(compat_sigset_t));
216        switch (_NSIG_WORDS) {
217        case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6]
218                | (((long)set32.sig[7]) << 32);
219        case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4]
220                | (((long)set32.sig[5]) << 32);
221        case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2]
222                | (((long)set32.sig[3]) << 32);
223        case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0]
224                | (((long)set32.sig[1]) << 32);
225        }
226        ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
227        
228        if (ret)
229            return -EFAULT;
230        new_ka.sa.sa_handler = (__sighandler_t) sa_handler;
231    }
232
233    ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
234
235    if (!ret && oact) {
236        switch (_NSIG_WORDS) {
237        case 4:
238            set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32);
239            set32.sig[6] = old_ka.sa.sa_mask.sig[3];
240        case 3:
241            set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32);
242            set32.sig[4] = old_ka.sa.sa_mask.sig[2];
243        case 2:
244            set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32);
245            set32.sig[2] = old_ka.sa.sa_mask.sig[1];
246        case 1:
247            set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32);
248            set32.sig[0] = old_ka.sa.sa_mask.sig[0];
249        }
250        ret = put_user((unsigned long)old_ka.sa.sa_handler, &oact->sa_handler);
251        ret |= __copy_to_user(&oact->sa_mask, &set32,
252                      sizeof(compat_sigset_t));
253        ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
254    }
255
256    return ret;
257}
258
259asmlinkage long
260sys32_sigaltstack(const stack_t32 __user *uss, stack_t32 __user *uoss)
261{
262    struct pt_regs *regs = task_pt_regs(current);
263    stack_t kss, koss;
264    unsigned long ss_sp;
265    int ret, err = 0;
266    mm_segment_t old_fs = get_fs();
267
268    if (uss) {
269        if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
270            return -EFAULT;
271        err |= __get_user(ss_sp, &uss->ss_sp);
272        err |= __get_user(kss.ss_size, &uss->ss_size);
273        err |= __get_user(kss.ss_flags, &uss->ss_flags);
274        if (err)
275            return -EFAULT;
276        kss.ss_sp = (void __user *) ss_sp;
277    }
278
279    set_fs (KERNEL_DS);
280    ret = do_sigaltstack((stack_t __force __user *) (uss ? &kss : NULL),
281                 (stack_t __force __user *) (uoss ? &koss : NULL),
282                 regs->gprs[15]);
283    set_fs (old_fs);
284
285    if (!ret && uoss) {
286        if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
287            return -EFAULT;
288        ss_sp = (unsigned long) koss.ss_sp;
289        err |= __put_user(ss_sp, &uoss->ss_sp);
290        err |= __put_user(koss.ss_size, &uoss->ss_size);
291        err |= __put_user(koss.ss_flags, &uoss->ss_flags);
292        if (err)
293            return -EFAULT;
294    }
295    return ret;
296}
297
298static int save_sigregs32(struct pt_regs *regs, _sigregs32 __user *sregs)
299{
300    _s390_regs_common32 regs32;
301    int err, i;
302
303    regs32.psw.mask = PSW32_MASK_MERGE(psw32_user_bits,
304                       (__u32)(regs->psw.mask >> 32));
305    regs32.psw.addr = PSW32_ADDR_AMODE31 | (__u32) regs->psw.addr;
306    for (i = 0; i < NUM_GPRS; i++)
307        regs32.gprs[i] = (__u32) regs->gprs[i];
308    save_access_regs(current->thread.acrs);
309    memcpy(regs32.acrs, current->thread.acrs, sizeof(regs32.acrs));
310    err = __copy_to_user(&sregs->regs, &regs32, sizeof(regs32));
311    if (err)
312        return err;
313    save_fp_regs(&current->thread.fp_regs);
314    /* s390_fp_regs and _s390_fp_regs32 are the same ! */
315    return __copy_to_user(&sregs->fpregs, &current->thread.fp_regs,
316                  sizeof(_s390_fp_regs32));
317}
318
319static int restore_sigregs32(struct pt_regs *regs,_sigregs32 __user *sregs)
320{
321    _s390_regs_common32 regs32;
322    int err, i;
323
324    /* Alwys make any pending restarted system call return -EINTR */
325    current_thread_info()->restart_block.fn = do_no_restart_syscall;
326
327    err = __copy_from_user(&regs32, &sregs->regs, sizeof(regs32));
328    if (err)
329        return err;
330    regs->psw.mask = PSW_MASK_MERGE(regs->psw.mask,
331                        (__u64)regs32.psw.mask << 32);
332    regs->psw.addr = (__u64)(regs32.psw.addr & PSW32_ADDR_INSN);
333    for (i = 0; i < NUM_GPRS; i++)
334        regs->gprs[i] = (__u64) regs32.gprs[i];
335    memcpy(current->thread.acrs, regs32.acrs, sizeof(current->thread.acrs));
336    restore_access_regs(current->thread.acrs);
337
338    err = __copy_from_user(&current->thread.fp_regs, &sregs->fpregs,
339                   sizeof(_s390_fp_regs32));
340    current->thread.fp_regs.fpc &= FPC_VALID_MASK;
341    if (err)
342        return err;
343
344    restore_fp_regs(&current->thread.fp_regs);
345    regs->svcnr = 0; /* disable syscall checks */
346    return 0;
347}
348
349static int save_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs)
350{
351    __u32 gprs_high[NUM_GPRS];
352    int i;
353
354    for (i = 0; i < NUM_GPRS; i++)
355        gprs_high[i] = regs->gprs[i] >> 32;
356
357    return __copy_to_user(uregs, &gprs_high, sizeof(gprs_high));
358}
359
360static int restore_sigregs_gprs_high(struct pt_regs *regs, __u32 __user *uregs)
361{
362    __u32 gprs_high[NUM_GPRS];
363    int err, i;
364
365    err = __copy_from_user(&gprs_high, uregs, sizeof(gprs_high));
366    if (err)
367        return err;
368    for (i = 0; i < NUM_GPRS; i++)
369        *(__u32 *)&regs->gprs[i] = gprs_high[i];
370    return 0;
371}
372
373asmlinkage long sys32_sigreturn(void)
374{
375    struct pt_regs *regs = task_pt_regs(current);
376    sigframe32 __user *frame = (sigframe32 __user *)regs->gprs[15];
377    sigset_t set;
378
379    if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
380        goto badframe;
381    if (__copy_from_user(&set.sig, &frame->sc.oldmask, _SIGMASK_COPY_SIZE32))
382        goto badframe;
383
384    sigdelsetmask(&set, ~_BLOCKABLE);
385    spin_lock_irq(&current->sighand->siglock);
386    current->blocked = set;
387    recalc_sigpending();
388    spin_unlock_irq(&current->sighand->siglock);
389
390    if (restore_sigregs32(regs, &frame->sregs))
391        goto badframe;
392    if (restore_sigregs_gprs_high(regs, frame->gprs_high))
393        goto badframe;
394
395    return regs->gprs[2];
396
397badframe:
398    force_sig(SIGSEGV, current);
399    return 0;
400}
401
402asmlinkage long sys32_rt_sigreturn(void)
403{
404    struct pt_regs *regs = task_pt_regs(current);
405    rt_sigframe32 __user *frame = (rt_sigframe32 __user *)regs->gprs[15];
406    sigset_t set;
407    stack_t st;
408    __u32 ss_sp;
409    int err;
410    mm_segment_t old_fs = get_fs();
411
412    if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
413        goto badframe;
414    if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
415        goto badframe;
416
417    sigdelsetmask(&set, ~_BLOCKABLE);
418    spin_lock_irq(&current->sighand->siglock);
419    current->blocked = set;
420    recalc_sigpending();
421    spin_unlock_irq(&current->sighand->siglock);
422
423    if (restore_sigregs32(regs, &frame->uc.uc_mcontext))
424        goto badframe;
425    if (restore_sigregs_gprs_high(regs, frame->gprs_high))
426        goto badframe;
427
428    err = __get_user(ss_sp, &frame->uc.uc_stack.ss_sp);
429    st.ss_sp = compat_ptr(ss_sp);
430    err |= __get_user(st.ss_size, &frame->uc.uc_stack.ss_size);
431    err |= __get_user(st.ss_flags, &frame->uc.uc_stack.ss_flags);
432    if (err)
433        goto badframe;
434
435    set_fs (KERNEL_DS);
436    do_sigaltstack((stack_t __force __user *)&st, NULL, regs->gprs[15]);
437    set_fs (old_fs);
438
439    return regs->gprs[2];
440
441badframe:
442    force_sig(SIGSEGV, current);
443    return 0;
444}
445
446/*
447 * Set up a signal frame.
448 */
449
450
451/*
452 * Determine which stack to use..
453 */
454static inline void __user *
455get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
456{
457    unsigned long sp;
458
459    /* Default to using normal stack */
460    sp = (unsigned long) A(regs->gprs[15]);
461
462    /* Overflow on alternate signal stack gives SIGSEGV. */
463    if (on_sig_stack(sp) && !on_sig_stack((sp - frame_size) & -8UL))
464        return (void __user *) -1UL;
465
466    /* This is the X/Open sanctioned signal stack switching. */
467    if (ka->sa.sa_flags & SA_ONSTACK) {
468        if (! sas_ss_flags(sp))
469            sp = current->sas_ss_sp + current->sas_ss_size;
470    }
471
472    /* This is the legacy signal stack switching. */
473    else if (!user_mode(regs) &&
474         !(ka->sa.sa_flags & SA_RESTORER) &&
475         ka->sa.sa_restorer) {
476        sp = (unsigned long) ka->sa.sa_restorer;
477    }
478
479    return (void __user *)((sp - frame_size) & -8ul);
480}
481
482static inline int map_signal(int sig)
483{
484    if (current_thread_info()->exec_domain
485        && current_thread_info()->exec_domain->signal_invmap
486        && sig < 32)
487        return current_thread_info()->exec_domain->signal_invmap[sig];
488        else
489        return sig;
490}
491
492static int setup_frame32(int sig, struct k_sigaction *ka,
493            sigset_t *set, struct pt_regs * regs)
494{
495    sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(sigframe32));
496    if (!access_ok(VERIFY_WRITE, frame, sizeof(sigframe32)))
497        goto give_sigsegv;
498
499    if (frame == (void __user *) -1UL)
500        goto give_sigsegv;
501
502    if (__copy_to_user(&frame->sc.oldmask, &set->sig, _SIGMASK_COPY_SIZE32))
503        goto give_sigsegv;
504
505    if (save_sigregs32(regs, &frame->sregs))
506        goto give_sigsegv;
507    if (save_sigregs_gprs_high(regs, frame->gprs_high))
508        goto give_sigsegv;
509    if (__put_user((unsigned long) &frame->sregs, &frame->sc.sregs))
510        goto give_sigsegv;
511
512    /* Set up to return from userspace. If provided, use a stub
513       already in userspace. */
514    if (ka->sa.sa_flags & SA_RESTORER) {
515        regs->gprs[14] = (__u64) ka->sa.sa_restorer;
516    } else {
517        regs->gprs[14] = (__u64) frame->retcode;
518        if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn,
519                       (u16 __user *)(frame->retcode)))
520            goto give_sigsegv;
521        }
522
523    /* Set up backchain. */
524    if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
525        goto give_sigsegv;
526
527    /* Set up registers for signal handler */
528    regs->gprs[15] = (__u64) frame;
529    regs->psw.addr = (__u64) ka->sa.sa_handler;
530
531    regs->gprs[2] = map_signal(sig);
532    regs->gprs[3] = (__u64) &frame->sc;
533
534    /* We forgot to include these in the sigcontext.
535       To avoid breaking binary compatibility, they are passed as args. */
536    regs->gprs[4] = current->thread.trap_no;
537    regs->gprs[5] = current->thread.prot_addr;
538
539    /* Place signal number on stack to allow backtrace from handler. */
540    if (__put_user(regs->gprs[2], (int __user *) &frame->signo))
541        goto give_sigsegv;
542    return 0;
543
544give_sigsegv:
545    force_sigsegv(sig, current);
546    return -EFAULT;
547}
548
549static int setup_rt_frame32(int sig, struct k_sigaction *ka, siginfo_t *info,
550               sigset_t *set, struct pt_regs * regs)
551{
552    int err = 0;
553    rt_sigframe32 __user *frame = get_sigframe(ka, regs, sizeof(rt_sigframe32));
554    if (!access_ok(VERIFY_WRITE, frame, sizeof(rt_sigframe32)))
555        goto give_sigsegv;
556
557    if (frame == (void __user *) -1UL)
558        goto give_sigsegv;
559
560    if (copy_siginfo_to_user32(&frame->info, info))
561        goto give_sigsegv;
562
563    /* Create the ucontext. */
564    err |= __put_user(UC_EXTENDED, &frame->uc.uc_flags);
565    err |= __put_user(0, &frame->uc.uc_link);
566    err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
567    err |= __put_user(sas_ss_flags(regs->gprs[15]),
568                      &frame->uc.uc_stack.ss_flags);
569    err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
570    err |= save_sigregs32(regs, &frame->uc.uc_mcontext);
571    err |= save_sigregs_gprs_high(regs, frame->gprs_high);
572    err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
573    if (err)
574        goto give_sigsegv;
575
576    /* Set up to return from userspace. If provided, use a stub
577       already in userspace. */
578    if (ka->sa.sa_flags & SA_RESTORER) {
579        regs->gprs[14] = (__u64) ka->sa.sa_restorer;
580    } else {
581        regs->gprs[14] = (__u64) frame->retcode;
582        err |= __put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn,
583                          (u16 __user *)(frame->retcode));
584    }
585
586    /* Set up backchain. */
587    if (__put_user(regs->gprs[15], (unsigned int __user *) frame))
588        goto give_sigsegv;
589
590    /* Set up registers for signal handler */
591    regs->gprs[15] = (__u64) frame;
592    regs->psw.addr = (__u64) ka->sa.sa_handler;
593
594    regs->gprs[2] = map_signal(sig);
595    regs->gprs[3] = (__u64) &frame->info;
596    regs->gprs[4] = (__u64) &frame->uc;
597    return 0;
598
599give_sigsegv:
600    force_sigsegv(sig, current);
601    return -EFAULT;
602}
603
604/*
605 * OK, we're invoking a handler
606 */
607
608int
609handle_signal32(unsigned long sig, struct k_sigaction *ka,
610        siginfo_t *info, sigset_t *oldset, struct pt_regs * regs)
611{
612    int ret;
613
614    /* Set up the stack frame */
615    if (ka->sa.sa_flags & SA_SIGINFO)
616        ret = setup_rt_frame32(sig, ka, info, oldset, regs);
617    else
618        ret = setup_frame32(sig, ka, oldset, regs);
619
620    if (ret == 0) {
621        spin_lock_irq(&current->sighand->siglock);
622        sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
623        if (!(ka->sa.sa_flags & SA_NODEFER))
624            sigaddset(&current->blocked,sig);
625        recalc_sigpending();
626        spin_unlock_irq(&current->sighand->siglock);
627    }
628    return ret;
629}
630
631

Archive Download this file



interactive