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