static int setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs, int signr, sigset_t *oldmask) { struct sigctx_irix5 __user *ctx; unsigned long sp; int error, i; sp = regs->regs[29]; sp -= sizeof(struct sigctx_irix5); sp &= ~(0xf); ctx = (struct sigctx_irix5 __user *) sp; if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))) goto segv_and_exit; error = __put_user(0, &ctx->weird_fpu_thing); error |= __put_user(~(0x00000001), &ctx->rmask); error |= __put_user(0, &ctx->regs[0]); for(i = 1; i < 32; i++) error |= __put_user((u64) regs->regs[i], &ctx->regs[i]); error |= __put_user((u64) regs->hi, &ctx->hi); error |= __put_user((u64) regs->lo, &ctx->lo); error |= __put_user((u64) regs->cp0_epc, &ctx->pc); error |= __put_user(!!used_math(), &ctx->usedfp); error |= __put_user((u64) regs->cp0_cause, &ctx->cp0_cause); error |= __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr); error |= __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */ error |= __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)) ? -EFAULT : 0; if (error) goto segv_and_exit; #ifdef DEBUG_SIG dump_irix5_sigctx(ctx); #endif regs->regs[4] = (unsigned long) signr; regs->regs[5] = 0; /* XXX sigcode XXX */ regs->regs[6] = regs->regs[29] = sp; regs->regs[7] = (unsigned long) ka->sa.sa_handler; regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer; return 1; segv_and_exit: force_sigsegv(signr, current); return 0; }
static void setup_irix_frame(struct k_sigaction *ka, struct pt_regs *regs, int signr, sigset_t *oldmask) { unsigned long sp; struct sigctx_irix5 *ctx; int i; sp = regs->regs[29]; sp -= sizeof(struct sigctx_irix5); sp &= ~(0xf); ctx = (struct sigctx_irix5 *) sp; if (!access_ok(VERIFY_WRITE, ctx, sizeof(*ctx))) goto segv_and_exit; __put_user(0, &ctx->weird_fpu_thing); __put_user(~(0x00000001), &ctx->rmask); __put_user(0, &ctx->regs[0]); for(i = 1; i < 32; i++) __put_user((u64) regs->regs[i], &ctx->regs[i]); __put_user((u64) regs->hi, &ctx->hi); __put_user((u64) regs->lo, &ctx->lo); __put_user((u64) regs->cp0_epc, &ctx->pc); __put_user(current->used_math, &ctx->usedfp); __put_user((u64) regs->cp0_cause, &ctx->cp0_cause); __put_user((u64) regs->cp0_badvaddr, &ctx->cp0_badvaddr); __put_user(0, &ctx->sstk_flags); /* XXX sigstack unimp... todo... */ __copy_to_user(&ctx->sigset, oldmask, sizeof(irix_sigset_t)); #ifdef DEBUG_SIG dump_irix5_sigctx(ctx); #endif regs->regs[4] = (unsigned long) signr; regs->regs[5] = 0; /* XXX sigcode XXX */ regs->regs[6] = regs->regs[29] = sp; regs->regs[7] = (unsigned long) ka->sa.sa_handler; regs->regs[25] = regs->cp0_epc = (unsigned long) ka->sa_restorer; return; segv_and_exit: if (signr == SIGSEGV) ka->sa.sa_handler = SIG_DFL; force_sig(SIGSEGV, current); }
asmlinkage void irix_sigreturn(struct pt_regs *regs) { struct sigctx_irix5 __user *context, *magic; unsigned long umask, mask; u64 *fregs; u32 usedfp; int error, sig, i, base = 0; sigset_t blocked; /* Always make any pending restarted system calls return -EINTR */ current_thread_info()->restart_block.fn = do_no_restart_syscall; if (regs->regs[2] == 1000) base = 1; context = (struct sigctx_irix5 __user *) regs->regs[base + 4]; magic = (struct sigctx_irix5 __user *) regs->regs[base + 5]; sig = (int) regs->regs[base + 6]; #ifdef DEBUG_SIG printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n", current->comm, current->pid, context, magic, sig); #endif if (!context) context = magic; if (!access_ok(VERIFY_READ, context, sizeof(struct sigctx_irix5))) goto badframe; #ifdef DEBUG_SIG dump_irix5_sigctx(context); #endif error = __get_user(regs->cp0_epc, &context->pc); error |= __get_user(umask, &context->rmask); mask = 2; for (i = 1; i < 32; i++, mask <<= 1) { if (umask & mask) error |= __get_user(regs->regs[i], &context->regs[i]); } error |= __get_user(regs->hi, &context->hi); error |= __get_user(regs->lo, &context->lo); error |= __get_user(usedfp, &context->usedfp); if ((umask & 1) && usedfp) { fregs = (u64 *) ¤t->thread.fpu; for(i = 0; i < 32; i++) error |= __get_user(fregs[i], &context->fpregs[i]); error |= __get_user(current->thread.fpu.hard.fcr31, &context->fpcsr); } /* XXX do sigstack crapola here... XXX */ error |= __copy_from_user(&blocked, &context->sigset, sizeof(blocked)) ? -EFAULT : 0; if (error) goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); current->blocked = blocked; recalc_sigpending(); spin_unlock_irq(¤t->sighand->siglock); /* * Don't let your children do this ... */ if (current_thread_info()->flags & TIF_SYSCALL_TRACE) do_syscall_trace(regs, 1); __asm__ __volatile__( "move\t$29,%0\n\t" "j\tsyscall_exit" :/* no outputs */ :"r" (®s)); /* Unreached */ badframe: force_sig(SIGSEGV, current); }
asmlinkage void irix_sigreturn(struct pt_regs *regs) { struct sigctx_irix5 *context, *magic; unsigned long umask, mask; u64 *fregs; int sig, i, base = 0; sigset_t blocked; if(regs->regs[2] == 1000) base = 1; context = (struct sigctx_irix5 *) regs->regs[base + 4]; magic = (struct sigctx_irix5 *) regs->regs[base + 5]; sig = (int) regs->regs[base + 6]; #ifdef DEBUG_SIG printk("[%s:%d] IRIX sigreturn(scp[%p],ucp[%p],sig[%d])\n", current->comm, current->pid, context, magic, sig); #endif if (!context) context = magic; if (!access_ok(VERIFY_READ, context, sizeof(struct sigctx_irix5))) goto badframe; #ifdef DEBUG_SIG dump_irix5_sigctx(context); #endif __get_user(regs->cp0_epc, &context->pc); umask = context->rmask; mask = 2; for (i = 1; i < 32; i++, mask <<= 1) { if(umask & mask) __get_user(regs->regs[i], &context->regs[i]); } __get_user(regs->hi, &context->hi); __get_user(regs->lo, &context->lo); if ((umask & 1) && context->usedfp) { fregs = (u64 *) ¤t->thread.fpu; for(i = 0; i < 32; i++) fregs[i] = (u64) context->fpregs[i]; __get_user(current->thread.fpu.hard.control, &context->fpcsr); } /* XXX do sigstack crapola here... XXX */ if (__copy_from_user(&blocked, &context->sigset, sizeof(blocked))) goto badframe; sigdelsetmask(&blocked, ~_BLOCKABLE); spin_lock_irq(¤t->sigmask_lock); current->blocked = blocked; recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); /* * Don't let your children do this ... */ if (current->ptrace & PT_TRACESYS) syscall_trace(); __asm__ __volatile__( "move\t$29,%0\n\t" "j\tret_from_sys_call" :/* no outputs */ :"r" (®s)); /* Unreached */ badframe: force_sig(SIGSEGV, current); }