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