if ((flags & IA64_SC_FLAG_FPH_VALID) != 0) {
struct ia64_psr *psr = ia64_psr(&scr->pt);
- __copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16);
+ err |= __copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16);
psr->mfh = 0; /* drop signal handler's fph contents... */
preempt_disable();
if (psr->dfh)
si.si_signo = SIGSEGV;
si.si_errno = 0;
si.si_code = SI_KERNEL;
- si.si_pid = current->pid;
+ si.si_pid = task_pid_vnr(current);
si.si_uid = current->uid;
si.si_addr = sc;
force_sig_info(SIGSEGV, &si, current);
setup_sigcontext (struct sigcontext __user *sc, sigset_t *mask, struct sigscratch *scr)
{
unsigned long flags = 0, ifs, cfm, nat;
- long err;
+ long err = 0;
ifs = scr->pt.cr_ifs;
ia64_flush_fph(current);
if ((current->thread.flags & IA64_THREAD_FPH_VALID)) {
flags |= IA64_SC_FLAG_FPH_VALID;
- __copy_to_user(&sc->sc_fr[32], current->thread.fph, 96*16);
+ err = __copy_to_user(&sc->sc_fr[32], current->thread.fph, 96*16);
}
nat = ia64_get_scratch_nat_bits(&scr->pt, scr->scratch_unat);
- err = __put_user(flags, &sc->sc_flags);
+ err |= __put_user(flags, &sc->sc_flags);
err |= __put_user(nat, &sc->sc_nat);
err |= PUT_SIGSET(mask, &sc->sc_mask);
err |= __put_user(cfm, &sc->sc_cfm);
err |= __copy_to_user(&sc->sc_gr[15], &scr->pt.r15, 8); /* r15 */
err |= __put_user(scr->pt.cr_iip + ia64_psr(&scr->pt)->ri, &sc->sc_ip);
- if (flags & IA64_SC_FLAG_IN_SYSCALL) {
- /* Clear scratch registers if the signal interrupted a system call. */
- err |= __put_user(0, &sc->sc_ar_ccv); /* ar.ccv */
- err |= __put_user(0, &sc->sc_br[7]); /* b7 */
- err |= __put_user(0, &sc->sc_gr[14]); /* r14 */
- err |= __clear_user(&sc->sc_ar25, 2*8); /* ar.csd & ar.ssd */
- err |= __clear_user(&sc->sc_gr[2], 2*8); /* r2-r3 */
- err |= __clear_user(&sc->sc_gr[16], 16*8); /* r16-r31 */
- } else {
+ if (!(flags & IA64_SC_FLAG_IN_SYSCALL)) {
/* Copy scratch regs to sigcontext if the signal didn't interrupt a syscall. */
err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv); /* ar.ccv */
err |= __put_user(scr->pt.b7, &sc->sc_br[7]); /* b7 */
si.si_signo = SIGSEGV;
si.si_errno = 0;
si.si_code = SI_KERNEL;
- si.si_pid = current->pid;
+ si.si_pid = task_pid_vnr(current);
si.si_uid = current->uid;
si.si_addr = addr;
force_sig_info(SIGSEGV, &si, current);