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 <asm/variant/core.h> 16 #include <asm/coprocessor.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 xtensa_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(¤t->sighand->siglock); 56 saveset = current->blocked; 57 siginitset(¤t->blocked, mask); 58 recalc_sigpending(); 59 spin_unlock_irq(¤t->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 xtensa_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(¤t->sighand->siglock); 84 saveset = current->blocked; 85 current->blocked = newset; 86 recalc_sigpending(); 87 spin_unlock_irq(¤t->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 xtensa_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 (!access_ok(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 (!access_ok(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 xtensa_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, XTENSA_CP_EXTRA_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 & ~PS_CALLINC_MASK) 220 | (ps & 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 = ¤t->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 (!access_ok(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_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 = ¤t->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 xtensa_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 (!access_ok(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(¤t->sighand->siglock); 372 current->blocked = set; 373 recalc_sigpending(); 374 spin_unlock_irq(¤t->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 xtensa_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 (!access_ok(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(¤t->sighand->siglock); 405 current->blocked = set; 406 recalc_sigpending(); 407 spin_unlock_irq(¤t->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 && ! sas_ss_flags(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 __invalidate_icache_range((unsigned long)codemem, 6UL); 502 __flush_invalidate_dcache_range((unsigned long)codemem, 6UL); 503 } 504 505 return err; 506 } 507 508 static void 509 set_thread_state(struct pt_regs *regs, void *stack, unsigned char *retaddr, 510 void *handler, unsigned long arg1, void *arg2, void *arg3) 511 { 512 /* Set up registers for signal handler */ 513 start_thread(regs, (unsigned long) handler, (unsigned long) stack); 514 515 /* Set up a stack frame for a call4 516 * Note: PS.CALLINC is set to one by start_thread 517 */ 518 regs->areg[4] = (((unsigned long) retaddr) & 0x3fffffff) | 0x40000000; 519 regs->areg[6] = arg1; 520 regs->areg[7] = (unsigned long) arg2; 521 regs->areg[8] = (unsigned long) arg3; 522 } 523 524 static void setup_frame(int sig, struct k_sigaction *ka, 525 sigset_t *set, struct pt_regs *regs) 526 { 527 struct sigframe *frame; 528 int err = 0; 529 int signal; 530 531 frame = get_sigframe(ka, regs->areg[1], sizeof(*frame)); 532 if (regs->depc > 64) 533 { 534 printk("!!!!!!! DEPC !!!!!!!\n"); 535 return; 536 } 537 538 539 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 540 goto give_sigsegv; 541 542 signal = current_thread_info()->exec_domain 543 && current_thread_info()->exec_domain->signal_invmap 544 && sig < 32 545 ? current_thread_info()->exec_domain->signal_invmap[sig] 546 : sig; 547 548 err |= setup_sigcontext(&frame->sc, &frame->cpstate, regs, set->sig[0]); 549 550 if (_NSIG_WORDS > 1) { 551 err |= __copy_to_user(frame->extramask, &set->sig[1], 552 sizeof(frame->extramask)); 553 } 554 555 /* Create sys_sigreturn syscall in stack frame */ 556 err |= gen_return_code(frame->retcode, USE_SIGRETURN); 557 558 if (err) 559 goto give_sigsegv; 560 561 /* Create signal handler execution context. 562 * Return context not modified until this point. 563 */ 564 set_thread_state(regs, frame, frame->retcode, 565 ka->sa.sa_handler, signal, &frame->sc, NULL); 566 567 /* Set access mode to USER_DS. Nomenclature is outdated, but 568 * functionality is used in uaccess.h 569 */ 570 set_fs(USER_DS); 571 572 573 #if DEBUG_SIG 574 printk("SIG deliver (%s:%d): signal=%d sp=%p pc=%08x\n", 575 current->comm, current->pid, signal, frame, regs->pc); 576 #endif 577 578 return; 579 580 give_sigsegv: 581 if (sig == SIGSEGV) 582 ka->sa.sa_handler = SIG_DFL; 583 force_sig(SIGSEGV, current); 584 } 585 586 static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 587 sigset_t *set, struct pt_regs *regs) 588 { 589 struct rt_sigframe *frame; 590 int err = 0; 591 int signal; 592 593 frame = get_sigframe(ka, regs->areg[1], sizeof(*frame)); 594 if (regs->depc > 64) 595 panic ("Double exception sys_sigreturn\n"); 596 597 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 598 goto give_sigsegv; 599 600 signal = current_thread_info()->exec_domain 601 && current_thread_info()->exec_domain->signal_invmap 602 && sig < 32 603 ? current_thread_info()->exec_domain->signal_invmap[sig] 604 : sig; 605 606 err |= copy_siginfo_to_user(&frame->info, info); 607 608 /* Create the ucontext. */ 609 err |= __put_user(0, &frame->uc.uc_flags); 610 err |= __put_user(0, &frame->uc.uc_link); 611 err |= __put_user((void *)current->sas_ss_sp, 612 &frame->uc.uc_stack.ss_sp); 613 err |= __put_user(sas_ss_flags(regs->areg[1]), 614 &frame->uc.uc_stack.ss_flags); 615 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 616 err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->cpstate, 617 regs, set->sig[0]); 618 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 619 620 /* Create sys_rt_sigreturn syscall in stack frame */ 621 err |= gen_return_code(frame->retcode, USE_RT_SIGRETURN); 622 623 if (err) 624 goto give_sigsegv; 625 626 /* Create signal handler execution context. 627 * Return context not modified until this point. 628 */ 629 set_thread_state(regs, frame, frame->retcode, 630 ka->sa.sa_handler, signal, &frame->info, &frame->uc); 631 632 /* Set access mode to USER_DS. Nomenclature is outdated, but 633 * functionality is used in uaccess.h 634 */ 635 set_fs(USER_DS); 636 637 #if DEBUG_SIG 638 printk("SIG rt deliver (%s:%d): signal=%d sp=%p pc=%08x\n", 639 current->comm, current->pid, signal, frame, regs->pc); 640 #endif 641 642 return; 643 644 give_sigsegv: 645 if (sig == SIGSEGV) 646 ka->sa.sa_handler = SIG_DFL; 647 force_sig(SIGSEGV, current); 648 } 649 650 651 652 /* 653 * Note that 'init' is a special process: it doesn't get signals it doesn't 654 * want to handle. Thus you cannot kill init even with a SIGKILL even by 655 * mistake. 656 * 657 * Note that we go through the signals twice: once to check the signals that 658 * the kernel can handle, and then we build all the user-level signal handling 659 * stack-frames in one go after that. 660 */ 661 int do_signal(struct pt_regs *regs, sigset_t *oldset) 662 { 663 siginfo_t info; 664 int signr; 665 struct k_sigaction ka; 666 667 if (!oldset) 668 oldset = ¤t->blocked; 669 670 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 671 672 /* Are we from a system call? */ 673 if (regs->syscall >= 0) { 674 /* If so, check system call restarting.. */ 675 switch (regs->areg[2]) { 676 case ERESTARTNOHAND: 677 case ERESTART_RESTARTBLOCK: 678 regs->areg[2] = -EINTR; 679 break; 680 681 case ERESTARTSYS: 682 if (!(ka.sa.sa_flags & SA_RESTART)) { 683 regs->areg[2] = -EINTR; 684 break; 685 } 686 /* fallthrough */ 687 case ERESTARTNOINTR: 688 regs->areg[2] = regs->syscall; 689 regs->pc -= 3; 690 } 691 } 692 693 if (signr == 0) 694 return 0; /* no signals delivered */ 695 696 /* Whee! Actually deliver the signal. */ 697 698 /* Set up the stack frame */ 699 if (ka.sa.sa_flags & SA_SIGINFO) 700 setup_rt_frame(signr, &ka, &info, oldset, regs); 701 else 702 setup_frame(signr, &ka, oldset, regs); 703 704 if (ka.sa.sa_flags & SA_ONESHOT) 705 ka.sa.sa_handler = SIG_DFL; 706 707 spin_lock_irq(¤t->sighand->siglock); 708 sigorsets(¤t->blocked, ¤t->blocked, &ka.sa.sa_mask); 709 if (!(ka.sa.sa_flags & SA_NODEFER)) 710 sigaddset(¤t->blocked, signr); 711 recalc_sigpending(); 712 spin_unlock_irq(¤t->sighand->siglock); 713 return 1; 714 } 715