Merge git://git.skbuff.net/gitroot/yoshfuji/linux-2.6-git-rfc3542
[linux-2.6] / arch / xtensa / kernel / signal.c
1 // TODO coprocessor stuff
2 /*
3  *  linux/arch/xtensa/kernel/signal.c
4  *
5  *  Copyright (C) 1991, 1992  Linus Torvalds
6  *  1997-11-28  Modified for POSIX.1b signals by Richard Henderson
7  *
8  *  Joe Taylor <joe@tensilica.com>
9  *  Chris Zankel <chris@zankel.net>
10  *
11  *
12  *
13  */
14
15 #include <xtensa/config/core.h>
16 #include <xtensa/hal.h>
17 #include <linux/sched.h>
18 #include <linux/mm.h>
19 #include <linux/smp.h>
20 #include <linux/smp_lock.h>
21 #include <linux/kernel.h>
22 #include <linux/signal.h>
23 #include <linux/errno.h>
24 #include <linux/wait.h>
25 #include <linux/ptrace.h>
26 #include <linux/unistd.h>
27 #include <linux/stddef.h>
28 #include <linux/personality.h>
29 #include <asm/ucontext.h>
30 #include <asm/uaccess.h>
31 #include <asm/pgtable.h>
32 #include <asm/cacheflush.h>
33
34 #define DEBUG_SIG  0
35
36 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
37
38 asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr, int options,
39                           struct rusage * ru);
40 asmlinkage int do_signal(struct pt_regs *regs, sigset_t *oldset);
41
42 extern struct task_struct *coproc_owners[];
43
44
45 /*
46  * Atomically swap in the new signal mask, and wait for a signal.
47  */
48
49 int sys_sigsuspend(struct pt_regs *regs)
50 {
51         old_sigset_t mask = (old_sigset_t) regs->areg[3];
52         sigset_t saveset;
53
54         mask &= _BLOCKABLE;
55         spin_lock_irq(&current->sighand->siglock);
56         saveset = current->blocked;
57         siginitset(&current->blocked, mask);
58         recalc_sigpending();
59         spin_unlock_irq(&current->sighand->siglock);
60
61         regs->areg[2] = -EINTR;
62         while (1) {
63                 current->state = TASK_INTERRUPTIBLE;
64                 schedule();
65                 if (do_signal(regs, &saveset))
66                         return -EINTR;
67         }
68 }
69
70 asmlinkage int
71 sys_rt_sigsuspend(struct pt_regs *regs)
72 {
73         sigset_t *unewset = (sigset_t *) regs->areg[4];
74         size_t sigsetsize = (size_t) regs->areg[3];
75         sigset_t saveset, newset;
76         /* XXX: Don't preclude handling different sized sigset_t's.  */
77         if (sigsetsize != sizeof(sigset_t))
78                 return -EINVAL;
79
80         if (copy_from_user(&newset, unewset, sizeof(newset)))
81                 return -EFAULT;
82         sigdelsetmask(&newset, ~_BLOCKABLE);
83         spin_lock_irq(&current->sighand->siglock);
84         saveset = current->blocked;
85         current->blocked = newset;
86         recalc_sigpending();
87         spin_unlock_irq(&current->sighand->siglock);
88
89         regs->areg[2] = -EINTR;
90         while (1) {
91                 current->state = TASK_INTERRUPTIBLE;
92                 schedule();
93                 if (do_signal(regs, &saveset))
94                         return -EINTR;
95         }
96 }
97
98 asmlinkage int
99 sys_sigaction(int sig, const struct old_sigaction *act,
100               struct old_sigaction *oact)
101 {
102         struct k_sigaction new_ka, old_ka;
103         int ret;
104
105         if (act) {
106                 old_sigset_t mask;
107                 if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
108                     __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
109                     __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
110                         return -EFAULT;
111                 __get_user(new_ka.sa.sa_flags, &act->sa_flags);
112                 __get_user(mask, &act->sa_mask);
113                 siginitset(&new_ka.sa.sa_mask, mask);
114         }
115
116         ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
117
118         if (!ret && oact) {
119                 if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
120                     __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
121                     __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
122                         return -EFAULT;
123                 __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
124                 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
125         }
126
127         return ret;
128 }
129
130 asmlinkage int
131 sys_sigaltstack(struct pt_regs *regs)
132 {
133         const stack_t *uss = (stack_t *) regs->areg[4];
134         stack_t *uoss = (stack_t *) regs->areg[3];
135
136         if (regs->depc > 64)
137                 panic ("Double exception sys_sigreturn\n");
138
139
140         return do_sigaltstack(uss, uoss, regs->areg[1]);
141 }
142
143
144 /*
145  * Do a signal return; undo the signal stack.
146  */
147
148 struct sigframe
149 {
150         struct sigcontext sc;
151         struct _cpstate cpstate;
152         unsigned long extramask[_NSIG_WORDS-1];
153         unsigned char retcode[6];
154         unsigned int reserved[4]; /* Reserved area for chaining */
155         unsigned int window[4]; /* Window of 4 registers for initial context */
156 };
157
158 struct rt_sigframe
159 {
160         struct siginfo info;
161         struct ucontext uc;
162         struct _cpstate cpstate;
163         unsigned char retcode[6];
164         unsigned int reserved[4]; /* Reserved area for chaining */
165         unsigned int window[4]; /* Window of 4 registers for initial context */
166 };
167
168 extern void release_all_cp (struct task_struct *);
169
170
171 // FIXME restore_cpextra
172 static inline int
173 restore_cpextra (struct _cpstate *buf)
174 {
175 #if 0
176         /* The signal handler may have used coprocessors in which
177          * case they are still enabled.  We disable them to force a
178          * reloading of the original task's CP state by the lazy
179          * context-switching mechanisms of CP exception handling.
180          * Also, we essentially discard any coprocessor state that the
181          * signal handler created. */
182
183         struct task_struct *tsk = current;
184         release_all_cp(tsk);
185         return __copy_from_user(tsk->thread.cpextra, buf, TOTAL_CPEXTRA_SIZE);
186 #endif
187         return 0;
188 }
189
190 /* Note: We don't copy double exception 'tregs', we have to finish double exc. first before we return to signal handler! This dbl.exc.handler might cause another double exception, but I think we are fine as the situation is the same as if we had returned to the signal handerl and got an interrupt immediately...
191  */
192
193
194 static int
195 restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc)
196 {
197         struct thread_struct *thread;
198         unsigned int err = 0;
199         unsigned long ps;
200         struct _cpstate *buf;
201
202 #define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
203         COPY(pc);
204         COPY(depc);
205         COPY(wmask);
206         COPY(lbeg);
207         COPY(lend);
208         COPY(lcount);
209         COPY(sar);
210         COPY(windowbase);
211         COPY(windowstart);
212 #undef COPY
213
214         /* For PS, restore only PS.CALLINC.
215          * Assume that all other bits are either the same as for the signal
216          * handler, or the user mode value doesn't matter (e.g. PS.OWB).
217          */
218         err |= __get_user(ps, &sc->sc_ps);
219         regs->ps = (regs->ps & ~XCHAL_PS_CALLINC_MASK)
220                 | (ps & XCHAL_PS_CALLINC_MASK);
221
222         /* Additional corruption checks */
223
224         if ((regs->windowbase >= (XCHAL_NUM_AREGS/4))
225         || ((regs->windowstart & ~((1<<(XCHAL_NUM_AREGS/4)) - 1)) != 0) )
226                 err = 1;
227         if ((regs->lcount > 0)
228         && ((regs->lbeg > TASK_SIZE) || (regs->lend > TASK_SIZE)) )
229                 err = 1;
230
231         /* Restore extended register state.
232          * See struct thread_struct in processor.h.
233          */
234         thread = &current->thread;
235
236         err |= __copy_from_user (regs->areg, sc->sc_areg, XCHAL_NUM_AREGS*4);
237         err |= __get_user(buf, &sc->sc_cpstate);
238         if (buf) {
239                 if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
240                         goto badframe;
241                 err |= restore_cpextra(buf);
242         }
243
244         regs->syscall = -1;             /* disable syscall checks */
245         return err;
246
247 badframe:
248         return 1;
249 }
250
251 static inline void
252 flush_my_cpstate(struct task_struct *tsk)
253 {
254         unsigned long flags;
255         local_irq_save(flags);
256
257 #if 0   // FIXME
258         for (i = 0; i < XCHAL_CP_NUM; i++) {
259                 if (tsk == coproc_owners[i]) {
260                         xthal_validate_cp(i);
261                         xthal_save_cpregs(tsk->thread.cpregs_ptr[i], i);
262
263                         /* Invalidate and "disown" the cp to allow
264                          * callers the chance to reset cp state in the
265                          * task_struct. */
266
267                         xthal_invalidate_cp(i);
268                         coproc_owners[i] = 0;
269                 }
270         }
271 #endif
272         local_irq_restore(flags);
273 }
274
275 /* Return codes:
276         0:  nothing saved
277         1:  stuff to save, successful
278        -1:  stuff to save, error happened
279 */
280 static int
281 save_cpextra (struct _cpstate *buf)
282 {
283 #if (XCHAL_EXTRA_SA_SIZE == 0) && (XCHAL_CP_NUM == 0)
284         return 0;
285 #else
286
287         /* FIXME: If a task has never used a coprocessor, there is
288          * no need to save and restore anything.  Tracking this
289          * information would allow us to optimize this section.
290          * Perhaps we can use current->used_math or (current->flags &
291          * PF_USEDFPU) or define a new field in the thread
292          * structure. */
293
294         /* We flush any live, task-owned cp state to the task_struct,
295          * then copy it all to the sigframe.  Then we clear all
296          * cp/extra state in the task_struct, effectively
297          * clearing/resetting all cp/extra state for the signal
298          * handler (cp-exception handling will load these new values
299          * into the cp/extra registers.)  This step is important for
300          * things like a floating-point cp, where the OS must reset
301          * the FCR to the default rounding mode. */
302
303         int err = 0;
304         struct task_struct *tsk = current;
305
306         flush_my_cpstate(tsk);
307         /* Note that we just copy everything: 'extra' and 'cp' state together.*/
308         err |= __copy_to_user(buf, tsk->thread.cp_save, XTENSA_CP_EXTRA_SIZE);
309         memset(tsk->thread.cp_save, 0, XTENSA_CP_EXTRA_SIZE);
310
311 #if (XTENSA_CP_EXTRA_SIZE == 0)
312 #error Sanity check on memset above, cpextra_size should not be zero.
313 #endif
314
315         return err ? -1 : 1;
316 #endif
317 }
318
319 static int
320 setup_sigcontext(struct sigcontext *sc, struct _cpstate *cpstate,
321                  struct pt_regs *regs, unsigned long mask)
322 {
323         struct thread_struct *thread;
324         int err = 0;
325
326 //printk("setup_sigcontext\n");
327 #define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
328         COPY(pc);
329         COPY(ps);
330         COPY(depc);
331         COPY(wmask);
332         COPY(lbeg);
333         COPY(lend);
334         COPY(lcount);
335         COPY(sar);
336         COPY(windowbase);
337         COPY(windowstart);
338 #undef COPY
339
340         /* Save extended register state.
341          * See struct thread_struct in processor.h.
342          */
343         thread = &current->thread;
344         err |= __copy_to_user (sc->sc_areg, regs->areg, XCHAL_NUM_AREGS * 4);
345         err |= save_cpextra(cpstate);
346         err |= __put_user(err ? NULL : cpstate, &sc->sc_cpstate);
347         /* non-iBCS2 extensions.. */
348         err |= __put_user(mask, &sc->oldmask);
349
350         return err;
351 }
352
353 asmlinkage int sys_sigreturn(struct pt_regs *regs)
354 {
355         struct sigframe *frame = (struct sigframe *)regs->areg[1];
356         sigset_t set;
357         if (regs->depc > 64)
358                 panic ("Double exception sys_sigreturn\n");
359
360         if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
361                 goto badframe;
362
363         if (__get_user(set.sig[0], &frame->sc.oldmask)
364             || (_NSIG_WORDS > 1
365                 && __copy_from_user(&set.sig[1], &frame->extramask,
366                                     sizeof(frame->extramask))))
367                 goto badframe;
368
369         sigdelsetmask(&set, ~_BLOCKABLE);
370
371         spin_lock_irq(&current->sighand->siglock);
372         current->blocked = set;
373         recalc_sigpending();
374         spin_unlock_irq(&current->sighand->siglock);
375
376         if (restore_sigcontext(regs, &frame->sc))
377                 goto badframe;
378         return regs->areg[2];
379
380 badframe:
381         force_sig(SIGSEGV, current);
382         return 0;
383 }
384
385 asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
386 {
387         struct rt_sigframe *frame = (struct rt_sigframe *)regs->areg[1];
388         sigset_t set;
389         stack_t st;
390         int ret;
391         if (regs->depc > 64)
392         {
393                 printk("!!!!!!! DEPC !!!!!!!\n");
394                 return 0;
395         }
396
397         if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
398                 goto badframe;
399
400         if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
401                 goto badframe;
402
403         sigdelsetmask(&set, ~_BLOCKABLE);
404         spin_lock_irq(&current->sighand->siglock);
405         current->blocked = set;
406         recalc_sigpending();
407         spin_unlock_irq(&current->sighand->siglock);
408
409         if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
410                 goto badframe;
411         ret = regs->areg[2];
412
413         if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
414                 goto badframe;
415         /* It is more difficult to avoid calling this function than to
416            call it and ignore errors.  */
417         do_sigaltstack(&st, NULL, regs->areg[1]);
418
419         return ret;
420
421 badframe:
422         force_sig(SIGSEGV, current);
423         return 0;
424 }
425
426 /*
427  * Set up a signal frame.
428  */
429
430 /*
431  * Determine which stack to use..
432  */
433 static inline void *
434 get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
435 {
436         if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! on_sig_stack(sp))
437                 sp = current->sas_ss_sp + current->sas_ss_size;
438
439         return (void *)((sp - frame_size) & -16ul);
440 }
441
442 #define USE_SIGRETURN           0
443 #define USE_RT_SIGRETURN        1
444
445 static int
446 gen_return_code(unsigned char *codemem, unsigned int use_rt_sigreturn)
447 {
448         unsigned int retcall;
449         int err = 0;
450
451 #if 0
452         /* Ignoring SA_RESTORER for now; it's supposed to be obsolete,
453          * and the xtensa glibc doesn't use it.
454          */
455         if (ka->sa.sa_flags & SA_RESTORER) {
456                 regs->pr = (unsigned long) ka->sa.sa_restorer;
457         } else
458 #endif /* 0 */
459         {
460
461 #if (__NR_sigreturn > 255) || (__NR_rt_sigreturn > 255)
462
463 /* The 12-bit immediate is really split up within the 24-bit MOVI
464  * instruction.  As long as the above system call numbers fit within
465  * 8-bits, the following code works fine. See the Xtensa ISA for
466  * details.
467  */
468
469 #error Generating the MOVI instruction below breaks!
470 #endif
471
472                 retcall = use_rt_sigreturn ? __NR_rt_sigreturn : __NR_sigreturn;
473
474 #ifdef __XTENSA_EB__   /* Big Endian version */
475                 /* Generate instruction:  MOVI a2, retcall */
476                 err |= __put_user(0x22, &codemem[0]);
477                 err |= __put_user(0x0a, &codemem[1]);
478                 err |= __put_user(retcall, &codemem[2]);
479                 /* Generate instruction:  SYSCALL */
480                 err |= __put_user(0x00, &codemem[3]);
481                 err |= __put_user(0x05, &codemem[4]);
482                 err |= __put_user(0x00, &codemem[5]);
483
484 #elif defined __XTENSA_EL__   /* Little Endian version */
485                 /* Generate instruction:  MOVI a2, retcall */
486                 err |= __put_user(0x22, &codemem[0]);
487                 err |= __put_user(0xa0, &codemem[1]);
488                 err |= __put_user(retcall, &codemem[2]);
489                 /* Generate instruction:  SYSCALL */
490                 err |= __put_user(0x00, &codemem[3]);
491                 err |= __put_user(0x50, &codemem[4]);
492                 err |= __put_user(0x00, &codemem[5]);
493 #else
494 #error Must use compiler for Xtensa processors.
495 #endif
496         }
497
498         /* Flush generated code out of the data cache */
499
500         if (err == 0)
501                 __flush_invalidate_cache_range((unsigned long)codemem, 6UL);
502
503         return err;
504 }
505
506 static void
507 set_thread_state(struct pt_regs *regs, void *stack, unsigned char *retaddr,
508         void *handler, unsigned long arg1, void *arg2, void *arg3)
509 {
510         /* Set up registers for signal handler */
511         start_thread(regs, (unsigned long) handler, (unsigned long) stack);
512
513         /* Set up a stack frame for a call4
514          * Note: PS.CALLINC is set to one by start_thread
515          */
516         regs->areg[4] = (((unsigned long) retaddr) & 0x3fffffff) | 0x40000000;
517         regs->areg[6] = arg1;
518         regs->areg[7] = (unsigned long) arg2;
519         regs->areg[8] = (unsigned long) arg3;
520 }
521
522 static void setup_frame(int sig, struct k_sigaction *ka,
523                         sigset_t *set, struct pt_regs *regs)
524 {
525         struct sigframe *frame;
526         int err = 0;
527         int signal;
528
529         frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
530         if (regs->depc > 64)
531         {
532                 printk("!!!!!!! DEPC !!!!!!!\n");
533                 return;
534         }
535
536
537         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
538                 goto give_sigsegv;
539
540         signal = current_thread_info()->exec_domain
541                 && current_thread_info()->exec_domain->signal_invmap
542                 && sig < 32
543                 ? current_thread_info()->exec_domain->signal_invmap[sig]
544                 : sig;
545
546         err |= setup_sigcontext(&frame->sc, &frame->cpstate, regs, set->sig[0]);
547
548         if (_NSIG_WORDS > 1) {
549                 err |= __copy_to_user(frame->extramask, &set->sig[1],
550                                       sizeof(frame->extramask));
551         }
552
553         /* Create sys_sigreturn syscall in stack frame */
554         err |= gen_return_code(frame->retcode, USE_SIGRETURN);
555
556         if (err)
557                 goto give_sigsegv;
558
559         /* Create signal handler execution context.
560          * Return context not modified until this point.
561          */
562         set_thread_state(regs, frame, frame->retcode,
563                 ka->sa.sa_handler, signal, &frame->sc, NULL);
564
565         /* Set access mode to USER_DS.  Nomenclature is outdated, but
566          * functionality is used in uaccess.h
567          */
568         set_fs(USER_DS);
569
570
571 #if DEBUG_SIG
572         printk("SIG deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
573                 current->comm, current->pid, signal, frame, regs->pc);
574 #endif
575
576         return;
577
578 give_sigsegv:
579         if (sig == SIGSEGV)
580                 ka->sa.sa_handler = SIG_DFL;
581         force_sig(SIGSEGV, current);
582 }
583
584 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
585                            sigset_t *set, struct pt_regs *regs)
586 {
587         struct rt_sigframe *frame;
588         int err = 0;
589         int signal;
590
591         frame = get_sigframe(ka, regs->areg[1], sizeof(*frame));
592         if (regs->depc > 64)
593                 panic ("Double exception sys_sigreturn\n");
594
595         if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
596                 goto give_sigsegv;
597
598         signal = current_thread_info()->exec_domain
599                 && current_thread_info()->exec_domain->signal_invmap
600                 && sig < 32
601                 ? current_thread_info()->exec_domain->signal_invmap[sig]
602                 : sig;
603
604         err |= copy_siginfo_to_user(&frame->info, info);
605
606         /* Create the ucontext.  */
607         err |= __put_user(0, &frame->uc.uc_flags);
608         err |= __put_user(0, &frame->uc.uc_link);
609         err |= __put_user((void *)current->sas_ss_sp,
610                           &frame->uc.uc_stack.ss_sp);
611         err |= __put_user(sas_ss_flags(regs->areg[1]),
612                           &frame->uc.uc_stack.ss_flags);
613         err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
614         err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate,
615                                 regs, set->sig[0]);
616         err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
617
618         /* Create sys_rt_sigreturn syscall in stack frame */
619         err |= gen_return_code(frame->retcode, USE_RT_SIGRETURN);
620
621         if (err)
622                 goto give_sigsegv;
623
624         /* Create signal handler execution context.
625          * Return context not modified until this point.
626          */
627         set_thread_state(regs, frame, frame->retcode,
628                 ka->sa.sa_handler, signal, &frame->info, &frame->uc);
629
630         /* Set access mode to USER_DS.  Nomenclature is outdated, but
631          * functionality is used in uaccess.h
632          */
633         set_fs(USER_DS);
634
635 #if DEBUG_SIG
636         printk("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08x\n",
637                 current->comm, current->pid, signal, frame, regs->pc);
638 #endif
639
640         return;
641
642 give_sigsegv:
643         if (sig == SIGSEGV)
644                 ka->sa.sa_handler = SIG_DFL;
645         force_sig(SIGSEGV, current);
646 }
647
648
649
650 /*
651  * Note that 'init' is a special process: it doesn't get signals it doesn't
652  * want to handle. Thus you cannot kill init even with a SIGKILL even by
653  * mistake.
654  *
655  * Note that we go through the signals twice: once to check the signals that
656  * the kernel can handle, and then we build all the user-level signal handling
657  * stack-frames in one go after that.
658  */
659 int do_signal(struct pt_regs *regs, sigset_t *oldset)
660 {
661         siginfo_t info;
662         int signr;
663         struct k_sigaction ka;
664
665         if (!oldset)
666                 oldset = &current->blocked;
667
668         signr = get_signal_to_deliver(&info, &ka, regs, NULL);
669
670         /* Are we from a system call? */
671         if (regs->syscall >= 0) {
672                 /* If so, check system call restarting.. */
673                 switch (regs->areg[2]) {
674                         case ERESTARTNOHAND:
675                         case ERESTART_RESTARTBLOCK:
676                                 regs->areg[2] = -EINTR;
677                                 break;
678
679                         case ERESTARTSYS:
680                                 if (!(ka.sa.sa_flags & SA_RESTART)) {
681                                         regs->areg[2] = -EINTR;
682                                         break;
683                                 }
684                         /* fallthrough */
685                         case ERESTARTNOINTR:
686                                 regs->areg[2] = regs->syscall;
687                                 regs->pc -= 3;
688                 }
689         }
690
691         if (signr == 0)
692                 return 0;               /* no signals delivered */
693
694         /* Whee!  Actually deliver the signal.  */
695
696         /* Set up the stack frame */
697         if (ka.sa.sa_flags & SA_SIGINFO)
698                 setup_rt_frame(signr, &ka, &info, oldset, regs);
699         else
700                 setup_frame(signr, &ka, oldset, regs);
701
702         if (ka.sa.sa_flags & SA_ONESHOT)
703                 ka.sa.sa_handler = SIG_DFL;
704
705         spin_lock_irq(&current->sighand->siglock);
706         sigorsets(&current->blocked, &current->blocked, &ka.sa.sa_mask);
707         if (!(ka.sa.sa_flags & SA_NODEFER))
708                 sigaddset(&current->blocked, signr);
709         recalc_sigpending();
710         spin_unlock_irq(&current->sighand->siglock);
711         return 1;
712 }