linux/arch/cris/arch-v10/kernel/signal.c
<<
>>
Prefs
   1/*
   2 *  linux/arch/cris/kernel/signal.c
   3 *
   4 *  Based on arch/i386/kernel/signal.c by
   5 *     Copyright (C) 1991, 1992  Linus Torvalds
   6 *     1997-11-28  Modified for POSIX.1b signals by Richard Henderson *
   7 *
   8 *  Ideas also taken from arch/arm.
   9 *
  10 *  Copyright (C) 2000-2007 Axis Communications AB
  11 *
  12 *  Authors:  Bjorn Wesen (bjornw@axis.com)
  13 *
  14 */
  15
  16#include <linux/sched.h>
  17#include <linux/mm.h>
  18#include <linux/smp.h>
  19#include <linux/kernel.h>
  20#include <linux/signal.h>
  21#include <linux/errno.h>
  22#include <linux/wait.h>
  23#include <linux/ptrace.h>
  24#include <linux/unistd.h>
  25#include <linux/stddef.h>
  26
  27#include <asm/processor.h>
  28#include <asm/ucontext.h>
  29#include <asm/uaccess.h>
  30
  31#define DEBUG_SIG 0
  32
  33#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
  34
  35/* a syscall in Linux/CRIS is a break 13 instruction which is 2 bytes */
  36/* manipulate regs so that upon return, it will be re-executed */
  37
  38/* We rely on that pc points to the instruction after "break 13", so the
  39 * library must never do strange things like putting it in a delay slot.
  40 */
  41#define RESTART_CRIS_SYS(regs) regs->r10 = regs->orig_r10; regs->irp -= 2;
  42
  43void do_signal(int canrestart, struct pt_regs *regs);
  44
  45/*
  46 * Atomically swap in the new signal mask, and wait for a signal.  Define
  47 * dummy arguments to be able to reach the regs argument.  (Note that this
  48 * arrangement relies on old_sigset_t occupying one register.)
  49 */
  50int sys_sigsuspend(old_sigset_t mask, long r11, long r12, long r13, long mof,
  51        long srp, struct pt_regs *regs)
  52{
  53        mask &= _BLOCKABLE;
  54        spin_lock_irq(&current->sighand->siglock);
  55        current->saved_sigmask = current->blocked;
  56        siginitset(&current->blocked, mask);
  57        recalc_sigpending();
  58        spin_unlock_irq(&current->sighand->siglock);
  59        current->state = TASK_INTERRUPTIBLE;
  60        schedule();
  61        set_thread_flag(TIF_RESTORE_SIGMASK);
  62        return -ERESTARTNOHAND;
  63}
  64
  65int sys_sigaction(int sig, const struct old_sigaction __user *act,
  66        struct old_sigaction *oact)
  67{
  68        struct k_sigaction new_ka, old_ka;
  69        int ret;
  70
  71        if (act) {
  72                old_sigset_t mask;
  73                if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
  74                    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
  75                    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
  76                        return -EFAULT;
  77                __get_user(new_ka.sa.sa_flags, &act->sa_flags);
  78                __get_user(mask, &act->sa_mask);
  79                siginitset(&new_ka.sa.sa_mask, mask);
  80        }
  81
  82        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
  83
  84        if (!ret && oact) {
  85                if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
  86                    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
  87                    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
  88                        return -EFAULT;
  89                __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
  90                __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
  91        }
  92
  93        return ret;
  94}
  95
  96int sys_sigaltstack(const stack_t *uss, stack_t __user *uoss)
  97{
  98        return do_sigaltstack(uss, uoss, rdusp());
  99}
 100
 101
 102/*
 103 * Do a signal return; undo the signal stack.
 104 */
 105
 106struct sigframe {
 107        struct sigcontext sc;
 108        unsigned long extramask[_NSIG_WORDS-1];
 109        unsigned char retcode[8];  /* trampoline code */
 110};
 111
 112struct rt_sigframe {
 113        struct siginfo *pinfo;
 114        void *puc;
 115        struct siginfo info;
 116        struct ucontext uc;
 117        unsigned char retcode[8];  /* trampoline code */
 118};
 119
 120
 121static int
 122restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
 123{
 124        unsigned int err = 0;
 125        unsigned long old_usp;
 126
 127        /* Always make any pending restarted system calls return -EINTR */
 128        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 129
 130        /* restore the regs from &sc->regs (same as sc, since regs is first)
 131         * (sc is already checked for VERIFY_READ since the sigframe was
 132         *  checked in sys_sigreturn previously)
 133         */
 134
 135        if (__copy_from_user(regs, sc, sizeof(struct pt_regs)))
 136                goto badframe;
 137
 138        /* make sure the U-flag is set so user-mode cannot fool us */
 139
 140        regs->dccr |= 1 << 8;
 141
 142        /* restore the old USP as it was before we stacked the sc etc.
 143         * (we cannot just pop the sigcontext since we aligned the sp and
 144         *  stuff after pushing it)
 145         */
 146
 147        err |= __get_user(old_usp, &sc->usp);
 148
 149        wrusp(old_usp);
 150
 151        /* TODO: the other ports use regs->orig_XX to disable syscall checks
 152         * after this completes, but we don't use that mechanism. maybe we can
 153         * use it now ?
 154         */
 155
 156        return err;
 157
 158badframe:
 159        return 1;
 160}
 161
 162/* Define dummy arguments to be able to reach the regs argument.  */
 163
 164asmlinkage int sys_sigreturn(long r10, long r11, long r12, long r13, long mof,
 165                             long srp, struct pt_regs *regs)
 166{
 167        struct sigframe __user *frame = (struct sigframe *)rdusp();
 168        sigset_t set;
 169
 170        /*
 171         * Since we stacked the signal on a dword boundary,
 172         * then frame should be dword aligned here.  If it's
 173         * not, then the user is trying to mess with us.
 174         */
 175        if (((long)frame) & 3)
 176                goto badframe;
 177
 178        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 179                goto badframe;
 180        if (__get_user(set.sig[0], &frame->sc.oldmask)
 181            || (_NSIG_WORDS > 1
 182                && __copy_from_user(&set.sig[1], frame->extramask,
 183                                    sizeof(frame->extramask))))
 184                goto badframe;
 185
 186        sigdelsetmask(&set, ~_BLOCKABLE);
 187        spin_lock_irq(&current->sighand->siglock);
 188        current->blocked = set;
 189        recalc_sigpending();
 190        spin_unlock_irq(&current->sighand->siglock);
 191
 192        if (restore_sigcontext(regs, &frame->sc))
 193                goto badframe;
 194
 195        /* TODO: SIGTRAP when single-stepping as in arm ? */
 196
 197        return regs->r10;
 198
 199badframe:
 200        force_sig(SIGSEGV, current);
 201        return 0;
 202}
 203
 204/* Define dummy arguments to be able to reach the regs argument.  */
 205
 206asmlinkage int sys_rt_sigreturn(long r10, long r11, long r12, long r13,
 207                                long mof, long srp, struct pt_regs *regs)
 208{
 209        struct rt_sigframe __user *frame = (struct rt_sigframe *)rdusp();
 210        sigset_t set;
 211
 212        /*
 213         * Since we stacked the signal on a dword boundary,
 214         * then frame should be dword aligned here.  If it's
 215         * not, then the user is trying to mess with us.
 216         */
 217        if (((long)frame) & 3)
 218                goto badframe;
 219
 220        if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
 221                goto badframe;
 222        if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
 223                goto badframe;
 224
 225        sigdelsetmask(&set, ~_BLOCKABLE);
 226        spin_lock_irq(&current->sighand->siglock);
 227        current->blocked = set;
 228        recalc_sigpending();
 229        spin_unlock_irq(&current->sighand->siglock);
 230
 231        if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
 232                goto badframe;
 233
 234        if (do_sigaltstack(&frame->uc.uc_stack, NULL, rdusp()) == -EFAULT)
 235                goto badframe;
 236
 237        return regs->r10;
 238
 239badframe:
 240        force_sig(SIGSEGV, current);
 241        return 0;
 242}
 243
 244/*
 245 * Set up a signal frame.
 246 */
 247
 248static int setup_sigcontext(struct sigcontext __user *sc,
 249        struct pt_regs *regs, unsigned long mask)
 250{
 251        int err = 0;
 252        unsigned long usp = rdusp();
 253
 254        /* copy the regs. they are first in sc so we can use sc directly */
 255
 256        err |= __copy_to_user(sc, regs, sizeof(struct pt_regs));
 257
 258        /* Set the frametype to CRIS_FRAME_NORMAL for the execution of
 259           the signal handler. The frametype will be restored to its previous
 260           value in restore_sigcontext. */
 261        regs->frametype = CRIS_FRAME_NORMAL;
 262
 263        /* then some other stuff */
 264
 265        err |= __put_user(mask, &sc->oldmask);
 266
 267        err |= __put_user(usp, &sc->usp);
 268
 269        return err;
 270}
 271
 272/* Figure out where we want to put the new signal frame
 273 * - usually on the stack. */
 274
 275static inline void __user *
 276get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size)
 277{
 278        unsigned long sp = rdusp();
 279
 280        /* This is the X/Open sanctioned signal stack switching.  */
 281        if (ka->sa.sa_flags & SA_ONSTACK) {
 282                if (! on_sig_stack(sp))
 283                        sp = current->sas_ss_sp + current->sas_ss_size;
 284        }
 285
 286        /* make sure the frame is dword-aligned */
 287
 288        sp &= ~3;
 289
 290        return (void __user*)(sp - frame_size);
 291}
 292
 293/* grab and setup a signal frame.
 294 *
 295 * basically we stack a lot of state info, and arrange for the
 296 * user-mode program to return to the kernel using either a
 297 * trampoline which performs the syscall sigreturn, or a provided
 298 * user-mode trampoline.
 299 */
 300
 301static int setup_frame(int sig, struct k_sigaction *ka,
 302                       sigset_t *set, struct pt_regs *regs)
 303{
 304        struct sigframe __user *frame;
 305        unsigned long return_ip;
 306        int err = 0;
 307
 308        frame = get_sigframe(ka, regs, sizeof(*frame));
 309
 310        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 311                goto give_sigsegv;
 312
 313        err |= setup_sigcontext(&frame->sc, regs, set->sig[0]);
 314        if (err)
 315                goto give_sigsegv;
 316
 317        if (_NSIG_WORDS > 1) {
 318                err |= __copy_to_user(frame->extramask, &set->sig[1],
 319                                      sizeof(frame->extramask));
 320        }
 321        if (err)
 322                goto give_sigsegv;
 323
 324        /* Set up to return from userspace.  If provided, use a stub
 325           already in userspace.  */
 326        if (ka->sa.sa_flags & SA_RESTORER) {
 327                return_ip = (unsigned long)ka->sa.sa_restorer;
 328        } else {
 329                /* trampoline - the desired return ip is the retcode itself */
 330                return_ip = (unsigned long)&frame->retcode;
 331                /* This is movu.w __NR_sigreturn, r9; break 13; */
 332                err |= __put_user(0x9c5f,         (short __user*)(frame->retcode+0));
 333                err |= __put_user(__NR_sigreturn, (short __user*)(frame->retcode+2));
 334                err |= __put_user(0xe93d,         (short __user*)(frame->retcode+4));
 335        }
 336
 337        if (err)
 338                goto give_sigsegv;
 339
 340        /* Set up registers for signal handler */
 341
 342        regs->irp = (unsigned long) ka->sa.sa_handler;  /* what we enter NOW   */
 343        regs->srp = return_ip;                          /* what we enter LATER */
 344        regs->r10 = sig;                                /* first argument is signo */
 345
 346        /* actually move the usp to reflect the stacked frame */
 347
 348        wrusp((unsigned long)frame);
 349
 350        return 0;
 351
 352give_sigsegv:
 353        force_sigsegv(sig, current);
 354        return -EFAULT;
 355}
 356
 357static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 358        sigset_t *set, struct pt_regs *regs)
 359{
 360        struct rt_sigframe __user *frame;
 361        unsigned long return_ip;
 362        int err = 0;
 363
 364        frame = get_sigframe(ka, regs, sizeof(*frame));
 365
 366        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 367                goto give_sigsegv;
 368
 369        err |= __put_user(&frame->info, &frame->pinfo);
 370        err |= __put_user(&frame->uc, &frame->puc);
 371        err |= copy_siginfo_to_user(&frame->info, info);
 372        if (err)
 373                goto give_sigsegv;
 374
 375        /* Clear all the bits of the ucontext we don't use.  */
 376        err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
 377
 378        err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
 379
 380        err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
 381
 382        if (err)
 383                goto give_sigsegv;
 384
 385        /* Set up to return from userspace.  If provided, use a stub
 386           already in userspace.  */
 387        if (ka->sa.sa_flags & SA_RESTORER) {
 388                return_ip = (unsigned long)ka->sa.sa_restorer;
 389        } else {
 390                /* trampoline - the desired return ip is the retcode itself */
 391                return_ip = (unsigned long)&frame->retcode;
 392                /* This is movu.w __NR_rt_sigreturn, r9; break 13; */
 393                err |= __put_user(0x9c5f, (short __user *)(frame->retcode+0));
 394                err |= __put_user(__NR_rt_sigreturn,
 395                        (short __user *)(frame->retcode+2));
 396                err |= __put_user(0xe93d, (short __user *)(frame->retcode+4));
 397        }
 398
 399        if (err)
 400                goto give_sigsegv;
 401
 402        /* TODO what is the current->exec_domain stuff and invmap ? */
 403
 404        /* Set up registers for signal handler */
 405
 406        /* What we enter NOW   */
 407        regs->irp = (unsigned long) ka->sa.sa_handler;
 408        /* What we enter LATER */
 409        regs->srp = return_ip;
 410        /* First argument is signo */
 411        regs->r10 = sig;
 412        /* Second argument is (siginfo_t *) */
 413        regs->r11 = (unsigned long)&frame->info;
 414        /* Third argument is unused */
 415        regs->r12 = 0;
 416
 417        /* Actually move the usp to reflect the stacked frame */
 418        wrusp((unsigned long)frame);
 419
 420        return 0;
 421
 422give_sigsegv:
 423        force_sigsegv(sig, current);
 424        return -EFAULT;
 425}
 426
 427/*
 428 * OK, we're invoking a handler
 429 */
 430
 431static inline int handle_signal(int canrestart, unsigned long sig,
 432        siginfo_t *info, struct k_sigaction *ka,
 433        sigset_t *oldset, struct pt_regs *regs)
 434{
 435        int ret;
 436
 437        /* Are we from a system call? */
 438        if (canrestart) {
 439                /* If so, check system call restarting.. */
 440                switch (regs->r10) {
 441                case -ERESTART_RESTARTBLOCK:
 442                case -ERESTARTNOHAND:
 443                        /* ERESTARTNOHAND means that the syscall should
 444                         * only be restarted if there was no handler for
 445                         * the signal, and since we only get here if there
 446                         * is a handler, we don't restart */
 447                        regs->r10 = -EINTR;
 448                        break;
 449                case -ERESTARTSYS:
 450                        /* ERESTARTSYS means to restart the syscall if
 451                         * there is no handler or the handler was
 452                         * registered with SA_RESTART */
 453                        if (!(ka->sa.sa_flags & SA_RESTART)) {
 454                                regs->r10 = -EINTR;
 455                                break;
 456                        }
 457                /* fallthrough */
 458                case -ERESTARTNOINTR:
 459                        /* ERESTARTNOINTR means that the syscall should
 460                         * be called again after the signal handler returns. */
 461                        RESTART_CRIS_SYS(regs);
 462                }
 463        }
 464
 465        /* Set up the stack frame */
 466        if (ka->sa.sa_flags & SA_SIGINFO)
 467                ret = setup_rt_frame(sig, ka, info, oldset, regs);
 468        else
 469                ret = setup_frame(sig, ka, oldset, regs);
 470
 471        if (ret == 0) {
 472                spin_lock_irq(&current->sighand->siglock);
 473                sigorsets(&current->blocked, &current->blocked,
 474                        &ka->sa.sa_mask);
 475                if (!(ka->sa.sa_flags & SA_NODEFER))
 476                        sigaddset(&current->blocked, sig);
 477                recalc_sigpending();
 478                spin_unlock_irq(&current->sighand->siglock);
 479        }
 480        return ret;
 481}
 482
 483/*
 484 * Note that 'init' is a special process: it doesn't get signals it doesn't
 485 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 486 * mistake.
 487 *
 488 * Also note that the regs structure given here as an argument, is the latest
 489 * pushed pt_regs. It may or may not be the same as the first pushed registers
 490 * when the initial usermode->kernelmode transition took place. Therefore
 491 * we can use user_mode(regs) to see if we came directly from kernel or user
 492 * mode below.
 493 */
 494
 495void do_signal(int canrestart, struct pt_regs *regs)
 496{
 497        siginfo_t info;
 498        int signr;
 499        struct k_sigaction ka;
 500        sigset_t *oldset;
 501
 502        /*
 503         * We want the common case to go fast, which
 504         * is why we may in certain cases get here from
 505         * kernel mode. Just return without doing anything
 506         * if so.
 507         */
 508        if (!user_mode(regs))
 509                return;
 510
 511        if (test_thread_flag(TIF_RESTORE_SIGMASK))
 512                oldset = &current->saved_sigmask;
 513        else
 514                oldset = &current->blocked;
 515
 516        signr = get_signal_to_deliver(&info, &ka, regs, NULL);
 517        if (signr > 0) {
 518                /* Whee!  Actually deliver the signal.  */
 519                if (handle_signal(canrestart, signr, &info, &ka,
 520                                oldset, regs)) {
 521                        /* a signal was successfully delivered; the saved
 522                         * sigmask will have been stored in the signal frame,
 523                         * and will be restored by sigreturn, so we can simply
 524                         * clear the TIF_RESTORE_SIGMASK flag */
 525                        if (test_thread_flag(TIF_RESTORE_SIGMASK))
 526                                clear_thread_flag(TIF_RESTORE_SIGMASK);
 527                }
 528                return;
 529        }
 530
 531        /* Did we come from a system call? */
 532        if (canrestart) {
 533                /* Restart the system call - no handlers present */
 534                if (regs->r10 == -ERESTARTNOHAND ||
 535                    regs->r10 == -ERESTARTSYS ||
 536                    regs->r10 == -ERESTARTNOINTR) {
 537                        RESTART_CRIS_SYS(regs);
 538                }
 539                if (regs->r10 == -ERESTART_RESTARTBLOCK) {
 540                        regs->r10 = __NR_restart_syscall;
 541                        regs->irp -= 2;
 542                }
 543        }
 544
 545        /* if there's no signal to deliver, we just put the saved sigmask
 546         * back */
 547        if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
 548                clear_thread_flag(TIF_RESTORE_SIGMASK);
 549                sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
 550        }
 551}
 552