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 ucontext32 {
  59        u32                 uc_flags;
  60        s32                 uc_link;
  61        compat_stack_t      uc_stack;
  62        struct sigcontext32 uc_mcontext;
  63        compat_sigset_t     uc_sigmask;   /* mask last for extensibility */
  64};
  65
  66struct sigframe32 {
  67        u32 sf_ass[4];          /* argument save space for o32 */
  68        u32 sf_pad[2];          /* Was: signal trampoline */
  69        struct sigcontext32 sf_sc;
  70        compat_sigset_t sf_mask;
  71};
  72
  73struct rt_sigframe32 {
  74        u32 rs_ass[4];                  /* argument save space for o32 */
  75        u32 rs_pad[2];                  /* Was: signal trampoline */
  76        compat_siginfo_t rs_info;
  77        struct ucontext32 rs_uc;
  78};
  79
  80/*
  81 * sigcontext handlers
  82 */
  83static int protected_save_fp_context32(struct sigcontext32 __user *sc)
  84{
  85        int err;
  86        while (1) {
  87                lock_fpu_owner();
  88                own_fpu_inatomic(1);
  89                err = save_fp_context32(sc); /* this might fail */
  90                unlock_fpu_owner();
  91                if (likely(!err))
  92                        break;
  93                /* touch the sigcontext and try again */
  94                err = __put_user(0, &sc->sc_fpregs[0]) |
  95                        __put_user(0, &sc->sc_fpregs[31]) |
  96                        __put_user(0, &sc->sc_fpc_csr);
  97                if (err)
  98                        break;  /* really bad sigcontext */
  99        }
 100        return err;
 101}
 102
 103static int protected_restore_fp_context32(struct sigcontext32 __user *sc)
 104{
 105        int err, tmp __maybe_unused;
 106        while (1) {
 107                lock_fpu_owner();
 108                own_fpu_inatomic(0);
 109                err = restore_fp_context32(sc); /* this might fail */
 110                unlock_fpu_owner();
 111                if (likely(!err))
 112                        break;
 113                /* touch the sigcontext and try again */
 114                err = __get_user(tmp, &sc->sc_fpregs[0]) |
 115                        __get_user(tmp, &sc->sc_fpregs[31]) |
 116                        __get_user(tmp, &sc->sc_fpc_csr);
 117                if (err)
 118                        break;  /* really bad sigcontext */
 119        }
 120        return err;
 121}
 122
 123static int setup_sigcontext32(struct pt_regs *regs,
 124                              struct sigcontext32 __user *sc)
 125{
 126        int err = 0;
 127        int i;
 128        u32 used_math;
 129
 130        err |= __put_user(regs->cp0_epc, &sc->sc_pc);
 131
 132        err |= __put_user(0, &sc->sc_regs[0]);
 133        for (i = 1; i < 32; i++)
 134                err |= __put_user(regs->regs[i], &sc->sc_regs[i]);
 135
 136        err |= __put_user(regs->hi, &sc->sc_mdhi);
 137        err |= __put_user(regs->lo, &sc->sc_mdlo);
 138        if (cpu_has_dsp) {
 139                err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp);
 140                err |= __put_user(mfhi1(), &sc->sc_hi1);
 141                err |= __put_user(mflo1(), &sc->sc_lo1);
 142                err |= __put_user(mfhi2(), &sc->sc_hi2);
 143                err |= __put_user(mflo2(), &sc->sc_lo2);
 144                err |= __put_user(mfhi3(), &sc->sc_hi3);
 145                err |= __put_user(mflo3(), &sc->sc_lo3);
 146        }
 147
 148        used_math = !!used_math();
 149        err |= __put_user(used_math, &sc->sc_used_math);
 150
 151        if (used_math) {
 152                /*
 153                 * Save FPU state to signal context.  Signal handler
 154                 * will "inherit" current FPU state.
 155                 */
 156                err |= protected_save_fp_context32(sc);
 157        }
 158        return err;
 159}
 160
 161static int
 162check_and_restore_fp_context32(struct sigcontext32 __user *sc)
 163{
 164        int err, sig;
 165
 166        err = sig = fpcsr_pending(&sc->sc_fpc_csr);
 167        if (err > 0)
 168                err = 0;
 169        err |= protected_restore_fp_context32(sc);
 170        return err ?: sig;
 171}
 172
 173static int restore_sigcontext32(struct pt_regs *regs,
 174                                struct sigcontext32 __user *sc)
 175{
 176        u32 used_math;
 177        int err = 0;
 178        s32 treg;
 179        int i;
 180
 181        /* Always make any pending restarted system calls return -EINTR */
 182        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 183
 184        err |= __get_user(regs->cp0_epc, &sc->sc_pc);
 185        err |= __get_user(regs->hi, &sc->sc_mdhi);
 186        err |= __get_user(regs->lo, &sc->sc_mdlo);
 187        if (cpu_has_dsp) {
 188                err |= __get_user(treg, &sc->sc_hi1); mthi1(treg);
 189                err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg);
 190                err |= __get_user(treg, &sc->sc_hi2); mthi2(treg);
 191                err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg);
 192                err |= __get_user(treg, &sc->sc_hi3); mthi3(treg);
 193                err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg);
 194                err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK);
 195        }
 196
 197        for (i = 1; i < 32; i++)
 198                err |= __get_user(regs->regs[i], &sc->sc_regs[i]);
 199
 200        err |= __get_user(used_math, &sc->sc_used_math);
 201        conditional_used_math(used_math);
 202
 203        if (used_math) {
 204                /* restore fpu context if we have used it before */
 205                if (!err)
 206                        err = check_and_restore_fp_context32(sc);
 207        } else {
 208                /* signal handler may have used FPU.  Give it up. */
 209                lose_fpu(0);
 210        }
 211
 212        return err;
 213}
 214
 215/*
 216 *
 217 */
 218extern void __put_sigset_unknown_nsig(void);
 219extern void __get_sigset_unknown_nsig(void);
 220
 221static inline int put_sigset(const sigset_t *kbuf, compat_sigset_t __user *ubuf)
 222{
 223        int err = 0;
 224
 225        if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)))
 226                return -EFAULT;
 227
 228        switch (_NSIG_WORDS) {
 229        default:
 230                __put_sigset_unknown_nsig();
 231        case 2:
 232                err |= __put_user(kbuf->sig[1] >> 32, &ubuf->sig[3]);
 233                err |= __put_user(kbuf->sig[1] & 0xffffffff, &ubuf->sig[2]);
 234        case 1:
 235                err |= __put_user(kbuf->sig[0] >> 32, &ubuf->sig[1]);
 236                err |= __put_user(kbuf->sig[0] & 0xffffffff, &ubuf->sig[0]);
 237        }
 238
 239        return err;
 240}
 241
 242static inline int get_sigset(sigset_t *kbuf, const compat_sigset_t __user *ubuf)
 243{
 244        int err = 0;
 245        unsigned long sig[4];
 246
 247        if (!access_ok(VERIFY_READ, ubuf, sizeof(*ubuf)))
 248                return -EFAULT;
 249
 250        switch (_NSIG_WORDS) {
 251        default:
 252                __get_sigset_unknown_nsig();
 253        case 2:
 254                err |= __get_user(sig[3], &ubuf->sig[3]);
 255                err |= __get_user(sig[2], &ubuf->sig[2]);
 256                kbuf->sig[1] = sig[2] | (sig[3] << 32);
 257        case 1:
 258                err |= __get_user(sig[1], &ubuf->sig[1]);
 259                err |= __get_user(sig[0], &ubuf->sig[0]);
 260                kbuf->sig[0] = sig[0] | (sig[1] << 32);
 261        }
 262
 263        return err;
 264}
 265
 266/*
 267 * Atomically swap in the new signal mask, and wait for a signal.
 268 */
 269
 270asmlinkage int sys32_sigsuspend(compat_sigset_t __user *uset)
 271{
 272        return compat_sys_rt_sigsuspend(uset, sizeof(compat_sigset_t));
 273}
 274
 275SYSCALL_DEFINE3(32_sigaction, long, sig, const struct compat_sigaction __user *, act,
 276        struct compat_sigaction __user *, oact)
 277{
 278        struct k_sigaction new_ka, old_ka;
 279        int ret;
 280        int err = 0;
 281
 282        if (act) {
 283                old_sigset_t mask;
 284                s32 handler;
 285
 286                if (!access_ok(VERIFY_READ, act, sizeof(*act)))
 287                        return -EFAULT;
 288                err |= __get_user(handler, &act->sa_handler);
 289                new_ka.sa.sa_handler = (void __user *)(s64)handler;
 290                err |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);
 291                err |= __get_user(mask, &act->sa_mask.sig[0]);
 292                if (err)
 293                        return -EFAULT;
 294
 295                siginitset(&new_ka.sa.sa_mask, mask);
 296        }
 297
 298        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 299
 300        if (!ret && oact) {
 301                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)))
 302                        return -EFAULT;
 303                err |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
 304                err |= __put_user((u32)(u64)old_ka.sa.sa_handler,
 305                                  &oact->sa_handler);
 306                err |= __put_user(old_ka.sa.sa_mask.sig[0], oact->sa_mask.sig);
 307                err |= __put_user(0, &oact->sa_mask.sig[1]);
 308                err |= __put_user(0, &oact->sa_mask.sig[2]);
 309                err |= __put_user(0, &oact->sa_mask.sig[3]);
 310                if (err)
 311                        return -EFAULT;
 312        }
 313
 314        return ret;
 315}
 316
 317int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
 318{
 319        int err;
 320
 321        if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
 322                return -EFAULT;
 323
 324        /* If you change siginfo_t structure, please be sure
 325           this code is fixed accordingly.
 326           It should never copy any pad contained in the structure
 327           to avoid security leaks, but must copy the generic
 328           3 ints plus the relevant union member.
 329           This routine must convert siginfo from 64bit to 32bit as well
 330           at the same time.  */
 331        err = __put_user(from->si_signo, &to->si_signo);
 332        err |= __put_user(from->si_errno, &to->si_errno);
 333        err |= __put_user((short)from->si_code, &to->si_code);
 334        if (from->si_code < 0)
 335                err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
 336        else {
 337                switch (from->si_code >> 16) {
 338                case __SI_TIMER >> 16:
 339                        err |= __put_user(from->si_tid, &to->si_tid);
 340                        err |= __put_user(from->si_overrun, &to->si_overrun);
 341                        err |= __put_user(from->si_int, &to->si_int);
 342                        break;
 343                case __SI_CHLD >> 16:
 344                        err |= __put_user(from->si_utime, &to->si_utime);
 345                        err |= __put_user(from->si_stime, &to->si_stime);
 346                        err |= __put_user(from->si_status, &to->si_status);
 347                default:
 348                        err |= __put_user(from->si_pid, &to->si_pid);
 349                        err |= __put_user(from->si_uid, &to->si_uid);
 350                        break;
 351                case __SI_FAULT >> 16:
 352                        err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
 353                        break;
 354                case __SI_POLL >> 16:
 355                        err |= __put_user(from->si_band, &to->si_band);
 356                        err |= __put_user(from->si_fd, &to->si_fd);
 357                        break;
 358                case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
 359                case __SI_MESGQ >> 16:
 360                        err |= __put_user(from->si_pid, &to->si_pid);
 361                        err |= __put_user(from->si_uid, &to->si_uid);
 362                        err |= __put_user(from->si_int, &to->si_int);
 363                        break;
 364                }
 365        }
 366        return err;
 367}
 368
 369int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 370{
 371        memset(to, 0, sizeof *to);
 372
 373        if (copy_from_user(to, from, 3*sizeof(int)) ||
 374            copy_from_user(to->_sifields._pad,
 375                           from->_sifields._pad, SI_PAD_SIZE32))
 376                return -EFAULT;
 377
 378        return 0;
 379}
 380
 381asmlinkage void sys32_sigreturn(nabi_no_regargs struct pt_regs regs)
 382{
 383        struct sigframe32 __user *frame;
 384        sigset_t blocked;
 385        int sig;
 386
 387        frame = (struct sigframe32 __user *) regs.regs[29];
 388        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 389                goto badframe;
 390        if (__copy_conv_sigset_from_user(&blocked, &frame->sf_mask))
 391                goto badframe;
 392
 393        set_current_blocked(&blocked);
 394
 395        sig = restore_sigcontext32(&regs, &frame->sf_sc);
 396        if (sig < 0)
 397                goto badframe;
 398        else if (sig)
 399                force_sig(sig, current);
 400
 401        /*
 402         * Don't let your children do this ...
 403         */
 404        __asm__ __volatile__(
 405                "move\t$29, %0\n\t"
 406                "j\tsyscall_exit"
 407                :/* no outputs */
 408                :"r" (&regs));
 409        /* Unreached */
 410
 411badframe:
 412        force_sig(SIGSEGV, current);
 413}
 414
 415asmlinkage void sys32_rt_sigreturn(nabi_no_regargs struct pt_regs regs)
 416{
 417        struct rt_sigframe32 __user *frame;
 418        sigset_t set;
 419        int sig;
 420
 421        frame = (struct rt_sigframe32 __user *) regs.regs[29];
 422        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 423                goto badframe;
 424        if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask))
 425                goto badframe;
 426
 427        set_current_blocked(&set);
 428
 429        sig = restore_sigcontext32(&regs, &frame->rs_uc.uc_mcontext);
 430        if (sig < 0)
 431                goto badframe;
 432        else if (sig)
 433                force_sig(sig, current);
 434
 435        if (compat_restore_altstack(&frame->rs_uc.uc_stack))
 436                goto badframe;
 437
 438        /*
 439         * Don't let your children do this ...
 440         */
 441        __asm__ __volatile__(
 442                "move\t$29, %0\n\t"
 443                "j\tsyscall_exit"
 444                :/* no outputs */
 445                :"r" (&regs));
 446        /* Unreached */
 447
 448badframe:
 449        force_sig(SIGSEGV, current);
 450}
 451
 452static int setup_frame_32(void *sig_return, struct k_sigaction *ka,
 453                          struct pt_regs *regs, int signr, sigset_t *set)
 454{
 455        struct sigframe32 __user *frame;
 456        int err = 0;
 457
 458        frame = get_sigframe(ka, regs, sizeof(*frame));
 459        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 460                goto give_sigsegv;
 461
 462        err |= setup_sigcontext32(regs, &frame->sf_sc);
 463        err |= __copy_conv_sigset_to_user(&frame->sf_mask, set);
 464
 465        if (err)
 466                goto give_sigsegv;
 467
 468        /*
 469         * Arguments to signal handler:
 470         *
 471         *   a0 = signal number
 472         *   a1 = 0 (should be cause)
 473         *   a2 = pointer to struct sigcontext
 474         *
 475         * $25 and c0_epc point to the signal handler, $29 points to the
 476         * struct sigframe.
 477         */
 478        regs->regs[ 4] = signr;
 479        regs->regs[ 5] = 0;
 480        regs->regs[ 6] = (unsigned long) &frame->sf_sc;
 481        regs->regs[29] = (unsigned long) frame;
 482        regs->regs[31] = (unsigned long) sig_return;
 483        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 484
 485        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 486               current->comm, current->pid,
 487               frame, regs->cp0_epc, regs->regs[31]);
 488
 489        return 0;
 490
 491give_sigsegv:
 492        force_sigsegv(signr, current);
 493        return -EFAULT;
 494}
 495
 496static int setup_rt_frame_32(void *sig_return, struct k_sigaction *ka,
 497                             struct pt_regs *regs, int signr, sigset_t *set,
 498                             siginfo_t *info)
 499{
 500        struct rt_sigframe32 __user *frame;
 501        int err = 0;
 502
 503        frame = get_sigframe(ka, regs, sizeof(*frame));
 504        if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))
 505                goto give_sigsegv;
 506
 507        /* Convert (siginfo_t -> compat_siginfo_t) and copy to user. */
 508        err |= copy_siginfo_to_user32(&frame->rs_info, info);
 509
 510        /* Create the ucontext.  */
 511        err |= __put_user(0, &frame->rs_uc.uc_flags);
 512        err |= __put_user(0, &frame->rs_uc.uc_link);
 513        err |= __compat_save_altstack(&frame->rs_uc.uc_stack, regs->regs[29]);
 514        err |= setup_sigcontext32(regs, &frame->rs_uc.uc_mcontext);
 515        err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set);
 516
 517        if (err)
 518                goto give_sigsegv;
 519
 520        /*
 521         * Arguments to signal handler:
 522         *
 523         *   a0 = signal number
 524         *   a1 = 0 (should be cause)
 525         *   a2 = pointer to ucontext
 526         *
 527         * $25 and c0_epc point to the signal handler, $29 points to
 528         * the struct rt_sigframe32.
 529         */
 530        regs->regs[ 4] = signr;
 531        regs->regs[ 5] = (unsigned long) &frame->rs_info;
 532        regs->regs[ 6] = (unsigned long) &frame->rs_uc;
 533        regs->regs[29] = (unsigned long) frame;
 534        regs->regs[31] = (unsigned long) sig_return;
 535        regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler;
 536
 537        DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n",
 538               current->comm, current->pid,
 539               frame, regs->cp0_epc, regs->regs[31]);
 540
 541        return 0;
 542
 543give_sigsegv:
 544        force_sigsegv(signr, current);
 545        return -EFAULT;
 546}
 547
 548/*
 549 * o32 compatibility on 64-bit kernels, without DSP ASE
 550 */
 551struct mips_abi mips_abi_32 = {
 552        .setup_frame    = setup_frame_32,
 553        .signal_return_offset =
 554                offsetof(struct mips_vdso, o32_signal_trampoline),
 555        .setup_rt_frame = setup_rt_frame_32,
 556        .rt_signal_return_offset =
 557                offsetof(struct mips_vdso, o32_rt_signal_trampoline),
 558        .restart        = __NR_O32_restart_syscall
 559};
 560
 561static int signal32_init(void)
 562{
 563        if (cpu_has_fpu) {
 564                save_fp_context32 = _save_fp_context32;
 565                restore_fp_context32 = _restore_fp_context32;
 566        } else {
 567                save_fp_context32 = fpu_emulator_save_context32;
 568                restore_fp_context32 = fpu_emulator_restore_context32;
 569        }
 570
 571        return 0;
 572}
 573
 574arch_initcall(signal32_init);
 575