linux/arch/parisc/kernel/signal.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 *  linux/arch/parisc/kernel/signal.c: Architecture-specific signal
   4 *  handling support.
   5 *
   6 *  Copyright (C) 2000 David Huggins-Daines <dhd@debian.org>
   7 *  Copyright (C) 2000 Linuxcare, Inc.
   8 *
   9 *  Based on the ia64, i386, and alpha versions.
  10 *
  11 *  Like the IA-64, we are a recent enough port (we are *starting*
  12 *  with glibc2.2) that we do not need to support the old non-realtime
  13 *  Linux signals.  Therefore we don't.
  14 */
  15
  16#include <linux/sched.h>
  17#include <linux/sched/debug.h>
  18#include <linux/mm.h>
  19#include <linux/smp.h>
  20#include <linux/kernel.h>
  21#include <linux/signal.h>
  22#include <linux/errno.h>
  23#include <linux/wait.h>
  24#include <linux/ptrace.h>
  25#include <linux/tracehook.h>
  26#include <linux/unistd.h>
  27#include <linux/stddef.h>
  28#include <linux/compat.h>
  29#include <linux/elf.h>
  30#include <asm/ucontext.h>
  31#include <asm/rt_sigframe.h>
  32#include <linux/uaccess.h>
  33#include <asm/cacheflush.h>
  34#include <asm/asm-offsets.h>
  35
  36#ifdef CONFIG_COMPAT
  37#include "signal32.h"
  38#endif
  39
  40#define DEBUG_SIG 0 
  41#define DEBUG_SIG_LEVEL 2
  42
  43#if DEBUG_SIG
  44#define DBG(LEVEL, ...) \
  45        ((DEBUG_SIG_LEVEL >= LEVEL) \
  46        ? printk(__VA_ARGS__) : (void) 0)
  47#else
  48#define DBG(LEVEL, ...)
  49#endif
  50        
  51/* gcc will complain if a pointer is cast to an integer of different
  52 * size.  If you really need to do this (and we do for an ELF32 user
  53 * application in an ELF64 kernel) then you have to do a cast to an
  54 * integer of the same size first.  The A() macro accomplishes
  55 * this. */
  56#define A(__x)  ((unsigned long)(__x))
  57
  58/*
  59 * Do a signal return - restore sigcontext.
  60 */
  61
  62/* Trampoline for calling rt_sigreturn() */
  63#define INSN_LDI_R25_0   0x34190000 /* ldi  0,%r25 (in_syscall=0) */
  64#define INSN_LDI_R25_1   0x34190002 /* ldi  1,%r25 (in_syscall=1) */
  65#define INSN_LDI_R20     0x3414015a /* ldi  __NR_rt_sigreturn,%r20 */
  66#define INSN_BLE_SR2_R0  0xe4008200 /* be,l 0x100(%sr2,%r0),%sr0,%r31 */
  67/* For debugging */
  68#define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */
  69
  70static long
  71restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
  72{
  73        long err = 0;
  74
  75        err |= __copy_from_user(regs->gr, sc->sc_gr, sizeof(regs->gr));
  76        err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
  77        err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq));
  78        err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq));
  79        err |= __get_user(regs->sar, &sc->sc_sar);
  80        DBG(2,"restore_sigcontext: iaoq is %#lx / %#lx\n",
  81                        regs->iaoq[0],regs->iaoq[1]);
  82        DBG(2,"restore_sigcontext: r28 is %ld\n", regs->gr[28]);
  83        return err;
  84}
  85
  86void
  87sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
  88{
  89        struct rt_sigframe __user *frame;
  90        sigset_t set;
  91        unsigned long usp = (regs->gr[30] & ~(0x01UL));
  92        unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
  93#ifdef CONFIG_64BIT
  94        struct compat_rt_sigframe __user * compat_frame;
  95        
  96        if (is_compat_task())
  97                sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
  98#endif
  99
 100        current->restart_block.fn = do_no_restart_syscall;
 101
 102        /* Unwind the user stack to get the rt_sigframe structure. */
 103        frame = (struct rt_sigframe __user *)
 104                (usp - sigframe_size);
 105        DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
 106
 107        regs->orig_r28 = 1; /* no restarts for sigreturn */
 108
 109#ifdef CONFIG_64BIT
 110        compat_frame = (struct compat_rt_sigframe __user *)frame;
 111        
 112        if (is_compat_task()) {
 113                DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
 114                if (get_compat_sigset(&set, &compat_frame->uc.uc_sigmask))
 115                        goto give_sigsegv;
 116        } else
 117#endif
 118        {
 119                if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
 120                        goto give_sigsegv;
 121        }
 122                
 123        set_current_blocked(&set);
 124
 125        /* Good thing we saved the old gr[30], eh? */
 126#ifdef CONFIG_64BIT
 127        if (is_compat_task()) {
 128                DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
 129                                &compat_frame->uc.uc_mcontext);
 130// FIXME: Load upper half from register file
 131                if (restore_sigcontext32(&compat_frame->uc.uc_mcontext, 
 132                                        &compat_frame->regs, regs))
 133                        goto give_sigsegv;
 134                DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", 
 135                                usp, &compat_frame->uc.uc_stack);
 136                if (compat_restore_altstack(&compat_frame->uc.uc_stack))
 137                        goto give_sigsegv;
 138        } else
 139#endif
 140        {
 141                DBG(1,"sys_rt_sigreturn: frame->uc.uc_mcontext 0x%p\n",
 142                                &frame->uc.uc_mcontext);
 143                if (restore_sigcontext(&frame->uc.uc_mcontext, regs))
 144                        goto give_sigsegv;
 145                DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", 
 146                                usp, &frame->uc.uc_stack);
 147                if (restore_altstack(&frame->uc.uc_stack))
 148                        goto give_sigsegv;
 149        }
 150                
 151
 152
 153        /* If we are on the syscall path IAOQ will not be restored, and
 154         * if we are on the interrupt path we must not corrupt gr31.
 155         */
 156        if (in_syscall)
 157                regs->gr[31] = regs->iaoq[0];
 158#if DEBUG_SIG
 159        DBG(1,"sys_rt_sigreturn: returning to %#lx, DUMPING REGS:\n", regs->iaoq[0]);
 160        show_regs(regs);
 161#endif
 162        return;
 163
 164give_sigsegv:
 165        DBG(1,"sys_rt_sigreturn: Sending SIGSEGV\n");
 166        force_sig(SIGSEGV);
 167        return;
 168}
 169
 170/*
 171 * Set up a signal frame.
 172 */
 173
 174static inline void __user *
 175get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
 176{
 177        /*FIXME: ELF32 vs. ELF64 has different frame_size, but since we
 178          don't use the parameter it doesn't matter */
 179
 180        DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n",
 181                        (unsigned long)ka, sp, frame_size);
 182        
 183        /* Align alternate stack and reserve 64 bytes for the signal
 184           handler's frame marker.  */
 185        if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
 186                sp = (current->sas_ss_sp + 0x7f) & ~0x3f; /* Stacks grow up! */
 187
 188        DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp);
 189        return (void __user *) sp; /* Stacks grow up.  Fun. */
 190}
 191
 192static long
 193setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_syscall)
 194                 
 195{
 196        unsigned long flags = 0;
 197        long err = 0;
 198
 199        if (on_sig_stack((unsigned long) sc))
 200                flags |= PARISC_SC_FLAG_ONSTACK;
 201        if (in_syscall) {
 202                flags |= PARISC_SC_FLAG_IN_SYSCALL;
 203                /* regs->iaoq is undefined in the syscall return path */
 204                err |= __put_user(regs->gr[31], &sc->sc_iaoq[0]);
 205                err |= __put_user(regs->gr[31]+4, &sc->sc_iaoq[1]);
 206                err |= __put_user(regs->sr[3], &sc->sc_iasq[0]);
 207                err |= __put_user(regs->sr[3], &sc->sc_iasq[1]);
 208                DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (in syscall)\n",
 209                        regs->gr[31], regs->gr[31]+4);
 210        } else {
 211                err |= __copy_to_user(sc->sc_iaoq, regs->iaoq, sizeof(regs->iaoq));
 212                err |= __copy_to_user(sc->sc_iasq, regs->iasq, sizeof(regs->iasq));
 213                DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (not in syscall)\n", 
 214                        regs->iaoq[0], regs->iaoq[1]);
 215        }
 216
 217        err |= __put_user(flags, &sc->sc_flags);
 218        err |= __copy_to_user(sc->sc_gr, regs->gr, sizeof(regs->gr));
 219        err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
 220        err |= __put_user(regs->sar, &sc->sc_sar);
 221        DBG(1,"setup_sigcontext: r28 is %ld\n", regs->gr[28]);
 222
 223        return err;
 224}
 225
 226static long
 227setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs,
 228               int in_syscall)
 229{
 230        struct rt_sigframe __user *frame;
 231        unsigned long rp, usp;
 232        unsigned long haddr, sigframe_size;
 233        unsigned long start, end;
 234        int err = 0;
 235#ifdef CONFIG_64BIT
 236        struct compat_rt_sigframe __user * compat_frame;
 237#endif
 238        
 239        usp = (regs->gr[30] & ~(0x01UL));
 240        /*FIXME: frame_size parameter is unused, remove it. */
 241        frame = get_sigframe(&ksig->ka, usp, sizeof(*frame));
 242
 243        DBG(1,"SETUP_RT_FRAME: START\n");
 244        DBG(1,"setup_rt_frame: frame %p info %p\n", frame, ksig->info);
 245
 246        
 247#ifdef CONFIG_64BIT
 248
 249        compat_frame = (struct compat_rt_sigframe __user *)frame;
 250        
 251        if (is_compat_task()) {
 252                DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
 253                err |= copy_siginfo_to_user32(&compat_frame->info, &ksig->info);
 254                err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]);
 255                DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc);
 256                DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
 257                err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, 
 258                                        &compat_frame->regs, regs, in_syscall);
 259                err |= put_compat_sigset(&compat_frame->uc.uc_sigmask, set,
 260                                         sizeof(compat_sigset_t));
 261        } else
 262#endif
 263        {       
 264                DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
 265                err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 266                err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]);
 267                DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc);
 268                DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext);
 269                err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall);
 270                /* FIXME: Should probably be converted as well for the compat case */
 271                err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 272        }
 273        
 274        if (err)
 275                return -EFAULT;
 276
 277        /* Set up to return from userspace.  If provided, use a stub
 278           already in userspace. The first words of tramp are used to
 279           save the previous sigrestartblock trampoline that might be
 280           on the stack. We start the sigreturn trampoline at 
 281           SIGRESTARTBLOCK_TRAMP+X. */
 282        err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0,
 283                        &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]);
 284        err |= __put_user(INSN_LDI_R20, 
 285                        &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]);
 286        err |= __put_user(INSN_BLE_SR2_R0, 
 287                        &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]);
 288        err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]);
 289
 290#if DEBUG_SIG
 291        /* Assert that we're flushing in the correct space... */
 292        {
 293                unsigned long sid;
 294                asm ("mfsp %%sr3,%0" : "=r" (sid));
 295                DBG(1,"setup_rt_frame: Flushing 64 bytes at space %#x offset %p\n",
 296                       sid, frame->tramp);
 297        }
 298#endif
 299
 300        start = (unsigned long) &frame->tramp[0];
 301        end = (unsigned long) &frame->tramp[TRAMP_SIZE];
 302        flush_user_dcache_range_asm(start, end);
 303        flush_user_icache_range_asm(start, end);
 304
 305        /* TRAMP Words 0-4, Length 5 = SIGRESTARTBLOCK_TRAMP
 306         * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP
 307         * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP
 308         */
 309        rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
 310
 311        if (err)
 312                return -EFAULT;
 313
 314        haddr = A(ksig->ka.sa.sa_handler);
 315        /* The sa_handler may be a pointer to a function descriptor */
 316#ifdef CONFIG_64BIT
 317        if (is_compat_task()) {
 318#endif
 319                if (haddr & PA_PLABEL_FDESC) {
 320                        Elf32_Fdesc fdesc;
 321                        Elf32_Fdesc __user *ufdesc = (Elf32_Fdesc __user *)A(haddr & ~3);
 322
 323                        err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
 324
 325                        if (err)
 326                                return -EFAULT;
 327
 328                        haddr = fdesc.addr;
 329                        regs->gr[19] = fdesc.gp;
 330                }
 331#ifdef CONFIG_64BIT
 332        } else {
 333                Elf64_Fdesc fdesc;
 334                Elf64_Fdesc __user *ufdesc = (Elf64_Fdesc __user *)A(haddr & ~3);
 335                
 336                err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
 337                
 338                if (err)
 339                        return -EFAULT;
 340                
 341                haddr = fdesc.addr;
 342                regs->gr[19] = fdesc.gp;
 343                DBG(1,"setup_rt_frame: 64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n",
 344                     haddr, regs->gr[19], in_syscall);
 345        }
 346#endif
 347
 348        /* The syscall return path will create IAOQ values from r31.
 349         */
 350        sigframe_size = PARISC_RT_SIGFRAME_SIZE;
 351#ifdef CONFIG_64BIT
 352        if (is_compat_task())
 353                sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
 354#endif
 355        if (in_syscall) {
 356                regs->gr[31] = haddr;
 357#ifdef CONFIG_64BIT
 358                if (!test_thread_flag(TIF_32BIT))
 359                        sigframe_size |= 1;
 360#endif
 361        } else {
 362                unsigned long psw = USER_PSW;
 363#ifdef CONFIG_64BIT
 364                if (!test_thread_flag(TIF_32BIT))
 365                        psw |= PSW_W;
 366#endif
 367
 368                /* If we are singlestepping, arrange a trap to be delivered
 369                   when we return to userspace. Note the semantics -- we
 370                   should trap before the first insn in the handler is
 371                   executed. Ref:
 372                        http://sources.redhat.com/ml/gdb/2004-11/msg00245.html
 373                 */
 374                if (pa_psw(current)->r) {
 375                        pa_psw(current)->r = 0;
 376                        psw |= PSW_R;
 377                        mtctl(-1, 0);
 378                }
 379
 380                regs->gr[0] = psw;
 381                regs->iaoq[0] = haddr | 3;
 382                regs->iaoq[1] = regs->iaoq[0] + 4;
 383        }
 384
 385        regs->gr[2]  = rp;                /* userland return pointer */
 386        regs->gr[26] = ksig->sig;               /* signal number */
 387        
 388#ifdef CONFIG_64BIT
 389        if (is_compat_task()) {
 390                regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
 391                regs->gr[24] = A(&compat_frame->uc);   /* ucontext pointer */
 392        } else
 393#endif
 394        {               
 395                regs->gr[25] = A(&frame->info); /* siginfo pointer */
 396                regs->gr[24] = A(&frame->uc);   /* ucontext pointer */
 397        }
 398        
 399        DBG(1,"setup_rt_frame: making sigreturn frame: %#lx + %#lx = %#lx\n",
 400               regs->gr[30], sigframe_size,
 401               regs->gr[30] + sigframe_size);
 402        /* Raise the user stack pointer to make a proper call frame. */
 403        regs->gr[30] = (A(frame) + sigframe_size);
 404
 405
 406        DBG(1,"setup_rt_frame: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
 407               current->comm, current->pid, frame, regs->gr[30],
 408               regs->iaoq[0], regs->iaoq[1], rp);
 409
 410        return 0;
 411}
 412
 413/*
 414 * OK, we're invoking a handler.
 415 */     
 416
 417static void
 418handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall)
 419{
 420        int ret;
 421        sigset_t *oldset = sigmask_to_save();
 422
 423        DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
 424               ksig->sig, ksig->ka, ksig->info, oldset, regs);
 425        
 426        /* Set up the stack frame */
 427        ret = setup_rt_frame(ksig, oldset, regs, in_syscall);
 428
 429        signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP) ||
 430                          test_thread_flag(TIF_BLOCKSTEP));
 431
 432        DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
 433                regs->gr[28]);
 434}
 435
 436/*
 437 * Check how the syscall number gets loaded into %r20 within
 438 * the delay branch in userspace and adjust as needed.
 439 */
 440
 441static void check_syscallno_in_delay_branch(struct pt_regs *regs)
 442{
 443        u32 opcode, source_reg;
 444        u32 __user *uaddr;
 445        int err;
 446
 447        /* Usually we don't have to restore %r20 (the system call number)
 448         * because it gets loaded in the delay slot of the branch external
 449         * instruction via the ldi instruction.
 450         * In some cases a register-to-register copy instruction might have
 451         * been used instead, in which case we need to copy the syscall
 452         * number into the source register before returning to userspace.
 453         */
 454
 455        /* A syscall is just a branch, so all we have to do is fiddle the
 456         * return pointer so that the ble instruction gets executed again.
 457         */
 458        regs->gr[31] -= 8; /* delayed branching */
 459
 460        /* Get assembler opcode of code in delay branch */
 461        uaddr = (unsigned int *) ((regs->gr[31] & ~3) + 4);
 462        err = get_user(opcode, uaddr);
 463        if (err)
 464                return;
 465
 466        /* Check if delay branch uses "ldi int,%r20" */
 467        if ((opcode & 0xffff0000) == 0x34140000)
 468                return; /* everything ok, just return */
 469
 470        /* Check if delay branch uses "nop" */
 471        if (opcode == INSN_NOP)
 472                return;
 473
 474        /* Check if delay branch uses "copy %rX,%r20" */
 475        if ((opcode & 0xffe0ffff) == 0x08000254) {
 476                source_reg = (opcode >> 16) & 31;
 477                regs->gr[source_reg] = regs->gr[20];
 478                return;
 479        }
 480
 481        pr_warn("syscall restart: %s (pid %d): unexpected opcode 0x%08x\n",
 482                current->comm, task_pid_nr(current), opcode);
 483}
 484
 485static inline void
 486syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
 487{
 488        if (regs->orig_r28)
 489                return;
 490        regs->orig_r28 = 1; /* no more restarts */
 491        /* Check the return code */
 492        switch (regs->gr[28]) {
 493        case -ERESTART_RESTARTBLOCK:
 494        case -ERESTARTNOHAND:
 495                DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
 496                regs->gr[28] = -EINTR;
 497                break;
 498
 499        case -ERESTARTSYS:
 500                if (!(ka->sa.sa_flags & SA_RESTART)) {
 501                        DBG(1,"ERESTARTSYS: putting -EINTR\n");
 502                        regs->gr[28] = -EINTR;
 503                        break;
 504                }
 505                fallthrough;
 506        case -ERESTARTNOINTR:
 507                check_syscallno_in_delay_branch(regs);
 508                break;
 509        }
 510}
 511
 512static inline void
 513insert_restart_trampoline(struct pt_regs *regs)
 514{
 515        if (regs->orig_r28)
 516                return;
 517        regs->orig_r28 = 1; /* no more restarts */
 518        switch(regs->gr[28]) {
 519        case -ERESTART_RESTARTBLOCK: {
 520                /* Restart the system call - no handlers present */
 521                unsigned int *usp = (unsigned int *)regs->gr[30];
 522                unsigned long start = (unsigned long) &usp[2];
 523                unsigned long end  = (unsigned long) &usp[5];
 524                long err = 0;
 525
 526                /* Setup a trampoline to restart the syscall
 527                 * with __NR_restart_syscall
 528                 *
 529                 *  0: <return address (orig r31)>
 530                 *  4: <2nd half for 64-bit>
 531                 *  8: ldw 0(%sp), %r31
 532                 * 12: be 0x100(%sr2, %r0)
 533                 * 16: ldi __NR_restart_syscall, %r20
 534                 */
 535#ifdef CONFIG_64BIT
 536                err |= put_user(regs->gr[31] >> 32, &usp[0]);
 537                err |= put_user(regs->gr[31] & 0xffffffff, &usp[1]);
 538                err |= put_user(0x0fc010df, &usp[2]);
 539#else
 540                err |= put_user(regs->gr[31], &usp[0]);
 541                err |= put_user(0x0fc0109f, &usp[2]);
 542#endif
 543                err |= put_user(0xe0008200, &usp[3]);
 544                err |= put_user(0x34140000, &usp[4]);
 545
 546                WARN_ON(err);
 547
 548                /* flush data/instruction cache for new insns */
 549                flush_user_dcache_range_asm(start, end);
 550                flush_user_icache_range_asm(start, end);
 551
 552                regs->gr[31] = regs->gr[30] + 8;
 553                return;
 554        }
 555        case -ERESTARTNOHAND:
 556        case -ERESTARTSYS:
 557        case -ERESTARTNOINTR:
 558                check_syscallno_in_delay_branch(regs);
 559                return;
 560        default:
 561                break;
 562        }
 563}
 564
 565/*
 566 * Note that 'init' is a special process: it doesn't get signals it doesn't
 567 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 568 * mistake.
 569 *
 570 * We need to be able to restore the syscall arguments (r21-r26) to
 571 * restart syscalls.  Thus, the syscall path should save them in the
 572 * pt_regs structure (it's okay to do so since they are caller-save
 573 * registers).  As noted below, the syscall number gets restored for
 574 * us due to the magic of delayed branching.
 575 */
 576asmlinkage void
 577do_signal(struct pt_regs *regs, long in_syscall)
 578{
 579        struct ksignal ksig;
 580
 581        DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
 582               regs, regs->sr[7], in_syscall);
 583
 584        if (get_signal(&ksig)) {
 585                DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
 586                /* Restart a system call if necessary. */
 587                if (in_syscall)
 588                        syscall_restart(regs, &ksig.ka);
 589
 590                handle_signal(&ksig, regs, in_syscall);
 591                return;
 592        }
 593
 594        /* Did we come from a system call? */
 595        if (in_syscall)
 596                insert_restart_trampoline(regs);
 597        
 598        DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", 
 599                regs->gr[28]);
 600
 601        restore_saved_sigmask();
 602}
 603
 604void do_notify_resume(struct pt_regs *regs, long in_syscall)
 605{
 606        if (test_thread_flag(TIF_SIGPENDING) ||
 607            test_thread_flag(TIF_NOTIFY_SIGNAL))
 608                do_signal(regs, in_syscall);
 609
 610        if (test_thread_flag(TIF_NOTIFY_RESUME))
 611                tracehook_notify_resume(regs);
 612}
 613