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