linux/arch/mips/kernel/signal.c
<<
>>
Prefs
   1/*
   2 * This file is subject to the terms and conditions of the GNU General Public
   3 * License.  See the file "COPYING" in the main directory of this archive
   4 * for more details.
   5 *
   6 * Copyright (C) 1991, 1992  Linus Torvalds
   7 * Copyright (C) 1994 - 2000  Ralf Baechle
   8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
   9 */
  10#include <linux/cache.h>
  11#include <linux/sched.h>
  12#include <linux/mm.h>
  13#include <linux/personality.h>
  14#include <linux/smp.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/unistd.h>
  21#include <linux/compiler.h>
  22#include <linux/uaccess.h>
  23
  24#include <asm/abi.h>
  25#include <asm/asm.h>
  26#include <linux/bitops.h>
  27#include <asm/cacheflush.h>
  28#include <asm/fpu.h>
  29#include <asm/sim.h>
  30#include <asm/ucontext.h>
  31#include <asm/cpu-features.h>
  32#include <asm/war.h>
  33
  34#include "signal-common.h"
  35
  36/*
  37 * Horribly complicated - with the bloody RM9000 workarounds enabled
  38 * the signal trampolines is moving to the end of the structure so we can
  39 * increase the alignment without breaking software compatibility.
  40 */
  41#if ICACHE_REFILLS_WORKAROUND_WAR == 0
  42
  43struct sigframe {
  44        u32 sf_ass[4];          /* argument save space for o32 */
  45        u32 sf_code[2];         /* signal trampoline */
  46        struct sigcontext sf_sc;
  47        sigset_t sf_mask;
  48};
  49
  50struct rt_sigframe {
  51        u32 rs_ass[4];          /* argument save space for o32 */
  52        u32 rs_code[2];         /* signal trampoline */
  53        struct siginfo rs_info;
  54        struct ucontext rs_uc;
  55};
  56
  57#else
  58
  59struct sigframe {
  60        u32 sf_ass[4];                  /* argument save space for o32 */
  61        u32 sf_pad[2];
  62        struct sigcontext sf_sc;        /* hw context */
  63        sigset_t sf_mask;
  64        u32 sf_code[8] ____cacheline_aligned;   /* signal trampoline */
  65};
  66
  67struct rt_sigframe {
  68        u32 rs_ass[4];                  /* argument save space for o32 */
  69        u32 rs_pad[2];
  70        struct siginfo rs_info;
  71        struct ucontext rs_uc;
  72        u32 rs_code[8] ____cacheline_aligned;   /* signal trampoline */
  73};
  74
  75#endif
  76
  77/*
  78 * Helper routines
  79 */
  80static int protected_save_fp_context(struct sigcontext __user *sc)
  81{
  82        int err;
  83        while (1) {
  84                lock_fpu_owner();
  85                own_fpu_inatomic(1);
  86                err = save_fp_context(sc); /* this might fail */
  87                unlock_fpu_owner();
  88                if (likely(!err))
  89                        break;
  90                /* touch the sigcontext and try again */
  91                err = __put_user(0, &sc->sc_fpregs[0]) |
  92                        __put_user(0, &sc->sc_fpregs[31]) |
  93                        __put_user(0, &sc->sc_fpc_csr);
  94                if (err)
  95                        break;  /* really bad sigcontext */
  96        }
  97        return err;
  98}
  99
 100static int protected_restore_fp_context(struct sigcontext __user *sc)
 101{
 102        int err, tmp;
 103        while (1) {
 104                lock_fpu_owner();
 105                own_fpu_inatomic(0);
 106                err = restore_fp_context(sc); /* this might fail */
 107                unlock_fpu_owner();
 108                if (likely(!err))
 109                        break;
 110                /* touch the sigcontext and try again */
 111                err = __get_user(tmp, &sc->sc_fpregs[0]) |
 112                        __get_user(tmp, &sc->sc_fpregs[31]) |
 113                        __get_user(tmp, &sc->sc_fpc_csr);
 114                if (err)
 115                        break;  /* really bad sigcontext */
 116        }
 117        return err;
 118}
 119
 120int setup_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 121{
 122        int err = 0;
 123        int i;
 124        unsigned int used_math;
 125
 126        err |= __put_user(regs->cp0_epc, &sc->sc_pc);
 127
 128        err |= __put_user(0, &sc->sc_regs[0]);
 129        for (i = 1; i < 32; i++)
 130                err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
 131
 132#ifdef CONFIG_CPU_HAS_SMARTMIPS
 133        err |= __put_user(regs->acx, &sc->sc_acx);
 134#endif
 135        err |= __put_user(regs->hi, &sc->sc_mdhi);
 136        err |= __put_user(regs->lo, &sc->sc_mdlo);
 137        if (cpu_has_dsp) {
 138                err |= __put_user(mfhi1(), &sc->sc_hi1);
 139                err |= __put_user(mflo1(), &sc->sc_lo1);
 140                err |= __put_user(mfhi2(), &sc->sc_hi2);
 141                err |= __put_user(mflo2(), &sc->sc_lo2);
 142                err |= __put_user(mfhi3(), &sc->sc_hi3);
 143                err |= __put_user(mflo3(), &sc->sc_lo3);
 144                err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
 145        }
 146
 147        used_math = !!used_math();
 148        err |= __put_user(used_math, &sc->sc_used_math);
 149
 150        if (used_math) {
 151                /*
 152                 * Save FPU state to signal context. Signal handler
 153                 * will "inherit" current FPU state.
 154                 */
 155                err |= protected_save_fp_context(sc);
 156        }
 157        return err;
 158}
 159
 160int fpcsr_pending(unsigned int __user *fpcsr)
 161{
 162        int err, sig = 0;
 163        unsigned int csr, enabled;
 164
 165        err = __get_user(csr, fpcsr);
 166        enabled = FPU_CSR_UNI_X | ((csr & FPU_CSR_ALL_E) << 5);
 167        /*
 168         * If the signal handler set some FPU exceptions, clear it and
 169         * send SIGFPE.
 170         */
 171        if (csr & enabled) {
 172                csr &= ~enabled;
 173                err |= __put_user(csr, fpcsr);
 174                sig = SIGFPE;
 175        }
 176        return err ?: sig;
 177}
 178
 179static int
 180check_and_restore_fp_context(struct sigcontext __user *sc)
 181{
 182        int err, sig;
 183
 184        err = sig = fpcsr_pending(&sc->sc_fpc_csr);
 185        if (err > 0)
 186                err = 0;
 187        err |= protected_restore_fp_context(sc);
 188        return err ?: sig;
 189}
 190
 191int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 192{
 193        unsigned int used_math;
 194        unsigned long treg;
 195        int err = 0;
 196        int i;
 197
 198        /* Always make any pending restarted system calls return -EINTR */
 199        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 200
 201        err |= __get_user(regs->cp0_epc, &sc->sc_pc);
 202
 203#ifdef CONFIG_CPU_HAS_SMARTMIPS
 204        err |= __get_user(regs->acx, &sc->sc_acx);
 205#endif
 206        err |= __get_user(regs->hi, &sc->sc_mdhi);
 207        err |= __get_user(regs->lo, &sc->sc_mdlo);
 208        if (cpu_has_dsp) {
 209                err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
 210                err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
 211                err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
 212                err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
 213                err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
 214                err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
 215                err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
 216        }
 217
 218        for (i = 1; i < 32; i++)
 219                err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
 220
 221        err |= __get_user(used_math, &sc->sc_used_math);
 222        conditional_used_math(used_math);
 223
 224        if (used_math) {
 225                /* restore fpu context if we have used it before */
 226                if (!err)
 227                        err = check_and_restore_fp_context(sc);
 228        } else {
 229                /* signal handler may have used FPU.  Give it up. */
 230                lose_fpu(0);
 231        }
 232
 233        return err;
 234}
 235
 236void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
 237                          size_t frame_size)
 238{
 239        unsigned long sp;
 240
 241        /* Default to using normal stack */
 242        sp = regs->regs[29];
 243
 244        /*
 245         * FPU emulator may have it's own trampoline active just
 246         * above the user stack, 16-bytes before the next lowest
 247         * 16 byte boundary.  Try to avoid trashing it.
 248         */
 249        sp -= 32;
 250
 251        /* This is the X/Open sanctioned signal stack switching.  */
 252        if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0))
 253                sp = current->sas_ss_sp + current->sas_ss_size;
 254
 255        return (void __user *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? ~(cpu_icache_line_size()-1) : ALMASK));
 256}
 257
 258int install_sigtramp(unsigned int __user *tramp, unsigned int syscall)
 259{
 260        int err;
 261
 262        /*
 263         * Set up the return code ...
 264         *
 265         *         li      v0, __NR__foo_sigreturn
 266         *         syscall
 267         */
 268
 269        err = __put_user(0x24020000 + syscall, tramp + 0);
 270        err |= __put_user(0x0000000c         , tramp + 1);
 271        if (ICACHE_REFILLS_WORKAROUND_WAR) {
 272                err |= __put_user(0, tramp + 2);
 273                err |= __put_user(0, tramp + 3);
 274                err |= __put_user(0, tramp + 4);
 275                err |= __put_user(0, tramp + 5);
 276                err |= __put_user(0, tramp + 6);
 277                err |= __put_user(0, tramp + 7);
 278        }
 279        flush_cache_sigtramp((unsigned long) tramp);
 280
 281        return err;
 282}
 283
 284/*
 285 * Atomically swap in the new signal mask, and wait for a signal.
 286 */
 287
 288#ifdef CONFIG_TRAD_SIGNALS
 289asmlinkage int sys_sigsuspend(nabi_no_regargs struct pt_regs regs)
 290{
 291        sigset_t newset;
 292        sigset_t __user *uset;
 293
 294        uset = (sigset_t __user *) regs.regs[4];
 295        if (copy_from_user(&newset, uset, sizeof(sigset_t)))
 296                return -EFAULT;
 297        sigdelsetmask(&newset, ~_BLOCKABLE);
 298
 299        spin_lock_irq(&current->sighand->siglock);
 300        current->saved_sigmask = current->blocked;
 301        current->blocked = newset;
 302        recalc_sigpending();
 303        spin_unlock_irq(&current->sighand->siglock);
 304
 305        current->state = TASK_INTERRUPTIBLE;
 306        schedule();
 307        set_thread_flag(TIF_RESTORE_SIGMASK);
 308        return -ERESTARTNOHAND;
 309}
 310#endif
 311
 312asmlinkage int sys_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 313{
 314        sigset_t newset;
 315        sigset_t __user *unewset;
 316        size_t sigsetsize;
 317
 318        /* XXX Don't preclude handling different sized sigset_t's.  */
 319        sigsetsize = regs.regs[5];
 320        if (sigsetsize != sizeof(sigset_t))
 321                return -EINVAL;
 322
 323        unewset = (sigset_t __user *) regs.regs[4];
 324        if (copy_from_user(&newset, unewset, sizeof(newset)))
 325                return -EFAULT;
 326        sigdelsetmask(&newset, ~_BLOCKABLE);
 327
 328        spin_lock_irq(&current->sighand->siglock);
 329        current->saved_sigmask = current->blocked;
 330        current->blocked = newset;
 331        recalc_sigpending();
 332        spin_unlock_irq(&current->sighand->siglock);
 333
 334        current->state = TASK_INTERRUPTIBLE;
 335        schedule();
 336        set_thread_flag(TIF_RESTORE_SIGMASK);
 337        return -ERESTARTNOHAND;
 338}
 339
 340#ifdef CONFIG_TRAD_SIGNALS
 341asmlinkage int sys_sigaction(int sig, const struct sigaction __user *act,
 342        struct sigaction __user *oact)
 343{
 344        struct k_sigaction new_ka, old_ka;
 345        int ret;
 346        int err = 0;
 347
 348        if (act) {
 349                old_sigset_t mask;
 350
 351                if (!access_ok(VERIFY_READ, act, sizeof(*act)))
 352                        return -EFAULT;
 353                err |= __get_user(new_ka.sa.sa_handler, &act->sa_handler);
 354                err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
 355                err |= __get_user(mask, &act->sa_mask.sig[0]);
 356                if (err)
 357                        return -EFAULT;
 358
 359                siginitset(&new_ka.sa.sa_mask, mask);
 360        }
 361
 362        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 363
 364        if (!ret && oact) {
 365                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
 366                        return -EFAULT;
 367                err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 368                err |= __put_user(old_ka.sa.sa_handler, &oact->sa_handler);
 369                err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
 370                err |= __put_user(0, &oact->sa_mask.sig[1]);
 371                err |= __put_user(0, &oact->sa_mask.sig[2]);
 372                err |= __put_user(0, &oact->sa_mask.sig[3]);
 373                if (err)
 374                        return -EFAULT;
 375        }
 376
 377        return ret;
 378}
 379#endif
 380
 381asmlinkage int sys_sigaltstack(nabi_no_regargs struct pt_regs regs)
 382{
 383        const stack_t __user *uss = (const stack_t __user *) regs.regs[4];
 384        stack_t __user *uoss = (stack_t __user *) regs.regs[5];
 385        unsigned long usp = regs.regs[29];
 386
 387        return do_sigaltstack(uss, uoss, usp);
 388}
 389
 390#ifdef CONFIG_TRAD_SIGNALS
 391asmlinkage void sys_sigreturn(nabi_no_regargs struct pt_regs regs)
 392{
 393        struct sigframe __user *frame;
 394        sigset_t blocked;
 395        int sig;
 396
 397        frame = (struct sigframe __user *) regs.regs[29];
 398        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 399                goto badframe;
 400        if (__copy_from_user(&blocked, &frame->sf_mask, sizeof(blocked)))
 401                goto badframe;
 402
 403        sigdelsetmask(&blocked, ~_BLOCKABLE);
 404        spin_lock_irq(&current->sighand->siglock);
 405        current->blocked = blocked;
 406        recalc_sigpending();
 407        spin_unlock_irq(&current->sighand->siglock);
 408
 409        sig = restore_sigcontext(&regs, &frame->sf_sc);
 410        if (sig < 0)
 411                goto badframe;
 412        else if (sig)
 413                force_sig(sig, current);
 414
 415        /*
 416         * Don't let your children do this ...
 417         */
 418        __asm__ __volatile__(
 419                "move\t$29, %0\n\t"
 420                "j\tsyscall_exit"
 421                :/* no outputs */
 422                :"r" (&regs));
 423        /* Unreached */
 424
 425badframe:
 426        force_sig(SIGSEGV, current);
 427}
 428#endif /* CONFIG_TRAD_SIGNALS */
 429
 430asmlinkage void sys_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 431{
 432        struct rt_sigframe __user *frame;
 433        sigset_t set;
 434        stack_t st;
 435        int sig;
 436
 437        frame = (struct rt_sigframe __user *) regs.regs[29];
 438        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 439                goto badframe;
 440        if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set)))
 441                goto badframe;
 442
 443        sigdelsetmask(&set, ~_BLOCKABLE);
 444        spin_lock_irq(&current->sighand->siglock);
 445        current->blocked = set;
 446        recalc_sigpending();
 447        spin_unlock_irq(&current->sighand->siglock);
 448
 449        sig = restore_sigcontext(&regs, &frame->rs_uc.uc_mcontext);
 450        if (sig < 0)
 451                goto badframe;
 452        else if (sig)
 453                force_sig(sig, current);
 454
 455        if (__copy_from_user(&st, &frame->rs_uc.uc_stack, sizeof(st)))
 456                goto badframe;
 457        /* It is more difficult to avoid calling this function than to
 458           call it and ignore errors.  */
 459        do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
 460
 461        /*
 462         * Don't let your children do this ...
 463         */
 464        __asm__ __volatile__(
 465                "move\t$29, %0\n\t"
 466                "j\tsyscall_exit"
 467                :/* no outputs */
 468                :"r" (&regs));
 469        /* Unreached */
 470
 471badframe:
 472        force_sig(SIGSEGV, current);
 473}
 474
 475#ifdef CONFIG_TRAD_SIGNALS
 476static int setup_frame(struct k_sigaction * ka, struct pt_regs *regs,
 477        int signr, sigset_t *set)
 478{
 479        struct sigframe __user *frame;
 480        int err = 0;
 481
 482        frame = get_sigframe(ka, regs, sizeof(*frame));
 483        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 484                goto give_sigsegv;
 485
 486        err |= install_sigtramp(frame->sf_code, __NR_sigreturn);
 487
 488        err |= setup_sigcontext(regs, &frame->sf_sc);
 489        err |= __copy_to_user(&frame->sf_mask, set, sizeof(*set));
 490        if (err)
 491                goto give_sigsegv;
 492
 493        /*
 494         * Arguments to signal handler:
 495         *
 496         *   a0 = signal number
 497         *   a1 = 0 (should be cause)
 498         *   a2 = pointer to struct sigcontext
 499         *
 500         * $25 and c0_epc point to the signal handler, $29 points to the
 501         * struct sigframe.
 502         */
 503        regs->regs[ 4] = signr;
 504        regs->regs[ 5] = 0;
 505        regs->regs[ 6] = (unsigned long) &frame->sf_sc;
 506        regs->regs[29] = (unsigned long) frame;
 507        regs->regs[31] = (unsigned long) frame->sf_code;
 508        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 509
 510        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 511               current->comm, current->pid,
 512               frame, regs->cp0_epc, regs->regs[31]);
 513        return 0;
 514
 515give_sigsegv:
 516        force_sigsegv(signr, current);
 517        return -EFAULT;
 518}
 519#endif
 520
 521static int setup_rt_frame(struct k_sigaction * ka, struct pt_regs *regs,
 522        int signr, sigset_t *set, siginfo_t *info)
 523{
 524        struct rt_sigframe __user *frame;
 525        int err = 0;
 526
 527        frame = get_sigframe(ka, regs, sizeof(*frame));
 528        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 529                goto give_sigsegv;
 530
 531        err |= install_sigtramp(frame->rs_code, __NR_rt_sigreturn);
 532
 533        /* Create siginfo.  */
 534        err |= copy_siginfo_to_user(&frame->rs_info, info);
 535
 536        /* Create the ucontext.  */
 537        err |= __put_user(0, &frame->rs_uc.uc_flags);
 538        err |= __put_user(NULL, &frame->rs_uc.uc_link);
 539        err |= __put_user((void __user *)current->sas_ss_sp,
 540                          &frame->rs_uc.uc_stack.ss_sp);
 541        err |= __put_user(sas_ss_flags(regs->regs[29]),
 542                          &frame->rs_uc.uc_stack.ss_flags);
 543        err |= __put_user(current->sas_ss_size,
 544                          &frame->rs_uc.uc_stack.ss_size);
 545        err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext);
 546        err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set));
 547
 548        if (err)
 549                goto give_sigsegv;
 550
 551        /*
 552         * Arguments to signal handler:
 553         *
 554         *   a0 = signal number
 555         *   a1 = 0 (should be cause)
 556         *   a2 = pointer to ucontext
 557         *
 558         * $25 and c0_epc point to the signal handler, $29 points to
 559         * the struct rt_sigframe.
 560         */
 561        regs->regs[ 4] = signr;
 562        regs->regs[ 5] = (unsigned long) &frame->rs_info;
 563        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 564        regs->regs[29] = (unsigned long) frame;
 565        regs->regs[31] = (unsigned long) frame->rs_code;
 566        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 567
 568        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 569               current->comm, current->pid,
 570               frame, regs->cp0_epc, regs->regs[31]);
 571
 572        return 0;
 573
 574give_sigsegv:
 575        force_sigsegv(signr, current);
 576        return -EFAULT;
 577}
 578
 579struct mips_abi mips_abi = {
 580#ifdef CONFIG_TRAD_SIGNALS
 581        .setup_frame    = setup_frame,
 582#endif
 583        .setup_rt_frame = setup_rt_frame,
 584        .restart        = __NR_restart_syscall
 585};
 586
 587static int handle_signal(unsigned long sig, siginfo_t *info,
 588        struct k_sigaction *ka, sigset_t *oldset, struct pt_regs *regs)
 589{
 590        int ret;
 591
 592        switch(regs->regs[0]) {
 593        case ERESTART_RESTARTBLOCK:
 594        case ERESTARTNOHAND:
 595                regs->regs[2] = EINTR;
 596                break;
 597        case ERESTARTSYS:
 598                if (!(ka->sa.sa_flags & SA_RESTART)) {
 599                        regs->regs[2] = EINTR;
 600                        break;
 601                }
 602        /* fallthrough */
 603        case ERESTARTNOINTR:            /* Userland will reload $v0.  */
 604                regs->regs[7] = regs->regs[26];
 605                regs->cp0_epc -= 8;
 606        }
 607
 608        regs->regs[0] = 0;              /* Don't deal with this again.  */
 609
 610        if (sig_uses_siginfo(ka))
 611                ret = current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info);
 612        else
 613                ret = current->thread.abi->setup_frame(ka, regs, sig, oldset);
 614
 615        spin_lock_irq(&current->sighand->siglock);
 616        sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
 617        if (!(ka->sa.sa_flags & SA_NODEFER))
 618                sigaddset(&current->blocked, sig);
 619        recalc_sigpending();
 620        spin_unlock_irq(&current->sighand->siglock);
 621
 622        return ret;
 623}
 624
 625static void do_signal(struct pt_regs *regs)
 626{
 627        struct k_sigaction ka;
 628        sigset_t *oldset;
 629        siginfo_t info;
 630        int signr;
 631
 632        /*
 633         * We want the common case to go fast, which is why we may in certain
 634         * cases get here from kernel mode. Just return without doing anything
 635         * if so.
 636         */
 637        if (!user_mode(regs))
 638                return;
 639
 640        if (test_thread_flag(TIF_RESTORE_SIGMASK))
 641                oldset = &current->saved_sigmask;
 642        else
 643                oldset = &current->blocked;
 644
 645        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 646        if (signr > 0) {
 647                /* Whee!  Actually deliver the signal.  */
 648                if (handle_signal(signr, &info, &ka, oldset, regs) == 0) {
 649                        /*
 650                         * A signal was successfully delivered; the saved
 651                         * sigmask will have been stored in the signal frame,
 652                         * and will be restored by sigreturn, so we can simply
 653                         * clear the TIF_RESTORE_SIGMASK flag.
 654                         */
 655                        if (test_thread_flag(TIF_RESTORE_SIGMASK))
 656                                clear_thread_flag(TIF_RESTORE_SIGMASK);
 657                }
 658
 659                return;
 660        }
 661
 662        /*
 663         * Who's code doesn't conform to the restartable syscall convention
 664         * dies here!!!  The li instruction, a single machine instruction,
 665         * must directly be followed by the syscall instruction.
 666         */
 667        if (regs->regs[0]) {
 668                if (regs->regs[2] == ERESTARTNOHAND ||
 669                    regs->regs[2] == ERESTARTSYS ||
 670                    regs->regs[2] == ERESTARTNOINTR) {
 671                        regs->regs[7] = regs->regs[26];
 672                        regs->cp0_epc -= 8;
 673                }
 674                if (regs->regs[2] == ERESTART_RESTARTBLOCK) {
 675                        regs->regs[2] = current->thread.abi->restart;
 676                        regs->regs[7] = regs->regs[26];
 677                        regs->cp0_epc -= 4;
 678                }
 679                regs->regs[0] = 0;      /* Don't deal with this again.  */
 680        }
 681
 682        /*
 683         * If there's no signal to deliver, we just put the saved sigmask
 684         * back
 685         */
 686        if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
 687                clear_thread_flag(TIF_RESTORE_SIGMASK);
 688                sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 689        }
 690}
 691
 692/*
 693 * notification of userspace execution resumption
 694 * - triggered by the TIF_WORK_MASK flags
 695 */
 696asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
 697        __u32 thread_info_flags)
 698{
 699        /* deal with pending signal delivery */
 700        if (thread_info_flags & (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK))
 701                do_signal(regs);
 702}
 703
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.