long ia64_rt_sigreturn (struct sigscratch *scr) { extern char ia64_strace_leave_kernel, ia64_leave_kernel; struct sigcontext __user *sc; struct siginfo si; sigset_t set; long retval; sc = &((struct sigframe __user *) (scr->pt.r12 + 16))->sc; /* * When we return to the previously executing context, r8 and r10 have already * been setup the way we want them. Indeed, if the signal wasn't delivered while * in a system call, we must not touch r8 or r10 as otherwise user-level state * could be corrupted. */ retval = (long) &ia64_leave_kernel; if (test_thread_flag(TIF_SYSCALL_TRACE) || test_thread_flag(TIF_SYSCALL_AUDIT)) /* * strace expects to be notified after sigreturn returns even though the * context to which we return may not be in the middle of a syscall. * Thus, the return-value that strace displays for sigreturn is * meaningless. */ retval = (long) &ia64_strace_leave_kernel; if (!access_ok(VERIFY_READ, sc, sizeof(*sc))) goto give_sigsegv; if (GET_SIGSET(&set, &sc->sc_mask)) goto give_sigsegv; set_current_blocked(&set); if (restore_sigcontext(sc, scr)) goto give_sigsegv; #if DEBUG_SIG printk("SIG return (%s:%d): sp=%lx ip=%lx\n", current->comm, current->pid, scr->pt.r12, scr->pt.cr_iip); #endif if (restore_altstack(&sc->sc_stack)) goto give_sigsegv; return retval; give_sigsegv: clear_siginfo(&si); si.si_signo = SIGSEGV; si.si_errno = 0; si.si_code = SI_KERNEL; si.si_pid = task_pid_vnr(current); si.si_uid = from_kuid_munged(current_user_ns(), current_uid()); si.si_addr = sc; force_sig_info(SIGSEGV, &si, current); return retval; }
long ia64_rt_sigsuspend (sigset_t *uset, size_t sigsetsize, struct sigscratch *scr) { sigset_t oldset, set; /* XXX: Don't preclude handling different sized sigset_t's. */ if (sigsetsize != sizeof(sigset_t)) return -EINVAL; if (!access_ok(VERIFY_READ, uset, sigsetsize)) return -EFAULT; if (GET_SIGSET(&set, uset)) return -EFAULT; sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); { oldset = current->blocked; current->blocked = set; recalc_sigpending(); } __set_current_state(TASK_INTERRUPTIBLE); spin_unlock_irq(¤t->sighand->siglock); /* * The return below usually returns to the signal handler. We need to * pre-set the correct error code here to ensure that the right values * get saved in sigcontext by ia64_do_signal. */ scr->pt.r8 = EINTR; scr->pt.r10 = -1; while (1) { schedule(); if (ia64_do_signal(&oldset, scr, 1)) return -EINTR; set_current_state(TASK_INTERRUPTIBLE); } }
long ia64_rt_sigreturn (struct sigscratch *scr) { extern char ia64_strace_leave_kernel, ia64_leave_kernel; struct sigcontext *sc; struct siginfo si; sigset_t set; long retval; sc = &((struct sigframe *) (scr->pt.r12 + 16))->sc; /* * When we return to the previously executing context, r8 and r10 have already * been setup the way we want them. Indeed, if the signal wasn't delivered while * in a system call, we must not touch r8 or r10 as otherwise user-level state * could be corrupted. */ retval = (long) &ia64_leave_kernel; if (current->ptrace & PT_TRACESYS) /* * strace expects to be notified after sigreturn returns even though the * context to which we return may not be in the middle of a syscall. * Thus, the return-value that strace displays for sigreturn is * meaningless. */ retval = (long) &ia64_strace_leave_kernel; if (!access_ok(VERIFY_READ, sc, sizeof(*sc))) goto give_sigsegv; if (GET_SIGSET(&set, &sc->sc_mask)) goto give_sigsegv; sigdelsetmask(&set, ~_BLOCKABLE); spin_lock_irq(¤t->sighand->siglock); { current->blocked = set; recalc_sigpending(); } spin_unlock_irq(¤t->sighand->siglock); if (restore_sigcontext(sc, scr)) goto give_sigsegv; #if DEBUG_SIG printk("SIG return (%s:%d): sp=%lx ip=%lx\n", current->comm, current->pid, scr->pt.r12, scr->pt.cr_iip); #endif /* * It is more difficult to avoid calling this function than to * call it and ignore errors. */ do_sigaltstack(&sc->sc_stack, 0, scr->pt.r12); return retval; give_sigsegv: si.si_signo = SIGSEGV; si.si_errno = 0; si.si_code = SI_KERNEL; si.si_pid = current->pid; si.si_uid = current->uid; si.si_addr = sc; force_sig_info(SIGSEGV, &si, current); return retval; }