root/arch/m68k/kernel/signal.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. frame_extra_sizes
  2. fixup_exception
  3. push_cache
  4. adjustformat
  5. save_a5_state
  6. frame_extra_sizes
  7. adjustformat
  8. save_a5_state
  9. push_cache
  10. restore_fpu_state
  11. rt_restore_fpu_state
  12. save_fpu_state
  13. rt_save_fpu_state
  14. restore_fpu_state
  15. rt_restore_fpu_state
  16. save_fpu_state
  17. rt_save_fpu_state
  18. siginfo_build_tests
  19. mangle_kernel_stack
  20. restore_sigcontext
  21. rt_restore_ucontext
  22. do_sigreturn
  23. do_rt_sigreturn
  24. setup_sigcontext
  25. rt_setup_ucontext
  26. get_sigframe
  27. setup_frame
  28. setup_rt_frame
  29. handle_restart
  30. handle_signal
  31. do_signal
  32. do_notify_resume

   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 
  68 static 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 
  86 static inline int frame_extra_sizes(int f)
  87 {
  88         return frame_size_change[f];
  89 }
  90 
  91 int 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 
 112 static 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 
 179 static inline void adjustformat(struct pt_regs *regs)
 180 {
 181 }
 182 
 183 static inline void save_a5_state(struct sigcontext *sc, struct pt_regs *regs)
 184 {
 185 }
 186 
 187 #else /* CONFIG_MMU */
 188 
 189 void ret_from_user_signal(void);
 190 void ret_from_user_rt_signal(void);
 191 
 192 static inline int frame_extra_sizes(int f)
 193 {
 194         /* No frame size adjustments required on non-MMU CPUs */
 195         return 0;
 196 }
 197 
 198 static 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 
 207 static 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 
 212 static 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 
 225 struct 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 
 236 struct 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 
 254 static unsigned char fpu_version;       /* version number of fpu, set by setup_frame */
 255 
 256 static 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 
 328 out:
 329         return err;
 330 }
 331 
 332 static 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 
 423 out:
 424         return err;
 425 }
 426 
 427 /*
 428  * Set up a signal frame.
 429  */
 430 static 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 
 483 static 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  */
 556 static inline int restore_fpu_state(struct sigcontext *sc)
 557 {
 558         return 0;
 559 }
 560 
 561 static inline int rt_restore_fpu_state(struct ucontext __user *uc)
 562 {
 563         return 0;
 564 }
 565 
 566 static inline void save_fpu_state(struct sigcontext *sc, struct pt_regs *regs)
 567 {
 568 }
 569 
 570 static 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 
 577 static 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 
 638 static 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 
 693 static inline int
 694 restore_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 
 727 badframe:
 728         return 1;
 729 }
 730 
 731 static inline int
 732 rt_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 
 781 badframe:
 782         return 1;
 783 }
 784 
 785 asmlinkage 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 
 805 badframe:
 806         force_sig(SIGSEGV);
 807         return 0;
 808 }
 809 
 810 asmlinkage 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 
 827 badframe:
 828         force_sig(SIGSEGV);
 829         return 0;
 830 }
 831 
 832 static 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 
 848 static 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 
 878 static inline void __user *
 879 get_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 
 886 static 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 
 963 static 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 
1047 static inline void
1048 handle_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  */
1083 static void
1084 handle_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  */
1112 static 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 
1133 void 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 }

/* [<][>][^][v][top][bottom][index][help] */