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/fpu.h>
  33#include <asm/war.h>
  34#include <asm/vdso.h>
  35#include <asm/dsp.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        return sigsuspend(&newset);
 292}
 293
 294asmlinkage int sys32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs)
 295{
 296        compat_sigset_t __user *uset;
 297        sigset_t newset;
 298        size_t sigsetsize;
 299
 300        /* XXX Don't preclude handling different sized sigset_t's.  */
 301        sigsetsize = regs.regs[5];
 302        if (sigsetsize != sizeof(compat_sigset_t))
 303                return -EINVAL;
 304
 305        uset = (compat_sigset_t __user *) regs.regs[4];
 306        if (get_sigset(&newset, uset))
 307                return -EFAULT;
 308        return sigsuspend(&newset);
 309}
 310
 311SYSCALL_DEFINE3(32_sigaction, long, sig, const struct sigaction32 __user *, act,
 312        struct sigaction32 __user *, oact)
 313{
 314        struct k_sigaction new_ka, old_ka;
 315        int ret;
 316        int err = 0;
 317
 318        if (act) {
 319                old_sigset_t mask;
 320                s32 handler;
 321
 322                if (!access_ok(VERIFY_READ, act, sizeof(*act)))
 323                        return -EFAULT;
 324                err |= __get_user(handler, &act->sa_handler);
 325                new_ka.sa.sa_handler = (void __user *)(s64)handler;
 326                err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
 327                err |= __get_user(mask, &act->sa_mask.sig[0]);
 328                if (err)
 329                        return -EFAULT;
 330
 331                siginitset(&new_ka.sa.sa_mask, mask);
 332        }
 333
 334        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 335
 336        if (!ret && oact) {
 337                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
 338                        return -EFAULT;
 339                err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 340                err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
 341                                  &oact->sa_handler);
 342                err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
 343                err |= __put_user(0, &oact->sa_mask.sig[1]);
 344                err |= __put_user(0, &oact->sa_mask.sig[2]);
 345                err |= __put_user(0, &oact->sa_mask.sig[3]);
 346                if (err)
 347                        return -EFAULT;
 348        }
 349
 350        return ret;
 351}
 352
 353asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs)
 354{
 355        const stack32_t __user *uss = (const stack32_t __user *) regs.regs[4];
 356        stack32_t __user *uoss = (stack32_t __user *) regs.regs[5];
 357        unsigned long usp = regs.regs[29];
 358        stack_t kss, koss;
 359        int ret, err = 0;
 360        mm_segment_t old_fs = get_fs();
 361        s32 sp;
 362
 363        if (uss) {
 364                if (!access_ok(VERIFY_READ, uss, sizeof(*uss)))
 365                        return -EFAULT;
 366                err |= __get_user(sp, &uss->ss_sp);
 367                kss.ss_sp = (void __user *) (long) sp;
 368                err |= __get_user(kss.ss_size, &uss->ss_size);
 369                err |= __get_user(kss.ss_flags, &uss->ss_flags);
 370                if (err)
 371                        return -EFAULT;
 372        }
 373
 374        set_fs(KERNEL_DS);
 375        ret = do_sigaltstack(uss ? (stack_t __user *)&kss : NULL,
 376                             uoss ? (stack_t __user *)&koss : NULL, usp);
 377        set_fs(old_fs);
 378
 379        if (!ret && uoss) {
 380                if (!access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)))
 381                        return -EFAULT;
 382                sp = (int) (unsigned long) koss.ss_sp;
 383                err |= __put_user(sp, &uoss->ss_sp);
 384                err |= __put_user(koss.ss_size, &uoss->ss_size);
 385                err |= __put_user(koss.ss_flags, &uoss->ss_flags);
 386                if (err)
 387                        return -EFAULT;
 388        }
 389        return ret;
 390}
 391
 392int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 393{
 394        int err;
 395
 396        if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
 397                return -EFAULT;
 398
 399        /* If you change siginfo_t structure, please be sure
 400           this code is fixed accordingly.
 401           It should never copy any pad contained in the structure
 402           to avoid security leaks, but must copy the generic
 403           3 ints plus the relevant union member.
 404           This routine must convert siginfo from 64bit to 32bit as well
 405           at the same time.  */
 406        err = __put_user(from->si_signo, &to->si_signo);
 407        err |= __put_user(from->si_errno, &to->si_errno);
 408        err |= __put_user((short)from->si_code, &to->si_code);
 409        if (from->si_code < 0)
 410                err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
 411        else {
 412                switch (from->si_code >> 16) {
 413                case __SI_TIMER >> 16:
 414                        err |= __put_user(from->si_tid, &to->si_tid);
 415                        err |= __put_user(from->si_overrun, &to->si_overrun);
 416                        err |= __put_user(from->si_int, &to->si_int);
 417                        break;
 418                case __SI_CHLD >> 16:
 419                        err |= __put_user(from->si_utime, &to->si_utime);
 420                        err |= __put_user(from->si_stime, &to->si_stime);
 421                        err |= __put_user(from->si_status, &to->si_status);
 422                default:
 423                        err |= __put_user(from->si_pid, &to->si_pid);
 424                        err |= __put_user(from->si_uid, &to->si_uid);
 425                        break;
 426                case __SI_FAULT >> 16:
 427                        err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
 428                        break;
 429                case __SI_POLL >> 16:
 430                        err |= __put_user(from->si_band, &to->si_band);
 431                        err |= __put_user(from->si_fd, &to->si_fd);
 432                        break;
 433                case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
 434                case __SI_MESGQ >> 16:
 435                        err |= __put_user(from->si_pid, &to->si_pid);
 436                        err |= __put_user(from->si_uid, &to->si_uid);
 437                        err |= __put_user(from->si_int, &to->si_int);
 438                        break;
 439                }
 440        }
 441        return err;
 442}
 443
 444int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 445{
 446        memset(to, 0, sizeof *to);
 447
 448        if (copy_from_user(to, from, 3*sizeof(int)) ||
 449            copy_from_user(to->_sifields._pad,
 450                           from->_sifields._pad, SI_PAD_SIZE32))
 451                return -EFAULT;
 452
 453        return 0;
 454}
 455
 456asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
 457{
 458        struct sigframe32 __user *frame;
 459        sigset_t blocked;
 460        int sig;
 461
 462        frame = (struct sigframe32 __user *) regs.regs[29];
 463        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 464                goto badframe;
 465        if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
 466                goto badframe;
 467
 468        set_current_blocked(&blocked);
 469
 470        sig = restore_sigcontext32(&regs, &frame->sf_sc);
 471        if (sig < 0)
 472                goto badframe;
 473        else if (sig)
 474                force_sig(sig, current);
 475
 476        /*
 477         * Don't let your children do this ...
 478         */
 479        __asm__ __volatile__(
 480                "move\t$29, %0\n\t"
 481                "j\tsyscall_exit"
 482                :/* no outputs */
 483                :"r" (&regs));
 484        /* Unreached */
 485
 486badframe:
 487        force_sig(SIGSEGV, current);
 488}
 489
 490asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 491{
 492        struct rt_sigframe32 __user *frame;
 493        mm_segment_t old_fs;
 494        sigset_t set;
 495        stack_t st;
 496        s32 sp;
 497        int sig;
 498
 499        frame = (struct rt_sigframe32 __user *) regs.regs[29];
 500        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 501                goto badframe;
 502        if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
 503                goto badframe;
 504
 505        set_current_blocked(&set);
 506
 507        sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
 508        if (sig < 0)
 509                goto badframe;
 510        else if (sig)
 511                force_sig(sig, current);
 512
 513        /* The ucontext contains a stack32_t, so we must convert!  */
 514        if (__get_user(sp, &frame->rs_uc.uc_stack.ss_sp))
 515                goto badframe;
 516        st.ss_sp = (void __user *)(long) sp;
 517        if (__get_user(st.ss_size, &frame->rs_uc.uc_stack.ss_size))
 518                goto badframe;
 519        if (__get_user(st.ss_flags, &frame->rs_uc.uc_stack.ss_flags))
 520                goto badframe;
 521
 522        /* It is more difficult to avoid calling this function than to
 523           call it and ignore errors.  */
 524        old_fs = get_fs();
 525        set_fs(KERNEL_DS);
 526        do_sigaltstack((stack_t __user *)&st, NULL, regs.regs[29]);
 527        set_fs(old_fs);
 528
 529        /*
 530         * Don't let your children do this ...
 531         */
 532        __asm__ __volatile__(
 533                "move\t$29, %0\n\t"
 534                "j\tsyscall_exit"
 535                :/* no outputs */
 536                :"r" (&regs));
 537        /* Unreached */
 538
 539badframe:
 540        force_sig(SIGSEGV, current);
 541}
 542
 543static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
 544                          struct pt_regs *regs, int signr, sigset_t *set)
 545{
 546        struct sigframe32 __user *frame;
 547        int err = 0;
 548
 549        frame = get_sigframe(ka, regs, sizeof(*frame));
 550        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 551                goto give_sigsegv;
 552
 553        err |= setup_sigcontext32(regs, &frame->sf_sc);
 554        err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
 555
 556        if (err)
 557                goto give_sigsegv;
 558
 559        /*
 560         * Arguments to signal handler:
 561         *
 562         *   a0 = signal number
 563         *   a1 = 0 (should be cause)
 564         *   a2 = pointer to struct sigcontext
 565         *
 566         * $25 and c0_epc point to the signal handler, $29 points to the
 567         * struct sigframe.
 568         */
 569        regs->regs[ 4] = signr;
 570        regs->regs[ 5] = 0;
 571        regs->regs[ 6] = (unsigned long) &frame->sf_sc;
 572        regs->regs[29] = (unsigned long) frame;
 573        regs->regs[31] = (unsigned long) sig_return;
 574        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 575
 576        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 577               current->comm, current->pid,
 578               frame, regs->cp0_epc, regs->regs[31]);
 579
 580        return 0;
 581
 582give_sigsegv:
 583        force_sigsegv(signr, current);
 584        return -EFAULT;
 585}
 586
 587static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
 588                             struct pt_regs *regs, int signr, sigset_t *set,
 589                             siginfo_t *info)
 590{
 591        struct rt_sigframe32 __user *frame;
 592        int err = 0;
 593        s32 sp;
 594
 595        frame = get_sigframe(ka, regs, sizeof(*frame));
 596        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 597                goto give_sigsegv;
 598
 599        /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
 600        err |= copy_siginfo_to_user32(&frame->rs_info, info);
 601
 602        /* Create the ucontext.  */
 603        err |= __put_user(0, &frame->rs_uc.uc_flags);
 604        err |= __put_user(0, &frame->rs_uc.uc_link);
 605        sp = (int) (long) current->sas_ss_sp;
 606        err |= __put_user(sp,
 607                          &frame->rs_uc.uc_stack.ss_sp);
 608        err |= __put_user(sas_ss_flags(regs->regs[29]),
 609                          &frame->rs_uc.uc_stack.ss_flags);
 610        err |= __put_user(current->sas_ss_size,
 611                          &frame->rs_uc.uc_stack.ss_size);
 612        err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
 613        err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
 614
 615        if (err)
 616                goto give_sigsegv;
 617
 618        /*
 619         * Arguments to signal handler:
 620         *
 621         *   a0 = signal number
 622         *   a1 = 0 (should be cause)
 623         *   a2 = pointer to ucontext
 624         *
 625         * $25 and c0_epc point to the signal handler, $29 points to
 626         * the struct rt_sigframe32.
 627         */
 628        regs->regs[ 4] = signr;
 629        regs->regs[ 5] = (unsigned long) &frame->rs_info;
 630        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 631        regs->regs[29] = (unsigned long) frame;
 632        regs->regs[31] = (unsigned long) sig_return;
 633        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 634
 635        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 636               current->comm, current->pid,
 637               frame, regs->cp0_epc, regs->regs[31]);
 638
 639        return 0;
 640
 641give_sigsegv:
 642        force_sigsegv(signr, current);
 643        return -EFAULT;
 644}
 645
 646/*
 647 * o32 compatibility on 64-bit kernels, without DSP ASE
 648 */
 649struct mips_abi mips_abi_32 = {
 650        .setup_frame    = setup_frame_32,
 651        .signal_return_offset =
 652                offsetof(struct mips_vdso, o32_signal_trampoline),
 653        .setup_rt_frame = setup_rt_frame_32,
 654        .rt_signal_return_offset =
 655                offsetof(struct mips_vdso, o32_rt_signal_trampoline),
 656        .restart        = __NR_O32_restart_syscall
 657};
 658
 659SYSCALL_DEFINE4(32_rt_sigaction, int, sig,
 660        const struct sigaction32 __user *, act,
 661        struct sigaction32 __user *, oact, unsigned int, sigsetsize)
 662{
 663        struct k_sigaction new_sa, old_sa;
 664        int ret = -EINVAL;
 665
 666        /* XXX: Don't preclude handling different sized sigset_t's.  */
 667        if (sigsetsize != sizeof(sigset_t))
 668                goto out;
 669
 670        if (act) {
 671                s32 handler;
 672                int err = 0;
 673
 674                if (!access_ok(VERIFY_READ, act, sizeof(*act)))
 675                        return -EFAULT;
 676                err |= __get_user(handler, &act->sa_handler);
 677                new_sa.sa.sa_handler = (void __user *)(s64)handler;
 678                err |= __get_user(new_sa.sa.sa_flags, &act->sa_flags);
 679                err |= get_sigset(&new_sa.sa.sa_mask, &act->sa_mask);
 680                if (err)
 681                        return -EFAULT;
 682        }
 683
 684        ret = do_sigaction(sig, act ? &new_sa : NULL, oact ? &old_sa : NULL);
 685
 686        if (!ret && oact) {
 687                int err = 0;
 688
 689                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
 690                        return -EFAULT;
 691
 692                err |= __put_user((u32)(u64)old_sa.sa.sa_handler,
 693                                   &oact->sa_handler);
 694                err |= __put_user(old_sa.sa.sa_flags, &oact->sa_flags);
 695                err |= put_sigset(&old_sa.sa.sa_mask, &oact->sa_mask);
 696                if (err)
 697                        return -EFAULT;
 698        }
 699out:
 700        return ret;
 701}
 702
 703SYSCALL_DEFINE4(32_rt_sigprocmask, int, how, compat_sigset_t __user *, set,
 704        compat_sigset_t __user *, oset, unsigned int, sigsetsize)
 705{
 706        sigset_t old_set, new_set;
 707        int ret;
 708        mm_segment_t old_fs = get_fs();
 709
 710        if (set && get_sigset(&new_set, set))
 711                return -EFAULT;
 712
 713        set_fs(KERNEL_DS);
 714        ret = sys_rt_sigprocmask(how, set ? (sigset_t __user *)&new_set : NULL,
 715                                 oset ? (sigset_t __user *)&old_set : NULL,
 716                                 sigsetsize);
 717        set_fs(old_fs);
 718
 719        if (!ret && oset && put_sigset(&old_set, oset))
 720                return -EFAULT;
 721
 722        return ret;
 723}
 724
 725SYSCALL_DEFINE2(32_rt_sigpending, compat_sigset_t __user *, uset,
 726        unsigned int, sigsetsize)
 727{
 728        int ret;
 729        sigset_t set;
 730        mm_segment_t old_fs = get_fs();
 731
 732        set_fs(KERNEL_DS);
 733        ret = sys_rt_sigpending((sigset_t __user *)&set, sigsetsize);
 734        set_fs(old_fs);
 735
 736        if (!ret && put_sigset(&set, uset))
 737                return -EFAULT;
 738
 739        return ret;
 740}
 741
 742SYSCALL_DEFINE3(32_rt_sigqueueinfo, int, pid, int, sig,
 743        compat_siginfo_t __user *, uinfo)
 744{
 745        siginfo_t info;
 746        int ret;
 747        mm_segment_t old_fs = get_fs();
 748
 749        if (copy_from_user(&info, uinfo, 3*sizeof(int)) ||
 750            copy_from_user(info._sifields._pad, uinfo->_sifields._pad, SI_PAD_SIZE))
 751                return -EFAULT;
 752        set_fs(KERNEL_DS);
 753        ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info);
 754        set_fs(old_fs);
 755        return ret;
 756}
 757
 758SYSCALL_DEFINE5(32_waitid, int, which, compat_pid_t, pid,
 759             compat_siginfo_t __user *, uinfo, int, options,
 760             struct compat_rusage __user *, uru)
 761{
 762        siginfo_t info;
 763        struct rusage ru;
 764        long ret;
 765        mm_segment_t old_fs = get_fs();
 766
 767        info.si_signo = 0;
 768        set_fs(KERNEL_DS);
 769        ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options,
 770                         uru ? (struct rusage __user *) &ru : NULL);
 771        set_fs(old_fs);
 772
 773        if (ret < 0 || info.si_signo == 0)
 774                return ret;
 775
 776        if (uru && (ret = put_compat_rusage(&ru, uru)))
 777                return ret;
 778
 779        BUG_ON(info.si_code & __SI_MASK);
 780        info.si_code |= __SI_CHLD;
 781        return copy_siginfo_to_user32(uinfo, &info);
 782}
 783
 784static int signal32_init(void)
 785{
 786        if (cpu_has_fpu) {
 787                save_fp_context32 = _save_fp_context32;
 788                restore_fp_context32 = _restore_fp_context32;
 789        } else {
 790                save_fp_context32 = fpu_emulator_save_context32;
 791                restore_fp_context32 = fpu_emulator_restore_context32;
 792        }
 793
 794        return 0;
 795}
 796
 797arch_initcall(signal32_init);
 798