Commit 861574d51bbd ("powerpc/uaccess: Implement masked user access")
provides optimised user access by avoiding the cost of access_ok().Convert signal32 functions to scoped user access. Scoped user access also make the code simpler. Signed-off-by: Christophe Leroy (CS GROUP) <[email protected]> --- arch/powerpc/kernel/signal_32.c | 456 +++++++++++++++----------------- 1 file changed, 217 insertions(+), 239 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c index 7a718ed32b27..f5d5139a1426 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -468,98 +468,98 @@ static long restore_user_regs(struct pt_regs *regs, { unsigned int save_r2 = 0; unsigned long msr; -#ifdef CONFIG_VSX - int i; -#endif - if (!user_read_access_begin(sr, sizeof(*sr))) - return 1; - /* - * restore general registers but not including MSR or SOFTE. Also - * take care of keeping r2 (TLS) intact if not a signal - */ - if (!sig) - save_r2 = (unsigned int)regs->gpr[2]; - unsafe_restore_general_regs(regs, sr, failed); - set_trap_norestart(regs); - unsafe_get_user(msr, &sr->mc_gregs[PT_MSR], failed); - if (!sig) - regs->gpr[2] = (unsigned long) save_r2; - - /* if doing signal return, restore the previous little-endian mode */ - if (sig) - regs_set_return_msr(regs, (regs->msr & ~MSR_LE) | (msr & MSR_LE)); + scoped_user_read_access(sr, failed) { + /* + * restore general registers but not including MSR or SOFTE. Also + * take care of keeping r2 (TLS) intact if not a signal + */ + if (!sig) + save_r2 = (unsigned int)regs->gpr[2]; + unsafe_restore_general_regs(regs, sr, failed); + set_trap_norestart(regs); + unsafe_get_user(msr, &sr->mc_gregs[PT_MSR], failed); + if (!sig) + regs->gpr[2] = (unsigned long)save_r2; + + /* if doing signal return, restore the previous little-endian mode */ + if (sig) + regs_set_return_msr(regs, (regs->msr & ~MSR_LE) | (msr & MSR_LE)); #ifdef CONFIG_ALTIVEC - /* - * Force the process to reload the altivec registers from - * current->thread when it next does altivec instructions - */ - regs_set_return_msr(regs, regs->msr & ~MSR_VEC); - if (msr & MSR_VEC) { - /* restore altivec registers from the stack */ - unsafe_copy_from_user(¤t->thread.vr_state, &sr->mc_vregs, - sizeof(sr->mc_vregs), failed); - current->thread.used_vr = true; - } else if (current->thread.used_vr) - memset(¤t->thread.vr_state, 0, - ELF_NVRREG * sizeof(vector128)); - - /* Always get VRSAVE back */ - unsafe_get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32], failed); - if (cpu_has_feature(CPU_FTR_ALTIVEC)) - mtspr(SPRN_VRSAVE, current->thread.vrsave); + /* + * Force the process to reload the altivec registers from + * current->thread when it next does altivec instructions + */ + regs_set_return_msr(regs, regs->msr & ~MSR_VEC); + if (msr & MSR_VEC) { + /* restore altivec registers from the stack */ + unsafe_copy_from_user(¤t->thread.vr_state, &sr->mc_vregs, + sizeof(sr->mc_vregs), failed); + current->thread.used_vr = true; + } else if (current->thread.used_vr) { + memset(¤t->thread.vr_state, 0, + ELF_NVRREG * sizeof(vector128)); + } + + /* Always get VRSAVE back */ + unsafe_get_user(current->thread.vrsave, (u32 __user *)&sr->mc_vregs[32], failed); + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + mtspr(SPRN_VRSAVE, current->thread.vrsave); #endif /* CONFIG_ALTIVEC */ - unsafe_copy_fpr_from_user(current, &sr->mc_fregs, failed); + unsafe_copy_fpr_from_user(current, &sr->mc_fregs, failed); #ifdef CONFIG_VSX - /* - * Force the process to reload the VSX registers from - * current->thread when it next does VSX instruction. - */ - regs_set_return_msr(regs, regs->msr & ~MSR_VSX); - if (msr & MSR_VSX) { /* - * Restore altivec registers from the stack to a local - * buffer, then write this out to the thread_struct + * Force the process to reload the VSX registers from + * current->thread when it next does VSX instruction. */ - unsafe_copy_vsx_from_user(current, &sr->mc_vsregs, failed); - current->thread.used_vsr = true; - } else if (current->thread.used_vsr) - for (i = 0; i < 32 ; i++) - current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0; + regs_set_return_msr(regs, regs->msr & ~MSR_VSX); + if (msr & MSR_VSX) { + /* + * Restore altivec registers from the stack to a local + * buffer, then write this out to the thread_struct + */ + unsafe_copy_vsx_from_user(current, &sr->mc_vsregs, failed); + current->thread.used_vsr = true; + } else if (current->thread.used_vsr) { + int i; + + for (i = 0; i < 32 ; i++) + current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0; + } #endif /* CONFIG_VSX */ - /* - * force the process to reload the FP registers from - * current->thread when it next does FP instructions - */ - regs_set_return_msr(regs, regs->msr & ~(MSR_FP | MSR_FE0 | MSR_FE1)); + /* + * force the process to reload the FP registers from + * current->thread when it next does FP instructions + */ + regs_set_return_msr(regs, regs->msr & ~(MSR_FP | MSR_FE0 | MSR_FE1)); #ifdef CONFIG_SPE - /* - * Force the process to reload the spe registers from - * current->thread when it next does spe instructions. - * Since this is user ABI, we must enforce the sizing. - */ - BUILD_BUG_ON(sizeof(current->thread.spe) != ELF_NEVRREG * sizeof(u32)); - regs_set_return_msr(regs, regs->msr & ~MSR_SPE); - if (msr & MSR_SPE) { - /* restore spe registers from the stack */ - unsafe_copy_from_user(¤t->thread.spe, &sr->mc_vregs, - sizeof(current->thread.spe), failed); - current->thread.used_spe = true; - } else if (current->thread.used_spe) - memset(¤t->thread.spe, 0, sizeof(current->thread.spe)); - - /* Always get SPEFSCR back */ - unsafe_get_user(current->thread.spefscr, (u32 __user *)&sr->mc_vregs + ELF_NEVRREG, failed); -#endif /* CONFIG_SPE */ + /* + * Force the process to reload the spe registers from + * current->thread when it next does spe instructions. + * Since this is user ABI, we must enforce the sizing. + */ + BUILD_BUG_ON(sizeof(current->thread.spe) != ELF_NEVRREG * sizeof(u32)); + regs_set_return_msr(regs, regs->msr & ~MSR_SPE); + if (msr & MSR_SPE) { + /* restore spe registers from the stack */ + unsafe_copy_from_user(¤t->thread.spe, &sr->mc_vregs, + sizeof(current->thread.spe), failed); + current->thread.used_spe = true; + } else if (current->thread.used_spe) { + memset(¤t->thread.spe, 0, sizeof(current->thread.spe)); + } - user_read_access_end(); + /* Always get SPEFSCR back */ + unsafe_get_user(current->thread.spefscr, + (u32 __user *)&sr->mc_vregs + ELF_NEVRREG, failed); +#endif /* CONFIG_SPE */ + } return 0; failed: - user_read_access_end(); return 1; } @@ -574,7 +574,6 @@ static long restore_tm_user_regs(struct pt_regs *regs, struct mcontext __user *tm_sr) { unsigned long msr, msr_hi; - int i; if (tm_suspend_disabled) return 1; @@ -585,86 +584,81 @@ static long restore_tm_user_regs(struct pt_regs *regs, * TFHAR is restored from the checkpointed NIP; TEXASR and TFIAR * were set by the signal delivery. */ - if (!user_read_access_begin(sr, sizeof(*sr))) - return 1; - - unsafe_restore_general_regs(¤t->thread.ckpt_regs, sr, failed); - unsafe_get_user(current->thread.tm_tfhar, &sr->mc_gregs[PT_NIP], failed); - unsafe_get_user(msr, &sr->mc_gregs[PT_MSR], failed); + scoped_user_read_access(sr, failed) { + unsafe_restore_general_regs(¤t->thread.ckpt_regs, sr, failed); + unsafe_get_user(current->thread.tm_tfhar, &sr->mc_gregs[PT_NIP], failed); + unsafe_get_user(msr, &sr->mc_gregs[PT_MSR], failed); - /* Restore the previous little-endian mode */ - regs_set_return_msr(regs, (regs->msr & ~MSR_LE) | (msr & MSR_LE)); + /* Restore the previous little-endian mode */ + regs_set_return_msr(regs, (regs->msr & ~MSR_LE) | (msr & MSR_LE)); - regs_set_return_msr(regs, regs->msr & ~MSR_VEC); - if (msr & MSR_VEC) { - /* restore altivec registers from the stack */ - unsafe_copy_from_user(¤t->thread.ckvr_state, &sr->mc_vregs, - sizeof(sr->mc_vregs), failed); - current->thread.used_vr = true; - } else if (current->thread.used_vr) { - memset(¤t->thread.vr_state, 0, - ELF_NVRREG * sizeof(vector128)); - memset(¤t->thread.ckvr_state, 0, - ELF_NVRREG * sizeof(vector128)); - } + regs_set_return_msr(regs, regs->msr & ~MSR_VEC); + if (msr & MSR_VEC) { + /* restore altivec registers from the stack */ + unsafe_copy_from_user(¤t->thread.ckvr_state, &sr->mc_vregs, + sizeof(sr->mc_vregs), failed); + current->thread.used_vr = true; + } else if (current->thread.used_vr) { + memset(¤t->thread.vr_state, 0, ELF_NVRREG * sizeof(vector128)); + memset(¤t->thread.ckvr_state, 0, ELF_NVRREG * sizeof(vector128)); + } - /* Always get VRSAVE back */ - unsafe_get_user(current->thread.ckvrsave, - (u32 __user *)&sr->mc_vregs[32], failed); - if (cpu_has_feature(CPU_FTR_ALTIVEC)) - mtspr(SPRN_VRSAVE, current->thread.ckvrsave); + /* Always get VRSAVE back */ + unsafe_get_user(current->thread.ckvrsave, + (u32 __user *)&sr->mc_vregs[32], failed); + if (cpu_has_feature(CPU_FTR_ALTIVEC)) + mtspr(SPRN_VRSAVE, current->thread.ckvrsave); - regs_set_return_msr(regs, regs->msr & ~(MSR_FP | MSR_FE0 | MSR_FE1)); + regs_set_return_msr(regs, regs->msr & ~(MSR_FP | MSR_FE0 | MSR_FE1)); - unsafe_copy_fpr_from_user(current, &sr->mc_fregs, failed); + unsafe_copy_fpr_from_user(current, &sr->mc_fregs, failed); - regs_set_return_msr(regs, regs->msr & ~MSR_VSX); - if (msr & MSR_VSX) { - /* - * Restore altivec registers from the stack to a local - * buffer, then write this out to the thread_struct - */ - unsafe_copy_ckvsx_from_user(current, &sr->mc_vsregs, failed); - current->thread.used_vsr = true; - } else if (current->thread.used_vsr) - for (i = 0; i < 32 ; i++) { - current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0; - current->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = 0; + regs_set_return_msr(regs, regs->msr & ~MSR_VSX); + if (msr & MSR_VSX) { + /* + * Restore altivec registers from the stack to a local + * buffer, then write this out to the thread_struct + */ + unsafe_copy_ckvsx_from_user(current, &sr->mc_vsregs, failed); + current->thread.used_vsr = true; + } else if (current->thread.used_vsr) { + int i; + + for (i = 0; i < 32 ; i++) { + current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = 0; + current->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] = 0; + } } + } - user_read_access_end(); - - if (!user_read_access_begin(tm_sr, sizeof(*tm_sr))) - return 1; + scoped_user_read_access(tm_sr, failed) { + unsafe_restore_general_regs(regs, tm_sr, failed); - unsafe_restore_general_regs(regs, tm_sr, failed); + /* restore altivec registers from the stack */ + if (msr & MSR_VEC) + unsafe_copy_from_user(¤t->thread.vr_state, &tm_sr->mc_vregs, + sizeof(sr->mc_vregs), failed); - /* restore altivec registers from the stack */ - if (msr & MSR_VEC) - unsafe_copy_from_user(¤t->thread.vr_state, &tm_sr->mc_vregs, - sizeof(sr->mc_vregs), failed); + /* Always get VRSAVE back */ + unsafe_get_user(current->thread.vrsave, + (u32 __user *)&tm_sr->mc_vregs[32], failed); - /* Always get VRSAVE back */ - unsafe_get_user(current->thread.vrsave, - (u32 __user *)&tm_sr->mc_vregs[32], failed); + unsafe_copy_ckfpr_from_user(current, &tm_sr->mc_fregs, failed); - unsafe_copy_ckfpr_from_user(current, &tm_sr->mc_fregs, failed); + if (msr & MSR_VSX) { + /* + * Restore altivec registers from the stack to a local + * buffer, then write this out to the thread_struct + */ + unsafe_copy_vsx_from_user(current, &tm_sr->mc_vsregs, failed); + current->thread.used_vsr = true; + } - if (msr & MSR_VSX) { - /* - * Restore altivec registers from the stack to a local - * buffer, then write this out to the thread_struct - */ - unsafe_copy_vsx_from_user(current, &tm_sr->mc_vsregs, failed); - current->thread.used_vsr = true; + /* Get the top half of the MSR from the user context */ + unsafe_get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR], failed); + msr_hi <<= 32; } - /* Get the top half of the MSR from the user context */ - unsafe_get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR], failed); - msr_hi <<= 32; - - user_read_access_end(); - /* If TM bits are set to the reserved value, it's an invalid context */ if (MSR_TM_RESV(msr_hi)) return 1; @@ -712,7 +706,6 @@ static long restore_tm_user_regs(struct pt_regs *regs, return 0; failed: - user_read_access_end(); return 1; } #else @@ -737,8 +730,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, struct task_struct *tsk) { struct rt_sigframe __user *frame; - struct mcontext __user *mctx; - struct mcontext __user *tm_mctx = NULL; unsigned long newsp = 0; unsigned long tramp; struct pt_regs *regs = tsk->thread.regs; @@ -747,52 +738,53 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, /* Set up Signal Frame */ frame = get_sigframe(ksig, tsk, sizeof(*frame), 1); - mctx = &frame->uc.uc_mcontext; -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - tm_mctx = &frame->uc_transact.uc_mcontext; -#endif if (MSR_TM_ACTIVE(msr)) prepare_save_tm_user_regs(); else prepare_save_user_regs(1); - if (!user_access_begin(frame, sizeof(*frame))) - goto badframe; + scoped_user_rw_access(frame, badframe) { + struct mcontext __user *mctx; + struct mcontext __user *tm_mctx = NULL; - /* Put the siginfo & fill in most of the ucontext */ - unsafe_put_user(0, &frame->uc.uc_flags, failed); + mctx = &frame->uc.uc_mcontext; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + tm_mctx = &frame->uc_transact.uc_mcontext; +#endif + /* Put the siginfo & fill in most of the ucontext */ + unsafe_put_user(0, &frame->uc.uc_flags, badframe); #ifdef CONFIG_PPC64 - unsafe_compat_save_altstack(&frame->uc.uc_stack, regs->gpr[1], failed); + unsafe_compat_save_altstack(&frame->uc.uc_stack, regs->gpr[1], badframe); #else - unsafe_save_altstack(&frame->uc.uc_stack, regs->gpr[1], failed); + unsafe_save_altstack(&frame->uc.uc_stack, regs->gpr[1], badframe); #endif - unsafe_put_user(to_user_ptr(&frame->uc.uc_mcontext), &frame->uc.uc_regs, failed); + unsafe_put_user(to_user_ptr(&frame->uc.uc_mcontext), &frame->uc.uc_regs, badframe); - if (MSR_TM_ACTIVE(msr)) { + if (MSR_TM_ACTIVE(msr)) { #ifdef CONFIG_PPC_TRANSACTIONAL_MEM - unsafe_put_user((unsigned long)&frame->uc_transact, - &frame->uc.uc_link, failed); - unsafe_put_user((unsigned long)tm_mctx, - &frame->uc_transact.uc_regs, failed); + unsafe_put_user((unsigned long)&frame->uc_transact, + &frame->uc.uc_link, badframe); + unsafe_put_user((unsigned long)tm_mctx, + &frame->uc_transact.uc_regs, badframe); #endif - unsafe_save_tm_user_regs(regs, mctx, tm_mctx, msr, failed); - } else { - unsafe_put_user(0, &frame->uc.uc_link, failed); - unsafe_save_user_regs(regs, mctx, tm_mctx, 1, failed); - } + unsafe_save_tm_user_regs(regs, mctx, tm_mctx, msr, badframe); + } else { + unsafe_put_user(0, &frame->uc.uc_link, badframe); + unsafe_save_user_regs(regs, mctx, tm_mctx, 1, badframe); + } - /* Save user registers on the stack */ - if (tsk->mm->context.vdso) { - tramp = VDSO32_SYMBOL(tsk->mm->context.vdso, sigtramp_rt32); - } else { - tramp = (unsigned long)mctx->mc_pad; - unsafe_put_user(PPC_RAW_LI(_R0, __NR_rt_sigreturn), &mctx->mc_pad[0], failed); - unsafe_put_user(PPC_RAW_SC(), &mctx->mc_pad[1], failed); - asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0])); + /* Save user registers on the stack */ + if (tsk->mm->context.vdso) { + tramp = VDSO32_SYMBOL(tsk->mm->context.vdso, sigtramp_rt32); + } else { + tramp = (unsigned long)mctx->mc_pad; + unsafe_put_user(PPC_RAW_LI(_R0, __NR_rt_sigreturn), &mctx->mc_pad[0], + badframe); + unsafe_put_user(PPC_RAW_SC(), &mctx->mc_pad[1], badframe); + asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0])); + } + unsafe_put_sigset_t(&frame->uc.uc_sigmask, oldset, badframe); } - unsafe_put_sigset_t(&frame->uc.uc_sigmask, oldset, failed); - - user_access_end(); if (copy_siginfo_to_user(&frame->info, &ksig->info)) goto badframe; @@ -820,9 +812,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset, return 0; -failed: - user_access_end(); - badframe: signal_fault(tsk, regs, "handle_rt_signal32", frame); @@ -837,8 +826,6 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, { struct sigcontext __user *sc; struct sigframe __user *frame; - struct mcontext __user *mctx; - struct mcontext __user *tm_mctx = NULL; unsigned long newsp = 0; unsigned long tramp; struct pt_regs *regs = tsk->thread.regs; @@ -847,46 +834,49 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, /* Set up Signal Frame */ frame = get_sigframe(ksig, tsk, sizeof(*frame), 1); - mctx = &frame->mctx; -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - tm_mctx = &frame->mctx_transact; -#endif if (MSR_TM_ACTIVE(msr)) prepare_save_tm_user_regs(); else prepare_save_user_regs(1); - if (!user_access_begin(frame, sizeof(*frame))) - goto badframe; - sc = (struct sigcontext __user *) &frame->sctx; + scoped_user_rw_access(frame, badframe) { + struct mcontext __user *mctx; + struct mcontext __user *tm_mctx = NULL; + + mctx = &frame->mctx; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + tm_mctx = &frame->mctx_transact; +#endif + sc = (struct sigcontext __user *)&frame->sctx; #if _NSIG != 64 #error "Please adjust handle_signal()" #endif - unsafe_put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler, failed); - unsafe_put_user(oldset->sig[0], &sc->oldmask, failed); + unsafe_put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler, badframe); + unsafe_put_user(oldset->sig[0], &sc->oldmask, badframe); #ifdef CONFIG_PPC64 - unsafe_put_user((oldset->sig[0] >> 32), &sc->_unused[3], failed); + unsafe_put_user((oldset->sig[0] >> 32), &sc->_unused[3], badframe); #else - unsafe_put_user(oldset->sig[1], &sc->_unused[3], failed); + unsafe_put_user(oldset->sig[1], &sc->_unused[3], badframe); #endif - unsafe_put_user(to_user_ptr(mctx), &sc->regs, failed); - unsafe_put_user(ksig->sig, &sc->signal, failed); + unsafe_put_user(to_user_ptr(mctx), &sc->regs, badframe); + unsafe_put_user(ksig->sig, &sc->signal, badframe); - if (MSR_TM_ACTIVE(msr)) - unsafe_save_tm_user_regs(regs, mctx, tm_mctx, msr, failed); - else - unsafe_save_user_regs(regs, mctx, tm_mctx, 1, failed); - - if (tsk->mm->context.vdso) { - tramp = VDSO32_SYMBOL(tsk->mm->context.vdso, sigtramp32); - } else { - tramp = (unsigned long)mctx->mc_pad; - unsafe_put_user(PPC_RAW_LI(_R0, __NR_sigreturn), &mctx->mc_pad[0], failed); - unsafe_put_user(PPC_RAW_SC(), &mctx->mc_pad[1], failed); - asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0])); + if (MSR_TM_ACTIVE(msr)) + unsafe_save_tm_user_regs(regs, mctx, tm_mctx, msr, badframe); + else + unsafe_save_user_regs(regs, mctx, tm_mctx, 1, badframe); + + if (tsk->mm->context.vdso) { + tramp = VDSO32_SYMBOL(tsk->mm->context.vdso, sigtramp32); + } else { + tramp = (unsigned long)mctx->mc_pad; + unsafe_put_user(PPC_RAW_LI(_R0, __NR_sigreturn), &mctx->mc_pad[0], + badframe); + unsafe_put_user(PPC_RAW_SC(), &mctx->mc_pad[1], badframe); + asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0])); + } } - user_access_end(); regs->link = tramp; @@ -908,9 +898,6 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset, return 0; -failed: - user_access_end(); - badframe: signal_fault(tsk, regs, "handle_signal32", frame); @@ -922,21 +909,19 @@ static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int sigset_t set; struct mcontext __user *mcp; - if (!user_read_access_begin(ucp, sizeof(*ucp))) - return -EFAULT; - - unsafe_get_sigset_t(&set, &ucp->uc_sigmask, failed); + scoped_user_read_access(ucp, failed) { + unsafe_get_sigset_t(&set, &ucp->uc_sigmask, failed); #ifdef CONFIG_PPC64 - { - u32 cmcp; + { + u32 cmcp; - unsafe_get_user(cmcp, &ucp->uc_regs, failed); - mcp = (struct mcontext __user *)(u64)cmcp; - } + unsafe_get_user(cmcp, &ucp->uc_regs, failed); + mcp = (struct mcontext __user *)(u64)cmcp; + } #else - unsafe_get_user(mcp, &ucp->uc_regs, failed); + unsafe_get_user(mcp, &ucp->uc_regs, failed); #endif - user_read_access_end(); + } set_current_blocked(&set); if (restore_user_regs(regs, mcp, sig)) @@ -945,7 +930,6 @@ static int do_setcontext(struct ucontext __user *ucp, struct pt_regs *regs, int return 0; failed: - user_read_access_end(); return -EFAULT; } @@ -960,13 +944,10 @@ static int do_setcontext_tm(struct ucontext __user *ucp, u32 cmcp; u32 tm_cmcp; - if (!user_read_access_begin(ucp, sizeof(*ucp))) - return -EFAULT; - - unsafe_get_sigset_t(&set, &ucp->uc_sigmask, failed); - unsafe_get_user(cmcp, &ucp->uc_regs, failed); - - user_read_access_end(); + scoped_user_read_access(ucp, failed) { + unsafe_get_sigset_t(&set, &ucp->uc_sigmask, failed); + unsafe_get_user(cmcp, &ucp->uc_regs, failed); + } if (__get_user(tm_cmcp, &tm_ucp->uc_regs)) return -EFAULT; @@ -981,7 +962,6 @@ static int do_setcontext_tm(struct ucontext __user *ucp, return 0; failed: - user_read_access_end(); return -EFAULT; } #endif @@ -1051,12 +1031,11 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, mctx = (struct mcontext __user *) ((unsigned long) &old_ctx->uc_mcontext & ~0xfUL); prepare_save_user_regs(ctx_has_vsx_region); - if (!user_write_access_begin(old_ctx, ctx_size)) - return -EFAULT; - unsafe_save_user_regs(regs, mctx, NULL, ctx_has_vsx_region, failed); - unsafe_put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked, failed); - unsafe_put_user(to_user_ptr(mctx), &old_ctx->uc_regs, failed); - user_write_access_end(); + scoped_user_write_access_size(old_ctx, ctx_size, failed) { + unsafe_save_user_regs(regs, mctx, NULL, ctx_has_vsx_region, failed); + unsafe_put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked, failed); + unsafe_put_user(to_user_ptr(mctx), &old_ctx->uc_regs, failed); + } } if (new_ctx == NULL) return 0; @@ -1084,7 +1063,6 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx, return 0; failed: - user_write_access_end(); return -EFAULT; } -- 2.54.0
