linux/arch/m68k/kernel/signal.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/m68k/kernel/signal.c
   3 *
   4 *  Copyright (C) 1991, 1992  Linus Torvalds
   5 *
   6 * This file is subject to the terms and conditions of the GNU General Public
   7 * License.  See the file COPYING in the main directory of this archive
   8 * for more details.
   9 */
  10
  11/*
  12 * Linux/m68k support by Hamish Macdonald
  13 *
  14 * 68060 fixes by Jesper Skov
  15 *
  16 * 1997-12-01  Modified for POSIX.1b signals by Andreas Schwab
  17 *
  18 * mathemu support by Roman Zippel
  19 *  (Note: fpstate in the signal context is completely ignored for the emulator
  20 *         and the internal floating point format is put on stack)
  21 */
  22
  23/*
  24 * ++roman (07/09/96): implemented signal stacks (specially for tosemu on
  25 * Atari :-) Current limitation: Only one sigstack can be active at one time.
  26 * If a second signal with SA_ONSTACK set arrives while working on a sigstack,
  27 * SA_ONSTACK is ignored. This behaviour avoids lots of trouble with nested
  28 * signal handlers!
  29 */
  30
  31#include <linux/sched.h>
  32#include <linux/mm.h>
  33#include <linux/kernel.h>
  34#include <linux/signal.h>
  35#include <linux/syscalls.h>
  36#include <linux/errno.h>
  37#include <linux/wait.h>
  38#include <linux/ptrace.h>
  39#include <linux/unistd.h>
  40#include <linux/stddef.h>
  41#include <linux/highuid.h>
  42#include <linux/personality.h>
  43#include <linux/tty.h>
  44#include <linux/binfmts.h>
  45#include <linux/module.h>
  46#include <linux/tracehook.h>
  47
  48#include <asm/setup.h>
  49#include <asm/uaccess.h>
  50#include <asm/pgtable.h>
  51#include <asm/traps.h>
  52#include <asm/ucontext.h>
  53
  54#ifdef CONFIG_MMU
  55
  56/*
  57 * Handle the slight differences in classic 68k and ColdFire trap frames.
  58 */
  59#ifdef CONFIG_COLDFIRE
  60#define FORMAT          4
  61#define FMT4SIZE        0
  62#else
  63#define FORMAT          0
  64#define FMT4SIZE        sizeof(((struct frame *)0)->un.fmt4)
  65#endif
  66
  67static const int frame_size_change[16] = {
  68  [1]   = -1, /* sizeof(((struct frame *)0)->un.fmt1), */
  69  [2]   = sizeof(((struct frame *)0)->un.fmt2),
  70  [3]   = sizeof(((struct frame *)0)->un.fmt3),
  71  [4]   = FMT4SIZE,
  72  [5]   = -1, /* sizeof(((struct frame *)0)->un.fmt5), */
  73  [6]   = -1, /* sizeof(((struct frame *)0)->un.fmt6), */
  74  [7]   = sizeof(((struct frame *)0)->un.fmt7),
  75  [8]   = -1, /* sizeof(((struct frame *)0)->un.fmt8), */
  76  [9]   = sizeof(((struct frame *)0)->un.fmt9),
  77  [10]  = sizeof(((struct frame *)0)->un.fmta),
  78  [11]  = sizeof(((struct frame *)0)->un.fmtb),
  79  [12]  = -1, /* sizeof(((struct frame *)0)->un.fmtc), */
  80  [13]  = -1, /* sizeof(((struct frame *)0)->un.fmtd), */
  81  [14]  = -1, /* sizeof(((struct frame *)0)->un.fmte), */
  82  [15]  = -1, /* sizeof(((struct frame *)0)->un.fmtf), */
  83};
  84
  85static inline int frame_extra_sizes(int f)
  86{
  87        return frame_size_change[f];
  88}
  89
  90int handle_kernel_fault(struct pt_regs *regs)
  91{
  92        const struct exception_table_entry *fixup;
  93        struct pt_regs *tregs;
  94
  95        /* Are we prepared to handle this kernel fault? */
  96        fixup = search_exception_tables(regs->pc);
  97        if (!fixup)
  98                return 0;
  99
 100        /* Create a new four word stack frame, discarding the old one. */
 101        regs->stkadj = frame_extra_sizes(regs->format);
 102        tregs = (struct pt_regs *)((long)regs + regs->stkadj);
 103        tregs->vector = regs->vector;
 104        tregs->format = FORMAT;
 105        tregs->pc = fixup->fixup;
 106        tregs->sr = regs->sr;
 107
 108        return 1;
 109}
 110
 111void ptrace_signal_deliver(struct pt_regs *regs, void *cookie)
 112{
 113        if (regs->orig_d0 < 0)
 114                return;
 115        switch (regs->d0) {
 116        case -ERESTARTNOHAND:
 117        case -ERESTARTSYS:
 118        case -ERESTARTNOINTR:
 119                regs->d0 = regs->orig_d0;
 120                regs->orig_d0 = -1;
 121                regs->pc -= 2;
 122                break;
 123        }
 124}
 125
 126static inline void push_cache (unsigned long vaddr)
 127{
 128        /*
 129         * Using the old cache_push_v() was really a big waste.
 130         *
 131         * What we are trying to do is to flush 8 bytes to ram.
 132         * Flushing 2 cache lines of 16 bytes is much cheaper than
 133         * flushing 1 or 2 pages, as previously done in
 134         * cache_push_v().
 135         *                                                     Jes
 136         */
 137        if (CPU_IS_040) {
 138                unsigned long temp;
 139
 140                __asm__ __volatile__ (".chip 68040\n\t"
 141                                      "nop\n\t"
 142                                      "ptestr (%1)\n\t"
 143                                      "movec %%mmusr,%0\n\t"
 144                                      ".chip 68k"
 145                                      : "=r" (temp)
 146                                      : "a" (vaddr));
 147
 148                temp &= PAGE_MASK;
 149                temp |= vaddr & ~PAGE_MASK;
 150
 151                __asm__ __volatile__ (".chip 68040\n\t"
 152                                      "nop\n\t"
 153                                      "cpushl %%bc,(%0)\n\t"
 154                                      ".chip 68k"
 155                                      : : "a" (temp));
 156        }
 157        else if (CPU_IS_060) {
 158                unsigned long temp;
 159                __asm__ __volatile__ (".chip 68060\n\t"
 160                                      "plpar (%0)\n\t"
 161                                      ".chip 68k"
 162                                      : "=a" (temp)
 163                                      : "0" (vaddr));
 164                __asm__ __volatile__ (".chip 68060\n\t"
 165                                      "cpushl %%bc,(%0)\n\t"
 166                                      ".chip 68k"
 167                                      : : "a" (temp));
 168        } else if (!CPU_IS_COLDFIRE) {
 169                /*
 170                 * 68030/68020 have no writeback cache;
 171                 * still need to clear icache.
 172                 * Note that vaddr is guaranteed to be long word aligned.
 173                 */
 174                unsigned long temp;
 175                asm volatile ("movec %%cacr,%0" : "=r" (temp));
 176                temp += 4;
 177                asm volatile ("movec %0,%%caar\n\t"
 178                              "movec %1,%%cacr"
 179                              : : "r" (vaddr), "r" (temp));
 180                asm volatile ("movec %0,%%caar\n\t"
 181                              "movec %1,%%cacr"
 182                              : : "r" (vaddr + 4), "r" (temp));
 183        }
 184}
 185
 186static inline void adjustformat(struct pt_regs *regs)
 187{
 188}
 189
 190static inline void save_a5_state(struct sigcontext *sc, struct pt_regs *regs)
 191{
 192}
 193
 194#else /* CONFIG_MMU */
 195
 196void ret_from_user_signal(void);
 197void ret_from_user_rt_signal(void);
 198
 199static inline int frame_extra_sizes(int f)
 200{
 201        /* No frame size adjustments required on non-MMU CPUs */
 202        return 0;
 203}
 204
 205static inline void adjustformat(struct pt_regs *regs)
 206{
 207        ((struct switch_stack *)regs - 1)->a5 = current->mm->start_data;
 208        /*
 209         * set format byte to make stack appear modulo 4, which it will
 210         * be when doing the rte
 211         */
 212        regs->format = 0x4;
 213}
 214
 215static inline void save_a5_state(struct sigcontext *sc, struct pt_regs *regs)
 216{
 217        sc->sc_a5 = ((struct switch_stack *)regs - 1)->a5;
 218}
 219
 220static inline void push_cache(unsigned long vaddr)
 221{
 222}
 223
 224#endif /* CONFIG_MMU */
 225
 226/*
 227 * Atomically swap in the new signal mask, and wait for a signal.
 228 */
 229asmlinkage int
 230sys_sigsuspend(int unused0, int unused1, old_sigset_t mask)
 231{
 232        sigset_t blocked;
 233        siginitset(&blocked, mask);
 234        return sigsuspend(&blocked);
 235}
 236
 237asmlinkage int
 238sys_sigaction(int sig, const struct old_sigaction __user *act,
 239              struct old_sigaction __user *oact)
 240{
 241        struct k_sigaction new_ka, old_ka;
 242        int ret;
 243
 244        if (act) {
 245                old_sigset_t mask;
 246                if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
 247                    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
 248                    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
 249                    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
 250                    __get_user(mask, &act->sa_mask))
 251                        return -EFAULT;
 252                siginitset(&new_ka.sa.sa_mask, mask);
 253        }
 254
 255        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
 256
 257        if (!ret && oact) {
 258                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
 259                    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
 260                    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
 261                    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
 262                    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
 263                        return -EFAULT;
 264        }
 265
 266        return ret;
 267}
 268
 269asmlinkage int
 270sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
 271{
 272        return do_sigaltstack(uss, uoss, rdusp());
 273}
 274
 275
 276/*
 277 * Do a signal return; undo the signal stack.
 278 *
 279 * Keep the return code on the stack quadword aligned!
 280 * That makes the cache flush below easier.
 281 */
 282
 283struct sigframe
 284{
 285        char __user *pretcode;
 286        int sig;
 287        int code;
 288        struct sigcontext __user *psc;
 289        char retcode[8];
 290        unsigned long extramask[_NSIG_WORDS-1];
 291        struct sigcontext sc;
 292};
 293
 294struct rt_sigframe
 295{
 296        char __user *pretcode;
 297        int sig;
 298        struct siginfo __user *pinfo;
 299        void __user *puc;
 300        char retcode[8];
 301        struct siginfo info;
 302        struct ucontext uc;
 303};
 304
 305#define FPCONTEXT_SIZE  216
 306#define uc_fpstate      uc_filler[0]
 307#define uc_formatvec    uc_filler[FPCONTEXT_SIZE/4]
 308#define uc_extra        uc_filler[FPCONTEXT_SIZE/4+1]
 309
 310#ifdef CONFIG_FPU
 311
 312static unsigned char fpu_version;       /* version number of fpu, set by setup_frame */
 313
 314static inline int restore_fpu_state(struct sigcontext *sc)
 315{
 316        int err = 1;
 317
 318        if (FPU_IS_EMU) {
 319            /* restore registers */
 320            memcpy(current->thread.fpcntl, sc->sc_fpcntl, 12);
 321            memcpy(current->thread.fp, sc->sc_fpregs, 24);
 322            return 0;
 323        }
 324
 325        if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
 326            /* Verify the frame format.  */
 327            if (!(CPU_IS_060 || CPU_IS_COLDFIRE) &&
 328                 (sc->sc_fpstate[0] != fpu_version))
 329                goto out;
 330            if (CPU_IS_020_OR_030) {
 331                if (m68k_fputype & FPU_68881 &&
 332                    !(sc->sc_fpstate[1] == 0x18 || sc->sc_fpstate[1] == 0xb4))
 333                    goto out;
 334                if (m68k_fputype & FPU_68882 &&
 335                    !(sc->sc_fpstate[1] == 0x38 || sc->sc_fpstate[1] == 0xd4))
 336                    goto out;
 337            } else if (CPU_IS_040) {
 338                if (!(sc->sc_fpstate[1] == 0x00 ||
 339                      sc->sc_fpstate[1] == 0x28 ||
 340                      sc->sc_fpstate[1] == 0x60))
 341                    goto out;
 342            } else if (CPU_IS_060) {
 343                if (!(sc->sc_fpstate[3] == 0x00 ||
 344                      sc->sc_fpstate[3] == 0x60 ||
 345                      sc->sc_fpstate[3] == 0xe0))
 346                    goto out;
 347            } else if (CPU_IS_COLDFIRE) {
 348                if (!(sc->sc_fpstate[0] == 0x00 ||
 349                      sc->sc_fpstate[0] == 0x05 ||
 350                      sc->sc_fpstate[0] == 0xe5))
 351                    goto out;
 352            } else
 353                goto out;
 354
 355            if (CPU_IS_COLDFIRE) {
 356                __asm__ volatile ("fmovemd %0,%%fp0-%%fp1\n\t"
 357                                  "fmovel %1,%%fpcr\n\t"
 358                                  "fmovel %2,%%fpsr\n\t"
 359                                  "fmovel %3,%%fpiar"
 360                                  : /* no outputs */
 361                                  : "m" (sc->sc_fpregs[0]),
 362                                    "m" (sc->sc_fpcntl[0]),
 363                                    "m" (sc->sc_fpcntl[1]),
 364                                    "m" (sc->sc_fpcntl[2]));
 365            } else {
 366                __asm__ volatile (".chip 68k/68881\n\t"
 367                                  "fmovemx %0,%%fp0-%%fp1\n\t"
 368                                  "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
 369                                  ".chip 68k"
 370                                  : /* no outputs */
 371                                  : "m" (*sc->sc_fpregs),
 372                                    "m" (*sc->sc_fpcntl));
 373            }
 374        }
 375
 376        if (CPU_IS_COLDFIRE) {
 377                __asm__ volatile ("frestore %0" : : "m" (*sc->sc_fpstate));
 378        } else {
 379                __asm__ volatile (".chip 68k/68881\n\t"
 380                                  "frestore %0\n\t"
 381                                  ".chip 68k"
 382                                  : : "m" (*sc->sc_fpstate));
 383        }
 384        err = 0;
 385
 386out:
 387        return err;
 388}
 389
 390static inline int rt_restore_fpu_state(struct ucontext __user *uc)
 391{
 392        unsigned char fpstate[FPCONTEXT_SIZE];
 393        int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0);
 394        fpregset_t fpregs;
 395        int err = 1;
 396
 397        if (FPU_IS_EMU) {
 398                /* restore fpu control register */
 399                if (__copy_from_user(current->thread.fpcntl,
 400                                uc->uc_mcontext.fpregs.f_fpcntl, 12))
 401                        goto out;
 402                /* restore all other fpu register */
 403                if (__copy_from_user(current->thread.fp,
 404                                uc->uc_mcontext.fpregs.f_fpregs, 96))
 405                        goto out;
 406                return 0;
 407        }
 408
 409        if (__get_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate))
 410                goto out;
 411        if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
 412                if (!(CPU_IS_060 || CPU_IS_COLDFIRE))
 413                        context_size = fpstate[1];
 414                /* Verify the frame format.  */
 415                if (!(CPU_IS_060 || CPU_IS_COLDFIRE) &&
 416                     (fpstate[0] != fpu_version))
 417                        goto out;
 418                if (CPU_IS_020_OR_030) {
 419                        if (m68k_fputype & FPU_68881 &&
 420                            !(context_size == 0x18 || context_size == 0xb4))
 421                                goto out;
 422                        if (m68k_fputype & FPU_68882 &&
 423                            !(context_size == 0x38 || context_size == 0xd4))
 424                                goto out;
 425                } else if (CPU_IS_040) {
 426                        if (!(context_size == 0x00 ||
 427                              context_size == 0x28 ||
 428                              context_size == 0x60))
 429                                goto out;
 430                } else if (CPU_IS_060) {
 431                        if (!(fpstate[3] == 0x00 ||
 432                              fpstate[3] == 0x60 ||
 433                              fpstate[3] == 0xe0))
 434                                goto out;
 435                } else if (CPU_IS_COLDFIRE) {
 436                        if (!(fpstate[3] == 0x00 ||
 437                              fpstate[3] == 0x05 ||
 438                              fpstate[3] == 0xe5))
 439                                goto out;
 440                } else
 441                        goto out;
 442                if (__copy_from_user(&fpregs, &uc->uc_mcontext.fpregs,
 443                                     sizeof(fpregs)))
 444                        goto out;
 445
 446                if (CPU_IS_COLDFIRE) {
 447                        __asm__ volatile ("fmovemd %0,%%fp0-%%fp7\n\t"
 448                                          "fmovel %1,%%fpcr\n\t"
 449                                          "fmovel %2,%%fpsr\n\t"
 450                                          "fmovel %3,%%fpiar"
 451                                          : /* no outputs */
 452                                          : "m" (fpregs.f_fpregs[0]),
 453                                            "m" (fpregs.f_fpcntl[0]),
 454                                            "m" (fpregs.f_fpcntl[1]),
 455                                            "m" (fpregs.f_fpcntl[2]));
 456                } else {
 457                        __asm__ volatile (".chip 68k/68881\n\t"
 458                                          "fmovemx %0,%%fp0-%%fp7\n\t"
 459                                          "fmoveml %1,%%fpcr/%%fpsr/%%fpiar\n\t"
 460                                          ".chip 68k"
 461                                          : /* no outputs */
 462                                          : "m" (*fpregs.f_fpregs),
 463                                            "m" (*fpregs.f_fpcntl));
 464                }
 465        }
 466        if (context_size &&
 467            __copy_from_user(fpstate + 4, (long __user *)&uc->uc_fpstate + 1,
 468                             context_size))
 469                goto out;
 470
 471        if (CPU_IS_COLDFIRE) {
 472                __asm__ volatile ("frestore %0" : : "m" (*fpstate));
 473        } else {
 474                __asm__ volatile (".chip 68k/68881\n\t"
 475                                  "frestore %0\n\t"
 476                                  ".chip 68k"
 477                                  : : "m" (*fpstate));
 478        }
 479        err = 0;
 480
 481out:
 482        return err;
 483}
 484
 485/*
 486 * Set up a signal frame.
 487 */
 488static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
 489{
 490        if (FPU_IS_EMU) {
 491                /* save registers */
 492                memcpy(sc->sc_fpcntl, current->thread.fpcntl, 12);
 493                memcpy(sc->sc_fpregs, current->thread.fp, 24);
 494                return;
 495        }
 496
 497        if (CPU_IS_COLDFIRE) {
 498                __asm__ volatile ("fsave %0"
 499                                  : : "m" (*sc->sc_fpstate) : "memory");
 500        } else {
 501                __asm__ volatile (".chip 68k/68881\n\t"
 502                                  "fsave %0\n\t"
 503                                  ".chip 68k"
 504                                  : : "m" (*sc->sc_fpstate) : "memory");
 505        }
 506
 507        if (CPU_IS_060 ? sc->sc_fpstate[2] : sc->sc_fpstate[0]) {
 508                fpu_version = sc->sc_fpstate[0];
 509                if (CPU_IS_020_OR_030 &&
 510                    regs->vector >= (VEC_FPBRUC * 4) &&
 511                    regs->vector <= (VEC_FPNAN * 4)) {
 512                        /* Clear pending exception in 68882 idle frame */
 513                        if (*(unsigned short *) sc->sc_fpstate == 0x1f38)
 514                                sc->sc_fpstate[0x38] |= 1 << 3;
 515                }
 516
 517                if (CPU_IS_COLDFIRE) {
 518                        __asm__ volatile ("fmovemd %%fp0-%%fp1,%0\n\t"
 519                                          "fmovel %%fpcr,%1\n\t"
 520                                          "fmovel %%fpsr,%2\n\t"
 521                                          "fmovel %%fpiar,%3"
 522                                          : "=m" (sc->sc_fpregs[0]),
 523                                            "=m" (sc->sc_fpcntl[0]),
 524                                            "=m" (sc->sc_fpcntl[1]),
 525                                            "=m" (sc->sc_fpcntl[2])
 526                                          : /* no inputs */
 527                                          : "memory");
 528                } else {
 529                        __asm__ volatile (".chip 68k/68881\n\t"
 530                                          "fmovemx %%fp0-%%fp1,%0\n\t"
 531                                          "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
 532                                          ".chip 68k"
 533                                          : "=m" (*sc->sc_fpregs),
 534                                            "=m" (*sc->sc_fpcntl)
 535                                          : /* no inputs */
 536                                          : "memory");
 537                }
 538        }
 539}
 540
 541static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)
 542{
 543        unsigned char fpstate[FPCONTEXT_SIZE];
 544        int context_size = CPU_IS_060 ? 8 : (CPU_IS_COLDFIRE ? 12 : 0);
 545        int err = 0;
 546
 547        if (FPU_IS_EMU) {
 548                /* save fpu control register */
 549                err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpcntl,
 550                                current->thread.fpcntl, 12);
 551                /* save all other fpu register */
 552                err |= copy_to_user(uc->uc_mcontext.fpregs.f_fpregs,
 553                                current->thread.fp, 96);
 554                return err;
 555        }
 556
 557        if (CPU_IS_COLDFIRE) {
 558                __asm__ volatile ("fsave %0" : : "m" (*fpstate) : "memory");
 559        } else {
 560                __asm__ volatile (".chip 68k/68881\n\t"
 561                                  "fsave %0\n\t"
 562                                  ".chip 68k"
 563                                  : : "m" (*fpstate) : "memory");
 564        }
 565
 566        err |= __put_user(*(long *)fpstate, (long __user *)&uc->uc_fpstate);
 567        if (CPU_IS_060 ? fpstate[2] : fpstate[0]) {
 568                fpregset_t fpregs;
 569                if (!(CPU_IS_060 || CPU_IS_COLDFIRE))
 570                        context_size = fpstate[1];
 571                fpu_version = fpstate[0];
 572                if (CPU_IS_020_OR_030 &&
 573                    regs->vector >= (VEC_FPBRUC * 4) &&
 574                    regs->vector <= (VEC_FPNAN * 4)) {
 575                        /* Clear pending exception in 68882 idle frame */
 576                        if (*(unsigned short *) fpstate == 0x1f38)
 577                                fpstate[0x38] |= 1 << 3;
 578                }
 579                if (CPU_IS_COLDFIRE) {
 580                        __asm__ volatile ("fmovemd %%fp0-%%fp7,%0\n\t"
 581                                          "fmovel %%fpcr,%1\n\t"
 582                                          "fmovel %%fpsr,%2\n\t"
 583                                          "fmovel %%fpiar,%3"
 584                                          : "=m" (fpregs.f_fpregs[0]),
 585                                            "=m" (fpregs.f_fpcntl[0]),
 586                                            "=m" (fpregs.f_fpcntl[1]),
 587                                            "=m" (fpregs.f_fpcntl[2])
 588                                          : /* no inputs */
 589                                          : "memory");
 590                } else {
 591                        __asm__ volatile (".chip 68k/68881\n\t"
 592                                          "fmovemx %%fp0-%%fp7,%0\n\t"
 593                                          "fmoveml %%fpcr/%%fpsr/%%fpiar,%1\n\t"
 594                                          ".chip 68k"
 595                                          : "=m" (*fpregs.f_fpregs),
 596                                            "=m" (*fpregs.f_fpcntl)
 597                                          : /* no inputs */
 598                                          : "memory");
 599                }
 600                err |= copy_to_user(&uc->uc_mcontext.fpregs, &fpregs,
 601                                    sizeof(fpregs));
 602        }
 603        if (context_size)
 604                err |= copy_to_user((long __user *)&uc->uc_fpstate + 1, fpstate + 4,
 605                                    context_size);
 606        return err;
 607}
 608
 609#else /* CONFIG_FPU */
 610
 611/*
 612 * For the case with no FPU configured these all do nothing.
 613 */
 614static inline int restore_fpu_state(struct sigcontext *sc)
 615{
 616        return 0;
 617}
 618
 619static inline int rt_restore_fpu_state(struct ucontext __user *uc)
 620{
 621        return 0;
 622}
 623
 624static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
 625{
 626}
 627
 628static inline int rt_save_fpu_state(struct ucontext __user *uc, struct pt_regs *regs)
 629{
 630        return 0;
 631}
 632
 633#endif /* CONFIG_FPU */
 634
 635static int mangle_kernel_stack(struct pt_regs *regs, int formatvec,
 636                               void __user *fp)
 637{
 638        int fsize = frame_extra_sizes(formatvec >> 12);
 639        if (fsize < 0) {
 640                /*
 641                 * user process trying to return with weird frame format
 642                 */
 643#ifdef DEBUG
 644                printk("user process returning with weird frame format\n");
 645#endif
 646                return 1;
 647        }
 648        if (!fsize) {
 649                regs->format = formatvec >> 12;
 650                regs->vector = formatvec & 0xfff;
 651        } else {
 652                struct switch_stack *sw = (struct switch_stack *)regs - 1;
 653                unsigned long buf[fsize / 2]; /* yes, twice as much */
 654
 655                /* that'll make sure that expansion won't crap over data */
 656                if (copy_from_user(buf + fsize / 4, fp, fsize))
 657                        return 1;
 658
 659                /* point of no return */
 660                regs->format = formatvec >> 12;
 661                regs->vector = formatvec & 0xfff;
 662#define frame_offset (sizeof(struct pt_regs)+sizeof(struct switch_stack))
 663                __asm__ __volatile__ (
 664#ifdef CONFIG_COLDFIRE
 665                         "   movel %0,%/sp\n\t"
 666                         "   bra ret_from_signal\n"
 667#else
 668                         "   movel %0,%/a0\n\t"
 669                         "   subl %1,%/a0\n\t"     /* make room on stack */
 670                         "   movel %/a0,%/sp\n\t"  /* set stack pointer */
 671                         /* move switch_stack and pt_regs */
 672                         "1: movel %0@+,%/a0@+\n\t"
 673                         "   dbra %2,1b\n\t"
 674                         "   lea %/sp@(%c3),%/a0\n\t" /* add offset of fmt */
 675                         "   lsrl  #2,%1\n\t"
 676                         "   subql #1,%1\n\t"
 677                         /* copy to the gap we'd made */
 678                         "2: movel %4@+,%/a0@+\n\t"
 679                         "   dbra %1,2b\n\t"
 680                         "   bral ret_from_signal\n"
 681#endif
 682                         : /* no outputs, it doesn't ever return */
 683                         : "a" (sw), "d" (fsize), "d" (frame_offset/4-1),
 684                           "n" (frame_offset), "a" (buf + fsize/4)
 685                         : "a0");
 686#undef frame_offset
 687        }
 688        return 0;
 689}
 690
 691static inline int
 692restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __user *fp)
 693{
 694        int formatvec;
 695        struct sigcontext context;
 696        int err = 0;
 697
 698        /* Always make any pending restarted system calls return -EINTR */
 699        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 700
 701        /* get previous context */
 702        if (copy_from_user(&context, usc, sizeof(context)))
 703                goto badframe;
 704
 705        /* restore passed registers */
 706        regs->d0 = context.sc_d0;
 707        regs->d1 = context.sc_d1;
 708        regs->a0 = context.sc_a0;
 709        regs->a1 = context.sc_a1;
 710        regs->sr = (regs->sr & 0xff00) | (context.sc_sr & 0xff);
 711        regs->pc = context.sc_pc;
 712        regs->orig_d0 = -1;             /* disable syscall checks */
 713        wrusp(context.sc_usp);
 714        formatvec = context.sc_formatvec;
 715
 716        err = restore_fpu_state(&context);
 717
 718        if (err || mangle_kernel_stack(regs, formatvec, fp))
 719                goto badframe;
 720
 721        return 0;
 722
 723badframe:
 724        return 1;
 725}
 726
 727static inline int
 728rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
 729                    struct ucontext __user *uc)
 730{
 731        int temp;
 732        greg_t __user *gregs = uc->uc_mcontext.gregs;
 733        unsigned long usp;
 734        int err;
 735
 736        /* Always make any pending restarted system calls return -EINTR */
 737        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 738
 739        err = __get_user(temp, &uc->uc_mcontext.version);
 740        if (temp != MCONTEXT_VERSION)
 741                goto badframe;
 742        /* restore passed registers */
 743        err |= __get_user(regs->d0, &gregs[0]);
 744        err |= __get_user(regs->d1, &gregs[1]);
 745        err |= __get_user(regs->d2, &gregs[2]);
 746        err |= __get_user(regs->d3, &gregs[3]);
 747        err |= __get_user(regs->d4, &gregs[4]);
 748        err |= __get_user(regs->d5, &gregs[5]);
 749        err |= __get_user(sw->d6, &gregs[6]);
 750        err |= __get_user(sw->d7, &gregs[7]);
 751        err |= __get_user(regs->a0, &gregs[8]);
 752        err |= __get_user(regs->a1, &gregs[9]);
 753        err |= __get_user(regs->a2, &gregs[10]);
 754        err |= __get_user(sw->a3, &gregs[11]);
 755        err |= __get_user(sw->a4, &gregs[12]);
 756        err |= __get_user(sw->a5, &gregs[13]);
 757        err |= __get_user(sw->a6, &gregs[14]);
 758        err |= __get_user(usp, &gregs[15]);
 759        wrusp(usp);
 760        err |= __get_user(regs->pc, &gregs[16]);
 761        err |= __get_user(temp, &gregs[17]);
 762        regs->sr = (regs->sr & 0xff00) | (temp & 0xff);
 763        regs->orig_d0 = -1;             /* disable syscall checks */
 764        err |= __get_user(temp, &uc->uc_formatvec);
 765
 766        err |= rt_restore_fpu_state(uc);
 767
 768        if (err || do_sigaltstack(&uc->uc_stack, NULL, usp) == -EFAULT)
 769                goto badframe;
 770
 771        if (mangle_kernel_stack(regs, temp, &uc->uc_extra))
 772                goto badframe;
 773
 774        return 0;
 775
 776badframe:
 777        return 1;
 778}
 779
 780asmlinkage int do_sigreturn(unsigned long __unused)
 781{
 782        struct switch_stack *sw = (struct switch_stack *) &__unused;
 783        struct pt_regs *regs = (struct pt_regs *) (sw + 1);
 784        unsigned long usp = rdusp();
 785        struct sigframe __user *frame = (struct sigframe __user *)(usp - 4);
 786        sigset_t set;
 787
 788        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 789                goto badframe;
 790        if (__get_user(set.sig[0], &frame->sc.sc_mask) ||
 791            (_NSIG_WORDS > 1 &&
 792             __copy_from_user(&set.sig[1], &frame->extramask,
 793                              sizeof(frame->extramask))))
 794                goto badframe;
 795
 796        set_current_blocked(&set);
 797
 798        if (restore_sigcontext(regs, &frame->sc, frame + 1))
 799                goto badframe;
 800        return regs->d0;
 801
 802badframe:
 803        force_sig(SIGSEGV, current);
 804        return 0;
 805}
 806
 807asmlinkage int do_rt_sigreturn(unsigned long __unused)
 808{
 809        struct switch_stack *sw = (struct switch_stack *) &__unused;
 810        struct pt_regs *regs = (struct pt_regs *) (sw + 1);
 811        unsigned long usp = rdusp();
 812        struct rt_sigframe __user *frame = (struct rt_sigframe __user *)(usp - 4);
 813        sigset_t set;
 814
 815        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 816                goto badframe;
 817        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
 818                goto badframe;
 819
 820        set_current_blocked(&set);
 821
 822        if (rt_restore_ucontext(regs, sw, &frame->uc))
 823                goto badframe;
 824        return regs->d0;
 825
 826badframe:
 827        force_sig(SIGSEGV, current);
 828        return 0;
 829}
 830
 831static void setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs,
 832                             unsigned long mask)
 833{
 834        sc->sc_mask = mask;
 835        sc->sc_usp = rdusp();
 836        sc->sc_d0 = regs->d0;
 837        sc->sc_d1 = regs->d1;
 838        sc->sc_a0 = regs->a0;
 839        sc->sc_a1 = regs->a1;
 840        sc->sc_sr = regs->sr;
 841        sc->sc_pc = regs->pc;
 842        sc->sc_formatvec = regs->format << 12 | regs->vector;
 843        save_a5_state(sc, regs);
 844        save_fpu_state(sc, regs);
 845}
 846
 847static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)
 848{
 849        struct switch_stack *sw = (struct switch_stack *)regs - 1;
 850        greg_t __user *gregs = uc->uc_mcontext.gregs;
 851        int err = 0;
 852
 853        err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
 854        err |= __put_user(regs->d0, &gregs[0]);
 855        err |= __put_user(regs->d1, &gregs[1]);
 856        err |= __put_user(regs->d2, &gregs[2]);
 857        err |= __put_user(regs->d3, &gregs[3]);
 858        err |= __put_user(regs->d4, &gregs[4]);
 859        err |= __put_user(regs->d5, &gregs[5]);
 860        err |= __put_user(sw->d6, &gregs[6]);
 861        err |= __put_user(sw->d7, &gregs[7]);
 862        err |= __put_user(regs->a0, &gregs[8]);
 863        err |= __put_user(regs->a1, &gregs[9]);
 864        err |= __put_user(regs->a2, &gregs[10]);
 865        err |= __put_user(sw->a3, &gregs[11]);
 866        err |= __put_user(sw->a4, &gregs[12]);
 867        err |= __put_user(sw->a5, &gregs[13]);
 868        err |= __put_user(sw->a6, &gregs[14]);
 869        err |= __put_user(rdusp(), &gregs[15]);
 870        err |= __put_user(regs->pc, &gregs[16]);
 871        err |= __put_user(regs->sr, &gregs[17]);
 872        err |= __put_user((regs->format << 12) | regs->vector, &uc->uc_formatvec);
 873        err |= rt_save_fpu_state(uc, regs);
 874        return err;
 875}
 876
 877static inline void __user *
 878get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
 879{
 880        unsigned long usp;
 881
 882        /* Default to using normal stack.  */
 883        usp = rdusp();
 884
 885        /* This is the X/Open sanctioned signal stack switching.  */
 886        if (ka->sa.sa_flags & SA_ONSTACK) {
 887                if (!sas_ss_flags(usp))
 888                        usp = current->sas_ss_sp + current->sas_ss_size;
 889        }
 890        return (void __user *)((usp - frame_size) & -8UL);
 891}
 892
 893static int setup_frame (int sig, struct k_sigaction *ka,
 894                         sigset_t *set, struct pt_regs *regs)
 895{
 896        struct sigframe __user *frame;
 897        int fsize = frame_extra_sizes(regs->format);
 898        struct sigcontext context;
 899        int err = 0;
 900
 901        if (fsize < 0) {
 902#ifdef DEBUG
 903                printk ("setup_frame: Unknown frame format %#x\n",
 904                        regs->format);
 905#endif
 906                goto give_sigsegv;
 907        }
 908
 909        frame = get_sigframe(ka, regs, sizeof(*frame) + fsize);
 910
 911        if (fsize)
 912                err |= copy_to_user (frame + 1, regs + 1, fsize);
 913
 914        err |= __put_user((current_thread_info()->exec_domain
 915                           && current_thread_info()->exec_domain->signal_invmap
 916                           && sig < 32
 917                           ? current_thread_info()->exec_domain->signal_invmap[sig]
 918                           : sig),
 919                          &frame->sig);
 920
 921        err |= __put_user(regs->vector, &frame->code);
 922        err |= __put_user(&frame->sc, &frame->psc);
 923
 924        if (_NSIG_WORDS > 1)
 925                err |= copy_to_user(frame->extramask, &set->sig[1],
 926                                    sizeof(frame->extramask));
 927
 928        setup_sigcontext(&context, regs, set->sig[0]);
 929        err |= copy_to_user (&frame->sc, &context, sizeof(context));
 930
 931        /* Set up to return from userspace.  */
 932#ifdef CONFIG_MMU
 933        err |= __put_user(frame->retcode, &frame->pretcode);
 934        /* moveq #,d0; trap #0 */
 935        err |= __put_user(0x70004e40 + (__NR_sigreturn << 16),
 936                          (long __user *)(frame->retcode));
 937#else
 938        err |= __put_user((void *) ret_from_user_signal, &frame->pretcode);
 939#endif
 940
 941        if (err)
 942                goto give_sigsegv;
 943
 944        push_cache ((unsigned long) &frame->retcode);
 945
 946        /*
 947         * Set up registers for signal handler.  All the state we are about
 948         * to destroy is successfully copied to sigframe.
 949         */
 950        wrusp ((unsigned long) frame);
 951        regs->pc = (unsigned long) ka->sa.sa_handler;
 952        adjustformat(regs);
 953
 954        /*
 955         * This is subtle; if we build more than one sigframe, all but the
 956         * first one will see frame format 0 and have fsize == 0, so we won't
 957         * screw stkadj.
 958         */
 959        if (fsize)
 960                regs->stkadj = fsize;
 961
 962        /* Prepare to skip over the extra stuff in the exception frame.  */
 963        if (regs->stkadj) {
 964                struct pt_regs *tregs =
 965                        (struct pt_regs *)((ulong)regs + regs->stkadj);
 966#ifdef DEBUG
 967                printk("Performing stackadjust=%04x\n", regs->stkadj);
 968#endif
 969                /* This must be copied with decreasing addresses to
 970                   handle overlaps.  */
 971                tregs->vector = 0;
 972                tregs->format = 0;
 973                tregs->pc = regs->pc;
 974                tregs->sr = regs->sr;
 975        }
 976        return 0;
 977
 978give_sigsegv:
 979        force_sigsegv(sig, current);
 980        return err;
 981}
 982
 983static int setup_rt_frame (int sig, struct k_sigaction *ka, siginfo_t *info,
 984                            sigset_t *set, struct pt_regs *regs)
 985{
 986        struct rt_sigframe __user *frame;
 987        int fsize = frame_extra_sizes(regs->format);
 988        int err = 0;
 989
 990        if (fsize < 0) {
 991#ifdef DEBUG
 992                printk ("setup_frame: Unknown frame format %#x\n",
 993                        regs->format);
 994#endif
 995                goto give_sigsegv;
 996        }
 997
 998        frame = get_sigframe(ka, regs, sizeof(*frame));
 999
1000        if (fsize)
1001                err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
1002
1003        err |= __put_user((current_thread_info()->exec_domain
1004                           && current_thread_info()->exec_domain->signal_invmap
1005                           && sig < 32
1006                           ? current_thread_info()->exec_domain->signal_invmap[sig]
1007                           : sig),
1008                          &frame->sig);
1009        err |= __put_user(&frame->info, &frame->pinfo);
1010        err |= __put_user(&frame->uc, &frame->puc);
1011        err |= copy_siginfo_to_user(&frame->info, info);
1012
1013        /* Create the ucontext.  */
1014        err |= __put_user(0, &frame->uc.uc_flags);
1015        err |= __put_user(NULL, &frame->uc.uc_link);
1016        err |= __put_user((void __user *)current->sas_ss_sp,
1017                          &frame->uc.uc_stack.ss_sp);
1018        err |= __put_user(sas_ss_flags(rdusp()),
1019                          &frame->uc.uc_stack.ss_flags);
1020        err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
1021        err |= rt_setup_ucontext(&frame->uc, regs);
1022        err |= copy_to_user (&frame->uc.uc_sigmask, set, sizeof(*set));
1023
1024        /* Set up to return from userspace.  */
1025#ifdef CONFIG_MMU
1026        err |= __put_user(frame->retcode, &frame->pretcode);
1027#ifdef __mcoldfire__
1028        /* movel #__NR_rt_sigreturn,d0; trap #0 */
1029        err |= __put_user(0x203c0000, (long __user *)(frame->retcode + 0));
1030        err |= __put_user(0x00004e40 + (__NR_rt_sigreturn << 16),
1031                          (long __user *)(frame->retcode + 4));
1032#else
1033        /* moveq #,d0; notb d0; trap #0 */
1034        err |= __put_user(0x70004600 + ((__NR_rt_sigreturn ^ 0xff) << 16),
1035                          (long __user *)(frame->retcode + 0));
1036        err |= __put_user(0x4e40, (short __user *)(frame->retcode + 4));
1037#endif
1038#else
1039        err |= __put_user((void *) ret_from_user_rt_signal, &frame->pretcode);
1040#endif /* CONFIG_MMU */
1041
1042        if (err)
1043                goto give_sigsegv;
1044
1045        push_cache ((unsigned long) &frame->retcode);
1046
1047        /*
1048         * Set up registers for signal handler.  All the state we are about
1049         * to destroy is successfully copied to sigframe.
1050         */
1051        wrusp ((unsigned long) frame);
1052        regs->pc = (unsigned long) ka->sa.sa_handler;
1053        adjustformat(regs);
1054
1055        /*
1056         * This is subtle; if we build more than one sigframe, all but the
1057         * first one will see frame format 0 and have fsize == 0, so we won't
1058         * screw stkadj.
1059         */
1060        if (fsize)
1061                regs->stkadj = fsize;
1062
1063        /* Prepare to skip over the extra stuff in the exception frame.  */
1064        if (regs->stkadj) {
1065                struct pt_regs *tregs =
1066                        (struct pt_regs *)((ulong)regs + regs->stkadj);
1067#ifdef DEBUG
1068                printk("Performing stackadjust=%04x\n", regs->stkadj);
1069#endif
1070                /* This must be copied with decreasing addresses to
1071                   handle overlaps.  */
1072                tregs->vector = 0;
1073                tregs->format = 0;
1074                tregs->pc = regs->pc;
1075                tregs->sr = regs->sr;
1076        }
1077        return 0;
1078
1079give_sigsegv:
1080        force_sigsegv(sig, current);
1081        return err;
1082}
1083
1084static inline void
1085handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
1086{
1087        switch (regs->d0) {
1088        case -ERESTARTNOHAND:
1089                if (!has_handler)
1090                        goto do_restart;
1091                regs->d0 = -EINTR;
1092                break;
1093
1094        case -ERESTART_RESTARTBLOCK:
1095                if (!has_handler) {
1096                        regs->d0 = __NR_restart_syscall;
1097                        regs->pc -= 2;
1098                        break;
1099                }
1100                regs->d0 = -EINTR;
1101                break;
1102
1103        case -ERESTARTSYS:
1104                if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
1105                        regs->d0 = -EINTR;
1106                        break;
1107                }
1108        /* fallthrough */
1109        case -ERESTARTNOINTR:
1110        do_restart:
1111                regs->d0 = regs->orig_d0;
1112                regs->pc -= 2;
1113                break;
1114        }
1115}
1116
1117/*
1118 * OK, we're invoking a handler
1119 */
1120static void
1121handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info,
1122              struct pt_regs *regs)
1123{
1124        sigset_t *oldset = sigmask_to_save();
1125        int err;
1126        /* are we from a system call? */
1127        if (regs->orig_d0 >= 0)
1128                /* If so, check system call restarting.. */
1129                handle_restart(regs, ka, 1);
1130
1131        /* set up the stack frame */
1132        if (ka->sa.sa_flags & SA_SIGINFO)
1133                err = setup_rt_frame(sig, ka, info, oldset, regs);
1134        else
1135                err = setup_frame(sig, ka, oldset, regs);
1136
1137        if (err)
1138                return;
1139
1140        signal_delivered(sig, info, ka, regs, 0);
1141
1142        if (test_thread_flag(TIF_DELAYED_TRACE)) {
1143                regs->sr &= ~0x8000;
1144                send_sig(SIGTRAP, current, 1);
1145        }
1146}
1147
1148/*
1149 * Note that 'init' is a special process: it doesn't get signals it doesn't
1150 * want to handle. Thus you cannot kill init even with a SIGKILL even by
1151 * mistake.
1152 */
1153static void do_signal(struct pt_regs *regs)
1154{
1155        siginfo_t info;
1156        struct k_sigaction ka;
1157        int signr;
1158
1159        current->thread.esp0 = (unsigned long) regs;
1160
1161        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
1162        if (signr > 0) {
1163                /* Whee!  Actually deliver the signal.  */
1164                handle_signal(signr, &ka, &info, regs);
1165                return;
1166        }
1167
1168        /* Did we come from a system call? */
1169        if (regs->orig_d0 >= 0)
1170                /* Restart the system call - no handlers present */
1171                handle_restart(regs, NULL, 0);
1172
1173        /* If there's no signal to deliver, we just restore the saved mask.  */
1174        restore_saved_sigmask();
1175}
1176
1177void do_notify_resume(struct pt_regs *regs)
1178{
1179        if (test_thread_flag(TIF_SIGPENDING))
1180                do_signal(regs);
1181
1182        if (test_and_clear_thread_flag(TIF_NOTIFY_RESUME))
1183                tracehook_notify_resume(regs);
1184}
1185