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 <linux/tracehook.h>
  30#include <asm/ucontext.h>
  31#include <asm/rt_sigframe.h>
  32#include <asm/uaccess.h>
  33#include <asm/pgalloc.h>
  34#include <asm/cacheflush.h>
  35#include <asm/asm-offsets.h>
  36
  37#ifdef CONFIG_COMPAT
  38#include "signal32.h"
  39#endif
  40
  41#define DEBUG_SIG 0 
  42#define DEBUG_SIG_LEVEL 2
  43
  44#if DEBUG_SIG
  45#define DBG(LEVEL, ...) \
  46        ((DEBUG_SIG_LEVEL >= LEVEL) \
  47        ? printk(__VA_ARGS__) : (void) 0)
  48#else
  49#define DBG(LEVEL, ...)
  50#endif
  51        
  52
  53#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
  54
  55/* gcc will complain if a pointer is cast to an integer of different
  56 * size.  If you really need to do this (and we do for an ELF32 user
  57 * application in an ELF64 kernel) then you have to do a cast to an
  58 * integer of the same size first.  The A() macro accomplishes
  59 * this. */
  60#define A(__x)  ((unsigned long)(__x))
  61
  62/*
  63 * Atomically swap in the new signal mask, and wait for a signal.
  64 */
  65#ifdef CONFIG_64BIT
  66#include "sys32.h"
  67#endif
  68
  69/*
  70 * Do a signal return - restore sigcontext.
  71 */
  72
  73/* Trampoline for calling rt_sigreturn() */
  74#define INSN_LDI_R25_0   0x34190000 /* ldi  0,%r25 (in_syscall=0) */
  75#define INSN_LDI_R25_1   0x34190002 /* ldi  1,%r25 (in_syscall=1) */
  76#define INSN_LDI_R20     0x3414015a /* ldi  __NR_rt_sigreturn,%r20 */
  77#define INSN_BLE_SR2_R0  0xe4008200 /* be,l 0x100(%sr2,%r0),%sr0,%r31 */
  78#define INSN_NOP         0x08000240 /* nop */
  79/* For debugging */
  80#define INSN_DIE_HORRIBLY 0x68000ccc /* stw %r0,0x666(%sr0,%r0) */
  81
  82static long
  83restore_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs)
  84{
  85        long err = 0;
  86
  87        err |= __copy_from_user(regs->gr, sc->sc_gr, sizeof(regs->gr));
  88        err |= __copy_from_user(regs->fr, sc->sc_fr, sizeof(regs->fr));
  89        err |= __copy_from_user(regs->iaoq, sc->sc_iaoq, sizeof(regs->iaoq));
  90        err |= __copy_from_user(regs->iasq, sc->sc_iasq, sizeof(regs->iasq));
  91        err |= __get_user(regs->sar, &sc->sc_sar);
  92        DBG(2,"restore_sigcontext: iaoq is 0x%#lx / 0x%#lx\n", 
  93                        regs->iaoq[0],regs->iaoq[1]);
  94        DBG(2,"restore_sigcontext: r28 is %ld\n", regs->gr[28]);
  95        return err;
  96}
  97
  98void
  99sys_rt_sigreturn(struct pt_regs *regs, int in_syscall)
 100{
 101        struct rt_sigframe __user *frame;
 102        struct siginfo si;
 103        sigset_t set;
 104        unsigned long usp = (regs->gr[30] & ~(0x01UL));
 105        unsigned long sigframe_size = PARISC_RT_SIGFRAME_SIZE;
 106#ifdef CONFIG_64BIT
 107        compat_sigset_t compat_set;
 108        struct compat_rt_sigframe __user * compat_frame;
 109        
 110        if (is_compat_task())
 111                sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
 112#endif
 113
 114
 115        /* Unwind the user stack to get the rt_sigframe structure. */
 116        frame = (struct rt_sigframe __user *)
 117                (usp - sigframe_size);
 118        DBG(2,"sys_rt_sigreturn: frame is %p\n", frame);
 119
 120#ifdef CONFIG_64BIT
 121        compat_frame = (struct compat_rt_sigframe __user *)frame;
 122        
 123        if (is_compat_task()) {
 124                DBG(2,"sys_rt_sigreturn: ELF32 process.\n");
 125                if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set)))
 126                        goto give_sigsegv;
 127                sigset_32to64(&set,&compat_set);
 128        } else
 129#endif
 130        {
 131                if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
 132                        goto give_sigsegv;
 133        }
 134                
 135        sigdelsetmask(&set, ~_BLOCKABLE);
 136        spin_lock_irq(&current->sighand->siglock);
 137        current->blocked = set;
 138        recalc_sigpending();
 139        spin_unlock_irq(&current->sighand->siglock);
 140
 141        /* Good thing we saved the old gr[30], eh? */
 142#ifdef CONFIG_64BIT
 143        if (is_compat_task()) {
 144                DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n",
 145                                &compat_frame->uc.uc_mcontext);
 146// FIXME: Load upper half from register file
 147                if (restore_sigcontext32(&compat_frame->uc.uc_mcontext, 
 148                                        &compat_frame->regs, regs))
 149                        goto give_sigsegv;
 150                DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", 
 151                                usp, &compat_frame->uc.uc_stack);
 152                if (do_sigaltstack32(&compat_frame->uc.uc_stack, NULL, usp) == -EFAULT)
 153                        goto give_sigsegv;
 154        } else
 155#endif
 156        {
 157                DBG(1,"sys_rt_sigreturn: frame->uc.uc_mcontext 0x%p\n",
 158                                &frame->uc.uc_mcontext);
 159                if (restore_sigcontext(&frame->uc.uc_mcontext, regs))
 160                        goto give_sigsegv;
 161                DBG(1,"sys_rt_sigreturn: usp %#08lx stack 0x%p\n", 
 162                                usp, &frame->uc.uc_stack);
 163                if (do_sigaltstack(&frame->uc.uc_stack, NULL, usp) == -EFAULT)
 164                        goto give_sigsegv;
 165        }
 166                
 167
 168
 169        /* If we are on the syscall path IAOQ will not be restored, and
 170         * if we are on the interrupt path we must not corrupt gr31.
 171         */
 172        if (in_syscall)
 173                regs->gr[31] = regs->iaoq[0];
 174#if DEBUG_SIG
 175        DBG(1,"sys_rt_sigreturn: returning to %#lx, DUMPING REGS:\n", regs->iaoq[0]);
 176        show_regs(regs);
 177#endif
 178        return;
 179
 180give_sigsegv:
 181        DBG(1,"sys_rt_sigreturn: Sending SIGSEGV\n");
 182        si.si_signo = SIGSEGV;
 183        si.si_errno = 0;
 184        si.si_code = SI_KERNEL;
 185        si.si_pid = task_pid_vnr(current);
 186        si.si_uid = current_uid();
 187        si.si_addr = &frame->uc;
 188        force_sig_info(SIGSEGV, &si, current);
 189        return;
 190}
 191
 192/*
 193 * Set up a signal frame.
 194 */
 195
 196static inline void __user *
 197get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
 198{
 199        /*FIXME: ELF32 vs. ELF64 has different frame_size, but since we
 200          don't use the parameter it doesn't matter */
 201
 202        DBG(1,"get_sigframe: ka = %#lx, sp = %#lx, frame_size = %#lx\n",
 203                        (unsigned long)ka, sp, frame_size);
 204        
 205        if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
 206                sp = current->sas_ss_sp; /* Stacks grow up! */
 207
 208        DBG(1,"get_sigframe: Returning sp = %#lx\n", (unsigned long)sp);
 209        return (void __user *) sp; /* Stacks grow up.  Fun. */
 210}
 211
 212static long
 213setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, int in_syscall)
 214                 
 215{
 216        unsigned long flags = 0;
 217        long err = 0;
 218
 219        if (on_sig_stack((unsigned long) sc))
 220                flags |= PARISC_SC_FLAG_ONSTACK;
 221        if (in_syscall) {
 222                flags |= PARISC_SC_FLAG_IN_SYSCALL;
 223                /* regs->iaoq is undefined in the syscall return path */
 224                err |= __put_user(regs->gr[31], &sc->sc_iaoq[0]);
 225                err |= __put_user(regs->gr[31]+4, &sc->sc_iaoq[1]);
 226                err |= __put_user(regs->sr[3], &sc->sc_iasq[0]);
 227                err |= __put_user(regs->sr[3], &sc->sc_iasq[1]);
 228                DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (in syscall)\n",
 229                        regs->gr[31], regs->gr[31]+4);
 230        } else {
 231                err |= __copy_to_user(sc->sc_iaoq, regs->iaoq, sizeof(regs->iaoq));
 232                err |= __copy_to_user(sc->sc_iasq, regs->iasq, sizeof(regs->iasq));
 233                DBG(1,"setup_sigcontext: iaoq %#lx / %#lx (not in syscall)\n", 
 234                        regs->iaoq[0], regs->iaoq[1]);
 235        }
 236
 237        err |= __put_user(flags, &sc->sc_flags);
 238        err |= __copy_to_user(sc->sc_gr, regs->gr, sizeof(regs->gr));
 239        err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));
 240        err |= __put_user(regs->sar, &sc->sc_sar);
 241        DBG(1,"setup_sigcontext: r28 is %ld\n", regs->gr[28]);
 242
 243        return err;
 244}
 245
 246static long
 247setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 248               sigset_t *set, struct pt_regs *regs, int in_syscall)
 249{
 250        struct rt_sigframe __user *frame;
 251        unsigned long rp, usp;
 252        unsigned long haddr, sigframe_size;
 253        int err = 0;
 254#ifdef CONFIG_64BIT
 255        compat_int_t compat_val;
 256        struct compat_rt_sigframe __user * compat_frame;
 257        compat_sigset_t compat_set;
 258#endif
 259        
 260        usp = (regs->gr[30] & ~(0x01UL));
 261        /*FIXME: frame_size parameter is unused, remove it. */
 262        frame = get_sigframe(ka, usp, sizeof(*frame));
 263
 264        DBG(1,"SETUP_RT_FRAME: START\n");
 265        DBG(1,"setup_rt_frame: frame %p info %p\n", frame, info);
 266
 267        
 268#ifdef CONFIG_64BIT
 269
 270        compat_frame = (struct compat_rt_sigframe __user *)frame;
 271        
 272        if (is_compat_task()) {
 273                DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info);
 274                err |= copy_siginfo_to_user32(&compat_frame->info, info);
 275                DBG(1,"SETUP_RT_FRAME: 1\n");
 276                compat_val = (compat_int_t)current->sas_ss_sp;
 277                err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_sp);
 278                DBG(1,"SETUP_RT_FRAME: 2\n");
 279                compat_val = (compat_int_t)current->sas_ss_size;
 280                err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_size);
 281                DBG(1,"SETUP_RT_FRAME: 3\n");
 282                compat_val = sas_ss_flags(regs->gr[30]);                
 283                err |= __put_user(compat_val, &compat_frame->uc.uc_stack.ss_flags);             
 284                DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &compat_frame->uc);
 285                DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &compat_frame->uc.uc_mcontext);
 286                err |= setup_sigcontext32(&compat_frame->uc.uc_mcontext, 
 287                                        &compat_frame->regs, regs, in_syscall);
 288                sigset_64to32(&compat_set,set);
 289                err |= __copy_to_user(&compat_frame->uc.uc_sigmask, &compat_set, sizeof(compat_set));
 290        } else
 291#endif
 292        {       
 293                DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &frame->info);
 294                err |= copy_siginfo_to_user(&frame->info, info);
 295                err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
 296                err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
 297                err |= __put_user(sas_ss_flags(regs->gr[30]),
 298                                  &frame->uc.uc_stack.ss_flags);
 299                DBG(1,"setup_rt_frame: frame->uc = 0x%p\n", &frame->uc);
 300                DBG(1,"setup_rt_frame: frame->uc.uc_mcontext = 0x%p\n", &frame->uc.uc_mcontext);
 301                err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, in_syscall);
 302                /* FIXME: Should probably be converted aswell for the compat case */
 303                err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 304        }
 305        
 306        if (err)
 307                goto give_sigsegv;
 308
 309        /* Set up to return from userspace.  If provided, use a stub
 310           already in userspace. The first words of tramp are used to
 311           save the previous sigrestartblock trampoline that might be
 312           on the stack. We start the sigreturn trampoline at 
 313           SIGRESTARTBLOCK_TRAMP+X. */
 314        err |= __put_user(in_syscall ? INSN_LDI_R25_1 : INSN_LDI_R25_0,
 315                        &frame->tramp[SIGRESTARTBLOCK_TRAMP+0]);
 316        err |= __put_user(INSN_LDI_R20, 
 317                        &frame->tramp[SIGRESTARTBLOCK_TRAMP+1]);
 318        err |= __put_user(INSN_BLE_SR2_R0, 
 319                        &frame->tramp[SIGRESTARTBLOCK_TRAMP+2]);
 320        err |= __put_user(INSN_NOP, &frame->tramp[SIGRESTARTBLOCK_TRAMP+3]);
 321
 322#if DEBUG_SIG
 323        /* Assert that we're flushing in the correct space... */
 324        {
 325                int sid;
 326                asm ("mfsp %%sr3,%0" : "=r" (sid));
 327                DBG(1,"setup_rt_frame: Flushing 64 bytes at space %#x offset %p\n",
 328                       sid, frame->tramp);
 329        }
 330#endif
 331
 332        flush_user_dcache_range((unsigned long) &frame->tramp[0],
 333                           (unsigned long) &frame->tramp[TRAMP_SIZE]);
 334        flush_user_icache_range((unsigned long) &frame->tramp[0],
 335                           (unsigned long) &frame->tramp[TRAMP_SIZE]);
 336
 337        /* TRAMP Words 0-4, Length 5 = SIGRESTARTBLOCK_TRAMP
 338         * TRAMP Words 5-9, Length 4 = SIGRETURN_TRAMP
 339         * So the SIGRETURN_TRAMP is at the end of SIGRESTARTBLOCK_TRAMP
 340         */
 341        rp = (unsigned long) &frame->tramp[SIGRESTARTBLOCK_TRAMP];
 342
 343        if (err)
 344                goto give_sigsegv;
 345
 346        haddr = A(ka->sa.sa_handler);
 347        /* The sa_handler may be a pointer to a function descriptor */
 348#ifdef CONFIG_64BIT
 349        if (is_compat_task()) {
 350#endif
 351                if (haddr & PA_PLABEL_FDESC) {
 352                        Elf32_Fdesc fdesc;
 353                        Elf32_Fdesc __user *ufdesc = (Elf32_Fdesc __user *)A(haddr & ~3);
 354
 355                        err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
 356
 357                        if (err)
 358                                goto give_sigsegv;
 359
 360                        haddr = fdesc.addr;
 361                        regs->gr[19] = fdesc.gp;
 362                }
 363#ifdef CONFIG_64BIT
 364        } else {
 365                Elf64_Fdesc fdesc;
 366                Elf64_Fdesc __user *ufdesc = (Elf64_Fdesc __user *)A(haddr & ~3);
 367                
 368                err = __copy_from_user(&fdesc, ufdesc, sizeof(fdesc));
 369                
 370                if (err)
 371                        goto give_sigsegv;
 372                
 373                haddr = fdesc.addr;
 374                regs->gr[19] = fdesc.gp;
 375                DBG(1,"setup_rt_frame: 64 bit signal, exe=%#lx, r19=%#lx, in_syscall=%d\n",
 376                     haddr, regs->gr[19], in_syscall);
 377        }
 378#endif
 379
 380        /* The syscall return path will create IAOQ values from r31.
 381         */
 382        sigframe_size = PARISC_RT_SIGFRAME_SIZE;
 383#ifdef CONFIG_64BIT
 384        if (is_compat_task())
 385                sigframe_size = PARISC_RT_SIGFRAME_SIZE32;
 386#endif
 387        if (in_syscall) {
 388                regs->gr[31] = haddr;
 389#ifdef CONFIG_64BIT
 390                if (!test_thread_flag(TIF_32BIT))
 391                        sigframe_size |= 1;
 392#endif
 393        } else {
 394                unsigned long psw = USER_PSW;
 395#ifdef CONFIG_64BIT
 396                if (!test_thread_flag(TIF_32BIT))
 397                        psw |= PSW_W;
 398#endif
 399
 400                /* If we are singlestepping, arrange a trap to be delivered
 401                   when we return to userspace. Note the semantics -- we
 402                   should trap before the first insn in the handler is
 403                   executed. Ref:
 404                        http://sources.redhat.com/ml/gdb/2004-11/msg00245.html
 405                 */
 406                if (pa_psw(current)->r) {
 407                        pa_psw(current)->r = 0;
 408                        psw |= PSW_R;
 409                        mtctl(-1, 0);
 410                }
 411
 412                regs->gr[0] = psw;
 413                regs->iaoq[0] = haddr | 3;
 414                regs->iaoq[1] = regs->iaoq[0] + 4;
 415        }
 416
 417        regs->gr[2]  = rp;                /* userland return pointer */
 418        regs->gr[26] = sig;               /* signal number */
 419        
 420#ifdef CONFIG_64BIT
 421        if (is_compat_task()) {
 422                regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */
 423                regs->gr[24] = A(&compat_frame->uc);   /* ucontext pointer */
 424        } else
 425#endif
 426        {               
 427                regs->gr[25] = A(&frame->info); /* siginfo pointer */
 428                regs->gr[24] = A(&frame->uc);   /* ucontext pointer */
 429        }
 430        
 431        DBG(1,"setup_rt_frame: making sigreturn frame: %#lx + %#lx = %#lx\n",
 432               regs->gr[30], sigframe_size,
 433               regs->gr[30] + sigframe_size);
 434        /* Raise the user stack pointer to make a proper call frame. */
 435        regs->gr[30] = (A(frame) + sigframe_size);
 436
 437
 438        DBG(1,"setup_rt_frame: sig deliver (%s,%d) frame=0x%p sp=%#lx iaoq=%#lx/%#lx rp=%#lx\n",
 439               current->comm, current->pid, frame, regs->gr[30],
 440               regs->iaoq[0], regs->iaoq[1], rp);
 441
 442        return 1;
 443
 444give_sigsegv:
 445        DBG(1,"setup_rt_frame: sending SIGSEGV\n");
 446        force_sigsegv(sig, current);
 447        return 0;
 448}
 449
 450/*
 451 * OK, we're invoking a handler.
 452 */     
 453
 454static long
 455handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka,
 456                sigset_t *oldset, struct pt_regs *regs, int in_syscall)
 457{
 458        DBG(1,"handle_signal: sig=%ld, ka=%p, info=%p, oldset=%p, regs=%p\n",
 459               sig, ka, info, oldset, regs);
 460        
 461        /* Set up the stack frame */
 462        if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall))
 463                return 0;
 464
 465        spin_lock_irq(&current->sighand->siglock);
 466        sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
 467        if (!(ka->sa.sa_flags & SA_NODEFER))
 468                sigaddset(&current->blocked,sig);
 469        recalc_sigpending();
 470        spin_unlock_irq(&current->sighand->siglock);
 471
 472        tracehook_signal_handler(sig, info, ka, regs, 0);
 473
 474        return 1;
 475}
 476
 477static inline void
 478syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
 479{
 480        /* Check the return code */
 481        switch (regs->gr[28]) {
 482        case -ERESTART_RESTARTBLOCK:
 483                current_thread_info()->restart_block.fn =
 484                        do_no_restart_syscall;
 485        case -ERESTARTNOHAND:
 486                DBG(1,"ERESTARTNOHAND: returning -EINTR\n");
 487                regs->gr[28] = -EINTR;
 488                break;
 489
 490        case -ERESTARTSYS:
 491                if (!(ka->sa.sa_flags & SA_RESTART)) {
 492                        DBG(1,"ERESTARTSYS: putting -EINTR\n");
 493                        regs->gr[28] = -EINTR;
 494                        break;
 495                }
 496                /* fallthrough */
 497        case -ERESTARTNOINTR:
 498                /* A syscall is just a branch, so all
 499                 * we have to do is fiddle the return pointer.
 500                 */
 501                regs->gr[31] -= 8; /* delayed branching */
 502                /* Preserve original r28. */
 503                regs->gr[28] = regs->orig_r28;
 504                break;
 505        }
 506}
 507
 508static inline void
 509insert_restart_trampoline(struct pt_regs *regs)
 510{
 511        switch(regs->gr[28]) {
 512        case -ERESTART_RESTARTBLOCK: {
 513                /* Restart the system call - no handlers present */
 514                unsigned int *usp = (unsigned int *)regs->gr[30];
 515
 516                /* Setup a trampoline to restart the syscall
 517                 * with __NR_restart_syscall
 518                 *
 519                 *  0: <return address (orig r31)>
 520                 *  4: <2nd half for 64-bit>
 521                 *  8: ldw 0(%sp), %r31
 522                 * 12: be 0x100(%sr2, %r0)
 523                 * 16: ldi __NR_restart_syscall, %r20
 524                 */
 525#ifdef CONFIG_64BIT
 526                put_user(regs->gr[31] >> 32, &usp[0]);
 527                put_user(regs->gr[31] & 0xffffffff, &usp[1]);
 528                put_user(0x0fc010df, &usp[2]);
 529#else
 530                put_user(regs->gr[31], &usp[0]);
 531                put_user(0x0fc0109f, &usp[2]);
 532#endif
 533                put_user(0xe0008200, &usp[3]);
 534                put_user(0x34140000, &usp[4]);
 535
 536                /* Stack is 64-byte aligned, and we only need
 537                 * to flush 1 cache line.
 538                 * Flushing one cacheline is cheap.
 539                 * "sync" on bigger (> 4 way) boxes is not.
 540                 */
 541                flush_user_dcache_range(regs->gr[30], regs->gr[30] + 4);
 542                flush_user_icache_range(regs->gr[30], regs->gr[30] + 4);
 543
 544                regs->gr[31] = regs->gr[30] + 8;
 545                /* Preserve original r28. */
 546                regs->gr[28] = regs->orig_r28;
 547
 548                return;
 549        }
 550        case -ERESTARTNOHAND:
 551        case -ERESTARTSYS:
 552        case -ERESTARTNOINTR: {
 553                /* Hooray for delayed branching.  We don't
 554                 * have to restore %r20 (the system call
 555                 * number) because it gets loaded in the delay
 556                 * slot of the branch external instruction.
 557                 */
 558                regs->gr[31] -= 8;
 559                /* Preserve original r28. */
 560                regs->gr[28] = regs->orig_r28;
 561
 562                return;
 563        }
 564        default:
 565                break;
 566        }
 567}
 568
 569/*
 570 * Note that 'init' is a special process: it doesn't get signals it doesn't
 571 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 572 * mistake.
 573 *
 574 * We need to be able to restore the syscall arguments (r21-r26) to
 575 * restart syscalls.  Thus, the syscall path should save them in the
 576 * pt_regs structure (it's okay to do so since they are caller-save
 577 * registers).  As noted below, the syscall number gets restored for
 578 * us due to the magic of delayed branching.
 579 */
 580asmlinkage void
 581do_signal(struct pt_regs *regs, long in_syscall)
 582{
 583        siginfo_t info;
 584        struct k_sigaction ka;
 585        int signr;
 586        sigset_t *oldset;
 587
 588        DBG(1,"\ndo_signal: oldset=0x%p, regs=0x%p, sr7 %#lx, in_syscall=%d\n",
 589               oldset, regs, regs->sr[7], in_syscall);
 590
 591        /* Everyone else checks to see if they are in kernel mode at
 592           this point and exits if that's the case.  I'm not sure why
 593           we would be called in that case, but for some reason we
 594           are. */
 595
 596        if (test_thread_flag(TIF_RESTORE_SIGMASK))
 597                oldset = &current->saved_sigmask;
 598        else
 599                oldset = &current->blocked;
 600
 601        DBG(1,"do_signal: oldset %08lx / %08lx\n", 
 602                oldset->sig[0], oldset->sig[1]);
 603
 604
 605        /* May need to force signal if handle_signal failed to deliver */
 606        while (1) {
 607          
 608                signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 609                DBG(3,"do_signal: signr = %d, regs->gr[28] = %ld\n", signr, regs->gr[28]); 
 610        
 611                if (signr <= 0)
 612                  break;
 613                
 614                /* Restart a system call if necessary. */
 615                if (in_syscall)
 616                        syscall_restart(regs, &ka);
 617
 618                /* Whee!  Actually deliver the signal.  If the
 619                   delivery failed, we need to continue to iterate in
 620                   this loop so we can deliver the SIGSEGV... */
 621                if (handle_signal(signr, &info, &ka, oldset,
 622                                  regs, in_syscall)) {
 623                        DBG(1,KERN_DEBUG "do_signal: Exit (success), regs->gr[28] = %ld\n",
 624                                regs->gr[28]);
 625                        if (test_thread_flag(TIF_RESTORE_SIGMASK))
 626                                clear_thread_flag(TIF_RESTORE_SIGMASK);
 627                        return;
 628                }
 629        }
 630        /* end of while(1) looping forever if we can't force a signal */
 631
 632        /* Did we come from a system call? */
 633        if (in_syscall)
 634                insert_restart_trampoline(regs);
 635        
 636        DBG(1,"do_signal: Exit (not delivered), regs->gr[28] = %ld\n", 
 637                regs->gr[28]);
 638
 639        if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
 640                clear_thread_flag(TIF_RESTORE_SIGMASK);
 641                sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 642        }
 643
 644        return;
 645}
 646
 647void do_notify_resume(struct pt_regs *regs, long in_syscall)
 648{
 649        if (test_thread_flag(TIF_SIGPENDING) ||
 650            test_thread_flag(TIF_RESTORE_SIGMASK))
 651                do_signal(regs, in_syscall);
 652
 653        if (test_thread_flag(TIF_NOTIFY_RESUME)) {
 654                clear_thread_flag(TIF_NOTIFY_RESUME);
 655                tracehook_notify_resume(regs);
 656                if (current->replacement_session_keyring)
 657                        key_replace_session_keyring();
 658        }
 659}
 660
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.