linux/arch/sparc/kernel/signal32.c
<<
>>
Prefs
   1/*  arch/sparc64/kernel/signal32.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 *  Copyright (C) 1997,1998 Jakub Jelinek   (jj@sunsite.mff.cuni.cz)
   8 */
   9
  10#include <linux/sched.h>
  11#include <linux/kernel.h>
  12#include <linux/signal.h>
  13#include <linux/errno.h>
  14#include <linux/wait.h>
  15#include <linux/ptrace.h>
  16#include <linux/unistd.h>
  17#include <linux/mm.h>
  18#include <linux/tty.h>
  19#include <linux/binfmts.h>
  20#include <linux/compat.h>
  21#include <linux/bitops.h>
  22#include <linux/tracehook.h>
  23
  24#include <asm/uaccess.h>
  25#include <asm/ptrace.h>
  26#include <asm/pgtable.h>
  27#include <asm/psrcompat.h>
  28#include <asm/fpumacro.h>
  29#include <asm/visasm.h>
  30#include <asm/compat_signal.h>
  31#include <asm/switch_to.h>
  32
  33#include "sigutil.h"
  34
  35/* This magic should be in g_upper[0] for all upper parts
  36 * to be valid.
  37 */
  38#define SIGINFO_EXTRA_V8PLUS_MAGIC      0x130e269
  39typedef struct {
  40        unsigned int g_upper[8];
  41        unsigned int o_upper[8];
  42        unsigned int asi;
  43} siginfo_extra_v8plus_t;
  44
  45struct signal_frame32 {
  46        struct sparc_stackf32   ss;
  47        __siginfo32_t           info;
  48        /* __siginfo_fpu_t * */ u32 fpu_save;
  49        unsigned int            insns[2];
  50        unsigned int            extramask[_COMPAT_NSIG_WORDS - 1];
  51        unsigned int            extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
  52        /* Only valid if (info.si_regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
  53        siginfo_extra_v8plus_t  v8plus;
  54        /* __siginfo_rwin_t * */u32 rwin_save;
  55} __attribute__((aligned(8)));
  56
  57struct rt_signal_frame32 {
  58        struct sparc_stackf32   ss;
  59        compat_siginfo_t        info;
  60        struct pt_regs32        regs;
  61        compat_sigset_t         mask;
  62        /* __siginfo_fpu_t * */ u32 fpu_save;
  63        unsigned int            insns[2];
  64        compat_stack_t          stack;
  65        unsigned int            extra_size; /* Should be sizeof(siginfo_extra_v8plus_t) */
  66        /* Only valid if (regs.psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS */
  67        siginfo_extra_v8plus_t  v8plus;
  68        /* __siginfo_rwin_t * */u32 rwin_save;
  69} __attribute__((aligned(8)));
  70
  71int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
  72{
  73        int err;
  74
  75        if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
  76                return -EFAULT;
  77
  78        /* If you change siginfo_t structure, please be sure
  79           this code is fixed accordingly.
  80           It should never copy any pad contained in the structure
  81           to avoid security leaks, but must copy the generic
  82           3 ints plus the relevant union member.
  83           This routine must convert siginfo from 64bit to 32bit as well
  84           at the same time.  */
  85        err = __put_user(from->si_signo, &to->si_signo);
  86        err |= __put_user(from->si_errno, &to->si_errno);
  87        err |= __put_user((short)from->si_code, &to->si_code);
  88        if (from->si_code < 0)
  89                err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
  90        else {
  91                switch (from->si_code >> 16) {
  92                case __SI_TIMER >> 16:
  93                        err |= __put_user(from->si_tid, &to->si_tid);
  94                        err |= __put_user(from->si_overrun, &to->si_overrun);
  95                        err |= __put_user(from->si_int, &to->si_int);
  96                        break;
  97                case __SI_CHLD >> 16:
  98                        err |= __put_user(from->si_utime, &to->si_utime);
  99                        err |= __put_user(from->si_stime, &to->si_stime);
 100                        err |= __put_user(from->si_status, &to->si_status);
 101                default:
 102                        err |= __put_user(from->si_pid, &to->si_pid);
 103                        err |= __put_user(from->si_uid, &to->si_uid);
 104                        break;
 105                case __SI_FAULT >> 16:
 106                        err |= __put_user(from->si_trapno, &to->si_trapno);
 107                        err |= __put_user((unsigned long)from->si_addr, &to->si_addr);
 108                        break;
 109                case __SI_POLL >> 16:
 110                        err |= __put_user(from->si_band, &to->si_band);
 111                        err |= __put_user(from->si_fd, &to->si_fd);
 112                        break;
 113                case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */
 114                case __SI_MESGQ >> 16:
 115                        err |= __put_user(from->si_pid, &to->si_pid);
 116                        err |= __put_user(from->si_uid, &to->si_uid);
 117                        err |= __put_user(from->si_int, &to->si_int);
 118                        break;
 119                }
 120        }
 121        return err;
 122}
 123
 124/* CAUTION: This is just a very minimalist implementation for the
 125 *          sake of compat_sys_rt_sigqueueinfo()
 126 */
 127int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
 128{
 129        if (!access_ok(VERIFY_WRITE, from, sizeof(compat_siginfo_t)))
 130                return -EFAULT;
 131
 132        if (copy_from_user(to, from, 3*sizeof(int)) ||
 133            copy_from_user(to->_sifields._pad, from->_sifields._pad,
 134                           SI_PAD_SIZE))
 135                return -EFAULT;
 136
 137        return 0;
 138}
 139
 140void do_sigreturn32(struct pt_regs *regs)
 141{
 142        struct signal_frame32 __user *sf;
 143        compat_uptr_t fpu_save;
 144        compat_uptr_t rwin_save;
 145        unsigned int psr;
 146        unsigned pc, npc;
 147        sigset_t set;
 148        unsigned seta[_COMPAT_NSIG_WORDS];
 149        int err, i;
 150        
 151        /* Always make any pending restarted system calls return -EINTR */
 152        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 153
 154        synchronize_user_stack();
 155
 156        regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
 157        sf = (struct signal_frame32 __user *) regs->u_regs[UREG_FP];
 158
 159        /* 1. Make sure we are not getting garbage from the user */
 160        if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
 161            (((unsigned long) sf) & 3))
 162                goto segv;
 163
 164        if (get_user(pc, &sf->info.si_regs.pc) ||
 165            __get_user(npc, &sf->info.si_regs.npc))
 166                goto segv;
 167
 168        if ((pc | npc) & 3)
 169                goto segv;
 170
 171        if (test_thread_flag(TIF_32BIT)) {
 172                pc &= 0xffffffff;
 173                npc &= 0xffffffff;
 174        }
 175        regs->tpc = pc;
 176        regs->tnpc = npc;
 177
 178        /* 2. Restore the state */
 179        err = __get_user(regs->y, &sf->info.si_regs.y);
 180        err |= __get_user(psr, &sf->info.si_regs.psr);
 181
 182        for (i = UREG_G1; i <= UREG_I7; i++)
 183                err |= __get_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
 184        if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
 185                err |= __get_user(i, &sf->v8plus.g_upper[0]);
 186                if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
 187                        unsigned long asi;
 188
 189                        for (i = UREG_G1; i <= UREG_I7; i++)
 190                                err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
 191                        err |= __get_user(asi, &sf->v8plus.asi);
 192                        regs->tstate &= ~TSTATE_ASI;
 193                        regs->tstate |= ((asi & 0xffUL) << 24UL);
 194                }
 195        }
 196
 197        /* User can only change condition codes in %tstate. */
 198        regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
 199        regs->tstate |= psr_to_tstate_icc(psr);
 200
 201        /* Prevent syscall restart.  */
 202        pt_regs_clear_syscall(regs);
 203
 204        err |= __get_user(fpu_save, &sf->fpu_save);
 205        if (!err && fpu_save)
 206                err |= restore_fpu_state(regs, compat_ptr(fpu_save));
 207        err |= __get_user(rwin_save, &sf->rwin_save);
 208        if (!err && rwin_save) {
 209                if (restore_rwin_state(compat_ptr(rwin_save)))
 210                        goto segv;
 211        }
 212        err |= __get_user(seta[0], &sf->info.si_mask);
 213        err |= copy_from_user(seta+1, &sf->extramask,
 214                              (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
 215        if (err)
 216                goto segv;
 217        switch (_NSIG_WORDS) {
 218                case 4: set.sig[3] = seta[6] + (((long)seta[7]) << 32);
 219                case 3: set.sig[2] = seta[4] + (((long)seta[5]) << 32);
 220                case 2: set.sig[1] = seta[2] + (((long)seta[3]) << 32);
 221                case 1: set.sig[0] = seta[0] + (((long)seta[1]) << 32);
 222        }
 223        set_current_blocked(&set);
 224        return;
 225
 226segv:
 227        force_sig(SIGSEGV, current);
 228}
 229
 230asmlinkage void do_rt_sigreturn32(struct pt_regs *regs)
 231{
 232        struct rt_signal_frame32 __user *sf;
 233        unsigned int psr, pc, npc;
 234        compat_uptr_t fpu_save;
 235        compat_uptr_t rwin_save;
 236        sigset_t set;
 237        compat_sigset_t seta;
 238        int err, i;
 239        
 240        /* Always make any pending restarted system calls return -EINTR */
 241        current_thread_info()->restart_block.fn = do_no_restart_syscall;
 242
 243        synchronize_user_stack();
 244        regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
 245        sf = (struct rt_signal_frame32 __user *) regs->u_regs[UREG_FP];
 246
 247        /* 1. Make sure we are not getting garbage from the user */
 248        if (!access_ok(VERIFY_READ, sf, sizeof(*sf)) ||
 249            (((unsigned long) sf) & 3))
 250                goto segv;
 251
 252        if (get_user(pc, &sf->regs.pc) || 
 253            __get_user(npc, &sf->regs.npc))
 254                goto segv;
 255
 256        if ((pc | npc) & 3)
 257                goto segv;
 258
 259        if (test_thread_flag(TIF_32BIT)) {
 260                pc &= 0xffffffff;
 261                npc &= 0xffffffff;
 262        }
 263        regs->tpc = pc;
 264        regs->tnpc = npc;
 265
 266        /* 2. Restore the state */
 267        err = __get_user(regs->y, &sf->regs.y);
 268        err |= __get_user(psr, &sf->regs.psr);
 269        
 270        for (i = UREG_G1; i <= UREG_I7; i++)
 271                err |= __get_user(regs->u_regs[i], &sf->regs.u_regs[i]);
 272        if ((psr & (PSR_VERS|PSR_IMPL)) == PSR_V8PLUS) {
 273                err |= __get_user(i, &sf->v8plus.g_upper[0]);
 274                if (i == SIGINFO_EXTRA_V8PLUS_MAGIC) {
 275                        unsigned long asi;
 276
 277                        for (i = UREG_G1; i <= UREG_I7; i++)
 278                                err |= __get_user(((u32 *)regs->u_regs)[2*i], &sf->v8plus.g_upper[i]);
 279                        err |= __get_user(asi, &sf->v8plus.asi);
 280                        regs->tstate &= ~TSTATE_ASI;
 281                        regs->tstate |= ((asi & 0xffUL) << 24UL);
 282                }
 283        }
 284
 285        /* User can only change condition codes in %tstate. */
 286        regs->tstate &= ~(TSTATE_ICC|TSTATE_XCC);
 287        regs->tstate |= psr_to_tstate_icc(psr);
 288
 289        /* Prevent syscall restart.  */
 290        pt_regs_clear_syscall(regs);
 291
 292        err |= __get_user(fpu_save, &sf->fpu_save);
 293        if (!err && fpu_save)
 294                err |= restore_fpu_state(regs, compat_ptr(fpu_save));
 295        err |= copy_from_user(&seta, &sf->mask, sizeof(compat_sigset_t));
 296        err |= compat_restore_altstack(&sf->stack);
 297        if (err)
 298                goto segv;
 299                
 300        err |= __get_user(rwin_save, &sf->rwin_save);
 301        if (!err && rwin_save) {
 302                if (restore_rwin_state(compat_ptr(rwin_save)))
 303                        goto segv;
 304        }
 305
 306        switch (_NSIG_WORDS) {
 307                case 4: set.sig[3] = seta.sig[6] + (((long)seta.sig[7]) << 32);
 308                case 3: set.sig[2] = seta.sig[4] + (((long)seta.sig[5]) << 32);
 309                case 2: set.sig[1] = seta.sig[2] + (((long)seta.sig[3]) << 32);
 310                case 1: set.sig[0] = seta.sig[0] + (((long)seta.sig[1]) << 32);
 311        }
 312        set_current_blocked(&set);
 313        return;
 314segv:
 315        force_sig(SIGSEGV, current);
 316}
 317
 318/* Checks if the fp is valid */
 319static int invalid_frame_pointer(void __user *fp, int fplen)
 320{
 321        if ((((unsigned long) fp) & 7) || ((unsigned long)fp) > 0x100000000ULL - fplen)
 322                return 1;
 323        return 0;
 324}
 325
 326static void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, unsigned long framesize)
 327{
 328        unsigned long sp;
 329        
 330        regs->u_regs[UREG_FP] &= 0x00000000ffffffffUL;
 331        sp = regs->u_regs[UREG_FP];
 332        
 333        /*
 334         * If we are on the alternate signal stack and would overflow it, don't.
 335         * Return an always-bogus address instead so we will die with SIGSEGV.
 336         */
 337        if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize)))
 338                return (void __user *) -1L;
 339
 340        /* This is the X/Open sanctioned signal stack switching.  */
 341        sp = sigsp(sp, ksig) - framesize;
 342
 343        /* Always align the stack frame.  This handles two cases.  First,
 344         * sigaltstack need not be mindful of platform specific stack
 345         * alignment.  Second, if we took this signal because the stack
 346         * is not aligned properly, we'd like to take the signal cleanly
 347         * and report that.
 348         */
 349        sp &= ~15UL;
 350
 351        return (void __user *) sp;
 352}
 353
 354/* The I-cache flush instruction only works in the primary ASI, which
 355 * right now is the nucleus, aka. kernel space.
 356 *
 357 * Therefore we have to kick the instructions out using the kernel
 358 * side linear mapping of the physical address backing the user
 359 * instructions.
 360 */
 361static void flush_signal_insns(unsigned long address)
 362{
 363        unsigned long pstate, paddr;
 364        pte_t *ptep, pte;
 365        pgd_t *pgdp;
 366        pud_t *pudp;
 367        pmd_t *pmdp;
 368
 369        /* Commit all stores of the instructions we are about to flush.  */
 370        wmb();
 371
 372        /* Disable cross-call reception.  In this way even a very wide
 373         * munmap() on another cpu can't tear down the page table
 374         * hierarchy from underneath us, since that can't complete
 375         * until the IPI tlb flush returns.
 376         */
 377
 378        __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate));
 379        __asm__ __volatile__("wrpr %0, %1, %%pstate"
 380                                : : "r" (pstate), "i" (PSTATE_IE));
 381
 382        pgdp = pgd_offset(current->mm, address);
 383        if (pgd_none(*pgdp))
 384                goto out_irqs_on;
 385        pudp = pud_offset(pgdp, address);
 386        if (pud_none(*pudp))
 387                goto out_irqs_on;
 388        pmdp = pmd_offset(pudp, address);
 389        if (pmd_none(*pmdp))
 390                goto out_irqs_on;
 391
 392        ptep = pte_offset_map(pmdp, address);
 393        pte = *ptep;
 394        if (!pte_present(pte))
 395                goto out_unmap;
 396
 397        paddr = (unsigned long) page_address(pte_page(pte));
 398
 399        __asm__ __volatile__("flush     %0 + %1"
 400                             : /* no outputs */
 401                             : "r" (paddr),
 402                               "r" (address & (PAGE_SIZE - 1))
 403                             : "memory");
 404
 405out_unmap:
 406        pte_unmap(ptep);
 407out_irqs_on:
 408        __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate));
 409
 410}
 411
 412static int setup_frame32(struct ksignal *ksig, struct pt_regs *regs,
 413                         sigset_t *oldset)
 414{
 415        struct signal_frame32 __user *sf;
 416        int i, err, wsaved;
 417        void __user *tail;
 418        int sigframe_size;
 419        u32 psr;
 420        unsigned int seta[_COMPAT_NSIG_WORDS];
 421
 422        /* 1. Make sure everything is clean */
 423        synchronize_user_stack();
 424        save_and_clear_fpu();
 425        
 426        wsaved = get_thread_wsaved();
 427
 428        sigframe_size = sizeof(*sf);
 429        if (current_thread_info()->fpsaved[0] & FPRS_FEF)
 430                sigframe_size += sizeof(__siginfo_fpu_t);
 431        if (wsaved)
 432                sigframe_size += sizeof(__siginfo_rwin_t);
 433
 434        sf = (struct signal_frame32 __user *)
 435                get_sigframe(ksig, regs, sigframe_size);
 436        
 437        if (invalid_frame_pointer(sf, sigframe_size)) {
 438                do_exit(SIGILL);
 439                return -EINVAL;
 440        }
 441
 442        tail = (sf + 1);
 443
 444        /* 2. Save the current process state */
 445        if (test_thread_flag(TIF_32BIT)) {
 446                regs->tpc &= 0xffffffff;
 447                regs->tnpc &= 0xffffffff;
 448        }
 449        err  = put_user(regs->tpc, &sf->info.si_regs.pc);
 450        err |= __put_user(regs->tnpc, &sf->info.si_regs.npc);
 451        err |= __put_user(regs->y, &sf->info.si_regs.y);
 452        psr = tstate_to_psr(regs->tstate);
 453        if (current_thread_info()->fpsaved[0] & FPRS_FEF)
 454                psr |= PSR_EF;
 455        err |= __put_user(psr, &sf->info.si_regs.psr);
 456        for (i = 0; i < 16; i++)
 457                err |= __put_user(regs->u_regs[i], &sf->info.si_regs.u_regs[i]);
 458        err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
 459        err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
 460        for (i = 1; i < 16; i++)
 461                err |= __put_user(((u32 *)regs->u_regs)[2*i],
 462                                  &sf->v8plus.g_upper[i]);
 463        err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
 464                          &sf->v8plus.asi);
 465
 466        if (psr & PSR_EF) {
 467                __siginfo_fpu_t __user *fp = tail;
 468                tail += sizeof(*fp);
 469                err |= save_fpu_state(regs, fp);
 470                err |= __put_user((u64)fp, &sf->fpu_save);
 471        } else {
 472                err |= __put_user(0, &sf->fpu_save);
 473        }
 474        if (wsaved) {
 475                __siginfo_rwin_t __user *rwp = tail;
 476                tail += sizeof(*rwp);
 477                err |= save_rwin_state(wsaved, rwp);
 478                err |= __put_user((u64)rwp, &sf->rwin_save);
 479                set_thread_wsaved(0);
 480        } else {
 481                err |= __put_user(0, &sf->rwin_save);
 482        }
 483
 484        switch (_NSIG_WORDS) {
 485        case 4: seta[7] = (oldset->sig[3] >> 32);
 486                seta[6] = oldset->sig[3];
 487        case 3: seta[5] = (oldset->sig[2] >> 32);
 488                seta[4] = oldset->sig[2];
 489        case 2: seta[3] = (oldset->sig[1] >> 32);
 490                seta[2] = oldset->sig[1];
 491        case 1: seta[1] = (oldset->sig[0] >> 32);
 492                seta[0] = oldset->sig[0];
 493        }
 494        err |= __put_user(seta[0], &sf->info.si_mask);
 495        err |= __copy_to_user(sf->extramask, seta + 1,
 496                              (_COMPAT_NSIG_WORDS - 1) * sizeof(unsigned int));
 497
 498        if (!wsaved) {
 499                err |= copy_in_user((u32 __user *)sf,
 500                                    (u32 __user *)(regs->u_regs[UREG_FP]),
 501                                    sizeof(struct reg_window32));
 502        } else {
 503                struct reg_window *rp;
 504
 505                rp = &current_thread_info()->reg_window[wsaved - 1];
 506                for (i = 0; i < 8; i++)
 507                        err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
 508                for (i = 0; i < 6; i++)
 509                        err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
 510                err |= __put_user(rp->ins[6], &sf->ss.fp);
 511                err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
 512        }       
 513        if (err)
 514                return err;
 515
 516        /* 3. signal handler back-trampoline and parameters */
 517        regs->u_regs[UREG_FP] = (unsigned long) sf;
 518        regs->u_regs[UREG_I0] = ksig->sig;
 519        regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
 520        regs->u_regs[UREG_I2] = (unsigned long) &sf->info;
 521
 522        /* 4. signal handler */
 523        regs->tpc = (unsigned long) ksig->ka.sa.sa_handler;
 524        regs->tnpc = (regs->tpc + 4);
 525        if (test_thread_flag(TIF_32BIT)) {
 526                regs->tpc &= 0xffffffff;
 527                regs->tnpc &= 0xffffffff;
 528        }
 529
 530        /* 5. return to kernel instructions */
 531        if (ksig->ka.ka_restorer) {
 532                regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
 533        } else {
 534                unsigned long address = ((unsigned long)&(sf->insns[0]));
 535
 536                regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
 537        
 538                err  = __put_user(0x821020d8, &sf->insns[0]); /*mov __NR_sigreturn, %g1*/
 539                err |= __put_user(0x91d02010, &sf->insns[1]); /*t 0x10*/
 540                if (err)
 541                        return err;
 542                flush_signal_insns(address);
 543        }
 544        return 0;
 545}
 546
 547static int setup_rt_frame32(struct ksignal *ksig, struct pt_regs *regs,
 548                            sigset_t *oldset)
 549{
 550        struct rt_signal_frame32 __user *sf;
 551        int i, err, wsaved;
 552        void __user *tail;
 553        int sigframe_size;
 554        u32 psr;
 555        compat_sigset_t seta;
 556
 557        /* 1. Make sure everything is clean */
 558        synchronize_user_stack();
 559        save_and_clear_fpu();
 560        
 561        wsaved = get_thread_wsaved();
 562
 563        sigframe_size = sizeof(*sf);
 564        if (current_thread_info()->fpsaved[0] & FPRS_FEF)
 565                sigframe_size += sizeof(__siginfo_fpu_t);
 566        if (wsaved)
 567                sigframe_size += sizeof(__siginfo_rwin_t);
 568
 569        sf = (struct rt_signal_frame32 __user *)
 570                get_sigframe(ksig, regs, sigframe_size);
 571        
 572        if (invalid_frame_pointer(sf, sigframe_size)) {
 573                do_exit(SIGILL);
 574                return -EINVAL;
 575        }
 576
 577        tail = (sf + 1);
 578
 579        /* 2. Save the current process state */
 580        if (test_thread_flag(TIF_32BIT)) {
 581                regs->tpc &= 0xffffffff;
 582                regs->tnpc &= 0xffffffff;
 583        }
 584        err  = put_user(regs->tpc, &sf->regs.pc);
 585        err |= __put_user(regs->tnpc, &sf->regs.npc);
 586        err |= __put_user(regs->y, &sf->regs.y);
 587        psr = tstate_to_psr(regs->tstate);
 588        if (current_thread_info()->fpsaved[0] & FPRS_FEF)
 589                psr |= PSR_EF;
 590        err |= __put_user(psr, &sf->regs.psr);
 591        for (i = 0; i < 16; i++)
 592                err |= __put_user(regs->u_regs[i], &sf->regs.u_regs[i]);
 593        err |= __put_user(sizeof(siginfo_extra_v8plus_t), &sf->extra_size);
 594        err |= __put_user(SIGINFO_EXTRA_V8PLUS_MAGIC, &sf->v8plus.g_upper[0]);
 595        for (i = 1; i < 16; i++)
 596                err |= __put_user(((u32 *)regs->u_regs)[2*i],
 597                                  &sf->v8plus.g_upper[i]);
 598        err |= __put_user((regs->tstate & TSTATE_ASI) >> 24UL,
 599                          &sf->v8plus.asi);
 600
 601        if (psr & PSR_EF) {
 602                __siginfo_fpu_t __user *fp = tail;
 603                tail += sizeof(*fp);
 604                err |= save_fpu_state(regs, fp);
 605                err |= __put_user((u64)fp, &sf->fpu_save);
 606        } else {
 607                err |= __put_user(0, &sf->fpu_save);
 608        }
 609        if (wsaved) {
 610                __siginfo_rwin_t __user *rwp = tail;
 611                tail += sizeof(*rwp);
 612                err |= save_rwin_state(wsaved, rwp);
 613                err |= __put_user((u64)rwp, &sf->rwin_save);
 614                set_thread_wsaved(0);
 615        } else {
 616                err |= __put_user(0, &sf->rwin_save);
 617        }
 618
 619        /* Update the siginfo structure.  */
 620        err |= copy_siginfo_to_user32(&sf->info, &ksig->info);
 621        
 622        /* Setup sigaltstack */
 623        err |= __compat_save_altstack(&sf->stack, regs->u_regs[UREG_FP]);
 624
 625        switch (_NSIG_WORDS) {
 626        case 4: seta.sig[7] = (oldset->sig[3] >> 32);
 627                seta.sig[6] = oldset->sig[3];
 628        case 3: seta.sig[5] = (oldset->sig[2] >> 32);
 629                seta.sig[4] = oldset->sig[2];
 630        case 2: seta.sig[3] = (oldset->sig[1] >> 32);
 631                seta.sig[2] = oldset->sig[1];
 632        case 1: seta.sig[1] = (oldset->sig[0] >> 32);
 633                seta.sig[0] = oldset->sig[0];
 634        }
 635        err |= __copy_to_user(&sf->mask, &seta, sizeof(compat_sigset_t));
 636
 637        if (!wsaved) {
 638                err |= copy_in_user((u32 __user *)sf,
 639                                    (u32 __user *)(regs->u_regs[UREG_FP]),
 640                                    sizeof(struct reg_window32));
 641        } else {
 642                struct reg_window *rp;
 643
 644                rp = &current_thread_info()->reg_window[wsaved - 1];
 645                for (i = 0; i < 8; i++)
 646                        err |= __put_user(rp->locals[i], &sf->ss.locals[i]);
 647                for (i = 0; i < 6; i++)
 648                        err |= __put_user(rp->ins[i], &sf->ss.ins[i]);
 649                err |= __put_user(rp->ins[6], &sf->ss.fp);
 650                err |= __put_user(rp->ins[7], &sf->ss.callers_pc);
 651        }
 652        if (err)
 653                return err;
 654        
 655        /* 3. signal handler back-trampoline and parameters */
 656        regs->u_regs[UREG_FP] = (unsigned long) sf;
 657        regs->u_regs[UREG_I0] = ksig->sig;
 658        regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
 659        regs->u_regs[UREG_I2] = (unsigned long) &sf->regs;
 660
 661        /* 4. signal handler */
 662        regs->tpc = (unsigned long) ksig->ka.sa.sa_handler;
 663        regs->tnpc = (regs->tpc + 4);
 664        if (test_thread_flag(TIF_32BIT)) {
 665                regs->tpc &= 0xffffffff;
 666                regs->tnpc &= 0xffffffff;
 667        }
 668
 669        /* 5. return to kernel instructions */
 670        if (ksig->ka.ka_restorer)
 671                regs->u_regs[UREG_I7] = (unsigned long)ksig->ka.ka_restorer;
 672        else {
 673                unsigned long address = ((unsigned long)&(sf->insns[0]));
 674
 675                regs->u_regs[UREG_I7] = (unsigned long) (&(sf->insns[0]) - 2);
 676        
 677                /* mov __NR_rt_sigreturn, %g1 */
 678                err |= __put_user(0x82102065, &sf->insns[0]);
 679
 680                /* t 0x10 */
 681                err |= __put_user(0x91d02010, &sf->insns[1]);
 682                if (err)
 683                        return err;
 684
 685                flush_signal_insns(address);
 686        }
 687        return 0;
 688}
 689
 690static inline void handle_signal32(struct ksignal *ksig, 
 691                                  struct pt_regs *regs)
 692{
 693        sigset_t *oldset = sigmask_to_save();
 694        int err;
 695
 696        if (ksig->ka.sa.sa_flags & SA_SIGINFO)
 697                err = setup_rt_frame32(ksig, regs, oldset);
 698        else
 699                err = setup_frame32(ksig, regs, oldset);
 700
 701        signal_setup_done(err, ksig, 0);
 702}
 703
 704static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs,
 705                                     struct sigaction *sa)
 706{
 707        switch (regs->u_regs[UREG_I0]) {
 708        case ERESTART_RESTARTBLOCK:
 709        case ERESTARTNOHAND:
 710        no_system_call_restart:
 711                regs->u_regs[UREG_I0] = EINTR;
 712                regs->tstate |= TSTATE_ICARRY;
 713                break;
 714        case ERESTARTSYS:
 715                if (!(sa->sa_flags & SA_RESTART))
 716                        goto no_system_call_restart;
 717                /* fallthrough */
 718        case ERESTARTNOINTR:
 719                regs->u_regs[UREG_I0] = orig_i0;
 720                regs->tpc -= 4;
 721                regs->tnpc -= 4;
 722        }
 723}
 724
 725/* Note that 'init' is a special process: it doesn't get signals it doesn't
 726 * want to handle. Thus you cannot kill init even with a SIGKILL even by
 727 * mistake.
 728 */
 729void do_signal32(struct pt_regs * regs)
 730{
 731        struct ksignal ksig;
 732        unsigned long orig_i0 = 0;
 733        int restart_syscall = 0;
 734        bool has_handler = get_signal(&ksig);
 735
 736        if (pt_regs_is_syscall(regs) &&
 737            (regs->tstate & (TSTATE_XCARRY | TSTATE_ICARRY))) {
 738                restart_syscall = 1;
 739                orig_i0 = regs->u_regs[UREG_G6];
 740        }
 741
 742        if (has_handler) {
 743                if (restart_syscall)
 744                        syscall_restart32(orig_i0, regs, &ksig.ka.sa);
 745                handle_signal32(&ksig, regs);
 746        } else {
 747                if (restart_syscall) {
 748                        switch (regs->u_regs[UREG_I0]) {
 749                        case ERESTARTNOHAND:
 750                        case ERESTARTSYS:
 751                        case ERESTARTNOINTR:
 752                                /* replay the system call when we are done */
 753                                regs->u_regs[UREG_I0] = orig_i0;
 754                                regs->tpc -= 4;
 755                                regs->tnpc -= 4;
 756                                pt_regs_clear_syscall(regs);
 757                        case ERESTART_RESTARTBLOCK:
 758                                regs->u_regs[UREG_G1] = __NR_restart_syscall;
 759                                regs->tpc -= 4;
 760                                regs->tnpc -= 4;
 761                                pt_regs_clear_syscall(regs);
 762                        }
 763                }
 764                restore_saved_sigmask();
 765        }
 766}
 767
 768struct sigstack32 {
 769        u32 the_stack;
 770        int cur_status;
 771};
 772
 773asmlinkage int do_sys32_sigstack(u32 u_ssptr, u32 u_ossptr, unsigned long sp)
 774{
 775        struct sigstack32 __user *ssptr =
 776                (struct sigstack32 __user *)((unsigned long)(u_ssptr));
 777        struct sigstack32 __user *ossptr =
 778                (struct sigstack32 __user *)((unsigned long)(u_ossptr));
 779        int ret = -EFAULT;
 780
 781        /* First see if old state is wanted. */
 782        if (ossptr) {
 783                if (put_user(current->sas_ss_sp + current->sas_ss_size,
 784                             &ossptr->the_stack) ||
 785                    __put_user(on_sig_stack(sp), &ossptr->cur_status))
 786                        goto out;
 787        }
 788        
 789        /* Now see if we want to update the new state. */
 790        if (ssptr) {
 791                u32 ss_sp;
 792
 793                if (get_user(ss_sp, &ssptr->the_stack))
 794                        goto out;
 795
 796                /* If the current stack was set with sigaltstack, don't
 797                 * swap stacks while we are on it.
 798                 */
 799                ret = -EPERM;
 800                if (current->sas_ss_sp && on_sig_stack(sp))
 801                        goto out;
 802                        
 803                /* Since we don't know the extent of the stack, and we don't
 804                 * track onstack-ness, but rather calculate it, we must
 805                 * presume a size.  Ho hum this interface is lossy.
 806                 */
 807                current->sas_ss_sp = (unsigned long)ss_sp - SIGSTKSZ;
 808                current->sas_ss_size = SIGSTKSZ;
 809        }
 810        
 811        ret = 0;
 812out:
 813        return ret;
 814}
 815