linux/arch/sparc/kernel/signal_64.c
<<
>>
Prefs
   1/*
   2 *  arch/sparc64/kernel/signal.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 *  Copyright (C) 1995, 2008 David S. Miller (davem@davemloft.net)
   6 *  Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
   7 *  Copyright (C) 1997 Eddie C. Dost   (ecd@skynet.be)
   8 *  Copyright (C) 1997,1998 Jakub Jelinek   (jj@sunsite.mff.cuni.cz)
   9 */
  10
  11#ifdef CONFIG_COMPAT
  12#include <linux/compat.h>       /* for compat_old_sigset_t */
  13#endif
  14#include <linux/sched.h>
  15#include <linux/kernel.h>
  16#include <linux/signal.h>
  17#include <linux/errno.h>
  18#include <linux/wait.h>
  19#include <linux/ptrace.h>
  20#include <linux/tracehook.h>
  21#include <linux/unistd.h>
  22#include <linux/mm.h>
  23#include <linux/tty.h>
  24#include <linux/binfmts.h>
  25#include <linux/bitops.h>
  26
  27#include <asm/uaccess.h>
  28#include <asm/ptrace.h>
  29#include <asm/pgtable.h>
  30#include <asm/fpumacro.h>
  31#include <asm/uctx.h>
  32#include <asm/siginfo.h>
  33#include <asm/visasm.h>
  34
  35#include "entry.h"
  36#include "systbls.h"
  37#include "sigutil.h"
  38
  39#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
  40
  41/* {set, get}context() needed for 64-bit SparcLinux userland. */
  42asmlinkage void sparc64_set_context(struct pt_regs *regs)
  43{
  44        struct ucontext __user *ucp = (struct ucontext __user *)
  45                regs->u_regs[UREG_I0];
  46        mc_gregset_t __user *grp;
  47        unsigned long pc, npc, tstate;
  48        unsigned long fp, i7;
  49        unsigned char fenab;
  50        int err;
  51
  52        flush_user_windows();
  53        if (get_thread_wsaved()                                 ||
  54            (((unsigned long)ucp) & (sizeof(unsigned long)-1))  ||
  55            (!__access_ok(ucp, sizeof(*ucp))))
  56                goto do_sigsegv;
  57        grp  = &ucp->uc_mcontext.mc_gregs;
  58        err  = __get_user(pc, &((*grp)[MC_PC]));
  59        err |= __get_user(npc, &((*grp)[MC_NPC]));
  60        if (err || ((pc | npc) & 3))
  61                goto do_sigsegv;
  62        if (regs->u_regs[UREG_I1]) {
  63                sigset_t set;
  64
  65                if (_NSIG_WORDS == 1) {
  66                        if (__get_user(set.sig[0], &ucp->uc_sigmask.sig[0]))
  67                                goto do_sigsegv;
  68                } else {
  69                        if (__copy_from_user(&set, &ucp->uc_sigmask, sizeof(sigset_t)))
  70                                goto do_sigsegv;
  71                }
  72                sigdelsetmask(&set, ~_BLOCKABLE);
  73                set_current_blocked(&set);
  74        }
  75        if (test_thread_flag(TIF_32BIT)) {
  76                pc &= 0xffffffff;
  77                npc &= 0xffffffff;
  78        }
  79        regs->tpc = pc;
  80        regs->tnpc = npc;
  81        err |= __get_user(regs->y, &((*grp)[MC_Y]));
  82        err |= __get_user(tstate, &((*grp)[MC_TSTATE]));
  83        regs->tstate &= ~(TSTATE_ASI | TSTATE_ICC | TSTATE_XCC);
  84        regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
  85        err |= __get_user(regs->u_regs[UREG_G1], (&(*grp)[MC_G1]));
  86        err |= __get_user(regs->u_regs[UREG_G2], (&(*grp)[MC_G2]));
  87        err |= __get_user(regs->u_regs[UREG_G3], (&(*grp)[MC_G3]));
  88        err |= __get_user(regs->u_regs[UREG_G4], (&(*grp)[MC_G4]));
  89        err |= __get_user(regs->u_regs[UREG_G5], (&(*grp)[MC_G5]));
  90        err |= __get_user(regs->u_regs[UREG_G6], (&(*grp)[MC_G6]));
  91
  92        /* Skip %g7 as that's the thread register in userspace.  */
  93
  94        err |= __get_user(regs->u_regs[UREG_I0], (&(*grp)[MC_O0]));
  95        err |= __get_user(regs->u_regs[UREG_I1], (&(*grp)[MC_O1]));
  96        err |= __get_user(regs->u_regs[UREG_I2], (&(*grp)[MC_O2]));
  97        err |= __get_user(regs->u_regs[UREG_I3], (&(*grp)[MC_O3]));
  98        err |= __get_user(regs->u_regs[UREG_I4], (&(*grp)[MC_O4]));
  99        err |= __get_user(regs->u_regs[UREG_I5], (&(*grp)[MC_O5]));
 100        err |= __get_user(regs->u_regs[UREG_I6], (&(*grp)[MC_O6]));
 101        err |= __get_user(regs->u_regs[UREG_I7], (&(*grp)[MC_O7]));
 102
 103        err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
 104        err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
 105        err |= __put_user(fp,
 106              (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
 107        err |= __put_user(i7,
 108              (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
 109
 110        err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
 111        if (fenab) {
 112                unsigned long *fpregs = current_thread_info()->fpregs;
 113                unsigned long fprs;
 114                
 115                fprs_write(0);
 116                err |= __get_user(fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
 117                if (fprs & FPRS_DL)
 118                        err |= copy_from_user(fpregs,
 119                                              &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs),
 120                                              (sizeof(unsigned int) * 32));
 121                if (fprs & FPRS_DU)
 122                        err |= copy_from_user(fpregs+16,
 123                         ((unsigned long __user *)&(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs))+16,
 124                         (sizeof(unsigned int) * 32));
 125                err |= __get_user(current_thread_info()->xfsr[0],
 126                                  &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
 127                err |= __get_user(current_thread_info()->gsr[0],
 128                                  &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
 129                regs->tstate &= ~TSTATE_PEF;
 130        }
 131        if (err)
 132                goto do_sigsegv;
 133
 134        return;
 135do_sigsegv:
 136        force_sig(SIGSEGV, current);
 137}
 138
 139asmlinkage void sparc64_get_context(struct pt_regs *regs)
 140{
 141        struct ucontext __user *ucp = (struct ucontext __user *)
 142                regs->u_regs[UREG_I0];
 143        mc_gregset_t __user *grp;
 144        mcontext_t __user *mcp;
 145        unsigned long fp, i7;
 146        unsigned char fenab;
 147        int err;
 148
 149        synchronize_user_stack();
 150        if (get_thread_wsaved() || clear_user(ucp, sizeof(*ucp)))
 151                goto do_sigsegv;
 152
 153#if 1
 154        fenab = 0; /* IMO get_context is like any other system call, thus modifies FPU state -jj */
 155#else
 156        fenab = (current_thread_info()->fpsaved[0] & FPRS_FEF);
 157#endif
 158                
 159        mcp = &ucp->uc_mcontext;
 160        grp = &mcp->mc_gregs;
 161
 162        /* Skip over the trap instruction, first. */
 163        if (test_thread_flag(TIF_32BIT)) {
 164                regs->tpc   = (regs->tnpc & 0xffffffff);
 165                regs->tnpc  = (regs->tnpc + 4) & 0xffffffff;
 166        } else {
 167                regs->tpc   = regs->tnpc;
 168                regs->tnpc += 4;
 169        }
 170        err = 0;
 171        if (_NSIG_WORDS == 1)
 172                err |= __put_user(current->blocked.sig[0],
 173                                  (unsigned long __user *)&ucp->uc_sigmask);
 174        else
 175                err |= __copy_to_user(&ucp->uc_sigmask, &current->blocked,
 176                                      sizeof(sigset_t));
 177
 178        err |= __put_user(regs->tstate, &((*grp)[MC_TSTATE]));
 179        err |= __put_user(regs->tpc, &((*grp)[MC_PC]));
 180        err |= __put_user(regs->tnpc, &((*grp)[MC_NPC]));
 181        err |= __put_user(regs->y, &((*grp)[MC_Y]));
 182        err |= __put_user(regs->u_regs[UREG_G1], &((*grp)[MC_G1]));
 183        err |= __put_user(regs->u_regs[UREG_G2], &((*grp)[MC_G2]));
 184        err |= __put_user(regs->u_regs[UREG_G3], &((*grp)[MC_G3]));
 185        err |= __put_user(regs->u_regs[UREG_G4], &((*grp)[MC_G4]));
 186        err |= __put_user(regs->u_regs[UREG_G5], &((*grp)[MC_G5]));
 187        err |= __put_user(regs->u_regs[UREG_G6], &((*grp)[MC_G6]));
 188        err |= __put_user(regs->u_regs[UREG_G7], &((*grp)[MC_G7]));
 189        err |= __put_user(regs->u_regs[UREG_I0], &((*grp)[MC_O0]));
 190        err |= __put_user(regs->u_regs[UREG_I1], &((*grp)[MC_O1]));
 191        err |= __put_user(regs->u_regs[UREG_I2], &((*grp)[MC_O2]));
 192        err |= __put_user(regs->u_regs[UREG_I3], &((*grp)[MC_O3]));
 193        err |= __put_user(regs->u_regs[UREG_I4], &((*grp)[MC_O4]));
 194        err |= __put_user(regs->u_regs[UREG_I5], &((*grp)[MC_O5]));
 195        err |= __put_user(regs->u_regs[UREG_I6], &((*grp)[MC_O6]));
 196        err |= __put_user(regs->u_regs[UREG_I7], &((*grp)[MC_O7]));
 197
 198        err |= __get_user(fp,
 199                 (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[6])));
 200        err |= __get_user(i7,
 201                 (&(((struct reg_window __user *)(STACK_BIAS+regs->u_regs[UREG_I6]))->ins[7])));
 202        err |= __put_user(fp, &(mcp->mc_fp));
 203        err |= __put_user(i7, &(mcp->mc_i7));
 204
 205        err |= __put_user(fenab, &(mcp->mc_fpregs.mcfpu_enab));
 206        if (fenab) {
 207                unsigned long *fpregs = current_thread_info()->fpregs;
 208                unsigned long fprs;
 209                
 210                fprs = current_thread_info()->fpsaved[0];
 211                if (fprs & FPRS_DL)
 212                        err |= copy_to_user(&(mcp->mc_fpregs.mcfpu_fregs), fpregs,
 213                                            (sizeof(unsigned int) * 32));
 214                if (fprs & FPRS_DU)
 215                        err |= copy_to_user(
 216                          ((unsigned long __user *)&(mcp->mc_fpregs.mcfpu_fregs))+16, fpregs+16,
 217                          (sizeof(unsigned int) * 32));
 218                err |= __put_user(current_thread_info()->xfsr[0], &(mcp->mc_fpregs.mcfpu_fsr));
 219                err |= __put_user(current_thread_info()->gsr[0], &(mcp->mc_fpregs.mcfpu_gsr));
 220                err |= __put_user(fprs, &(mcp->mc_fpregs.mcfpu_fprs));
 221        }
 222        if (err)
 223                goto do_sigsegv;
 224
 225        return;
 226do_sigsegv:
 227        force_sig(SIGSEGV, current);
 228}
 229
 230struct rt_signal_frame {
 231        struct sparc_stackf     ss;
 232        siginfo_t               info;
 233        struct pt_regs          regs;
 234        __siginfo_fpu_t __user  *fpu_save;
 235        stack_t                 stack;
 236        sigset_t                mask;
 237        __siginfo_rwin_t        *rwin_save;
 238};
 239
 240static long _sigpause_common(old_sigset_t set)
 241{
 242        sigset_t blocked;
 243
 244        current->saved_sigmask = current->blocked;
 245
 246        set &= _BLOCKABLE;
 247        siginitset(&blocked, set);
 248        set_current_blocked(&blocked);
 249
 250        current->state = TASK_INTERRUPTIBLE;
 251        schedule();
 252
 253        set_restore_sigmask();
 254
 255        return -ERESTARTNOHAND;
 256}
 257
 258asmlinkage long sys_sigpause(unsigned int set)
 259{
 260        return _sigpause_common(set);
 261}
 262
 263asmlinkage long sys_sigsuspend(old_sigset_t set)
 264{
 265        return _sigpause_common(set);
 266}
 267
 268void do_rt_sigreturn(struct pt_regs *regs)
 269{
 270        struct rt_signal_frame __user *sf;
 271        unsigned long tpc, tnpc, tstate;
 272        __siginfo_fpu_t __user *fpu_save;
 273        __siginfo_rwin_t __user *rwin_save;
 274        sigset_t set;
 275        int err;
 276
 277        /* Always make any pending restarted system calls return -EINTR */
 278        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 279
 280        synchronize_user_stack ();
 281        sf = (struct rt_signal_frame __user *)
 282                (regs->u_regs [UREG_FP] + STACK_BIAS);
 283
 284        /* 1. Make sure we are not getting garbage from the user */
 285        if (((unsigned long) sf) & 3)
 286                goto segv;
 287
 288        err = get_user(tpc, &sf->regs.tpc);
 289        err |= __get_user(tnpc, &sf->regs.tnpc);
 290        if (test_thread_flag(TIF_32BIT)) {
 291                tpc &= 0xffffffff;
 292                tnpc &= 0xffffffff;
 293        }
 294        err |= ((tpc | tnpc) & 3);
 295
 296        /* 2. Restore the state */
 297        err |= __get_user(regs->y, &sf->regs.y);
 298        err |= __get_user(tstate, &sf->regs.tstate);
 299        err |= copy_from_user(regs->u_regs, sf->regs.u_regs, sizeof(regs->u_regs));
 300
 301        /* User can only change condition codes and %asi in %tstate. */
 302        regs->tstate &= ~(TSTATE_ASI | TSTATE_ICC | TSTATE_XCC);
 303        regs->tstate |= (tstate & (TSTATE_ASI | TSTATE_ICC | TSTATE_XCC));
 304
 305        err |= __get_user(fpu_save, &sf->fpu_save);
 306        if (!err && fpu_save)
 307                err |= restore_fpu_state(regs, fpu_save);
 308
 309        err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
 310        err |= do_sigaltstack(&sf->stack, NULL, (unsigned long)sf);
 311
 312        if (err)
 313                goto segv;
 314
 315        err |= __get_user(rwin_save, &sf->rwin_save);
 316        if (!err && rwin_save) {
 317                if (restore_rwin_state(rwin_save))
 318                        goto segv;
 319        }
 320
 321        regs->tpc = tpc;
 322        regs->tnpc = tnpc;
 323
 324        /* Prevent syscall restart.  */
 325        pt_regs_clear_syscall(regs);
 326
 327        sigdelsetmask(&set, ~_BLOCKABLE);
 328        set_current_blocked(&set);
 329        return;
 330segv:
 331        force_sig(SIGSEGV, current);
 332}
 333
 334/* Checks if the fp is valid */
 335static int invalid_frame_pointer(void __user *fp)
 336{
 337        if (((unsigned long) fp) & 15)
 338                return 1;
 339        return 0;
 340}
 341
 342static inline void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, unsigned long framesize)
 343{
 344        unsigned long sp = regs->u_regs[UREG_FP] + STACK_BIAS;
 345
 346        /*
 347         * If we are on the alternate signal stack and would overflow it, don't.
 348         * Return an always-bogus address instead so we will die with SIGSEGV.
 349         */
 350        if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
 351                return (void __user *) -1L;
 352
 353        /* This is the X/Open sanctioned signal stack switching.  */
 354        if (ka->sa.sa_flags & SA_ONSTACK) {
 355                if (sas_ss_flags(sp) == 0)
 356                        sp = current->sas_ss_sp + current->sas_ss_size;
 357        }
 358
 359        sp -= framesize;
 360
 361        /* Always align the stack frame.  This handles two cases.  First,
 362         * sigaltstack need not be mindful of platform specific stack
 363         * alignment.  Second, if we took this signal because the stack
 364         * is not aligned properly, we'd like to take the signal cleanly
 365         * and report that.
 366         */
 367        sp &= ~15UL;
 368
 369        return (void __user *) sp;
 370}
 371
 372static inline int
 373setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
 374               int signo, sigset_t *oldset, siginfo_t *info)
 375{
 376        struct rt_signal_frame __user *sf;
 377        int wsaved, err, sf_size;
 378        void __user *tail;
 379
 380        /* 1. Make sure everything is clean */
 381        synchronize_user_stack();
 382        save_and_clear_fpu();
 383        
 384        wsaved = get_thread_wsaved();
 385
 386        sf_size = sizeof(struct rt_signal_frame);
 387        if (current_thread_info()->fpsaved[0] & FPRS_FEF)
 388                sf_size += sizeof(__siginfo_fpu_t);
 389        if (wsaved)
 390                sf_size += sizeof(__siginfo_rwin_t);
 391        sf = (struct rt_signal_frame __user *)
 392                get_sigframe(ka, regs, sf_size);
 393
 394        if (invalid_frame_pointer (sf))
 395                goto sigill;
 396
 397        tail = (sf + 1);
 398
 399        /* 2. Save the current process state */
 400        err = copy_to_user(&sf->regs, regs, sizeof (*regs));
 401
 402        if (current_thread_info()->fpsaved[0] & FPRS_FEF) {
 403                __siginfo_fpu_t __user *fpu_save = tail;
 404                tail += sizeof(__siginfo_fpu_t);
 405                err |= save_fpu_state(regs, fpu_save);
 406                err |= __put_user((u64)fpu_save, &sf->fpu_save);
 407        } else {
 408                err |= __put_user(0, &sf->fpu_save);
 409        }
 410        if (wsaved) {
 411                __siginfo_rwin_t __user *rwin_save = tail;
 412                tail += sizeof(__siginfo_rwin_t);
 413                err |= save_rwin_state(wsaved, rwin_save);
 414                err |= __put_user((u64)rwin_save, &sf->rwin_save);
 415                set_thread_wsaved(0);
 416        } else {
 417                err |= __put_user(0, &sf->rwin_save);
 418        }
 419        
 420        /* Setup sigaltstack */
 421        err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
 422        err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
 423        err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
 424
 425        err |= copy_to_user(&sf->mask, oldset, sizeof(sigset_t));
 426
 427        if (!wsaved) {
 428                err |= copy_in_user((u64 __user *)sf,
 429                                    (u64 __user *)(regs->u_regs[UREG_FP] +
 430                                                   STACK_BIAS),
 431                                    sizeof(struct reg_window));
 432        } else {
 433                struct reg_window *rp;
 434
 435                rp = &current_thread_info()->reg_window[wsaved - 1];
 436                err |= copy_to_user(sf, rp, sizeof(struct reg_window));
 437        }
 438        if (info)
 439                err |= copy_siginfo_to_user(&sf->info, info);
 440        else {
 441                err |= __put_user(signo, &sf->info.si_signo);
 442                err |= __put_user(SI_NOINFO, &sf->info.si_code);
 443        }
 444        if (err)
 445                goto sigsegv;
 446        
 447        /* 3. signal handler back-trampoline and parameters */
 448        regs->u_regs[UREG_FP] = ((unsigned long) sf) - STACK_BIAS;
 449        regs->u_regs[UREG_I0] = signo;
 450        regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
 451
 452        /* The sigcontext is passed in this way because of how it
 453         * is defined in GLIBC's /usr/include/bits/sigcontext.h
 454         * for sparc64.  It includes the 128 bytes of siginfo_t.
 455         */
 456        regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
 457
 458        /* 5. signal handler */
 459        regs->tpc = (unsigned long) ka->sa.sa_handler;
 460        regs->tnpc = (regs->tpc + 4);
 461        if (test_thread_flag(TIF_32BIT)) {
 462                regs->tpc &= 0xffffffff;
 463                regs->tnpc &= 0xffffffff;
 464        }
 465        /* 4. return to kernel instructions */
 466        regs->u_regs[UREG_I7] = (unsigned long)ka->ka_restorer;
 467        return 0;
 468
 469sigill:
 470        do_exit(SIGILL);
 471        return -EINVAL;
 472
 473sigsegv:
 474        force_sigsegv(signo, current);
 475        return -EFAULT;
 476}
 477
 478static inline int handle_signal(unsigned long signr, struct k_sigaction *ka,
 479                                siginfo_t *info,
 480                                sigset_t *oldset, struct pt_regs *regs)
 481{
 482        sigset_t blocked;
 483        int err;
 484
 485        err = setup_rt_frame(ka, regs, signr, oldset,
 486                             (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL);
 487        if (err)
 488                return err;
 489        sigorsets(&blocked, &current->blocked, &ka->sa.sa_mask);
 490        if (!(ka->sa.sa_flags & SA_NOMASK))
 491                sigaddset(&blocked, signr);
 492        set_current_blocked(&blocked);
 493
 494        tracehook_signal_handler(signr, info, ka, regs, 0);
 495
 496        return 0;
 497}
 498
 499static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
 500                                   struct sigaction *sa)
 501{
 502        switch (regs->u_regs[UREG_I0]) {
 503        case ERESTART_RESTARTBLOCK:
 504        case ERESTARTNOHAND:
 505        no_system_call_restart:
 506                regs->u_regs[UREG_I0] = EINTR;
 507                regs->tstate |= (TSTATE_ICARRY|TSTATE_XCARRY);
 508                break;
 509        case ERESTARTSYS:
 510                if (!(sa->sa_flags & SA_RESTART))
 511                        goto no_system_call_restart;
 512                /* fallthrough */
 513        case ERESTARTNOINTR:
 514                regs->u_regs[UREG_I0] = orig_i0;
 515                regs->tpc -= 4;
 516                regs->tnpc -= 4;
 517        }
 518}
 519
 520/* Note that 'init' is a special process: it doesn't get signals it doesn't
 521 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 522 * mistake.
 523 */
 524static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
 525{
 526        struct k_sigaction ka;
 527        int restart_syscall;
 528        sigset_t *oldset;
 529        siginfo_t info;
 530        int signr;
 531        
 532        /* It's a lot of work and synchronization to add a new ptrace
 533         * register for GDB to save and restore in order to get
 534         * orig_i0 correct for syscall restarts when debugging.
 535         *
 536         * Although it should be the case that most of the global
 537         * registers are volatile across a system call, glibc already
 538         * depends upon that fact that we preserve them.  So we can't
 539         * just use any global register to save away the orig_i0 value.
 540         *
 541         * In particular %g2, %g3, %g4, and %g5 are all assumed to be
 542         * preserved across a system call trap by various pieces of
 543         * code in glibc.
 544         *
 545         * %g7 is used as the "thread register".   %g6 is not used in
 546         * any fixed manner.  %g6 is used as a scratch register and
 547         * a compiler temporary, but it's value is never used across
 548         * a system call.  Therefore %g6 is usable for orig_i0 storage.
 549         */
 550        if (pt_regs_is_syscall(regs) &&
 551            (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY)))
 552                regs->u_regs[UREG_G6] = orig_i0;
 553
 554        if (current_thread_info()->status & TS_RESTORE_SIGMASK)
 555                oldset = &current->saved_sigmask;
 556        else
 557                oldset = &current->blocked;
 558
 559#ifdef CONFIG_COMPAT
 560        if (test_thread_flag(TIF_32BIT)) {
 561                extern void do_signal32(sigset_t *, struct pt_regs *);
 562                do_signal32(oldset, regs);
 563                return;
 564        }
 565#endif  
 566
 567        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 568
 569        restart_syscall = 0;
 570        if (pt_regs_is_syscall(regs) &&
 571            (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
 572                restart_syscall = 1;
 573                orig_i0 = regs->u_regs[UREG_G6];
 574        }
 575
 576        if (signr > 0) {
 577                if (restart_syscall)
 578                        syscall_restart(orig_i0, regs, &ka.sa);
 579                if (handle_signal(signr, &ka, &info, oldset, regs) == 0) {
 580                        /* A signal was successfully delivered; the saved
 581                         * sigmask will have been stored in the signal frame,
 582                         * and will be restored by sigreturn, so we can simply
 583                         * clear the TS_RESTORE_SIGMASK flag.
 584                         */
 585                        current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 586                }
 587                return;
 588        }
 589        if (restart_syscall &&
 590            (regs->u_regs[UREG_I0] == ERESTARTNOHAND ||
 591             regs->u_regs[UREG_I0] == ERESTARTSYS ||
 592             regs->u_regs[UREG_I0] == ERESTARTNOINTR)) {
 593                /* replay the system call when we are done */
 594                regs->u_regs[UREG_I0] = orig_i0;
 595                regs->tpc -= 4;
 596                regs->tnpc -= 4;
 597                pt_regs_clear_syscall(regs);
 598        }
 599        if (restart_syscall &&
 600            regs->u_regs[UREG_I0] == ERESTART_RESTARTBLOCK) {
 601                regs->u_regs[UREG_G1] = __NR_restart_syscall;
 602                regs->tpc -= 4;
 603                regs->tnpc -= 4;
 604                pt_regs_clear_syscall(regs);
 605        }
 606
 607        /* If there's no signal to deliver, we just put the saved sigmask
 608         * back
 609         */
 610        if (current_thread_info()->status & TS_RESTORE_SIGMASK) {
 611                current_thread_info()->status &= ~TS_RESTORE_SIGMASK;
 612                set_current_blocked(&current->saved_sigmask);
 613        }
 614}
 615
 616void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long thread_info_flags)
 617{
 618        if (thread_info_flags & _TIF_SIGPENDING)
 619                do_signal(regs, orig_i0);
 620        if (thread_info_flags & _TIF_NOTIFY_RESUME) {
 621                clear_thread_flag(TIF_NOTIFY_RESUME);
 622                tracehook_notify_resume(regs);
 623                if (current->replacement_session_keyring)
 624                        key_replace_session_keyring();
 625        }
 626}
 627
 628
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.