linux/arch/sparc/kernel/signal_32.c
<<
>>
Prefs
   1/*  linux/arch/sparc/kernel/signal.c
   2 *
   3 *  Copyright (C) 1991, 1992  Linus Torvalds
   4 *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
   5 *  Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
   6 *  Copyright (C) 1997 Eddie C. Dost   (ecd@skynet.be)
   7 */
   8
   9#include <linux/sched.h>
  10#include <linux/kernel.h>
  11#include <linux/signal.h>
  12#include <linux/errno.h>
  13#include <linux/wait.h>
  14#include <linux/ptrace.h>
  15#include <linux/unistd.h>
  16#include <linux/mm.h>
  17#include <linux/tty.h>
  18#include <linux/smp.h>
  19#include <linux/binfmts.h>      /* do_coredum */
  20#include <linux/bitops.h>
  21#include <linux/tracehook.h>
  22
  23#include <linux/uaccess.h>
  24#include <asm/ptrace.h>
  25#include <asm/pgalloc.h>
  26#include <asm/pgtable.h>
  27#include <asm/cacheflush.h>     /* flush_sig_insns */
  28#include <asm/switch_to.h>
  29
  30#include "sigutil.h"
  31#include "kernel.h"
  32
  33extern void fpsave(unsigned long *fpregs, unsigned long *fsr,
  34                   void *fpqueue, unsigned long *fpqdepth);
  35extern void fpload(unsigned long *fpregs, unsigned long *fsr);
  36
  37struct signal_frame {
  38        struct sparc_stackf     ss;
  39        __siginfo32_t           info;
  40        __siginfo_fpu_t __user  *fpu_save;
  41        unsigned long           insns[2] __attribute__ ((aligned (8)));
  42        unsigned int            extramask[_NSIG_WORDS - 1];
  43        unsigned int            extra_size; /* Should be 0 */
  44        __siginfo_rwin_t __user *rwin_save;
  45} __attribute__((aligned(8)));
  46
  47struct rt_signal_frame {
  48        struct sparc_stackf     ss;
  49        siginfo_t               info;
  50        struct pt_regs          regs;
  51        sigset_t                mask;
  52        __siginfo_fpu_t __user  *fpu_save;
  53        unsigned int            insns[2];
  54        stack_t                 stack;
  55        unsigned int            extra_size; /* Should be 0 */
  56        __siginfo_rwin_t __user *rwin_save;
  57} __attribute__((aligned(8)));
  58
  59/* Align macros */
  60#define SF_ALIGNEDSZ  (((sizeof(struct signal_frame) + 7) & (~7)))
  61#define RT_ALIGNEDSZ  (((sizeof(struct rt_signal_frame) + 7) & (~7)))
  62
  63/* Checks if the fp is valid.  We always build signal frames which are
  64 * 16-byte aligned, therefore we can always enforce that the restore
  65 * frame has that property as well.
  66 */
  67static inline bool invalid_frame_pointer(void __user *fp, int fplen)
  68{
  69        if ((((unsigned long) fp) & 15) || !__access_ok((unsigned long)fp, fplen))
  70                return true;
  71
  72        return false;
  73}
  74
  75asmlinkage void do_sigreturn(struct pt_regs *regs)
  76{
  77        unsigned long up_psr, pc, npc, ufp;
  78        struct signal_frame __user *sf;
  79        sigset_t set;
  80        __siginfo_fpu_t __user *fpu_save;
  81        __siginfo_rwin_t __user *rwin_save;
  82        int err;
  83
  84        /* Always make any pending restarted system calls return -EINTR */
  85        current->restart_block.fn = do_no_restart_syscall;
  86
  87        synchronize_user_stack();
  88
  89        sf = (struct signal_frame __user *) regs->u_regs[UREG_FP];
  90
  91        /* 1. Make sure we are not getting garbage from the user */
  92        if (invalid_frame_pointer(sf, sizeof(*sf)))
  93                goto segv_and_exit;
  94
  95        if (get_user(ufp, &sf->info.si_regs.u_regs[UREG_FP]))
  96                goto segv_and_exit;
  97
  98        if (ufp & 0x7)
  99                goto segv_and_exit;
 100
 101        err = __get_user(pc,  &sf->info.si_regs.pc);
 102        err |= __get_user(npc, &sf->info.si_regs.npc);
 103
 104        if ((pc | npc) & 3)
 105                goto segv_and_exit;
 106
 107        /* 2. Restore the state */
 108        up_psr = regs->psr;
 109        err |= __copy_from_user(regs, &sf->info.si_regs, sizeof(struct pt_regs));
 110
 111        /* User can only change condition codes and FPU enabling in %psr. */
 112        regs->psr = (up_psr & ~(PSR_ICC | PSR_EF))
 113                  | (regs->psr & (PSR_ICC | PSR_EF));
 114
 115        /* Prevent syscall restart.  */
 116        pt_regs_clear_syscall(regs);
 117
 118        err |= __get_user(fpu_save, &sf->fpu_save);
 119        if (fpu_save)
 120                err |= restore_fpu_state(regs, fpu_save);
 121        err |= __get_user(rwin_save, &sf->rwin_save);
 122        if (rwin_save)
 123                err |= restore_rwin_state(rwin_save);
 124
 125        /* This is pretty much atomic, no amount locking would prevent
 126         * the races which exist anyways.
 127         */
 128        err |= __get_user(set.sig[0], &sf->info.si_mask);
 129        err |= __copy_from_user(&set.sig[1], &sf->extramask,
 130                                (_NSIG_WORDS-1) * sizeof(unsigned int));
 131                           
 132        if (err)
 133                goto segv_and_exit;
 134
 135        set_current_blocked(&set);
 136        return;
 137
 138segv_and_exit:
 139        force_sig(SIGSEGV, current);
 140}
 141
 142asmlinkage void do_rt_sigreturn(struct pt_regs *regs)
 143{
 144        struct rt_signal_frame __user *sf;
 145        unsigned int psr, pc, npc, ufp;
 146        __siginfo_fpu_t __user *fpu_save;
 147        __siginfo_rwin_t __user *rwin_save;
 148        sigset_t set;
 149        int err;
 150
 151        synchronize_user_stack();
 152        sf = (struct rt_signal_frame __user *) regs->u_regs[UREG_FP];
 153        if (invalid_frame_pointer(sf, sizeof(*sf)))
 154                goto segv;
 155
 156        if (get_user(ufp, &sf->regs.u_regs[UREG_FP]))
 157                goto segv;
 158
 159        if (ufp & 0x7)
 160                goto segv;
 161
 162        err = __get_user(pc, &sf->regs.pc);
 163        err |= __get_user(npc, &sf->regs.npc);
 164        err |= ((pc | npc) & 0x03);
 165
 166        err |= __get_user(regs->y, &sf->regs.y);
 167        err |= __get_user(psr, &sf->regs.psr);
 168
 169        err |= __copy_from_user(&regs->u_regs[UREG_G1],
 170                                &sf->regs.u_regs[UREG_G1], 15 * sizeof(u32));
 171
 172        regs->psr = (regs->psr & ~PSR_ICC) | (psr & PSR_ICC);
 173
 174        /* Prevent syscall restart.  */
 175        pt_regs_clear_syscall(regs);
 176
 177        err |= __get_user(fpu_save, &sf->fpu_save);
 178        if (!err && fpu_save)
 179                err |= restore_fpu_state(regs, fpu_save);
 180        err |= __copy_from_user(&set, &sf->mask, sizeof(sigset_t));
 181        err |= restore_altstack(&sf->stack);
 182        
 183        if (err)
 184                goto segv;
 185                
 186        regs->pc = pc;
 187        regs->npc = npc;
 188        
 189        err |= __get_user(rwin_save, &sf->rwin_save);
 190        if (!err && rwin_save) {
 191                if (restore_rwin_state(rwin_save))
 192                        goto segv;
 193        }
 194
 195        set_current_blocked(&set);
 196        return;
 197segv:
 198        force_sig(SIGSEGV, current);
 199}
 200
 201static inline void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
 202{
 203        unsigned long sp = regs->u_regs[UREG_FP];
 204
 205        /*
 206         * If we are on the alternate signal stack and would overflow it, don't.
 207         * Return an always-bogus address instead so we will die with SIGSEGV.
 208         */
 209        if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
 210                return (void __user *) -1L;
 211
 212        /* This is the X/Open sanctioned signal stack switching.  */
 213        sp = sigsp(sp, ksig) - framesize;
 214
 215        /* Always align the stack frame.  This handles two cases.  First,
 216         * sigaltstack need not be mindful of platform specific stack
 217         * alignment.  Second, if we took this signal because the stack
 218         * is not aligned properly, we'd like to take the signal cleanly
 219         * and report that.
 220         */
 221        sp &= ~15UL;
 222
 223        return (void __user *) sp;
 224}
 225
 226static int setup_frame(struct ksignal *ksig, struct pt_regs *regs,
 227                       sigset_t *oldset)
 228{
 229        struct signal_frame __user *sf;
 230        int sigframe_size, err, wsaved;
 231        void __user *tail;
 232
 233        /* 1. Make sure everything is clean */
 234        synchronize_user_stack();
 235
 236        wsaved = current_thread_info()->w_saved;
 237
 238        sigframe_size = sizeof(*sf);
 239        if (used_math())
 240                sigframe_size += sizeof(__siginfo_fpu_t);
 241        if (wsaved)
 242                sigframe_size += sizeof(__siginfo_rwin_t);
 243
 244        sf = (struct signal_frame __user *)
 245                get_sigframe(ksig, regs, sigframe_size);
 246
 247        if (invalid_frame_pointer(sf, sigframe_size)) {
 248                do_exit(SIGILL);
 249                return -EINVAL;
 250        }
 251
 252        tail = sf + 1;
 253
 254        /* 2. Save the current process state */
 255        err = __copy_to_user(&sf->info.si_regs, regs, sizeof(struct pt_regs));
 256        
 257        err |= __put_user(0, &sf->extra_size);
 258
 259        if (used_math()) {
 260                __siginfo_fpu_t __user *fp = tail;
 261                tail += sizeof(*fp);
 262                err |= save_fpu_state(regs, fp);
 263                err |= __put_user(fp, &sf->fpu_save);
 264        } else {
 265                err |= __put_user(0, &sf->fpu_save);
 266        }
 267        if (wsaved) {
 268                __siginfo_rwin_t __user *rwp = tail;
 269                tail += sizeof(*rwp);
 270                err |= save_rwin_state(wsaved, rwp);
 271                err |= __put_user(rwp, &sf->rwin_save);
 272        } else {
 273                err |= __put_user(0, &sf->rwin_save);
 274        }
 275
 276        err |= __put_user(oldset->sig[0], &sf->info.si_mask);
 277        err |= __copy_to_user(sf->extramask, &oldset->sig[1],
 278                              (_NSIG_WORDS - 1) * sizeof(unsigned int));
 279        if (!wsaved) {
 280                err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
 281                                      sizeof(struct reg_window32));
 282        } else {
 283                struct reg_window32 *rp;
 284
 285                rp = &current_thread_info()->reg_window[wsaved - 1];
 286                err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
 287        }
 288        if (err)
 289                return err;
 290        
 291        /* 3. signal handler back-trampoline and parameters */
 292        regs->u_regs[UREG_FP] = (unsigned long) sf;
 293        regs->u_regs[UREG_I0] = ksig->sig;
 294        regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
 295        regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
 296
 297        /* 4. signal handler */
 298        regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
 299        regs->npc = (regs->pc + 4);
 300
 301        /* 5. return to kernel instructions */
 302        if (ksig->ka.ka_restorer)
 303                regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
 304        else {
 305                regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2);
 306
 307                /* mov __NR_sigreturn, %g1 */
 308                err |= __put_user(0x821020d8, &sf->insns[0]);
 309
 310                /* t 0x10 */
 311                err |= __put_user(0x91d02010, &sf->insns[1]);
 312                if (err)
 313                        return err;
 314
 315                /* Flush instruction space. */
 316                flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
 317        }
 318        return 0;
 319}
 320
 321static int setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs,
 322                          sigset_t *oldset)
 323{
 324        struct rt_signal_frame __user *sf;
 325        int sigframe_size, wsaved;
 326        void __user *tail;
 327        unsigned int psr;
 328        int err;
 329
 330        synchronize_user_stack();
 331        wsaved = current_thread_info()->w_saved;
 332        sigframe_size = sizeof(*sf);
 333        if (used_math())
 334                sigframe_size += sizeof(__siginfo_fpu_t);
 335        if (wsaved)
 336                sigframe_size += sizeof(__siginfo_rwin_t);
 337        sf = (struct rt_signal_frame __user *)
 338                get_sigframe(ksig, regs, sigframe_size);
 339        if (invalid_frame_pointer(sf, sigframe_size)) {
 340                do_exit(SIGILL);
 341                return -EINVAL;
 342        }
 343
 344        tail = sf + 1;
 345        err  = __put_user(regs->pc, &sf->regs.pc);
 346        err |= __put_user(regs->npc, &sf->regs.npc);
 347        err |= __put_user(regs->y, &sf->regs.y);
 348        psr = regs->psr;
 349        if (used_math())
 350                psr |= PSR_EF;
 351        err |= __put_user(psr, &sf->regs.psr);
 352        err |= __copy_to_user(&sf->regs.u_regs, regs->u_regs, sizeof(regs->u_regs));
 353        err |= __put_user(0, &sf->extra_size);
 354
 355        if (psr & PSR_EF) {
 356                __siginfo_fpu_t __user *fp = tail;
 357                tail += sizeof(*fp);
 358                err |= save_fpu_state(regs, fp);
 359                err |= __put_user(fp, &sf->fpu_save);
 360        } else {
 361                err |= __put_user(0, &sf->fpu_save);
 362        }
 363        if (wsaved) {
 364                __siginfo_rwin_t __user *rwp = tail;
 365                tail += sizeof(*rwp);
 366                err |= save_rwin_state(wsaved, rwp);
 367                err |= __put_user(rwp, &sf->rwin_save);
 368        } else {
 369                err |= __put_user(0, &sf->rwin_save);
 370        }
 371        err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
 372        
 373        /* Setup sigaltstack */
 374        err |= __save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
 375        
 376        if (!wsaved) {
 377                err |= __copy_to_user(sf, (char *) regs->u_regs[UREG_FP],
 378                                      sizeof(struct reg_window32));
 379        } else {
 380                struct reg_window32 *rp;
 381
 382                rp = &current_thread_info()->reg_window[wsaved - 1];
 383                err |= __copy_to_user(sf, rp, sizeof(struct reg_window32));
 384        }
 385
 386        err |= copy_siginfo_to_user(&sf->info, &ksig->info);
 387
 388        if (err)
 389                return err;
 390
 391        regs->u_regs[UREG_FP] = (unsigned long) sf;
 392        regs->u_regs[UREG_I0] = ksig->sig;
 393        regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
 394        regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
 395
 396        regs->pc = (unsigned long) ksig->ka.sa.sa_handler;
 397        regs->npc = (regs->pc + 4);
 398
 399        if (ksig->ka.ka_restorer)
 400                regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
 401        else {
 402                regs->u_regs[UREG_I7] = (unsigned long)(&(sf->insns[0]) - 2);
 403
 404                /* mov __NR_sigreturn, %g1 */
 405                err |= __put_user(0x821020d8, &sf->insns[0]);
 406
 407                /* t 0x10 */
 408                err |= __put_user(0x91d02010, &sf->insns[1]);
 409                if (err)
 410                        return err;
 411
 412                /* Flush instruction space. */
 413                flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
 414        }
 415        return 0;
 416}
 417
 418static inline void
 419handle_signal(struct ksignal *ksig, struct pt_regs *regs)
 420{
 421        sigset_t *oldset = sigmask_to_save();
 422        int err;
 423
 424        if (ksig->ka.sa.sa_flags & SA_SIGINFO)
 425                err = setup_rt_frame(ksig, regs, oldset);
 426        else
 427                err = setup_frame(ksig, regs, oldset);
 428        signal_setup_done(err, ksig, 0);
 429}
 430
 431static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs,
 432                                   struct sigaction *sa)
 433{
 434        switch(regs->u_regs[UREG_I0]) {
 435        case ERESTART_RESTARTBLOCK:
 436        case ERESTARTNOHAND:
 437        no_system_call_restart:
 438                regs->u_regs[UREG_I0] = EINTR;
 439                regs->psr |= PSR_C;
 440                break;
 441        case ERESTARTSYS:
 442                if (!(sa->sa_flags & SA_RESTART))
 443                        goto no_system_call_restart;
 444                /* fallthrough */
 445        case ERESTARTNOINTR:
 446                regs->u_regs[UREG_I0] = orig_i0;
 447                regs->pc -= 4;
 448                regs->npc -= 4;
 449        }
 450}
 451
 452/* Note that 'init' is a special process: it doesn't get signals it doesn't
 453 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 454 * mistake.
 455 */
 456static void do_signal(struct pt_regs *regs, unsigned long orig_i0)
 457{
 458        struct ksignal ksig;
 459        int restart_syscall;
 460        bool has_handler;
 461
 462        /* It's a lot of work and synchronization to add a new ptrace
 463         * register for GDB to save and restore in order to get
 464         * orig_i0 correct for syscall restarts when debugging.
 465         *
 466         * Although it should be the case that most of the global
 467         * registers are volatile across a system call, glibc already
 468         * depends upon that fact that we preserve them.  So we can't
 469         * just use any global register to save away the orig_i0 value.
 470         *
 471         * In particular %g2, %g3, %g4, and %g5 are all assumed to be
 472         * preserved across a system call trap by various pieces of
 473         * code in glibc.
 474         *
 475         * %g7 is used as the "thread register".   %g6 is not used in
 476         * any fixed manner.  %g6 is used as a scratch register and
 477         * a compiler temporary, but it's value is never used across
 478         * a system call.  Therefore %g6 is usable for orig_i0 storage.
 479         */
 480        if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C))
 481                regs->u_regs[UREG_G6] = orig_i0;
 482
 483        has_handler = get_signal(&ksig);
 484
 485        /* If the debugger messes with the program counter, it clears
 486         * the software "in syscall" bit, directing us to not perform
 487         * a syscall restart.
 488         */
 489        restart_syscall = 0;
 490        if (pt_regs_is_syscall(regs) && (regs->psr & PSR_C)) {
 491                restart_syscall = 1;
 492                orig_i0 = regs->u_regs[UREG_G6];
 493        }
 494
 495        if (has_handler) {
 496                if (restart_syscall)
 497                        syscall_restart(orig_i0, regs, &ksig.ka.sa);
 498                handle_signal(&ksig, regs);
 499        } else {
 500                if (restart_syscall) {
 501                        switch (regs->u_regs[UREG_I0]) {
 502                        case ERESTARTNOHAND:
 503                        case ERESTARTSYS:
 504                        case ERESTARTNOINTR:
 505                                /* replay the system call when we are done */
 506                                regs->u_regs[UREG_I0] = orig_i0;
 507                                regs->pc -= 4;
 508                                regs->npc -= 4;
 509                                pt_regs_clear_syscall(regs);
 510                        case ERESTART_RESTARTBLOCK:
 511                                regs->u_regs[UREG_G1] = __NR_restart_syscall;
 512                                regs->pc -= 4;
 513                                regs->npc -= 4;
 514                                pt_regs_clear_syscall(regs);
 515                        }
 516                }
 517                restore_saved_sigmask();
 518        }
 519}
 520
 521void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0,
 522                      unsigned long thread_info_flags)
 523{
 524        if (thread_info_flags & _TIF_SIGPENDING)
 525                do_signal(regs, orig_i0);
 526        if (thread_info_flags & _TIF_NOTIFY_RESUME) {
 527                clear_thread_flag(TIF_NOTIFY_RESUME);
 528                tracehook_notify_resume(regs);
 529        }
 530}
 531
 532asmlinkage int do_sys_sigstack(struct sigstack __user *ssptr,
 533                               struct sigstack __user *ossptr,
 534                               unsigned long sp)
 535{
 536        int ret = -EFAULT;
 537
 538        /* First see if old state is wanted. */
 539        if (ossptr) {
 540                if (put_user(current->sas_ss_sp + current->sas_ss_size,
 541                             &ossptr->the_stack) ||
 542                    __put_user(on_sig_stack(sp), &ossptr->cur_status))
 543                        goto out;
 544        }
 545
 546        /* Now see if we want to update the new state. */
 547        if (ssptr) {
 548                char *ss_sp;
 549
 550                if (get_user(ss_sp, &ssptr->the_stack))
 551                        goto out;
 552                /* If the current stack was set with sigaltstack, don't
 553                   swap stacks while we are on it.  */
 554                ret = -EPERM;
 555                if (current->sas_ss_sp && on_sig_stack(sp))
 556                        goto out;
 557
 558                /* Since we don't know the extent of the stack, and we don't
 559                   track onstack-ness, but rather calculate it, we must
 560                   presume a size.  Ho hum this interface is lossy.  */
 561                current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
 562                current->sas_ss_size = SIGSTKSZ;
 563        }
 564        ret = 0;
 565out:
 566        return ret;
 567}
 568