1/* 2 * linux/arch/m68knommu/kernel/signal.c 3 * 4 * Copyright (C) 1991, 1992 Linus Torvalds 5 * 6 * This file is subject to the terms and conditions of the GNU General Public 7 * License. See the file COPYING in the main directory of this archive 8 * for more details. 9 */ 10 11/* 12 * Linux/m68k support by Hamish Macdonald 13 * 14 * 68060 fixes by Jesper Skov 15 * 16 * 1997-12-01 Modified for POSIX.1b signals by Andreas Schwab 17 * 18 * mathemu support by Roman Zippel 19 * (Note: fpstate in the signal context is completely ignored for the emulator 20 * and the internal floating point format is put on stack) 21 */ 22 23/* 24 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on 25 * Atari :-) Current limitation: Only one sigstack can be active at one time. 26 * If a second signal with SA_ONSTACK set arrives while working on a sigstack, 27 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested 28 * signal handlers! 29 */ 30 31#include <linux/sched.h> 32#include <linux/mm.h> 33#include <linux/kernel.h> 34#include <linux/signal.h> 35#include <linux/syscalls.h> 36#include <linux/errno.h> 37#include <linux/wait.h> 38#include <linux/ptrace.h> 39#include <linux/unistd.h> 40#include <linux/stddef.h> 41#include <linux/highuid.h> 42#include <linux/tty.h> 43#include <linux/personality.h> 44#include <linux/binfmts.h> 45 46#include <asm/setup.h> 47#include <asm/uaccess.h> 48#include <asm/pgtable.h> 49#include <asm/traps.h> 50#include <asm/ucontext.h> 51 52#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) 53 54asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs); 55 56/* 57 * Atomically swap in the new signal mask, and wait for a signal. 58 */ 59asmlinkage int do_sigsuspend(struct pt_regs *regs) 60{ 61 old_sigset_t mask = regs->d3; 62 sigset_t saveset; 63 64 mask &= _BLOCKABLE; 65 spin_lock_irq(¤t->sighand->siglock); 66 saveset = current->blocked; 67 siginitset(¤t->blocked, mask); 68 recalc_sigpending(); 69 spin_unlock_irq(¤t->sighand->siglock); 70 71 regs->d0 = -EINTR; 72 while (1) { 73 current->state = TASK_INTERRUPTIBLE; 74 schedule(); 75 if (do_signal(&saveset, regs)) 76 return -EINTR; 77 } 78} 79 80asmlinkage int 81do_rt_sigsuspend(struct pt_regs *regs) 82{ 83 sigset_t *unewset = (sigset_t *)regs->d1; 84 size_t sigsetsize = (size_t)regs->d2; 85 sigset_t saveset, newset; 86 87 if (sigsetsize != sizeof(sigset_t)) 88 return -EINVAL; 89 90 if (copy_from_user(&newset, unewset, sizeof(newset))) 91 return -EFAULT; 92 sigdelsetmask(&newset, ~_BLOCKABLE); 93 94 spin_lock_irq(¤t->sighand->siglock); 95 saveset = current->blocked; 96 current->blocked = newset; 97 recalc_sigpending(); 98 spin_unlock_irq(¤t->sighand->siglock); 99 100 regs->d0 = -EINTR; 101 while (1) { 102 current->state = TASK_INTERRUPTIBLE; 103 schedule(); 104 if (do_signal(&saveset, regs)) 105 return -EINTR; 106 } 107} 108 109asmlinkage int 110sys_sigaction(int sig, const struct old_sigaction *act, 111 struct old_sigaction *oact) 112{ 113 struct k_sigaction new_ka, old_ka; 114 int ret; 115 116 if (act) { 117 old_sigset_t mask; 118 if (!access_ok(VERIFY_READ, act, sizeof(*act)) || 119 __get_user(new_ka.sa.sa_handler, &act->sa_handler) || 120 __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) 121 return -EFAULT; 122 __get_user(new_ka.sa.sa_flags, &act->sa_flags); 123 __get_user(mask, &act->sa_mask); 124 siginitset(&new_ka.sa.sa_mask, mask); 125 } 126 127 ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); 128 129 if (!ret && oact) { 130 if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || 131 __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || 132 __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) 133 return -EFAULT; 134 __put_user(old_ka.sa.sa_flags, &oact->sa_flags); 135 __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); 136 } 137 138 return ret; 139} 140 141asmlinkage int 142sys_sigaltstack(const stack_t *uss, stack_t *uoss) 143{ 144 return do_sigaltstack(uss, uoss, rdusp()); 145} 146 147 148/* 149 * Do a signal return; undo the signal stack. 150 * 151 * Keep the return code on the stack quadword aligned! 152 * That makes the cache flush below easier. 153 */ 154 155struct sigframe 156{ 157 char *pretcode; 158 int sig; 159 int code; 160 struct sigcontext *psc; 161 char retcode[8]; 162 unsigned long extramask[_NSIG_WORDS-1]; 163 struct sigcontext sc; 164}; 165 166struct rt_sigframe 167{ 168 char *pretcode; 169 int sig; 170 struct siginfo *pinfo; 171 void *puc; 172 char retcode[8]; 173 struct siginfo info; 174 struct ucontext uc; 175}; 176 177#ifdef CONFIG_FPU 178 179static unsigned char fpu_version = 0; /* version number of fpu, set by setup_frame */ 180 181static inline int restore_fpu_state(struct sigcontext *sc) 182{ 183 int err = 1; 184 185 if (FPU_IS_EMU) { 186 /* restore registers */ 187 memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12); 188 memcpy(current->thread.fp, sc->sc_fpregs, 24); 189 return 0; 190 } 191 192 if (sc->sc_fpstate[0]) { 193 /* Verify the frame format. */ 194 if (sc->sc_fpstate[0] != fpu_version) 195 goto out; 196 197 __asm__ volatile (".chip 68k/68881\n\t" 198 "fmovemx %0,%/fp0-%/fp1\n\t" 199 "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t" 200 ".chip 68k" 201 : /* no outputs */ 202 : "m" (*sc->sc_fpregs), "m" (*sc->sc_fpcntl)); 203 } 204 __asm__ volatile (".chip 68k/68881\n\t" 205 "frestore %0\n\t" 206 ".chip 68k" : : "m" (*sc->sc_fpstate)); 207 err = 0; 208 209out: 210 return err; 211} 212 213#define FPCONTEXT_SIZE 216 214#define uc_fpstate uc_filler[0] 215#define uc_formatvec uc_filler[FPCONTEXT_SIZE/4] 216#define uc_extra uc_filler[FPCONTEXT_SIZE/4+1] 217 218static inline int rt_restore_fpu_state(struct ucontext *uc) 219{ 220 unsigned char fpstate[FPCONTEXT_SIZE]; 221 int context_size = 0; 222 fpregset_t fpregs; 223 int err = 1; 224 225 if (FPU_IS_EMU) { 226 /* restore fpu control register */ 227 if (__copy_from_user(current->thread.fpcntl, 228 &uc->uc_mcontext.fpregs.f_pcr, 12)) 229 goto out; 230 /* restore all other fpu register */ 231 if (__copy_from_user(current->thread.fp, 232 uc->uc_mcontext.fpregs.f_fpregs, 96)) 233 goto out; 234 return 0; 235 } 236 237 if (__get_user(*(long *)fpstate, (long *)&uc->uc_fpstate)) 238 goto out; 239 if (fpstate[0]) { 240 context_size = fpstate[1]; 241 242 /* Verify the frame format. */ 243 if (fpstate[0] != fpu_version) 244 goto out; 245 if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs, 246 sizeof(fpregs))) 247 goto out; 248 __asm__ volatile (".chip 68k/68881\n\t" 249 "fmovemx %0,%/fp0-%/fp7\n\t" 250 "fmoveml %1,%/fpcr/%/fpsr/%/fpiar\n\t" 251 ".chip 68k" 252 : /* no outputs */ 253 : "m" (*fpregs.f_fpregs), 254 "m" (fpregs.f_pcr)); 255 } 256 if (context_size && 257 __copy_from_user(fpstate + 4, (long *)&uc->uc_fpstate + 1, 258 context_size)) 259 goto out; 260 __asm__ volatile (".chip 68k/68881\n\t" 261 "frestore %0\n\t" 262 ".chip 68k" : : "m" (*fpstate)); 263 err = 0; 264 265out: 266 return err; 267} 268 269#endif 270 271static inline int 272restore_sigcontext(struct pt_regs *regs, struct sigcontext *usc, void *fp, 273 int *pd0) 274{ 275 int formatvec; 276 struct sigcontext context; 277 int err = 0; 278 279 /* get previous context */ 280 if (copy_from_user(&context, usc, sizeof(context))) 281 goto badframe; 282 283 /* restore passed registers */ 284 regs->d1 = context.sc_d1; 285 regs->a0 = context.sc_a0; 286 regs->a1 = context.sc_a1; 287 ((struct switch_stack *)regs - 1)->a5 = context.sc_a5; 288 regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff); 289 regs->pc = context.sc_pc; 290 regs->orig_d0 = -1; /* disable syscall checks */ 291 wrusp(context.sc_usp); 292 formatvec = context.sc_formatvec; 293 regs->format = formatvec >> 12; 294 regs->vector = formatvec & 0xfff; 295 296#ifdef CONFIG_FPU 297 err = restore_fpu_state(&context); 298#endif 299 300 *pd0 = context.sc_d0; 301 return err; 302 303badframe: 304 return 1; 305} 306 307static inline int 308rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw, 309 struct ucontext *uc, int *pd0) 310{ 311 int temp; 312 greg_t *gregs = uc->uc_mcontext.gregs; 313 unsigned long usp; 314 int err; 315 316 err = __get_user(temp, &uc->uc_mcontext.version); 317 if (temp != MCONTEXT_VERSION) 318 goto badframe; 319 /* restore passed registers */ 320 err |= __get_user(regs->d0, &gregs[0]); 321 err |= __get_user(regs->d1, &gregs[1]); 322 err |= __get_user(regs->d2, &gregs[2]); 323 err |= __get_user(regs->d3, &gregs[3]); 324 err |= __get_user(regs->d4, &gregs[4]); 325 err |= __get_user(regs->d5, &gregs[5]); 326 err |= __get_user(sw->d6, &gregs[6]); 327 err |= __get_user(sw->d7, &gregs[7]); 328 err |= __get_user(regs->a0, &gregs[8]); 329 err |= __get_user(regs->a1, &gregs[9]); 330 err |= __get_user(regs->a2, &gregs[10]); 331 err |= __get_user(sw->a3, &gregs[11]); 332 err |= __get_user(sw->a4, &gregs[12]); 333 err |= __get_user(sw->a5, &gregs[13]); 334 err |= __get_user(sw->a6, &gregs[14]); 335 err |= __get_user(usp, &gregs[15]); 336 wrusp(usp); 337 err |= __get_user(regs->pc, &gregs[16]); 338 err |= __get_user(temp, &gregs[17]); 339 regs->sr = (regs->sr & 0xff00) | (temp & 0xff); 340 regs->orig_d0 = -1; /* disable syscall checks */ 341 regs->format = temp >> 12; 342 regs->vector = temp & 0xfff; 343 344 if (do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT) 345 goto badframe; 346 347 *pd0 = regs->d0; 348 return err; 349 350badframe: 351 return 1; 352} 353 354asmlinkage int do_sigreturn(unsigned long __unused) 355{ 356 struct switch_stack *sw = (struct switch_stack *) &__unused; 357 struct pt_regs *regs = (struct pt_regs *) (sw + 1); 358 unsigned long usp = rdusp(); 359 struct sigframe *frame = (struct sigframe *)(usp - 4); 360 sigset_t set; 361 int d0; 362 363 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 364 goto badframe; 365 if (__get_user(set.sig[0], &frame->sc.sc_mask) || 366 (_NSIG_WORDS > 1 && 367 __copy_from_user(&set.sig[1], &frame->extramask, 368 sizeof(frame->extramask)))) 369 goto badframe; 370 371 sigdelsetmask(&set, ~_BLOCKABLE); 372 spin_lock_irq(¤t->sighand->siglock); 373 current->blocked = set; 374 recalc_sigpending(); 375 spin_unlock_irq(¤t->sighand->siglock); 376 377 if (restore_sigcontext(regs, &frame->sc, frame + 1, &d0)) 378 goto badframe; 379 return d0; 380 381badframe: 382 force_sig(SIGSEGV, current); 383 return 0; 384} 385 386asmlinkage int do_rt_sigreturn(unsigned long __unused) 387{ 388 struct switch_stack *sw = (struct switch_stack *) &__unused; 389 struct pt_regs *regs = (struct pt_regs *) (sw + 1); 390 unsigned long usp = rdusp(); 391 struct rt_sigframe *frame = (struct rt_sigframe *)(usp - 4); 392 sigset_t set; 393 int d0; 394 395 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 396 goto badframe; 397 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) 398 goto badframe; 399 400 sigdelsetmask(&set, ~_BLOCKABLE); 401 spin_lock_irq(¤t->sighand->siglock); 402 current->blocked = set; 403 recalc_sigpending(); 404 spin_unlock_irq(¤t->sighand->siglock); 405 406 if (rt_restore_ucontext(regs, sw, &frame->uc, &d0)) 407 goto badframe; 408 return d0; 409 410badframe: 411 force_sig(SIGSEGV, current); 412 return 0; 413} 414 415#ifdef CONFIG_FPU 416/* 417 * Set up a signal frame. 418 */ 419 420static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs) 421{ 422 if (FPU_IS_EMU) { 423 /* save registers */ 424 memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12); 425 memcpy(sc->sc_fpregs, current->thread.fp, 24); 426 return; 427 } 428 429 __asm__ volatile (".chip 68k/68881\n\t" 430 "fsave %0\n\t" 431 ".chip 68k" 432 : : "m" (*sc->sc_fpstate) : "memory"); 433 434 if (sc->sc_fpstate[0]) { 435 fpu_version = sc->sc_fpstate[0]; 436 __asm__ volatile (".chip 68k/68881\n\t" 437 "fmovemx %/fp0-%/fp1,%0\n\t" 438 "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t" 439 ".chip 68k" 440 : /* no outputs */ 441 : "m" (*sc->sc_fpregs), 442 "m" (*sc->sc_fpcntl) 443 : "memory"); 444 } 445} 446 447static inline int rt_save_fpu_state(struct ucontext *uc, struct pt_regs *regs) 448{ 449 unsigned char fpstate[FPCONTEXT_SIZE]; 450 int context_size = 0; 451 int err = 0; 452 453 if (FPU_IS_EMU) { 454 /* save fpu control register */ 455 err |= copy_to_user(&uc->uc_mcontext.fpregs.f_pcr, 456 current->thread.fpcntl, 12); 457 /* save all other fpu register */ 458 err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs, 459 current->thread.fp, 96); 460 return err; 461 } 462 463 __asm__ volatile (".chip 68k/68881\n\t" 464 "fsave %0\n\t" 465 ".chip 68k" 466 : : "m" (*fpstate) : "memory"); 467 468 err |= __put_user(*(long *)fpstate, (long *)&uc->uc_fpstate); 469 if (fpstate[0]) { 470 fpregset_t fpregs; 471 context_size = fpstate[1]; 472 fpu_version = fpstate[0]; 473 __asm__ volatile (".chip 68k/68881\n\t" 474 "fmovemx %/fp0-%/fp7,%0\n\t" 475 "fmoveml %/fpcr/%/fpsr/%/fpiar,%1\n\t" 476 ".chip 68k" 477 : /* no outputs */ 478 : "m" (*fpregs.f_fpregs), 479 "m" (fpregs.f_pcr) 480 : "memory"); 481 err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs, 482 sizeof(fpregs)); 483 } 484 if (context_size) 485 err |= copy_to_user((long *)&uc->uc_fpstate + 1, fpstate + 4, 486 context_size); 487 return err; 488} 489 490#endif 491 492static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, 493 unsigned long mask) 494{ 495 sc->sc_mask = mask; 496 sc->sc_usp = rdusp(); 497 sc->sc_d0 = regs->d0; 498 sc->sc_d1 = regs->d1; 499 sc->sc_a0 = regs->a0; 500 sc->sc_a1 = regs->a1; 501 sc->sc_a5 = ((struct switch_stack *)regs - 1)->a5; 502 sc->sc_sr = regs->sr; 503 sc->sc_pc = regs->pc; 504 sc->sc_formatvec = regs->format << 12 | regs->vector; 505#ifdef CONFIG_FPU 506 save_fpu_state(sc, regs); 507#endif 508} 509 510static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs) 511{ 512 struct switch_stack *sw = (struct switch_stack *)regs - 1; 513 greg_t *gregs = uc->uc_mcontext.gregs; 514 int err = 0; 515 516 err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); 517 err |= __put_user(regs->d0, &gregs[0]); 518 err |= __put_user(regs->d1, &gregs[1]); 519 err |= __put_user(regs->d2, &gregs[2]); 520 err |= __put_user(regs->d3, &gregs[3]); 521 err |= __put_user(regs->d4, &gregs[4]); 522 err |= __put_user(regs->d5, &gregs[5]); 523 err |= __put_user(sw->d6, &gregs[6]); 524 err |= __put_user(sw->d7, &gregs[7]); 525 err |= __put_user(regs->a0, &gregs[8]); 526 err |= __put_user(regs->a1, &gregs[9]); 527 err |= __put_user(regs->a2, &gregs[10]); 528 err |= __put_user(sw->a3, &gregs[11]); 529 err |= __put_user(sw->a4, &gregs[12]); 530 err |= __put_user(sw->a5, &gregs[13]); 531 err |= __put_user(sw->a6, &gregs[14]); 532 err |= __put_user(rdusp(), &gregs[15]); 533 err |= __put_user(regs->pc, &gregs[16]); 534 err |= __put_user(regs->sr, &gregs[17]); 535#ifdef CONFIG_FPU 536 err |= rt_save_fpu_state(uc, regs); 537#endif 538 return err; 539} 540 541static inline void push_cache (unsigned long vaddr) 542{ 543} 544 545static inline void * 546get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) 547{ 548 unsigned long usp; 549 550 /* Default to using normal stack. */ 551 usp = rdusp(); 552 553 /* This is the X/Open sanctioned signal stack switching. */ 554 if (ka->sa.sa_flags & SA_ONSTACK) { 555 if (!sas_ss_flags(usp)) 556 usp = current->sas_ss_sp + current->sas_ss_size; 557 } 558 return (void *)((usp - frame_size) & -8UL); 559} 560 561static void setup_frame (int sig, struct k_sigaction *ka, 562 sigset_t *set, struct pt_regs *regs) 563{ 564 struct sigframe *frame; 565 struct sigcontext context; 566 int err = 0; 567 568 frame = get_sigframe(ka, regs, sizeof(*frame)); 569 570 err |= __put_user((current_thread_info()->exec_domain 571 && current_thread_info()->exec_domain->signal_invmap 572 && sig < 32 573 ? current_thread_info()->exec_domain->signal_invmap[sig] 574 : sig), 575 &frame->sig); 576 577 err |= __put_user(regs->vector, &frame->code); 578 err |= __put_user(&frame->sc, &frame->psc); 579 580 if (_NSIG_WORDS > 1) 581 err |= copy_to_user(frame->extramask, &set->sig[1], 582 sizeof(frame->extramask)); 583 584 setup_sigcontext(&context, regs, set->sig[0]); 585 err |= copy_to_user (&frame->sc, &context, sizeof(context)); 586 587 /* Set up to return from userspace. */ 588 err |= __put_user(frame->retcode, &frame->pretcode); 589 /* moveq #,d0; trap #0 */ 590 err |= __put_user(0x70004e40 + (__NR_sigreturn << 16), 591 (long *)(frame->retcode)); 592 593 if (err) 594 goto give_sigsegv; 595 596 push_cache ((unsigned long) &frame->retcode); 597 598 /* Set up registers for signal handler */ 599 wrusp ((unsigned long) frame); 600 regs->pc = (unsigned long) ka->sa.sa_handler; 601 ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data; 602 regs->format = 0x4; /*set format byte to make stack appear modulo 4 603 which it will be when doing the rte */ 604 605adjust_stack: 606 /* Prepare to skip over the extra stuff in the exception frame. */ 607 if (regs->stkadj) { 608 struct pt_regs *tregs = 609 (struct pt_regs *)((ulong)regs + regs->stkadj); 610#if defined(DEBUG) 611 printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj); 612#endif 613 /* This must be copied with decreasing addresses to 614 handle overlaps. */ 615 tregs->vector = 0; 616 tregs->format = 0; 617 tregs->pc = regs->pc; 618 tregs->sr = regs->sr; 619 } 620 return; 621 622give_sigsegv: 623 force_sigsegv(sig, current); 624 goto adjust_stack; 625} 626 627static void setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info, 628 sigset_t *set, struct pt_regs *regs) 629{ 630 struct rt_sigframe *frame; 631 int err = 0; 632 633 frame = get_sigframe(ka, regs, sizeof(*frame)); 634 635 err |= __put_user((current_thread_info()->exec_domain 636 && current_thread_info()->exec_domain->signal_invmap 637 && sig < 32 638 ? current_thread_info()->exec_domain->signal_invmap[sig] 639 : sig), 640 &frame->sig); 641 err |= __put_user(&frame->info, &frame->pinfo); 642 err |= __put_user(&frame->uc, &frame->puc); 643 err |= copy_siginfo_to_user(&frame->info, info); 644 645 /* Create the ucontext. */ 646 err |= __put_user(0, &frame->uc.uc_flags); 647 err |= __put_user(0, &frame->uc.uc_link); 648 err |= __put_user((void *)current->sas_ss_sp, 649 &frame->uc.uc_stack.ss_sp); 650 err |= __put_user(sas_ss_flags(rdusp()), 651 &frame->uc.uc_stack.ss_flags); 652 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 653 err |= rt_setup_ucontext(&frame->uc, regs); 654 err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set)); 655 656 /* Set up to return from userspace. */ 657 err |= __put_user(frame->retcode, &frame->pretcode); 658 /* moveq #,d0; notb d0; trap #0 */ 659 err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16), 660 (long *)(frame->retcode + 0)); 661 err |= __put_user(0x4e40, (short *)(frame->retcode + 4)); 662 663 if (err) 664 goto give_sigsegv; 665 666 push_cache ((unsigned long) &frame->retcode); 667 668 /* Set up registers for signal handler */ 669 wrusp ((unsigned long) frame); 670 regs->pc = (unsigned long) ka->sa.sa_handler; 671 ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data; 672 regs->format = 0x4; /*set format byte to make stack appear modulo 4 673 which it will be when doing the rte */ 674 675adjust_stack: 676 /* Prepare to skip over the extra stuff in the exception frame. */ 677 if (regs->stkadj) { 678 struct pt_regs *tregs = 679 (struct pt_regs *)((ulong)regs + regs->stkadj); 680#if defined(DEBUG) 681 printk(KERN_DEBUG "Performing stackadjust=%04x\n", regs->stkadj); 682#endif 683 /* This must be copied with decreasing addresses to 684 handle overlaps. */ 685 tregs->vector = 0; 686 tregs->format = 0; 687 tregs->pc = regs->pc; 688 tregs->sr = regs->sr; 689 } 690 return; 691 692give_sigsegv: 693 force_sigsegv(sig, current); 694 goto adjust_stack; 695} 696 697static inline void 698handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler) 699{ 700 switch (regs->d0) { 701 case -ERESTARTNOHAND: 702 if (!has_handler) 703 goto do_restart; 704 regs->d0 = -EINTR; 705 break; 706 707 case -ERESTARTSYS: 708 if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) { 709 regs->d0 = -EINTR; 710 break; 711 } 712 /* fallthrough */ 713 case -ERESTARTNOINTR: 714 do_restart: 715 regs->d0 = regs->orig_d0; 716 regs->pc -= 2; 717 break; 718 } 719} 720 721/* 722 * OK, we're invoking a handler 723 */ 724static void 725handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, 726 sigset_t *oldset, struct pt_regs *regs) 727{ 728 /* are we from a system call? */ 729 if (regs->orig_d0 >= 0) 730 /* If so, check system call restarting.. */ 731 handle_restart(regs, ka, 1); 732 733 /* set up the stack frame */ 734 if (ka->sa.sa_flags & SA_SIGINFO) 735 setup_rt_frame(sig, ka, info, oldset, regs); 736 else 737 setup_frame(sig, ka, oldset, regs); 738 739 if (ka->sa.sa_flags & SA_ONESHOT) 740 ka->sa.sa_handler = SIG_DFL; 741 742 spin_lock_irq(¤t->sighand->siglock); 743 sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); 744 if (!(ka->sa.sa_flags & SA_NODEFER)) 745 sigaddset(¤t->blocked,sig); 746 recalc_sigpending(); 747 spin_unlock_irq(¤t->sighand->siglock); 748} 749 750/* 751 * Note that 'init' is a special process: it doesn't get signals it doesn't 752 * want to handle. Thus you cannot kill init even with a SIGKILL even by 753 * mistake. 754 */ 755asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) 756{ 757 struct k_sigaction ka; 758 siginfo_t info; 759 int signr; 760 761 /* 762 * We want the common case to go fast, which 763 * is why we may in certain cases get here from 764 * kernel mode. Just return without doing anything 765 * if so. 766 */ 767 if (!user_mode(regs)) 768 return 1; 769 770 if (!oldset) 771 oldset = ¤t->blocked; 772 773 signr = get_signal_to_deliver(&info, &ka, regs, NULL); 774 if (signr > 0) { 775 /* Whee! Actually deliver the signal. */ 776 handle_signal(signr, &ka, &info, oldset, regs); 777 return 1; 778 } 779 780 /* Did we come from a system call? */ 781 if (regs->orig_d0 >= 0) { 782 /* Restart the system call - no handlers present */ 783 if (regs->d0 == -ERESTARTNOHAND 784 || regs->d0 == -ERESTARTSYS 785 || regs->d0 == -ERESTARTNOINTR) { 786 regs->d0 = regs->orig_d0; 787 regs->pc -= 2; 788 } else if (regs->d0 == -ERESTART_RESTARTBLOCK) { 789 regs->d0 = __NR_restart_syscall; 790 regs->pc -= 2; 791 } 792 } 793 return 0; 794} 795