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        sigframe_size = PARISC_RT_SIGFRAME_SIZE;
 241#ifdef CONFIG_64BIT
 242        if (is_compat_task()) {
 243                /* The gcc alloca implementation leaves garbage in the upper 32 bits of sp */
 244                usp = (compat_uint_t)usp;
 245                sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
 246        }
 247#endif
 248        frame = get_sigframe(&ksig->ka, usp, sigframe_size);
 249
 250        DBG(1,"SETUP_RT_FRAME: START\n");
 251        DBG(1,"setup_rt_frame: frame %p info %p\n", frame, ksig->info);
 252
 253        start = (unsigned long) frame;
 254        if (start >= user_addr_max() - sigframe_size)
 255                return -EFAULT;
 256        
 257#ifdef CONFIG_64BIT
 258
 259        compat_frame = (struct compat_rt_sigframe __user *)frame;
 260        
 261        if (is_compat_task()) {
 262                DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
 263                err |= copy_siginfo_to_user32(&compat_frame->info, &ksig->info);
 264                err |= __compat_save_altstack( &compat_frame->uc.uc_stack, regs->gr[30]);
 265                DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc);
 266                DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
 267                err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, 
 268                                        &compat_frame->regs, regs, in_syscall);
 269                err |= put_compat_sigset(&compat_frame->uc.uc_sigmask, set,
 270                                         sizeof(compat_sigset_t));
 271        } else
 272#endif
 273        {       
 274                DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
 275                err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 276                err |= __save_altstack(&frame->uc.uc_stack, regs->gr[30]);
 277                DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc);
 278                DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext);
 279                err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall);
 280                /* FIXME: Should probably be converted as well for the compat case */
 281                err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 282        }
 283        
 284        if (err)
 285                return -EFAULT;
 286
 287        /* Set up to return from userspace.  If provided, use a stub
 288           already in userspace. The first words of tramp are used to
 289           save the previous sigrestartblock trampoline that might be
 290           on the stack. We start the sigreturn trampoline at 
 291           SIGRESTARTBLOCK_TRAMP+X. */
 292        err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0,
 293                        &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]);
 294        err |= __put_user(INSN_LDI_R20, 
 295                        &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]);
 296        err |= __put_user(INSN_BLE_SR2_R0, 
 297                        &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]);
 298        err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]);
 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        if (in_syscall) {
 351                regs->gr[31] = haddr;
 352#ifdef CONFIG_64BIT
 353                if (!test_thread_flag(TIF_32BIT))
 354                        sigframe_size |= 1;
 355#endif
 356        } else {
 357                unsigned long psw = USER_PSW;
 358#ifdef CONFIG_64BIT
 359                if (!test_thread_flag(TIF_32BIT))
 360                        psw |= PSW_W;
 361#endif
 362
 363                /* If we are singlestepping, arrange a trap to be delivered
 364                   when we return to userspace. Note the semantics -- we
 365                   should trap before the first insn in the handler is
 366                   executed. Ref:
 367                        http://sources.redhat.com/ml/gdb/2004-11/msg00245.html
 368                 */
 369                if (pa_psw(current)->r) {
 370                        pa_psw(current)->r = 0;
 371                        psw |= PSW_R;
 372                        mtctl(-1, 0);
 373                }
 374
 375                regs->gr[0] = psw;
 376                regs->iaoq[0] = haddr | 3;
 377                regs->iaoq[1] = regs->iaoq[0] + 4;
 378        }
 379
 380        regs->gr[2]  = rp;                /* userland return pointer */
 381        regs->gr[26] = ksig->sig;               /* signal number */
 382        
 383#ifdef CONFIG_64BIT
 384        if (is_compat_task()) {
 385                regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
 386                regs->gr[24] = A(&compat_frame->uc);   /* ucontext pointer */
 387        } else
 388#endif
 389        {               
 390                regs->gr[25] = A(&frame->info); /* siginfo pointer */
 391                regs->gr[24] = A(&frame->uc);   /* ucontext pointer */
 392        }
 393        
 394        DBG(1,"setup_rt_frame: making sigreturn frame: %#lx + %#lx = %#lx\n",
 395               regs->gr[30], sigframe_size,
 396               regs->gr[30] + sigframe_size);
 397        /* Raise the user stack pointer to make a proper call frame. */
 398        regs->gr[30] = (A(frame) + sigframe_size);
 399
 400
 401        DBG(1,"setup_rt_frame: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
 402               current->comm, current->pid, frame, regs->gr[30],
 403               regs->iaoq[0], regs->iaoq[1], rp);
 404
 405        return 0;
 406}
 407
 408/*
 409 * OK, we're invoking a handler.
 410 */     
 411
 412static void
 413handle_signal(struct ksignal *ksig, struct pt_regs *regs, int in_syscall)
 414{
 415        int ret;
 416        sigset_t *oldset = sigmask_to_save();
 417
 418        DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
 419               ksig->sig, ksig->ka, ksig->info, oldset, regs);
 420        
 421        /* Set up the stack frame */
 422        ret = setup_rt_frame(ksig, oldset, regs, in_syscall);
 423
 424        signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP) ||
 425                          test_thread_flag(TIF_BLOCKSTEP));
 426
 427        DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
 428                regs->gr[28]);
 429}
 430
 431/*
 432 * Check how the syscall number gets loaded into %r20 within
 433 * the delay branch in userspace and adjust as needed.
 434 */
 435
 436static void check_syscallno_in_delay_branch(struct pt_regs *regs)
 437{
 438        u32 opcode, source_reg;
 439        u32 __user *uaddr;
 440        int err;
 441
 442        /* Usually we don't have to restore %r20 (the system call number)
 443         * because it gets loaded in the delay slot of the branch external
 444         * instruction via the ldi instruction.
 445         * In some cases a register-to-register copy instruction might have
 446         * been used instead, in which case we need to copy the syscall
 447         * number into the source register before returning to userspace.
 448         */
 449
 450        /* A syscall is just a branch, so all we have to do is fiddle the
 451         * return pointer so that the ble instruction gets executed again.
 452         */
 453        regs->gr[31] -= 8; /* delayed branching */
 454
 455        /* Get assembler opcode of code in delay branch */
 456        uaddr = (unsigned int *) ((regs->gr[31] & ~3) + 4);
 457        err = get_user(opcode, uaddr);
 458        if (err)
 459                return;
 460
 461        /* Check if delay branch uses "ldi int,%r20" */
 462        if ((opcode & 0xffff0000) == 0x34140000)
 463                return; /* everything ok, just return */
 464
 465        /* Check if delay branch uses "nop" */
 466        if (opcode == INSN_NOP)
 467                return;
 468
 469        /* Check if delay branch uses "copy %rX,%r20" */
 470        if ((opcode & 0xffe0ffff) == 0x08000254) {
 471                source_reg = (opcode >> 16) & 31;
 472                regs->gr[source_reg] = regs->gr[20];
 473                return;
 474        }
 475
 476        pr_warn("syscall restart: %s (pid %d): unexpected opcode 0x%08x\n",
 477                current->comm, task_pid_nr(current), opcode);
 478}
 479
 480static inline void
 481syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
 482{
 483        if (regs->orig_r28)
 484                return;
 485        regs->orig_r28 = 1; /* no more restarts */
 486        /* Check the return code */
 487        switch (regs->gr[28]) {
 488        case -ERESTART_RESTARTBLOCK:
 489        case -ERESTARTNOHAND:
 490                DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
 491                regs->gr[28] = -EINTR;
 492                break;
 493        case -ERESTARTSYS:
 494                if (!(ka->sa.sa_flags & SA_RESTART)) {
 495                        DBG(1,"ERESTARTSYS: putting -EINTR\n");
 496                        regs->gr[28] = -EINTR;
 497                        break;
 498                }
 499                fallthrough;
 500        case -ERESTARTNOINTR:
 501                check_syscallno_in_delay_branch(regs);
 502                break;
 503        }
 504}
 505
 506static inline void
 507insert_restart_trampoline(struct pt_regs *regs)
 508{
 509        if (regs->orig_r28)
 510                return;
 511        regs->orig_r28 = 1; /* no more restarts */
 512        switch(regs->gr[28]) {
 513        case -ERESTART_RESTARTBLOCK: {
 514                /* Restart the system call - no handlers present */
 515                unsigned int *usp = (unsigned int *)regs->gr[30];
 516                unsigned long start = (unsigned long) &usp[2];
 517                unsigned long end  = (unsigned long) &usp[5];
 518                long err = 0;
 519
 520                /* check that we don't exceed the stack */
 521                if (A(&usp[0]) >= user_addr_max() - 5 * sizeof(int))
 522                        return;
 523
 524                /* Setup a trampoline to restart the syscall
 525                 * with __NR_restart_syscall
 526                 *
 527                 *  0: <return address (orig r31)>
 528                 *  4: <2nd half for 64-bit>
 529                 *  8: ldw 0(%sp), %r31
 530                 * 12: be 0x100(%sr2, %r0)
 531                 * 16: ldi __NR_restart_syscall, %r20
 532                 */
 533#ifdef CONFIG_64BIT
 534                err |= put_user(regs->gr[31] >> 32, &usp[0]);
 535                err |= put_user(regs->gr[31] & 0xffffffff, &usp[1]);
 536                err |= put_user(0x0fc010df, &usp[2]);
 537#else
 538                err |= put_user(regs->gr[31], &usp[0]);
 539                err |= put_user(0x0fc0109f, &usp[2]);
 540#endif
 541                err |= put_user(0xe0008200, &usp[3]);
 542                err |= put_user(0x34140000, &usp[4]);
 543
 544                WARN_ON(err);
 545
 546                /* flush data/instruction cache for new insns */
 547                flush_user_dcache_range_asm(start, end);
 548                flush_user_icache_range_asm(start, end);
 549
 550                regs->gr[31] = regs->gr[30] + 8;
 551                return;
 552        }
 553        case -ERESTARTNOHAND:
 554        case -ERESTARTSYS:
 555        case -ERESTARTNOINTR:
 556                check_syscallno_in_delay_branch(regs);
 557                return;
 558        default:
 559                break;
 560        }
 561}
 562
 563/*
 564 * We need to be able to restore the syscall arguments (r21-r26) to
 565 * restart syscalls.  Thus, the syscall path should save them in the
 566 * pt_regs structure (it's okay to do so since they are caller-save
 567 * registers).  As noted below, the syscall number gets restored for
 568 * us due to the magic of delayed branching.
 569 */
 570asmlinkage void
 571do_signal(struct pt_regs *regs, long in_syscall)
 572{
 573        struct ksignal ksig;
 574
 575        DBG(1,"\ndo_signal: regs=0x%p, sr7 %#lx, in_syscall=%d\n",
 576               regs, regs->sr[7], in_syscall);
 577
 578        if (get_signal(&ksig)) {
 579                DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]);
 580                /* Restart a system call if necessary. */
 581                if (in_syscall)
 582                        syscall_restart(regs, &ksig.ka);
 583
 584                handle_signal(&ksig, regs, in_syscall);
 585                return;
 586        }
 587
 588        /* Did we come from a system call? */
 589        if (in_syscall)
 590                insert_restart_trampoline(regs);
 591        
 592        DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", 
 593                regs->gr[28]);
 594
 595        restore_saved_sigmask();
 596}
 597
 598void do_notify_resume(struct pt_regs *regs, long in_syscall)
 599{
 600        if (test_thread_flag(TIF_SIGPENDING) ||
 601            test_thread_flag(TIF_NOTIFY_SIGNAL))
 602                do_signal(regs, in_syscall);
 603
 604        if (test_thread_flag(TIF_NOTIFY_RESUME))
 605                tracehook_notify_resume(regs);
 606}
 607