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