linux/arch/sh/kernel/signal_64.c
<<
>>
Prefs
   1/*
   2 * arch/sh/kernel/signal_64.c
   3 *
   4 * Copyright (C) 2000, 2001  Paolo Alberelli
   5 * Copyright (C) 2003 - 2008  Paul Mundt
   6 * Copyright (C) 2004  Richard Curnow
   7 *
   8 * This file is subject to the terms and conditions of the GNU General Public
   9 * License.  See the file "COPYING" in the main directory of this archive
  10 * for more details.
  11 */
  12#include <linux/rwsem.h>
  13#include <linux/sched.h>
  14#include <linux/mm.h>
  15#include <linux/smp.h>
  16#include <linux/kernel.h>
  17#include <linux/signal.h>
  18#include <linux/errno.h>
  19#include <linux/wait.h>
  20#include <linux/personality.h>
  21#include <linux/ptrace.h>
  22#include <linux/unistd.h>
  23#include <linux/stddef.h>
  24#include <linux/tracehook.h>
  25#include <asm/ucontext.h>
  26#include <asm/uaccess.h>
  27#include <asm/pgtable.h>
  28#include <asm/cacheflush.h>
  29#include <asm/fpu.h>
  30
  31#define REG_RET 9
  32#define REG_ARG1 2
  33#define REG_ARG2 3
  34#define REG_ARG3 4
  35#define REG_SP 15
  36#define REG_PR 18
  37#define REF_REG_RET regs->regs[REG_RET]
  38#define REF_REG_SP regs->regs[REG_SP]
  39#define DEREF_REG_PR regs->regs[REG_PR]
  40
  41#define DEBUG_SIG 0
  42
  43static void
  44handle_signal(struct ksignal *ksig, struct pt_regs *regs);
  45
  46static inline void
  47handle_syscall_restart(struct pt_regs *regs, struct sigaction *sa)
  48{
  49        /* If we're not from a syscall, bail out */
  50        if (regs->syscall_nr < 0)
  51                return;
  52
  53        /* check for system call restart.. */
  54        switch (regs->regs[REG_RET]) {
  55                case -ERESTART_RESTARTBLOCK:
  56                case -ERESTARTNOHAND:
  57                no_system_call_restart:
  58                        regs->regs[REG_RET] = -EINTR;
  59                        break;
  60
  61                case -ERESTARTSYS:
  62                        if (!(sa->sa_flags & SA_RESTART))
  63                                goto no_system_call_restart;
  64                /* fallthrough */
  65                case -ERESTARTNOINTR:
  66                        /* Decode syscall # */
  67                        regs->regs[REG_RET] = regs->syscall_nr;
  68                        regs->pc -= 4;
  69                        break;
  70        }
  71}
  72
  73/*
  74 * Note that 'init' is a special process: it doesn't get signals it doesn't
  75 * want to handle. Thus you cannot kill init even with a SIGKILL even by
  76 * mistake.
  77 *
  78 * Note that we go through the signals twice: once to check the signals that
  79 * the kernel can handle, and then we build all the user-level signal handling
  80 * stack-frames in one go after that.
  81 */
  82static void do_signal(struct pt_regs *regs)
  83{
  84        struct ksignal ksig;
  85
  86        /*
  87         * We want the common case to go fast, which
  88         * is why we may in certain cases get here from
  89         * kernel mode. Just return without doing anything
  90         * if so.
  91         */
  92        if (!user_mode(regs))
  93                return;
  94
  95        if (get_signal(&ksig)) {
  96                handle_syscall_restart(regs, &ksig.ka.sa);
  97
  98                /* Whee!  Actually deliver the signal.  */
  99                handle_signal(&ksig, regs);
 100                return;
 101        }
 102
 103        /* Did we come from a system call? */
 104        if (regs->syscall_nr >= 0) {
 105                /* Restart the system call - no handlers present */
 106                switch (regs->regs[REG_RET]) {
 107                case -ERESTARTNOHAND:
 108                case -ERESTARTSYS:
 109                case -ERESTARTNOINTR:
 110                        /* Decode Syscall # */
 111                        regs->regs[REG_RET] = regs->syscall_nr;
 112                        regs->pc -= 4;
 113                        break;
 114
 115                case -ERESTART_RESTARTBLOCK:
 116                        regs->regs[REG_RET] = __NR_restart_syscall;
 117                        regs->pc -= 4;
 118                        break;
 119                }
 120        }
 121
 122        /* No signal to deliver -- put the saved sigmask back */
 123        restore_saved_sigmask();
 124}
 125
 126/*
 127 * Do a signal return; undo the signal stack.
 128 */
 129struct sigframe {
 130        struct sigcontext sc;
 131        unsigned long extramask[_NSIG_WORDS-1];
 132        long long retcode[2];
 133};
 134
 135struct rt_sigframe {
 136        struct siginfo __user *pinfo;
 137        void *puc;
 138        struct siginfo info;
 139        struct ucontext uc;
 140        long long retcode[2];
 141};
 142
 143#ifdef CONFIG_SH_FPU
 144static inline int
 145restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
 146{
 147        int err = 0;
 148        int fpvalid;
 149
 150        err |= __get_user (fpvalid, &sc->sc_fpvalid);
 151        conditional_used_math(fpvalid);
 152        if (! fpvalid)
 153                return err;
 154
 155        if (current == last_task_used_math) {
 156                last_task_used_math = NULL;
 157                regs->sr |= SR_FD;
 158        }
 159
 160        err |= __copy_from_user(&current->thread.xstate->hardfpu, &sc->sc_fpregs[0],
 161                                (sizeof(long long) * 32) + (sizeof(int) * 1));
 162
 163        return err;
 164}
 165
 166static inline int
 167setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
 168{
 169        int err = 0;
 170        int fpvalid;
 171
 172        fpvalid = !!used_math();
 173        err |= __put_user(fpvalid, &sc->sc_fpvalid);
 174        if (! fpvalid)
 175                return err;
 176
 177        if (current == last_task_used_math) {
 178                enable_fpu();
 179                save_fpu(current);
 180                disable_fpu();
 181                last_task_used_math = NULL;
 182                regs->sr |= SR_FD;
 183        }
 184
 185        err |= __copy_to_user(&sc->sc_fpregs[0], &current->thread.xstate->hardfpu,
 186                              (sizeof(long long) * 32) + (sizeof(int) * 1));
 187        clear_used_math();
 188
 189        return err;
 190}
 191#else
 192static inline int
 193restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
 194{
 195        return 0;
 196}
 197static inline int
 198setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user *sc)
 199{
 200        return 0;
 201}
 202#endif
 203
 204static int
 205restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, long long *r2_p)
 206{
 207        unsigned int err = 0;
 208        unsigned long long current_sr, new_sr;
 209#define SR_MASK 0xffff8cfd
 210
 211#define COPY(x)         err |= __get_user(regs->x, &sc->sc_##x)
 212
 213        COPY(regs[0]);  COPY(regs[1]);  COPY(regs[2]);  COPY(regs[3]);
 214        COPY(regs[4]);  COPY(regs[5]);  COPY(regs[6]);  COPY(regs[7]);
 215        COPY(regs[8]);  COPY(regs[9]);  COPY(regs[10]); COPY(regs[11]);
 216        COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]);
 217        COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]);
 218        COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]);
 219        COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]);
 220        COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]);
 221        COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]);
 222        COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]);
 223        COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]);
 224        COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]);
 225        COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]);
 226        COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]);
 227        COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]);
 228        COPY(regs[60]); COPY(regs[61]); COPY(regs[62]);
 229        COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]);
 230        COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]);
 231
 232        /* Prevent the signal handler manipulating SR in a way that can
 233           crash the kernel. i.e. only allow S, Q, M, PR, SZ, FR to be
 234           modified */
 235        current_sr = regs->sr;
 236        err |= __get_user(new_sr, &sc->sc_sr);
 237        regs->sr &= SR_MASK;
 238        regs->sr |= (new_sr & ~SR_MASK);
 239
 240        COPY(pc);
 241
 242#undef COPY
 243
 244        /* Must do this last in case it sets regs->sr.fd (i.e. after rest of sr
 245         * has been restored above.) */
 246        err |= restore_sigcontext_fpu(regs, sc);
 247
 248        regs->syscall_nr = -1;          /* disable syscall checks */
 249        err |= __get_user(*r2_p, &sc->sc_regs[REG_RET]);
 250        return err;
 251}
 252
 253asmlinkage int sys_sigreturn(unsigned long r2, unsigned long r3,
 254                                   unsigned long r4, unsigned long r5,
 255                                   unsigned long r6, unsigned long r7,
 256                                   struct pt_regs * regs)
 257{
 258        struct sigframe __user *frame = (struct sigframe __user *) (long) REF_REG_SP;
 259        sigset_t set;
 260        long long ret;
 261
 262        /* Always make any pending restarted system calls return -EINTR */
 263        current->restart_block.fn = do_no_restart_syscall;
 264
 265        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 266                goto badframe;
 267
 268        if (__get_user(set.sig[0], &frame->sc.oldmask)
 269            || (_NSIG_WORDS > 1
 270                && __copy_from_user(&set.sig[1], &frame->extramask,
 271                                    sizeof(frame->extramask))))
 272                goto badframe;
 273
 274        set_current_blocked(&set);
 275
 276        if (restore_sigcontext(regs, &frame->sc, &ret))
 277                goto badframe;
 278        regs->pc -= 4;
 279
 280        return (int) ret;
 281
 282badframe:
 283        force_sig(SIGSEGV, current);
 284        return 0;
 285}
 286
 287asmlinkage int sys_rt_sigreturn(unsigned long r2, unsigned long r3,
 288                                unsigned long r4, unsigned long r5,
 289                                unsigned long r6, unsigned long r7,
 290                                struct pt_regs * regs)
 291{
 292        struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (long) REF_REG_SP;
 293        sigset_t set;
 294        long long ret;
 295
 296        /* Always make any pending restarted system calls return -EINTR */
 297        current->restart_block.fn = do_no_restart_syscall;
 298
 299        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 300                goto badframe;
 301
 302        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
 303                goto badframe;
 304
 305        set_current_blocked(&set);
 306
 307        if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &ret))
 308                goto badframe;
 309        regs->pc -= 4;
 310
 311        if (restore_altstack(&frame->uc.uc_stack))
 312                goto badframe;
 313
 314        return (int) ret;
 315
 316badframe:
 317        force_sig(SIGSEGV, current);
 318        return 0;
 319}
 320
 321/*
 322 * Set up a signal frame.
 323 */
 324static int
 325setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
 326                 unsigned long mask)
 327{
 328        int err = 0;
 329
 330        /* Do this first, otherwise is this sets sr->fd, that value isn't preserved. */
 331        err |= setup_sigcontext_fpu(regs, sc);
 332
 333#define COPY(x)         err |= __put_user(regs->x, &sc->sc_##x)
 334
 335        COPY(regs[0]);  COPY(regs[1]);  COPY(regs[2]);  COPY(regs[3]);
 336        COPY(regs[4]);  COPY(regs[5]);  COPY(regs[6]);  COPY(regs[7]);
 337        COPY(regs[8]);  COPY(regs[9]);  COPY(regs[10]); COPY(regs[11]);
 338        COPY(regs[12]); COPY(regs[13]); COPY(regs[14]); COPY(regs[15]);
 339        COPY(regs[16]); COPY(regs[17]); COPY(regs[18]); COPY(regs[19]);
 340        COPY(regs[20]); COPY(regs[21]); COPY(regs[22]); COPY(regs[23]);
 341        COPY(regs[24]); COPY(regs[25]); COPY(regs[26]); COPY(regs[27]);
 342        COPY(regs[28]); COPY(regs[29]); COPY(regs[30]); COPY(regs[31]);
 343        COPY(regs[32]); COPY(regs[33]); COPY(regs[34]); COPY(regs[35]);
 344        COPY(regs[36]); COPY(regs[37]); COPY(regs[38]); COPY(regs[39]);
 345        COPY(regs[40]); COPY(regs[41]); COPY(regs[42]); COPY(regs[43]);
 346        COPY(regs[44]); COPY(regs[45]); COPY(regs[46]); COPY(regs[47]);
 347        COPY(regs[48]); COPY(regs[49]); COPY(regs[50]); COPY(regs[51]);
 348        COPY(regs[52]); COPY(regs[53]); COPY(regs[54]); COPY(regs[55]);
 349        COPY(regs[56]); COPY(regs[57]); COPY(regs[58]); COPY(regs[59]);
 350        COPY(regs[60]); COPY(regs[61]); COPY(regs[62]);
 351        COPY(tregs[0]); COPY(tregs[1]); COPY(tregs[2]); COPY(tregs[3]);
 352        COPY(tregs[4]); COPY(tregs[5]); COPY(tregs[6]); COPY(tregs[7]);
 353        COPY(sr);       COPY(pc);
 354
 355#undef COPY
 356
 357        err |= __put_user(mask, &sc->oldmask);
 358
 359        return err;
 360}
 361
 362/*
 363 * Determine which stack to use..
 364 */
 365static inline void __user *
 366get_sigframe(struct k_sigaction *ka, unsigned long sp, size_t frame_size)
 367{
 368        if ((ka->sa.sa_flags & SA_ONSTACK) != 0 && ! sas_ss_flags(sp))
 369                sp = current->sas_ss_sp + current->sas_ss_size;
 370
 371        return (void __user *)((sp - frame_size) & -8ul);
 372}
 373
 374void sa_default_restorer(void);         /* See comments below */
 375void sa_default_rt_restorer(void);      /* See comments below */
 376
 377static int setup_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
 378{
 379        struct sigframe __user *frame;
 380        int err = 0, sig = ksig->sig;
 381        int signal;
 382
 383        frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
 384
 385        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 386                return -EFAULT;
 387
 388        err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
 389
 390        /* Give up earlier as i386, in case */
 391        if (err)
 392                return -EFAULT;
 393
 394        if (_NSIG_WORDS > 1) {
 395                err |= __copy_to_user(frame->extramask, &set->sig[1],
 396                                      sizeof(frame->extramask)); }
 397
 398        /* Give up earlier as i386, in case */
 399        if (err)
 400                return -EFAULT;
 401
 402        /* Set up to return from userspace.  If provided, use a stub
 403           already in userspace.  */
 404        if (ksig->ka.sa.sa_flags & SA_RESTORER) {
 405                /*
 406                 * On SH5 all edited pointers are subject to NEFF
 407                 */
 408                DEREF_REG_PR = neff_sign_extend((unsigned long)
 409                        ksig->ka->sa.sa_restorer | 0x1);
 410        } else {
 411                /*
 412                 * Different approach on SH5.
 413                 * . Endianness independent asm code gets placed in entry.S .
 414                 *   This is limited to four ASM instructions corresponding
 415                 *   to two long longs in size.
 416                 * . err checking is done on the else branch only
 417                 * . flush_icache_range() is called upon __put_user() only
 418                 * . all edited pointers are subject to NEFF
 419                 * . being code, linker turns ShMedia bit on, always
 420                 *   dereference index -1.
 421                 */
 422                DEREF_REG_PR = neff_sign_extend((unsigned long)
 423                        frame->retcode | 0x01);
 424
 425                if (__copy_to_user(frame->retcode,
 426                        (void *)((unsigned long)sa_default_restorer & (~1)), 16) != 0)
 427                        return -EFAULT;
 428
 429                /* Cohere the trampoline with the I-cache. */
 430                flush_cache_sigtramp(DEREF_REG_PR-1);
 431        }
 432
 433        /*
 434         * Set up registers for signal handler.
 435         * All edited pointers are subject to NEFF.
 436         */
 437        regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
 438        regs->regs[REG_ARG1] = sig; /* Arg for signal handler */
 439
 440        /* FIXME:
 441           The glibc profiling support for SH-5 needs to be passed a sigcontext
 442           so it can retrieve the PC.  At some point during 2003 the glibc
 443           support was changed to receive the sigcontext through the 2nd
 444           argument, but there are still versions of libc.so in use that use
 445           the 3rd argument.  Until libc.so is stabilised, pass the sigcontext
 446           through both 2nd and 3rd arguments.
 447        */
 448
 449        regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
 450        regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->sc;
 451
 452        regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
 453
 454        /* Broken %016Lx */
 455        pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
 456                 sig, current->comm, current->pid, frame,
 457                 regs->pc >> 32, regs->pc & 0xffffffff,
 458                 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
 459
 460        return 0;
 461}
 462
 463static int setup_rt_frame(struct ksignal *kig, sigset_t *set,
 464                          struct pt_regs *regs)
 465{
 466        struct rt_sigframe __user *frame;
 467        int err = 0, sig = ksig->sig;
 468
 469        frame = get_sigframe(&ksig->ka, regs->regs[REG_SP], sizeof(*frame));
 470
 471        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 472                return -EFAULT;
 473
 474        err |= __put_user(&frame->info, &frame->pinfo);
 475        err |= __put_user(&frame->uc, &frame->puc);
 476        err |= copy_siginfo_to_user(&frame->info, &ksig->info);
 477
 478        /* Give up earlier as i386, in case */
 479        if (err)
 480                return -EFAULT;
 481
 482        /* Create the ucontext.  */
 483        err |= __put_user(0, &frame->uc.uc_flags);
 484        err |= __put_user(0, &frame->uc.uc_link);
 485        err |= __save_altstack(&frame->uc.uc_stack, regs->regs[REG_SP]);
 486        err |= setup_sigcontext(&frame->uc.uc_mcontext,
 487                                regs, set->sig[0]);
 488        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 489
 490        /* Give up earlier as i386, in case */
 491        if (err)
 492                return -EFAULT;
 493
 494        /* Set up to return from userspace.  If provided, use a stub
 495           already in userspace.  */
 496        if (ksig->ka.sa.sa_flags & SA_RESTORER) {
 497                /*
 498                 * On SH5 all edited pointers are subject to NEFF
 499                 */
 500                DEREF_REG_PR = neff_sign_extend((unsigned long)
 501                        ksig->ka.sa.sa_restorer | 0x1);
 502        } else {
 503                /*
 504                 * Different approach on SH5.
 505                 * . Endianness independent asm code gets placed in entry.S .
 506                 *   This is limited to four ASM instructions corresponding
 507                 *   to two long longs in size.
 508                 * . err checking is done on the else branch only
 509                 * . flush_icache_range() is called upon __put_user() only
 510                 * . all edited pointers are subject to NEFF
 511                 * . being code, linker turns ShMedia bit on, always
 512                 *   dereference index -1.
 513                 */
 514                DEREF_REG_PR = neff_sign_extend((unsigned long)
 515                        frame->retcode | 0x01);
 516
 517                if (__copy_to_user(frame->retcode,
 518                        (void *)((unsigned long)sa_default_rt_restorer & (~1)), 16) != 0)
 519                        return -EFAULT;
 520
 521                /* Cohere the trampoline with the I-cache. */
 522                flush_icache_range(DEREF_REG_PR-1, DEREF_REG_PR-1+15);
 523        }
 524
 525        /*
 526         * Set up registers for signal handler.
 527         * All edited pointers are subject to NEFF.
 528         */
 529        regs->regs[REG_SP] = neff_sign_extend((unsigned long)frame);
 530        regs->regs[REG_ARG1] = sig; /* Arg for signal handler */
 531        regs->regs[REG_ARG2] = (unsigned long long)(unsigned long)(signed long)&frame->info;
 532        regs->regs[REG_ARG3] = (unsigned long long)(unsigned long)(signed long)&frame->uc.uc_mcontext;
 533        regs->pc = neff_sign_extend((unsigned long)ksig->ka.sa.sa_handler);
 534
 535        pr_debug("SIG deliver (#%d,%s:%d): sp=%p pc=%08Lx%08Lx link=%08Lx%08Lx\n",
 536                 sig, current->comm, current->pid, frame,
 537                 regs->pc >> 32, regs->pc & 0xffffffff,
 538                 DEREF_REG_PR >> 32, DEREF_REG_PR & 0xffffffff);
 539
 540        return 0;
 541}
 542
 543/*
 544 * OK, we're invoking a handler
 545 */
 546static void
 547handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 548{
 549        sigset_t *oldset = sigmask_to_save();
 550        int ret;
 551
 552        /* Set up the stack frame */
 553        if (ksig->ka.sa.sa_flags & SA_SIGINFO)
 554                ret = setup_rt_frame(ksig, oldset, regs);
 555        else
 556                ret = setup_frame(ksig, oldset, regs);
 557
 558        signal_setup_done(ret, ksig, test_thread_flag(TIF_SINGLESTEP));
 559}
 560
 561asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
 562{
 563        if (thread_info_flags & _TIF_SIGPENDING)
 564                do_signal(regs);
 565
 566        if (thread_info_flags & _TIF_NOTIFY_RESUME) {
 567                clear_thread_flag(TIF_NOTIFY_RESUME);
 568                tracehook_notify_resume(regs);
 569        }
 570}
 571