linux-old/arch/ia64/kernel/signal.c
<<
>>
Prefs
   1/*
   2 * Architecture-specific signal handling support.
   3 *
   4 * Copyright (C) 1999-2002 Hewlett-Packard Co
   5 *      David Mosberger-Tang <davidm@hpl.hp.com>
   6 *
   7 * Derived from i386 and Alpha versions.
   8 */
   9
  10#include <linux/config.h>
  11#include <linux/errno.h>
  12#include <linux/kernel.h>
  13#include <linux/mm.h>
  14#include <linux/ptrace.h>
  15#include <linux/sched.h>
  16#include <linux/signal.h>
  17#include <linux/smp.h>
  18#include <linux/smp_lock.h>
  19#include <linux/stddef.h>
  20#include <linux/unistd.h>
  21#include <linux/wait.h>
  22
  23#include <asm/ia32.h>
  24#include <asm/uaccess.h>
  25#include <asm/rse.h>
  26#include <asm/sigcontext.h>
  27
  28#include "sigframe.h"
  29
  30#define DEBUG_SIG       0
  31#define STACK_ALIGN     16              /* minimal alignment for stack pointer */
  32#define _BLOCKABLE      (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
  33
  34#if _NSIG_WORDS > 1
  35# define PUT_SIGSET(k,u)        __copy_to_user((u)->sig, (k)->sig, sizeof(sigset_t))
  36# define GET_SIGSET(k,u)        __copy_from_user((k)->sig, (u)->sig, sizeof(sigset_t))
  37#else
  38# define PUT_SIGSET(k,u)        __put_user((k)->sig[0], &(u)->sig[0])
  39# define GET_SIGSET(k,u)        __get_user((k)->sig[0], &(u)->sig[0])
  40#endif
  41
  42extern long ia64_do_signal (sigset_t *, struct sigscratch *, long);     /* forward decl */
  43
  44register double f16 asm ("f16"); register double f17 asm ("f17");
  45register double f18 asm ("f18"); register double f19 asm ("f19");
  46register double f20 asm ("f20"); register double f21 asm ("f21");
  47register double f22 asm ("f22"); register double f23 asm ("f23");
  48
  49register double f24 asm ("f24"); register double f25 asm ("f25");
  50register double f26 asm ("f26"); register double f27 asm ("f27");
  51register double f28 asm ("f28"); register double f29 asm ("f29");
  52register double f30 asm ("f30"); register double f31 asm ("f31");
  53
  54long
  55ia64_rt_sigsuspend (sigset_t *uset, size_t sigsetsize, struct sigscratch *scr)
  56{
  57        sigset_t oldset, set;
  58
  59        /* XXX: Don't preclude handling different sized sigset_t's.  */
  60        if (sigsetsize != sizeof(sigset_t))
  61                return -EINVAL;
  62
  63        if (!access_ok(VERIFY_READ, uset, sigsetsize))
  64                return -EFAULT;
  65
  66        if (GET_SIGSET(&set, uset))
  67                return -EFAULT;
  68
  69        sigdelsetmask(&set, ~_BLOCKABLE);
  70
  71        spin_lock_irq(&current->sigmask_lock);
  72        {
  73                oldset = current->blocked;
  74                current->blocked = set;
  75                recalc_sigpending(current);
  76        }
  77        spin_unlock_irq(&current->sigmask_lock);
  78
  79        /*
  80         * The return below usually returns to the signal handler.  We need to
  81         * pre-set the correct error code here to ensure that the right values
  82         * get saved in sigcontext by ia64_do_signal.
  83         */
  84        scr->pt.r8 = EINTR;
  85        scr->pt.r10 = -1;
  86
  87        while (1) {
  88                current->state = TASK_INTERRUPTIBLE;
  89                schedule();
  90                if (ia64_do_signal(&oldset, scr, 1))
  91                        return -EINTR;
  92        }
  93}
  94
  95asmlinkage long
  96sys_sigaltstack (const stack_t *uss, stack_t *uoss, long arg2, long arg3, long arg4,
  97                 long arg5, long arg6, long arg7, long stack)
  98{
  99        struct pt_regs *pt = (struct pt_regs *) &stack;
 100
 101        return do_sigaltstack(uss, uoss, pt->r12);
 102}
 103
 104static long
 105restore_sigcontext (struct sigcontext *sc, struct sigscratch *scr)
 106{
 107        unsigned long ip, flags, nat, um, cfm;
 108        long err;
 109
 110        /* restore scratch that always needs gets updated during signal delivery: */
 111        err = __get_user(flags, &sc->sc_flags);
 112
 113        err |= __get_user(nat, &sc->sc_nat);
 114        err |= __get_user(ip, &sc->sc_ip);                      /* instruction pointer */
 115        err |= __get_user(cfm, &sc->sc_cfm);
 116        err |= __get_user(um, &sc->sc_um);                      /* user mask */
 117        err |= __get_user(scr->pt.ar_rsc, &sc->sc_ar_rsc);
 118        err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat);
 119        err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr);
 120        err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
 121        err |= __get_user(scr->pt.pr, &sc->sc_pr);              /* predicates */
 122        err |= __get_user(scr->pt.b0, &sc->sc_br[0]);           /* b0 (rp) */
 123        err |= __copy_from_user(&scr->pt.r1, &sc->sc_gr[1], 8); /* r1 */
 124        err |= __copy_from_user(&scr->pt.r8, &sc->sc_gr[8], 4*8);       /* r8-r11 */
 125        err |= __copy_from_user(&scr->pt.r12, &sc->sc_gr[12], 2*8);     /* r12-r13 */
 126        err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8);       /* r15 */
 127        
 128        if ((flags & IA64_SC_FLAG_IN_SYSCALL)==0)
 129        {
 130                // Only get user sig context when not in syscall. 
 131                err |= __get_user(scr->pt.ar_ccv, &sc->sc_ar_ccv);
 132                err |= __get_user(scr->pt.ar_csd, &sc->sc_ar25);        /* ar.csd */
 133                err |= __get_user(scr->pt.ar_ssd, &sc->sc_ar26);        /* ar.ssd */
 134                err |= __get_user(scr->pt.b6, &sc->sc_br[6]);           /* b6 */
 135                err |= __get_user(scr->pt.b7, &sc->sc_br[7]);           /* b7 */
 136                err |= __copy_from_user(&scr->pt.r2, &sc->sc_gr[2], 2*8);       /* r2-r3 */
 137                err |= __copy_from_user(&scr->pt.r14, &sc->sc_gr[14], 8);       /* r14 */
 138                err |= __copy_from_user(&scr->pt.r16, &sc->sc_gr[16], 16*8);    /* r16-r31 */
 139        }
 140
 141        scr->pt.cr_ifs = cfm | (1UL << 63);
 142
 143        /* establish new instruction pointer: */
 144        scr->pt.cr_iip = ip & ~0x3UL;
 145        ia64_psr(&scr->pt)->ri = ip & 0x3;
 146        scr->pt.cr_ipsr = (scr->pt.cr_ipsr & ~IA64_PSR_UM) | (um & IA64_PSR_UM);
 147
 148        scr->scratch_unat = ia64_put_scratch_nat_bits(&scr->pt, nat);
 149
 150        if ((flags & IA64_SC_FLAG_FPH_VALID) != 0) {
 151                struct ia64_psr *psr = ia64_psr(&scr->pt);
 152
 153                __copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16);
 154                psr->mfh = 0;   /* drop signal handler's fph contents... */
 155                if (psr->dfh)
 156                        ia64_drop_fpu(current);
 157                else {
 158                        /* We already own the local fph, otherwise psr->dfh wouldn't be 0.  */
 159                        __ia64_load_fpu(current->thread.fph);
 160                        ia64_set_local_fpu_owner(current);
 161                }
 162        }
 163        return err;
 164}
 165
 166int
 167copy_siginfo_to_user (siginfo_t *to, siginfo_t *from)
 168{
 169        if (!access_ok(VERIFY_WRITE, to, sizeof(siginfo_t)))
 170                return -EFAULT;
 171        if (from->si_code < 0) {
 172                if (__copy_to_user(to, from, sizeof(siginfo_t)))
 173                        return -EFAULT;
 174                return 0;
 175        } else {
 176                int err;
 177
 178                /*
 179                 * If you change siginfo_t structure, please be sure
 180                 * this code is fixed accordingly.  It should never
 181                 * copy any pad contained in the structure to avoid
 182                 * security leaks, but must copy the generic 3 ints
 183                 * plus the relevant union member.
 184                 */
 185                err = __put_user(from->si_signo, &to->si_signo);
 186                err |= __put_user(from->si_errno, &to->si_errno);
 187                err |= __put_user((short)from->si_code, &to->si_code);
 188                switch (from->si_code >> 16) {
 189                      case __SI_FAULT >> 16:
 190                        err |= __put_user(from->si_flags, &to->si_flags);
 191                        err |= __put_user(from->si_isr, &to->si_isr);
 192                      case __SI_POLL >> 16:
 193                        err |= __put_user(from->si_addr, &to->si_addr);
 194                        err |= __put_user(from->si_imm, &to->si_imm);
 195                        break;
 196                      case __SI_CHLD >> 16:
 197                        err |= __put_user(from->si_utime, &to->si_utime);
 198                        err |= __put_user(from->si_stime, &to->si_stime);
 199                        err |= __put_user(from->si_status, &to->si_status);
 200                      case __SI_PROF >> 16:
 201                        err |= __put_user(from->si_uid, &to->si_uid);
 202                        err |= __put_user(from->si_pid, &to->si_pid);
 203                        if (from->si_code == PROF_OVFL) {
 204                                err |= __put_user(from->si_pfm_ovfl[0], &to->si_pfm_ovfl[0]);
 205                                err |= __put_user(from->si_pfm_ovfl[1], &to->si_pfm_ovfl[1]);
 206                                err |= __put_user(from->si_pfm_ovfl[2], &to->si_pfm_ovfl[2]);
 207                                err |= __put_user(from->si_pfm_ovfl[3], &to->si_pfm_ovfl[3]);
 208                        }
 209                        break;
 210                      default:
 211                        err |= __put_user(from->si_uid, &to->si_uid);
 212                        err |= __put_user(from->si_pid, &to->si_pid);
 213                        break;
 214                      /* case __SI_RT: This is not generated by the kernel as of now.  */
 215                }
 216                return err;
 217        }
 218}
 219
 220int
 221copy_siginfo_from_user (siginfo_t *to, siginfo_t *from)
 222{
 223        if (!access_ok(VERIFY_READ, from, sizeof(siginfo_t)))
 224                return -EFAULT;
 225        if (__copy_from_user(to, from, sizeof(siginfo_t)) != 0)
 226                return -EFAULT;
 227
 228        if (SI_FROMUSER(to))
 229                return 0;
 230
 231        to->si_code &= ~__SI_MASK;
 232        if (to->si_code != 0) {
 233                switch (to->si_signo) {
 234                      case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: case SIGTRAP:
 235                        to->si_code |= __SI_FAULT;
 236                        break;
 237
 238                      case SIGCHLD:
 239                        to->si_code |= __SI_CHLD;
 240                        break;
 241
 242                      case SIGPOLL:
 243                        to->si_code |= __SI_POLL;
 244                        break;
 245
 246                      case SIGPROF:
 247                        to->si_code |= __SI_PROF;
 248                        break;
 249
 250                      default:
 251                        break;
 252                }
 253        }
 254        return 0;
 255}
 256
 257long
 258ia64_rt_sigreturn (struct sigscratch *scr)
 259{
 260        extern char ia64_strace_leave_kernel, ia64_leave_kernel;
 261        struct sigcontext *sc;
 262        struct siginfo si;
 263        sigset_t set;
 264        long retval;
 265
 266        sc = &((struct sigframe *) (scr->pt.r12 + 16))->sc;
 267
 268        /*
 269         * When we return to the previously executing context, r8 and r10 have already
 270         * been setup the way we want them.  Indeed, if the signal wasn't delivered while
 271         * in a system call, we must not touch r8 or r10 as otherwise user-level state
 272         * could be corrupted.
 273         */
 274        retval = (long) &ia64_leave_kernel;
 275        if (current->ptrace & PT_TRACESYS)
 276                /*
 277                 * strace expects to be notified after sigreturn returns even though the
 278                 * context to which we return may not be in the middle of a syscall.
 279                 * Thus, the return-value that strace displays for sigreturn is
 280                 * meaningless.
 281                 */
 282                retval = (long) &ia64_strace_leave_kernel;
 283
 284        if (!access_ok(VERIFY_READ, sc, sizeof(*sc)))
 285                goto give_sigsegv;
 286
 287        if (GET_SIGSET(&set, &sc->sc_mask))
 288                goto give_sigsegv;
 289
 290        sigdelsetmask(&set, ~_BLOCKABLE);
 291
 292        spin_lock_irq(&current->sigmask_lock);
 293        {
 294                current->blocked = set;
 295                recalc_sigpending(current);
 296        }
 297        spin_unlock_irq(&current->sigmask_lock);
 298
 299        if (restore_sigcontext(sc, scr))
 300                goto give_sigsegv;
 301
 302#if DEBUG_SIG
 303        printk("SIG return (%s:%d): sp=%lx ip=%lx\n",
 304               current->comm, current->pid, scr->pt.r12, scr->pt.cr_iip);
 305#endif
 306        /*
 307         * It is more difficult to avoid calling this function than to
 308         * call it and ignore errors.
 309         */
 310        do_sigaltstack(&sc->sc_stack, 0, scr->pt.r12);
 311        return retval;
 312
 313  give_sigsegv:
 314        si.si_signo = SIGSEGV;
 315        si.si_errno = 0;
 316        si.si_code = SI_KERNEL;
 317        si.si_pid = current->pid;
 318        si.si_uid = current->uid;
 319        si.si_addr = sc;
 320        force_sig_info(SIGSEGV, &si, current);
 321        return retval;
 322}
 323
 324/*
 325 * This does just the minimum required setup of sigcontext.
 326 * Specifically, it only installs data that is either not knowable at
 327 * the user-level or that gets modified before execution in the
 328 * trampoline starts.  Everything else is done at the user-level.
 329 */
 330static long
 331setup_sigcontext (struct sigcontext *sc, sigset_t *mask, struct sigscratch *scr)
 332{
 333        unsigned long flags = 0, ifs, cfm, nat;
 334        long err;
 335
 336        ifs = scr->pt.cr_ifs;
 337
 338        if (on_sig_stack((unsigned long) sc))
 339                flags |= IA64_SC_FLAG_ONSTACK;
 340        if ((ifs & (1UL << 63)) == 0) {
 341                /* if cr_ifs isn't valid, we got here through a syscall */
 342                flags |= IA64_SC_FLAG_IN_SYSCALL;
 343                cfm = scr->ar_pfs & ((1UL << 38) - 1);
 344        } else
 345                cfm = ifs & ((1UL << 38) - 1);
 346        ia64_flush_fph(current);
 347        if ((current->thread.flags & IA64_THREAD_FPH_VALID)) {
 348                flags |= IA64_SC_FLAG_FPH_VALID;
 349                __copy_to_user(&sc->sc_fr[32], current->thread.fph, 96*16);
 350        }
 351
 352        nat = ia64_get_scratch_nat_bits(&scr->pt, scr->scratch_unat);
 353
 354        err  = __put_user(flags, &sc->sc_flags);
 355
 356        err |= __put_user(nat, &sc->sc_nat);
 357        err |= PUT_SIGSET(mask, &sc->sc_mask);
 358        err |= __put_user(cfm, &sc->sc_cfm);
 359        err |= __put_user(scr->pt.cr_ipsr & IA64_PSR_UM, &sc->sc_um);
 360        err |= __put_user(scr->pt.ar_rsc, &sc->sc_ar_rsc);
 361        err |= __put_user(scr->pt.ar_unat, &sc->sc_ar_unat);            /* ar.unat */
 362        err |= __put_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr);            /* ar.fpsr */
 363        err |= __put_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
 364        err |= __put_user(scr->pt.pr, &sc->sc_pr);                      /* predicates */
 365        err |= __put_user(scr->pt.b0, &sc->sc_br[0]);                   /* b0 (rp) */
 366        err |= __copy_to_user(&sc->sc_gr[1], &scr->pt.r1, 8);           /* r1 */
 367        err |= __copy_to_user(&sc->sc_gr[8], &scr->pt.r8, 4*8);         /* r8-r11 */
 368        err |= __copy_to_user(&sc->sc_gr[12], &scr->pt.r12, 2*8);       /* r12-r13 */
 369        err |= __copy_to_user(&sc->sc_gr[15], &scr->pt.r15, 8);         /* r15 */
 370        err |= __put_user(scr->pt.cr_iip + ia64_psr(&scr->pt)->ri, &sc->sc_ip);
 371
 372        if (flags & IA64_SC_FLAG_IN_SYSCALL)
 373        {
 374                // Clear scratch registers in sig context for asynchronized signal.
 375                err |= __clear_user(&sc->sc_ar_ccv, 8);
 376                err |= __clear_user(&sc->sc_ar25,8);                            /* ar.csd */
 377                err |= __clear_user(&sc->sc_ar26,8);                            /* ar.ssd */
 378                err |= __clear_user(&sc->sc_br[6],8);                           /* b6 */
 379                err |= __clear_user(&sc->sc_br[7],8);                           /* b7 */
 380
 381                err |= __clear_user(&sc->sc_gr[2], 2*8);                        /* r2-r3 */
 382                err |= __clear_user(&sc->sc_gr[14],8);                          /* r14 */
 383                err |= __clear_user(&sc->sc_gr[16],16*8);                       /* r16-r31 */
 384        } else
 385        {
 386                // Copy scratch registers in sig context from pt_regs for synchronized signal.
 387                err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv);
 388                err |= __put_user(scr->pt.ar_csd, &sc->sc_ar25);                /* ar.csd */
 389                err |= __put_user(scr->pt.ar_ssd, &sc->sc_ar26);                /* ar.ssd */
 390                err |= __put_user(scr->pt.b6, &sc->sc_br[6]);                   /* b6 */
 391                err |= __put_user(scr->pt.b7, &sc->sc_br[7]);                   /* b7 */
 392
 393                err |= __copy_to_user(&sc->sc_gr[2], &scr->pt.r2, 2*8);         /* r2-r3 */
 394                err |= __copy_to_user(&sc->sc_gr[14], &scr->pt.r14, 8);         /* r14 */
 395                err |= __copy_to_user(&sc->sc_gr[16], &scr->pt.r16, 16*8);      /* r16-r31 */
 396        }
 397        return err;
 398}
 399
 400/*
 401 * Check whether the register-backing store is already on the signal stack.
 402 */
 403static inline int
 404rbs_on_sig_stack (unsigned long bsp)
 405{
 406        return (bsp - current->sas_ss_sp < current->sas_ss_size);
 407}
 408
 409static long
 410setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
 411             struct sigscratch *scr)
 412{
 413        extern char ia64_sigtramp[], __start_gate_section[];
 414        unsigned long tramp_addr, new_rbs = 0;
 415        struct sigframe *frame;
 416        struct siginfo si;
 417        long err;
 418
 419        frame = (void *) scr->pt.r12;
 420        tramp_addr = GATE_ADDR + (ia64_sigtramp - __start_gate_section);
 421        if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags((unsigned long) frame) == 0) {
 422                frame = (void *) ((current->sas_ss_sp + current->sas_ss_size)
 423                                  & ~(STACK_ALIGN - 1));
 424                /*
 425                 * We need to check for the register stack being on the signal stack
 426                 * separately, because it's switched separately (memory stack is switched
 427                 * in the kernel, register stack is switched in the signal trampoline).
 428                 */
 429                if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
 430                        new_rbs  = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
 431        }
 432        frame = (void *) frame - ((sizeof(*frame) + STACK_ALIGN - 1) & ~(STACK_ALIGN - 1));
 433
 434        if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
 435                goto give_sigsegv;
 436
 437        err  = __put_user(sig, &frame->arg0);
 438        err |= __put_user(&frame->info, &frame->arg1);
 439        err |= __put_user(&frame->sc, &frame->arg2);
 440        err |= __put_user(new_rbs, &frame->sc.sc_rbs_base);
 441        err |= __put_user(0, &frame->sc.sc_loadrs);     /* initialize to zero */
 442        err |= __put_user(ka->sa.sa_handler, &frame->handler);
 443
 444        err |= copy_siginfo_to_user(&frame->info, info);
 445
 446        err |= __put_user(current->sas_ss_sp, &frame->sc.sc_stack.ss_sp);
 447        err |= __put_user(current->sas_ss_size, &frame->sc.sc_stack.ss_size);
 448        err |= __put_user(sas_ss_flags(scr->pt.r12), &frame->sc.sc_stack.ss_flags);
 449        err |= setup_sigcontext(&frame->sc, set, scr);
 450
 451        if (err)
 452                goto give_sigsegv;
 453
 454        scr->pt.r12 = (unsigned long) frame - 16;       /* new stack pointer */
 455        scr->pt.ar_fpsr = FPSR_DEFAULT;                 /* reset fpsr for signal handler */
 456        scr->pt.cr_iip = tramp_addr;
 457        ia64_psr(&scr->pt)->ri = 0;                     /* start executing in first slot */
 458        /*
 459         * Force the interruption function mask to zero.  This has no effect when a
 460         * system-call got interrupted by a signal (since, in that case, scr->pt_cr_ifs is
 461         * ignored), but it has the desirable effect of making it possible to deliver a
 462         * signal with an incomplete register frame (which happens when a mandatory RSE
 463         * load faults).  Furthermore, it has no negative effect on the getting the user's
 464         * dirty partition preserved, because that's governed by scr->pt.loadrs.
 465         */
 466        scr->pt.cr_ifs = (1UL << 63);
 467
 468        /*
 469         * Note: this affects only the NaT bits of the scratch regs (the ones saved in
 470         * pt_regs), which is exactly what we want.
 471         */
 472        scr->scratch_unat = 0; /* ensure NaT bits of r12 is clear */
 473
 474#if DEBUG_SIG
 475        printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%lx\n",
 476               current->comm, current->pid, sig, scr->pt.r12, scr->pt.cr_iip, scr->pt.r3);
 477#endif
 478        return 1;
 479
 480  give_sigsegv:
 481        if (sig == SIGSEGV)
 482                ka->sa.sa_handler = SIG_DFL;
 483        si.si_signo = SIGSEGV;
 484        si.si_errno = 0;
 485        si.si_code = SI_KERNEL;
 486        si.si_pid = current->pid;
 487        si.si_uid = current->uid;
 488        si.si_addr = frame;
 489        force_sig_info(SIGSEGV, &si, current);
 490        return 0;
 491}
 492
 493static long
 494handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *oldset,
 495               struct sigscratch *scr)
 496{
 497#ifdef CONFIG_IA32_SUPPORT
 498        if (IS_IA32_PROCESS(&scr->pt)) {
 499                /* send signal to IA-32 process */
 500                if (!ia32_setup_frame1(sig, ka, info, oldset, &scr->pt))
 501                        return 0;
 502        } else
 503#endif
 504        /* send signal to IA-64 process */
 505        if (!setup_frame(sig, ka, info, oldset, scr))
 506                return 0;
 507
 508        if (ka->sa.sa_flags & SA_ONESHOT)
 509                ka->sa.sa_handler = SIG_DFL;
 510
 511        if (!(ka->sa.sa_flags & SA_NODEFER)) {
 512                spin_lock_irq(&current->sigmask_lock);
 513                {
 514                        sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
 515                        sigaddset(&current->blocked, sig);
 516                        recalc_sigpending(current);
 517                }
 518                spin_unlock_irq(&current->sigmask_lock);
 519        }
 520        return 1;
 521}
 522
 523/*
 524 * Note that `init' is a special process: it doesn't get signals it doesn't want to
 525 * handle.  Thus you cannot kill init even with a SIGKILL even by mistake.
 526 */
 527long
 528ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
 529{
 530        struct signal_struct *sig;
 531        struct k_sigaction *ka;
 532        siginfo_t info;
 533        long restart = in_syscall;
 534        long errno = scr->pt.r8;
 535
 536        /*
 537         * In the ia64_leave_kernel code path, we want the common case to go fast, which
 538         * is why we may in certain cases get here from kernel mode. Just return without
 539         * doing anything if so.
 540         */
 541        if (!user_mode(&scr->pt))
 542                return 0;
 543
 544        if (!oldset)
 545                oldset = &current->blocked;
 546
 547#ifdef CONFIG_IA32_SUPPORT
 548        if (IS_IA32_PROCESS(&scr->pt)) {
 549                if (in_syscall) {
 550                        if (errno >= 0)
 551                                restart = 0;
 552                        else
 553                                errno = -errno;
 554                }
 555        } else
 556#endif
 557        if (scr->pt.r10 != -1) {
 558                /*
 559                 * A system calls has to be restarted only if one of the error codes
 560                 * ERESTARTNOHAND, ERESTARTSYS, or ERESTARTNOINTR is returned.  If r10
 561                 * isn't -1 then r8 doesn't hold an error code and we don't need to
 562                 * restart the syscall, so we can clear the "restart" flag here.
 563                 */
 564                restart = 0;
 565        }
 566
 567        for (;;) {
 568                unsigned long signr;
 569
 570                spin_lock_irq(&current->sigmask_lock);
 571                signr = dequeue_signal(&current->blocked, &info);
 572                spin_unlock_irq(&current->sigmask_lock);
 573
 574                if (!signr)
 575                        break;
 576
 577                if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) {
 578                        /* Let the debugger run.  */
 579                        current->exit_code = signr;
 580                        current->thread.siginfo = &info;
 581                        current->state = TASK_STOPPED;
 582                        notify_parent(current, SIGCHLD);
 583                        schedule();
 584
 585                        signr = current->exit_code;
 586                        current->thread.siginfo = 0;
 587
 588                        /* We're back.  Did the debugger cancel the sig?  */
 589                        if (!signr)
 590                                continue;
 591                        current->exit_code = 0;
 592
 593                        /* The debugger continued.  Ignore SIGSTOP.  */
 594                        if (signr == SIGSTOP)
 595                                continue;
 596
 597                        /* Update the siginfo structure.  Is this good?  */
 598                        if (signr != info.si_signo) {
 599                                info.si_signo = signr;
 600                                info.si_errno = 0;
 601                                info.si_code = SI_USER;
 602                                info.si_pid = current->p_pptr->pid;
 603                                info.si_uid = current->p_pptr->uid;
 604                        }
 605
 606                        /* If the (new) signal is now blocked, requeue it.  */
 607                        if (sigismember(&current->blocked, signr)) {
 608                                send_sig_info(signr, &info, current);
 609                                continue;
 610                        }
 611                }
 612
 613                ka = &current->sig->action[signr - 1];
 614                if (ka->sa.sa_handler == SIG_IGN) {
 615                        if (signr != SIGCHLD)
 616                                continue;
 617                        /* Check for SIGCHLD: it's special.  */
 618                        while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0)
 619                                /* nothing */;
 620                        continue;
 621                }
 622
 623                if (ka->sa.sa_handler == SIG_DFL) {
 624                        int exit_code = signr;
 625
 626                        /* Init gets no signals it doesn't want.  */
 627                        if (current->pid == 1)
 628                                continue;
 629
 630                        switch (signr) {
 631                              case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG:
 632                                continue;
 633
 634                              case SIGTSTP: case SIGTTIN: case SIGTTOU:
 635                                if (is_orphaned_pgrp(current->pgrp))
 636                                        continue;
 637                                /* FALLTHRU */
 638
 639                              case SIGSTOP:
 640                                current->state = TASK_STOPPED;
 641                                current->exit_code = signr;
 642                                sig = current->p_pptr->sig;
 643                                if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP))
 644                                        notify_parent(current, SIGCHLD);
 645                                schedule();
 646                                continue;
 647
 648                              case SIGQUIT: case SIGILL: case SIGTRAP:
 649                              case SIGABRT: case SIGFPE: case SIGSEGV:
 650                              case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ:
 651                                if (do_coredump(signr, &scr->pt))
 652                                        exit_code |= 0x80;
 653                                /* FALLTHRU */
 654
 655                              default:
 656                                sig_exit(signr, exit_code, &info);
 657                                /* NOTREACHED */
 658                        }
 659                }
 660
 661                if (restart) {
 662                        switch (errno) {
 663                              case ERESTARTSYS:
 664                                if ((ka->sa.sa_flags & SA_RESTART) == 0) {
 665                              case ERESTARTNOHAND:
 666#ifdef CONFIG_IA32_SUPPORT
 667                                        if (IS_IA32_PROCESS(&scr->pt))
 668                                                scr->pt.r8 = -EINTR;
 669                                        else
 670#endif
 671                                        scr->pt.r8 = EINTR;
 672                                        /* note: scr->pt.r10 is already -1 */
 673                                        break;
 674                                }
 675                              case ERESTARTNOINTR:
 676#ifdef CONFIG_IA32_SUPPORT
 677                                if (IS_IA32_PROCESS(&scr->pt)) {
 678                                        scr->pt.r8 = scr->pt.r1;
 679                                        scr->pt.cr_iip -= 2;
 680                                } else
 681#endif
 682                                ia64_decrement_ip(&scr->pt);
 683                        }
 684                }
 685
 686                /* Whee!  Actually deliver the signal.  If the
 687                   delivery failed, we need to continue to iterate in
 688                   this loop so we can deliver the SIGSEGV... */
 689                if (handle_signal(signr, ka, &info, oldset, scr))
 690                        return 1;
 691        }
 692
 693        /* Did we come from a system call? */
 694        if (restart) {
 695                /* Restart the system call - no handlers present */
 696                if (errno == ERESTARTNOHAND || errno == ERESTARTSYS || errno == ERESTARTNOINTR) {
 697#ifdef CONFIG_IA32_SUPPORT
 698                        if (IS_IA32_PROCESS(&scr->pt)) {
 699                                scr->pt.r8 = scr->pt.r1;
 700                                scr->pt.cr_iip -= 2;
 701                        } else
 702#endif
 703                        /*
 704                         * Note: the syscall number is in r15 which is
 705                         * saved in pt_regs so all we need to do here
 706                         * is adjust ip so that the "break"
 707                         * instruction gets re-executed.
 708                         */
 709                        ia64_decrement_ip(&scr->pt);
 710                }
 711        }
 712        return 0;
 713}
 714
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.