linux/arch/mips/kernel/signal32.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, 2006  Ralf Baechle
   8 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
   9 */
  10#include <linux/cache.h>
  11#include <linux/compat.h>
  12#include <linux/sched.h>
  13#include <linux/mm.h>
  14#include <linux/smp.h>
  15#include <linux/kernel.h>
  16#include <linux/signal.h>
  17#include <linux/syscalls.h>
  18#include <linux/errno.h>
  19#include <linux/wait.h>
  20#include <linux/ptrace.h>
  21#include <linux/suspend.h>
  22#include <linux/compiler.h>
  23#include <linux/uaccess.h>
  24
  25#include <asm/abi.h>
  26#include <asm/asm.h>
  27#include <asm/compat-signal.h>
  28#include <linux/bitops.h>
  29#include <asm/cacheflush.h>
  30#include <asm/sim.h>
  31#include <asm/ucontext.h>
  32#include <asm/system.h>
  33#include <asm/fpu.h>
  34#include <asm/war.h>
  35#include <asm/vdso.h>
  36
  37#include "signal-common.h"
  38
  39static int (*save_fp_context32)(struct sigcontext32 __user *sc);
  40static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
  41
  42extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
  43extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
  44
  45extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
  46extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
  47
  48/*
  49 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
  50 */
  51#define __NR_O32_restart_syscall        4253
  52
  53/* 32-bit compatibility types */
  54
  55typedef unsigned int __sighandler32_t;
  56typedef void (*vfptr_t)(void);
  57
  58struct sigaction32 {
  59        unsigned int            sa_flags;
  60        __sighandler32_t        sa_handler;
  61        compat_sigset_t         sa_mask;
  62};
  63
  64/* IRIX compatible stack_t  */
  65typedef struct sigaltstack32 {
  66        s32 ss_sp;
  67        compat_size_t ss_size;
  68        int ss_flags;
  69} stack32_t;
  70
  71struct ucontext32 {
  72        u32                 uc_flags;
  73        s32                 uc_link;
  74        stack32_t           uc_stack;
  75        struct sigcontext32 uc_mcontext;
  76        compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
  77};
  78
  79struct sigframe32 {
  80        u32 sf_ass[4];          /* argument save space for o32 */
  81        u32 sf_pad[2];          /* Was: signal trampoline */
  82        struct sigcontext32 sf_sc;
  83        compat_sigset_t sf_mask;
  84};
  85
  86struct rt_sigframe32 {
  87        u32 rs_ass[4];                  /* argument save space for o32 */
  88        u32 rs_pad[2];                  /* Was: signal trampoline */
  89        compat_siginfo_t rs_info;
  90        struct ucontext32 rs_uc;
  91};
  92
  93/*
  94 * sigcontext handlers
  95 */
  96static int protected_save_fp_context32(struct sigcontext32 __user *sc)
  97{
  98        int err;
  99        while (1) {
 100                lock_fpu_owner();
 101                own_fpu_inatomic(1);
 102                err = save_fp_context32(sc); /* this might fail */
 103                unlock_fpu_owner();
 104                if (likely(!err))
 105                        break;
 106                /* touch the sigcontext and try again */
 107                err = __put_user(0, &sc->sc_fpregs[0]) |
 108                        __put_user(0, &sc->sc_fpregs[31]) |
 109                        __put_user(0, &sc->sc_fpc_csr);
 110                if (err)
 111                        break;  /* really bad sigcontext */
 112        }
 113        return err;
 114}
 115
 116static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
 117{
 118        int err, tmp __maybe_unused;
 119        while (1) {
 120                lock_fpu_owner();
 121                own_fpu_inatomic(0);
 122                err = restore_fp_context32(sc); /* this might fail */
 123                unlock_fpu_owner();
 124                if (likely(!err))
 125                        break;
 126                /* touch the sigcontext and try again */
 127                err = __get_user(tmp, &sc->sc_fpregs[0]) |
 128                        __get_user(tmp, &sc->sc_fpregs[31]) |
 129                        __get_user(tmp, &sc->sc_fpc_csr);
 130                if (err)
 131                        break;  /* really bad sigcontext */
 132        }
 133        return err;
 134}
 135
 136static int setup_sigcontext32(struct pt_regs *regs,
 137                              struct sigcontext32 __user *sc)
 138{
 139        int err = 0;
 140        int i;
 141        u32 used_math;
 142
 143        err |= __put_user(regs->cp0_epc, &sc->sc_pc);
 144
 145        err |= __put_user(0, &sc->sc_regs[0]);
 146        for (i = 1; i < 32; i++)
 147                err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
 148
 149        err |= __put_user(regs->hi, &sc->sc_mdhi);
 150        err |= __put_user(regs->lo, &sc->sc_mdlo);
 151        if (cpu_has_dsp) {
 152                err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
 153                err |= __put_user(mfhi1(), &sc->sc_hi1);
 154                err |= __put_user(mflo1(), &sc->sc_lo1);
 155                err |= __put_user(mfhi2(), &sc->sc_hi2);
 156                err |= __put_user(mflo2(), &sc->sc_lo2);
 157                err |= __put_user(mfhi3(), &sc->sc_hi3);
 158                err |= __put_user(mflo3(), &sc->sc_lo3);
 159        }
 160
 161        used_math = !!used_math();
 162        err |= __put_user(used_math, &sc->sc_used_math);
 163
 164        if (used_math) {
 165                /*
 166                 * Save FPU state to signal context.  Signal handler
 167                 * will "inherit" current FPU state.
 168                 */
 169                err |= protected_save_fp_context32(sc);
 170        }
 171        return err;
 172}
 173
 174static int
 175check_and_restore_fp_context32(struct sigcontext32 __user *sc)
 176{
 177        int err, sig;
 178
 179        err = sig = fpcsr_pending(&sc->sc_fpc_csr);
 180        if (err > 0)
 181                err = 0;
 182        err |= protected_restore_fp_context32(sc);
 183        return err ?: sig;
 184}
 185
 186static int restore_sigcontext32(struct pt_regs *regs,
 187                                struct sigcontext32 __user *sc)
 188{
 189        u32 used_math;
 190        int err = 0;
 191        s32 treg;
 192        int i;
 193
 194        /* Always make any pending restarted system calls return -EINTR */
 195        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 196
 197        err |= __get_user(regs->cp0_epc, &sc->sc_pc);
 198        err |= __get_user(regs->hi, &sc->sc_mdhi);
 199        err |= __get_user(regs->lo, &sc->sc_mdlo);
 200        if (cpu_has_dsp) {
 201                err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
 202                err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
 203                err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
 204                err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
 205                err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
 206                err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
 207                err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
 208        }
 209
 210        for (i = 1; i < 32; i++)
 211                err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
 212
 213        err |= __get_user(used_math, &sc->sc_used_math);
 214        conditional_used_math(used_math);
 215
 216        if (used_math) {
 217                /* restore fpu context if we have used it before */
 218                if (!err)
 219                        err = check_and_restore_fp_context32(sc);
 220        } else {
 221                /* signal handler may have used FPU.  Give it up. */
 222                lose_fpu(0);
 223        }
 224
 225        return err;
 226}
 227
 228/*
 229 *
 230 */
 231extern void __put_sigset_unknown_nsig(void);
 232extern void __get_sigset_unknown_nsig(void);
 233
 234static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
 235{
 236        int err = 0;
 237
 238        if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
 239                return -EFAULT;
 240
 241        switch (_NSIG_WORDS) {
 242        default:
 243                __put_sigset_unknown_nsig();
 244        case 2:
 245                err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
 246                err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
 247        case 1:
 248                err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
 249                err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
 250        }
 251
 252        return err;
 253}
 254
 255static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
 256{
 257        int err = 0;
 258        unsigned long sig[4];
 259
 260        if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
 261                return -EFAULT;
 262
 263        switch (_NSIG_WORDS) {
 264        default:
 265                __get_sigset_unknown_nsig();
 266        case 2:
 267                err |= __get_user(sig[3], &ubuf->sig[3]);
 268                err |= __get_user(sig[2], &ubuf->sig[2]);
 269                kbuf->sig[1] = sig[2] | (sig[3] << 32);
 270        case 1:
 271                err |= __get_user(sig[1], &ubuf->sig[1]);
 272                err |= __get_user(sig[0], &ubuf->sig[0]);
 273                kbuf->sig[0] = sig[0] | (sig[1] << 32);
 274        }
 275
 276        return err;
 277}
 278
 279/*
 280 * Atomically swap in the new signal mask, and wait for a signal.
 281 */
 282
 283asmlinkage int sys32_sigsuspend(nabi_no_regargs struct pt_regs regs)
 284{
 285        compat_sigset_t __user *uset;
 286        sigset_t newset;
 287
 288        uset = (compat_sigset_t __user *) regs.regs[4];
 289        if (get_sigset(&newset, uset))
 290                return -EFAULT;
 291        sigdelsetmask(&newset, ~_BLOCKABLE);
 292
 293        spin_lock_irq(&current->sighand->siglock);
 294        current->saved_sigmask = current->blocked;
 295        current->blocked = newset;
 296        recalc_sigpending();
 297        spin_unlock_irq(&current->sighand->siglock);
 298
 299        current->state = TASK_INTERRUPTIBLE;
 300        schedule();
 301        set_thread_flag(TIF_RESTORE_SIGMASK);
 302        return -ERESTARTNOHAND;
 303}
 304
 305asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 306{
 307        compat_sigset_t __user *uset;
 308        sigset_t newset;
 309        size_t sigsetsize;
 310
 311        /* XXX Don't preclude handling different sized sigset_t's.  */
 312        sigsetsize = regs.regs[5];
 313        if (sigsetsize != sizeof(compat_sigset_t))
 314                return -EINVAL;
 315
 316        uset = (compat_sigset_t __user *) regs.regs[4];
 317        if (get_sigset(&newset, uset))
 318                return -EFAULT;
 319        sigdelsetmask(&newset, ~_BLOCKABLE);
 320
 321        spin_lock_irq(&current->sighand->siglock);
 322        current->saved_sigmask = current->blocked;
 323        current->blocked = newset;
 324        recalc_sigpending();
 325        spin_unlock_irq(&current->sighand->siglock);
 326
 327        current->state = TASK_INTERRUPTIBLE;
 328        schedule();
 329        set_thread_flag(TIF_RESTORE_SIGMASK);
 330        return -ERESTARTNOHAND;
 331}
 332
 333SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
 334        struct sigaction32 __user *, oact)
 335{
 336        struct k_sigaction new_ka, old_ka;
 337        int ret;
 338        int err = 0;
 339
 340        if (act) {
 341                old_sigset_t mask;
 342                s32 handler;
 343
 344                if (!access_ok(VERIFY_READ, act, sizeof(*act)))
 345                        return -EFAULT;
 346                err |= __get_user(handler, &act->sa_handler);
 347                new_ka.sa.sa_handler = (void __user *)(s64)handler;
 348                err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
 349                err |= __get_user(mask, &act->sa_mask.sig[0]);
 350                if (err)
 351                        return -EFAULT;
 352
 353                siginitset(&new_ka.sa.sa_mask, mask);
 354        }
 355
 356        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 357
 358        if (!ret && oact) {
 359                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
 360                        return -EFAULT;
 361                err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 362                err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
 363                                  &oact->sa_handler);
 364                err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
 365                err |= __put_user(0, &oact->sa_mask.sig[1]);
 366                err |= __put_user(0, &oact->sa_mask.sig[2]);
 367                err |= __put_user(0, &oact->sa_mask.sig[3]);
 368                if (err)
 369                        return -EFAULT;
 370        }
 371
 372        return ret;
 373}
 374
 375asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
 376{
 377        const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
 378        stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
 379        unsigned long usp = regs.regs[29];
 380        stack_t kss, koss;
 381        int ret, err = 0;
 382        mm_segment_t old_fs = get_fs();
 383        s32 sp;
 384
 385        if (uss) {
 386                if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
 387                        return -EFAULT;
 388                err |= __get_user(sp, &uss->ss_sp);
 389                kss.ss_sp = (void __user *) (long) sp;
 390                err |= __get_user(kss.ss_size, &uss->ss_size);
 391                err |= __get_user(kss.ss_flags, &uss->ss_flags);
 392                if (err)
 393                        return -EFAULT;
 394        }
 395
 396        set_fs(KERNEL_DS);
 397        ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
 398                             uoss ? (stack_t __user *)&koss : NULL, usp);
 399        set_fs(old_fs);
 400
 401        if (!ret && uoss) {
 402                if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
 403                        return -EFAULT;
 404                sp = (int) (unsigned long) koss.ss_sp;
 405                err |= __put_user(sp, &uoss->ss_sp);
 406                err |= __put_user(koss.ss_size, &uoss->ss_size);
 407                err |= __put_user(koss.ss_flags, &uoss->ss_flags);
 408                if (err)
 409                        return -EFAULT;
 410        }
 411        return ret;
 412}
 413
 414int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 415{
 416        int err;
 417
 418        if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
 419                return -EFAULT;
 420
 421        /* If you change siginfo_t structure, please be sure
 422           this code is fixed accordingly.
 423           It should never copy any pad contained in the structure
 424           to avoid security leaks, but must copy the generic
 425           3 ints plus the relevant union member.
 426           This routine must convert siginfo from 64bit to 32bit as well
 427           at the same time.  */
 428        err = __put_user(from->si_signo, &to->si_signo);
 429        err |= __put_user(from->si_errno, &to->si_errno);
 430        err |= __put_user((short)from->si_code, &to->si_code);
 431        if (from->si_code < 0)
 432                err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
 433        else {
 434                switch (from->si_code >> 16) {
 435                case __SI_TIMER >> 16:
 436                        err |= __put_user(from->si_tid, &to->si_tid);
 437                        err |= __put_user(from->si_overrun, &to->si_overrun);
 438                        err |= __put_user(from->si_int, &to->si_int);
 439                        break;
 440                case __SI_CHLD >> 16:
 441                        err |= __put_user(from->si_utime, &to->si_utime);
 442                        err |= __put_user(from->si_stime, &to->si_stime);
 443                        err |= __put_user(from->si_status, &to->si_status);
 444                default:
 445                        err |= __put_user(from->si_pid, &to->si_pid);
 446                        err |= __put_user(from->si_uid, &to->si_uid);
 447                        break;
 448                case __SI_FAULT >> 16:
 449                        err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
 450                        break;
 451                case __SI_POLL >> 16:
 452                        err |= __put_user(from->si_band, &to->si_band);
 453                        err |= __put_user(from->si_fd, &to->si_fd);
 454                        break;
 455                case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
 456                case __SI_MESGQ >> 16:
 457                        err |= __put_user(from->si_pid, &to->si_pid);
 458                        err |= __put_user(from->si_uid, &to->si_uid);
 459                        err |= __put_user(from->si_int, &to->si_int);
 460                        break;
 461                }
 462        }
 463        return err;
 464}
 465
 466int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 467{
 468        memset(to, 0, sizeof *to);
 469
 470        if (copy_from_user(to, from, 3*sizeof(int)) ||
 471            copy_from_user(to->_sifields._pad,
 472                           from->_sifields._pad, SI_PAD_SIZE32))
 473                return -EFAULT;
 474
 475        return 0;
 476}
 477
 478asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
 479{
 480        struct sigframe32 __user *frame;
 481        sigset_t blocked;
 482        int sig;
 483
 484        frame = (struct sigframe32 __user *) regs.regs[29];
 485        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 486                goto badframe;
 487        if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
 488                goto badframe;
 489
 490        sigdelsetmask(&blocked, ~_BLOCKABLE);
 491        spin_lock_irq(&current->sighand->siglock);
 492        current->blocked = blocked;
 493        recalc_sigpending();
 494        spin_unlock_irq(&current->sighand->siglock);
 495
 496        sig = restore_sigcontext32(&regs, &frame->sf_sc);
 497        if (sig < 0)
 498                goto badframe;
 499        else if (sig)
 500                force_sig(sig, current);
 501
 502        /*
 503         * Don't let your children do this ...
 504         */
 505        __asm__ __volatile__(
 506                "move\t$29, %0\n\t"
 507                "j\tsyscall_exit"
 508                :/* no outputs */
 509                :"r" (&regs));
 510        /* Unreached */
 511
 512badframe:
 513        force_sig(SIGSEGV, current);
 514}
 515
 516asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 517{
 518        struct rt_sigframe32 __user *frame;
 519        mm_segment_t old_fs;
 520        sigset_t set;
 521        stack_t st;
 522        s32 sp;
 523        int sig;
 524
 525        frame = (struct rt_sigframe32 __user *) regs.regs[29];
 526        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 527                goto badframe;
 528        if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
 529                goto badframe;
 530
 531        sigdelsetmask(&set, ~_BLOCKABLE);
 532        spin_lock_irq(&current->sighand->siglock);
 533        current->blocked = set;
 534        recalc_sigpending();
 535        spin_unlock_irq(&current->sighand->siglock);
 536
 537        sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
 538        if (sig < 0)
 539                goto badframe;
 540        else if (sig)
 541                force_sig(sig, current);
 542
 543        /* The ucontext contains a stack32_t, so we must convert!  */
 544        if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
 545                goto badframe;
 546        st.ss_sp = (void __user *)(long) sp;
 547        if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
 548                goto badframe;
 549        if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
 550                goto badframe;
 551
 552        /* It is more difficult to avoid calling this function than to
 553           call it and ignore errors.  */
 554        old_fs = get_fs();
 555        set_fs(KERNEL_DS);
 556        do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
 557        set_fs(old_fs);
 558
 559        /*
 560         * Don't let your children do this ...
 561         */
 562        __asm__ __volatile__(
 563                "move\t$29, %0\n\t"
 564                "j\tsyscall_exit"
 565                :/* no outputs */
 566                :"r" (&regs));
 567        /* Unreached */
 568
 569badframe:
 570        force_sig(SIGSEGV, current);
 571}
 572
 573static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
 574                          struct pt_regs *regs, int signr, sigset_t *set)
 575{
 576        struct sigframe32 __user *frame;
 577        int err = 0;
 578
 579        frame = get_sigframe(ka, regs, sizeof(*frame));
 580        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 581                goto give_sigsegv;
 582
 583        err |= setup_sigcontext32(regs, &frame->sf_sc);
 584        err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
 585
 586        if (err)
 587                goto give_sigsegv;
 588
 589        /*
 590         * Arguments to signal handler:
 591         *
 592         *   a0 = signal number
 593         *   a1 = 0 (should be cause)
 594         *   a2 = pointer to struct sigcontext
 595         *
 596         * $25 and c0_epc point to the signal handler, $29 points to the
 597         * struct sigframe.
 598         */
 599        regs->regs[ 4] = signr;
 600        regs->regs[ 5] = 0;
 601        regs->regs[ 6] = (unsigned long) &frame->sf_sc;
 602        regs->regs[29] = (unsigned long) frame;
 603        regs->regs[31] = (unsigned long) sig_return;
 604        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 605
 606        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 607               current->comm, current->pid,
 608               frame, regs->cp0_epc, regs->regs[31]);
 609
 610        return 0;
 611
 612give_sigsegv:
 613        force_sigsegv(signr, current);
 614        return -EFAULT;
 615}
 616
 617static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
 618                             struct pt_regs *regs, int signr, sigset_t *set,
 619                             siginfo_t *info)
 620{
 621        struct rt_sigframe32 __user *frame;
 622        int err = 0;
 623        s32 sp;
 624
 625        frame = get_sigframe(ka, regs, sizeof(*frame));
 626        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 627                goto give_sigsegv;
 628
 629        /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
 630        err |= copy_siginfo_to_user32(&frame->rs_info, info);
 631
 632        /* Create the ucontext.  */
 633        err |= __put_user(0, &frame->rs_uc.uc_flags);
 634        err |= __put_user(0, &frame->rs_uc.uc_link);
 635        sp = (int) (long) current->sas_ss_sp;
 636        err |= __put_user(sp,
 637                          &frame->rs_uc.uc_stack.ss_sp);
 638        err |= __put_user(sas_ss_flags(regs->regs[29]),
 639                          &frame->rs_uc.uc_stack.ss_flags);
 640        err |= __put_user(current->sas_ss_size,
 641                          &frame->rs_uc.uc_stack.ss_size);
 642        err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
 643        err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
 644
 645        if (err)
 646                goto give_sigsegv;
 647
 648        /*
 649         * Arguments to signal handler:
 650         *
 651         *   a0 = signal number
 652         *   a1 = 0 (should be cause)
 653         *   a2 = pointer to ucontext
 654         *
 655         * $25 and c0_epc point to the signal handler, $29 points to
 656         * the struct rt_sigframe32.
 657         */
 658        regs->regs[ 4] = signr;
 659        regs->regs[ 5] = (unsigned long) &frame->rs_info;
 660        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 661        regs->regs[29] = (unsigned long) frame;
 662        regs->regs[31] = (unsigned long) sig_return;
 663        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 664
 665        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 666               current->comm, current->pid,
 667               frame, regs->cp0_epc, regs->regs[31]);
 668
 669        return 0;
 670
 671give_sigsegv:
 672        force_sigsegv(signr, current);
 673        return -EFAULT;
 674}
 675
 676/*
 677 * o32 compatibility on 64-bit kernels, without DSP ASE
 678 */
 679struct mips_abi mips_abi_32 = {
 680        .setup_frame    = setup_frame_32,
 681        .signal_return_offset =
 682                offsetof(struct mips_vdso, o32_signal_trampoline),
 683        .setup_rt_frame = setup_rt_frame_32,
 684        .rt_signal_return_offset =
 685                offsetof(struct mips_vdso, o32_rt_signal_trampoline),
 686        .restart        = __NR_O32_restart_syscall
 687};
 688
 689SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
 690        const struct sigaction32 __user *, act,
 691        struct sigaction32 __user *, oact, unsigned int, sigsetsize)
 692{
 693        struct k_sigaction new_sa, old_sa;
 694        int ret = -EINVAL;
 695
 696        /* XXX: Don't preclude handling different sized sigset_t's.  */
 697        if (sigsetsize != sizeof(sigset_t))
 698                goto out;
 699
 700        if (act) {
 701                s32 handler;
 702                int err = 0;
 703
 704                if (!access_ok(VERIFY_READ, act, sizeof(*act)))
 705                        return -EFAULT;
 706                err |= __get_user(handler, &act->sa_handler);
 707                new_sa.sa.sa_handler = (void __user *)(s64)handler;
 708                err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
 709                err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
 710                if (err)
 711                        return -EFAULT;
 712        }
 713
 714        ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
 715
 716        if (!ret && oact) {
 717                int err = 0;
 718
 719                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
 720                        return -EFAULT;
 721
 722                err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
 723                                   &oact->sa_handler);
 724                err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
 725                err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
 726                if (err)
 727                        return -EFAULT;
 728        }
 729out:
 730        return ret;
 731}
 732
 733SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
 734        compat_sigset_t __user *, oset, unsigned int, sigsetsize)
 735{
 736        sigset_t old_set, new_set;
 737        int ret;
 738        mm_segment_t old_fs = get_fs();
 739
 740        if (set && get_sigset(&new_set, set))
 741                return -EFAULT;
 742
 743        set_fs(KERNEL_DS);
 744        ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
 745                                 oset ? (sigset_t __user *)&old_set : NULL,
 746                                 sigsetsize);
 747        set_fs(old_fs);
 748
 749        if (!ret && oset && put_sigset(&old_set, oset))
 750                return -EFAULT;
 751
 752        return ret;
 753}
 754
 755SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
 756        unsigned int, sigsetsize)
 757{
 758        int ret;
 759        sigset_t set;
 760        mm_segment_t old_fs = get_fs();
 761
 762        set_fs(KERNEL_DS);
 763        ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
 764        set_fs(old_fs);
 765
 766        if (!ret && put_sigset(&set, uset))
 767                return -EFAULT;
 768
 769        return ret;
 770}
 771
 772SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
 773        compat_siginfo_t __user *, uinfo)
 774{
 775        siginfo_t info;
 776        int ret;
 777        mm_segment_t old_fs = get_fs();
 778
 779        if (copy_from_user(&info, uinfo, 3*sizeof(int)) ||
 780            copy_from_user(info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
 781                return -EFAULT;
 782        set_fs(KERNEL_DS);
 783        ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
 784        set_fs(old_fs);
 785        return ret;
 786}
 787
 788SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
 789             compat_siginfo_t __user *, uinfo, int, options,
 790             struct compat_rusage __user *, uru)
 791{
 792        siginfo_t info;
 793        struct rusage ru;
 794        long ret;
 795        mm_segment_t old_fs = get_fs();
 796
 797        info.si_signo = 0;
 798        set_fs(KERNEL_DS);
 799        ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
 800                         uru ? (struct rusage __user *) &ru : NULL);
 801        set_fs(old_fs);
 802
 803        if (ret < 0 || info.si_signo == 0)
 804                return ret;
 805
 806        if (uru && (ret = put_compat_rusage(&ru, uru)))
 807                return ret;
 808
 809        BUG_ON(info.si_code & __SI_MASK);
 810        info.si_code |= __SI_CHLD;
 811        return copy_siginfo_to_user32(uinfo, &info);
 812}
 813
 814static int signal32_init(void)
 815{
 816        if (cpu_has_fpu) {
 817                save_fp_context32 = _save_fp_context32;
 818                restore_fp_context32 = _restore_fp_context32;
 819        } else {
 820                save_fp_context32 = fpu_emulator_save_context32;
 821                restore_fp_context32 = fpu_emulator_restore_context32;
 822        }
 823
 824        return 0;
 825}
 826
 827arch_initcall(signal32_init);
 828