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