From nobody Mon Jun 8 04:11:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4AE1637EFEE for ; Tue, 2 Jun 2026 08:46:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390014; cv=none; b=X+yHfcte1sckDW2rhA1mzBX0XQSoTlk/oU0rT6xspoZnDXbQcB0MXtN/Jf06HDs3poi3VrAKA4Xc6Lc9fxnSxTneYbMiaj2hjR6SzEH8zWFy3PjIxnW5l5sGgwsZQ07el1uCQ+oluRFB+erBGquEtDi3i3l76UwyNZXu1k7HWdY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390014; c=relaxed/simple; bh=NudAOrXGuk31+TSU2hNrOuNcV501EprG3myB9gtNJ/8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ik7Ue5HF72nv0ahXIasKdLK4ts2Ju6q4iq15+dQfzsnaiDFylJgcOT1hP5IpHZa859Fl9sHzUd7cC3r1JEXu86H9YyhR24xH7v2BPStxo6mKaQedWJGK+Jj92vux/srimBrKkOUdUVgrbte1qWb4vXl+4R3I6RAxHIGk+heZUKk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Kj0n5IlR; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Kj0n5IlR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 099511F00899; Tue, 2 Jun 2026 08:46:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780390011; bh=1vwc/KR3sNRx33HkEWDynGkEORnc/I5YEMTBxDajIjw=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=Kj0n5IlRAZfZSFbi59rB0HGzhF20u2WsE8XpvBC0d7g3o6i/LEmkzds0Rn8XGIQ7i lL6pSv+ozbtcfdXgETwtvXqCpWc3N1m4B1vrmu9fXbQmF/FIybGABvtSPq1q4dxYFG qU7OuIK04KWoLtx9LyD2LGV1hD29FxvW9DNc3WzYvJovn3WVR7n7Qqi9W1VR/CPFH7 QCXjqX91WbWtDTYUQZMLgVNm0e0vK2DSHZmXi6B7Brxkuai8xUf6FLsJOjxtzdRhVc +akc+d5l576Ok4D7QXl+BfDnf8RsdyQcco52vbpu+xM9qBKomuosbLGBWGTREHoYZd YuKbDMPNc9Bjg== From: "Christophe Leroy (CS GROUP)" To: Michael Ellerman , Nicholas Piggin , Madhavan Srinivasan Cc: "Christophe Leroy (CS GROUP)" , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 1/8] powerpc/signal32: Convert to scoped user access Date: Tue, 2 Jun 2026 10:46:30 +0200 Message-ID: <4d101e232543f54dfb4eb7a2806e180e63f6c918.1780389863.git.chleroy@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=23207; i=chleroy@kernel.org; h=from:subject:message-id; bh=NudAOrXGuk31+TSU2hNrOuNcV501EprG3myB9gtNJ/8=; b=owGbwMvMwCV2d0KB2p7V54MZT6slMWTJzcg9OV2FYdLi4xKJGUrP/S6VyeXkZEy+uSrvXYSmu qPmrT/bO0pYGMS4GGTFFFmO/+feNaPrS2r+1F36MHNYmUCGMHBxCsBETLYzfNOb0ML2RYFT5jW/ bc5LyVMsIYLX/R2+Pm6uisnYssHgJMP/kOk/ePZu4mi+IHZGSN8qRFEoTUL3bV2T4cuLou6v3rH wAgA= X-Developer-Key: i=chleroy@kernel.org; a=openpgp; fpr=10FFE6F8B390DE17ACC2632368A92FEB01B8DD78 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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) --- 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_3= 2.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 =3D 0; unsigned long msr; -#ifdef CONFIG_VSX - int i; -#endif =20 - 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 =3D (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] =3D (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 =3D (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] =3D (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)); =20 #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 =3D 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 =3D 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); =20 #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 =3D true; - } else if (current->thread.used_vsr) - for (i =3D 0; i < 32 ; i++) - current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] =3D 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 =3D true; + } else if (current->thread.used_vsr) { + int i; + + for (i =3D 0; i < 32 ; i++) + current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] =3D 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)); =20 #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) !=3D 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 =3D 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 + EL= F_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) !=3D 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 =3D true; + } else if (current->thread.used_spe) { + memset(¤t->thread.spe, 0, sizeof(current->thread.spe)); + } =20 - 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; =20 failed: - user_read_access_end(); return 1; } =20 @@ -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; =20 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); =20 - /* 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)); =20 - 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 =3D 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 =3D 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)); + } =20 - /* 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); =20 - 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)); =20 - unsafe_copy_fpr_from_user(current, &sr->mc_fregs, failed); + unsafe_copy_fpr_from_user(current, &sr->mc_fregs, failed); =20 - 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 =3D true; - } else if (current->thread.used_vsr) - for (i =3D 0; i < 32 ; i++) { - current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] =3D 0; - current->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] =3D 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 =3D true; + } else if (current->thread.used_vsr) { + int i; + + for (i =3D 0; i < 32 ; i++) { + current->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] =3D 0; + current->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET] =3D 0; + } } + } =20 - 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); =20 - 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); =20 - /* 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); =20 - /* 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); =20 - 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 =3D true; + } =20 - 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 =3D 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 <<=3D 32; } =20 - /* 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 <<=3D 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; =20 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 =3D NULL; unsigned long newsp =3D 0; unsigned long tramp; struct pt_regs *regs =3D tsk->thread.regs; @@ -747,52 +738,53 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t= *oldset, =20 /* Set up Signal Frame */ frame =3D get_sigframe(ksig, tsk, sizeof(*frame), 1); - mctx =3D &frame->uc.uc_mcontext; -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - tm_mctx =3D &frame->uc_transact.uc_mcontext; -#endif if (MSR_TM_ACTIVE(msr)) prepare_save_tm_user_regs(); else prepare_save_user_regs(1); =20 - if (!user_access_begin(frame, sizeof(*frame))) - goto badframe; + scoped_user_rw_access(frame, badframe) { + struct mcontext __user *mctx; + struct mcontext __user *tm_mctx =3D NULL; =20 - /* Put the siginfo & fill in most of the ucontext */ - unsafe_put_user(0, &frame->uc.uc_flags, failed); + mctx =3D &frame->uc.uc_mcontext; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + tm_mctx =3D &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); =20 - 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); + } =20 - /* Save user registers on the stack */ - if (tsk->mm->context.vdso) { - tramp =3D VDSO32_SYMBOL(tsk->mm->context.vdso, sigtramp_rt32); - } else { - tramp =3D (unsigned long)mctx->mc_pad; - unsafe_put_user(PPC_RAW_LI(_R0, __NR_rt_sigreturn), &mctx->mc_pad[0], fa= iled); - 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 =3D VDSO32_SYMBOL(tsk->mm->context.vdso, sigtramp_rt32); + } else { + tramp =3D (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(); =20 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, =20 return 0; =20 -failed: - user_access_end(); - badframe: signal_fault(tsk, regs, "handle_rt_signal32", frame); =20 @@ -837,8 +826,6 @@ int handle_signal32(struct ksignal *ksig, sigset_t *old= set, { struct sigcontext __user *sc; struct sigframe __user *frame; - struct mcontext __user *mctx; - struct mcontext __user *tm_mctx =3D NULL; unsigned long newsp =3D 0; unsigned long tramp; struct pt_regs *regs =3D tsk->thread.regs; @@ -847,46 +834,49 @@ int handle_signal32(struct ksignal *ksig, sigset_t *o= ldset, =20 /* Set up Signal Frame */ frame =3D get_sigframe(ksig, tsk, sizeof(*frame), 1); - mctx =3D &frame->mctx; -#ifdef CONFIG_PPC_TRANSACTIONAL_MEM - tm_mctx =3D &frame->mctx_transact; -#endif if (MSR_TM_ACTIVE(msr)) prepare_save_tm_user_regs(); else prepare_save_user_regs(1); =20 - if (!user_access_begin(frame, sizeof(*frame))) - goto badframe; - sc =3D (struct sigcontext __user *) &frame->sctx; + scoped_user_rw_access(frame, badframe) { + struct mcontext __user *mctx; + struct mcontext __user *tm_mctx =3D NULL; + + mctx =3D &frame->mctx; +#ifdef CONFIG_PPC_TRANSACTIONAL_MEM + tm_mctx =3D &frame->mctx_transact; +#endif + sc =3D (struct sigcontext __user *)&frame->sctx; =20 #if _NSIG !=3D 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, badfr= ame); + 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); =20 - 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 =3D VDSO32_SYMBOL(tsk->mm->context.vdso, sigtramp32); - } else { - tramp =3D (unsigned long)mctx->mc_pad; - unsafe_put_user(PPC_RAW_LI(_R0, __NR_sigreturn), &mctx->mc_pad[0], faile= d); - 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 =3D VDSO32_SYMBOL(tsk->mm->context.vdso, sigtramp32); + } else { + tramp =3D (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(); =20 regs->link =3D tramp; =20 @@ -908,9 +898,6 @@ int handle_signal32(struct ksignal *ksig, sigset_t *old= set, =20 return 0; =20 -failed: - user_access_end(); - badframe: signal_fault(tsk, regs, "handle_signal32", frame); =20 @@ -922,21 +909,19 @@ static int do_setcontext(struct ucontext __user *ucp,= struct pt_regs *regs, int sigset_t set; struct mcontext __user *mcp; =20 - 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; =20 - unsafe_get_user(cmcp, &ucp->uc_regs, failed); - mcp =3D (struct mcontext __user *)(u64)cmcp; - } + unsafe_get_user(cmcp, &ucp->uc_regs, failed); + mcp =3D (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(); + } =20 set_current_blocked(&set); if (restore_user_regs(regs, mcp, sig)) @@ -945,7 +930,6 @@ static int do_setcontext(struct ucontext __user *ucp, s= truct pt_regs *regs, int return 0; =20 failed: - user_read_access_end(); return -EFAULT; } =20 @@ -960,13 +944,10 @@ static int do_setcontext_tm(struct ucontext __user *u= cp, u32 cmcp; u32 tm_cmcp; =20 - 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); + } =20 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; =20 failed: - user_read_access_end(); return -EFAULT; } #endif @@ -1051,12 +1031,11 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user= *, old_ctx, mctx =3D (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 =3D=3D NULL) return 0; @@ -1084,7 +1063,6 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *= , old_ctx, return 0; =20 failed: - user_write_access_end(); return -EFAULT; } =20 --=20 2.54.0 From nobody Mon Jun 8 04:11:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C435833B975 for ; Tue, 2 Jun 2026 08:46:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390015; cv=none; b=L9nJR3Uku2oB3M2SNeVVaCJqoMDBvzAMfzZL5CbQs6yUaKuBMj6KSYeUj2ZVIJA8HqKnAswSPpFU9X40+jv6eruzvXbGxA8/0LkmT0NnyE8Ujf4aW1bT6xJwWyO/OmqRP9Q+BuzY6Ci1ng0BF7ezbMmV58jEytu9SKlDgUFDS4I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390015; c=relaxed/simple; bh=nyPy/c43MhBW1KA2zDfA5Z3s1fWNtAUmFemUa0E/v/E=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bOfzAkyI5A9Y+ad0mariF4Y53eGCId6eAjLSXwZbNLksHCf30yASfu1sEPjv0xExVdVhO3fqkUHxzshXPHo2rSKwCZ623wdlgq/5A/IHwbWfpAjkaLhFzTona2IGpWoiZBwXdrpW+25fLfxVd1dnwB5DHlLJDN/IkUpKNLKoUes= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=af5nuutZ; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="af5nuutZ" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8AFD31F00893; Tue, 2 Jun 2026 08:46:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780390014; bh=wEIia4owzoHXAM5Q1QiHWFkRbAEC+rQaMKj1YQisyR8=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=af5nuutZ4ehhaAE98FT7ZzpFCifrcNB2J+b8i1fQyxybDE/z69S96sBtjBGsmrgMs 4lRukFZtE4/cVPtyzUaLy1fk6w295u6zDYruGwsYuAg7uWumov334Su1qSSxNG62dr M/OdrfCkQHyQl/VBi0B5S9fZunQfeaRjTP2E/2tuomxcHDCXy+wwqciEIxnyZkdEX7 wS+nq/0B4WzZfZsJo/kH1/ZfU8CPIIfEqXa7yQIbT9FyiBwm3Yq1DwFGCnnjdyd7xR VV8rGHNBe0N2DioKLSFvoTJGnFPO34D9C4pZl4CWXG/pUh6AdpSgv8MP0mRbDjUdj1 VoGTTbsMd9M1w== From: "Christophe Leroy (CS GROUP)" To: Michael Ellerman , Nicholas Piggin , Madhavan Srinivasan Cc: "Christophe Leroy (CS GROUP)" , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 2/8] powerpc/signal64: Untangle setup_tm_sigcontexts() and user_access_begin() Date: Tue, 2 Jun 2026 10:46:31 +0200 Message-ID: <3273e04aedba47f9196edf3ef59f38e7ceaabdb9.1780389863.git.chleroy@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2951; i=chleroy@kernel.org; h=from:subject:message-id; bh=nyPy/c43MhBW1KA2zDfA5Z3s1fWNtAUmFemUa0E/v/E=; b=owGbwMvMwCV2d0KB2p7V54MZT6slMWTJzciduenz0qyvoUkSBy+LNr4S468MOK59PfWwzLRZo lP2zV6S0lHKwiDGxSArpshy/D/3rhldX1Lzp+7Sh5nDygQyhIGLUwAm8n8Jw/9io9TzL3V2cihY KafVvmjK11mc0ma2O+PmuYvfX2yJ+K/KyPD2lf7u5ih1vb8PPjXOvJz3o/jTPu1TtwvTE67zmzA p17IBAA== X-Developer-Key: i=chleroy@kernel.org; a=openpgp; fpr=10FFE6F8B390DE17ACC2632368A92FEB01B8DD78 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Call setup_tm_sigcontexts() before opening user access to avoid having to close and open again. Signed-off-by: Christophe Leroy (CS GROUP) --- v2: Add a stub setup_tm_sigcontexts() for when CONFIG_PPC_TRANSACTIONAL_MEM= is not set --- arch/powerpc/kernel/signal_64.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_6= 4.c index 86bb5bb4c143..9b4cd0bbf4a7 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -203,8 +203,7 @@ static long notrace __unsafe_setup_sigcontext(struct si= gcontext __user *sc, * examine the transactional registers in the 2nd sigcontext to determine = the * real origin of the signal. */ -static long setup_tm_sigcontexts(struct sigcontext __user *sc, - struct sigcontext __user *tm_sc, +static long setup_tm_sigcontexts(struct rt_sigframe __user *frame, struct task_struct *tsk, int signr, sigset_t *set, unsigned long handler, unsigned long msr) @@ -217,6 +216,8 @@ static long setup_tm_sigcontexts(struct sigcontext __us= er *sc, * Userland shall check AT_HWCAP to know wether it can rely on the * v_regs pointer or not. */ + struct sigcontext __user *sc =3D &frame->uc.uc_mcontext; + struct sigcontext __user *tm_sc =3D &frame->uc_transact.uc_mcontext; #ifdef CONFIG_ALTIVEC elf_vrreg_t __user *v_regs =3D sigcontext_vmx_regs(sc); elf_vrreg_t __user *tm_v_regs =3D sigcontext_vmx_regs(tm_sc); @@ -325,6 +326,15 @@ static long setup_tm_sigcontexts(struct sigcontext __u= ser *sc, =20 return err; } +#else +static long setup_tm_sigcontexts(struct rt_sigframe __user *frame, + struct task_struct *tsk, + int signr, sigset_t *set, unsigned long handler, + unsigned long msr) +{ + BUILD_BUG(); + return -EINVAL; +} #endif =20 /* @@ -872,6 +882,9 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *= set, */ if (!MSR_TM_ACTIVE(msr)) prepare_setup_sigcontext(tsk); + else + err |=3D setup_tm_sigcontexts(frame, tsk, ksig->sig, NULL, + (unsigned long)ksig->ka.sa.sa_handler, msr); =20 if (!user_write_access_begin(frame, sizeof(*frame))) goto badframe; @@ -889,19 +902,6 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t = *set, * ucontext_t (for transactional state) with its uc_link ptr. */ unsafe_put_user(&frame->uc_transact, &frame->uc.uc_link, badframe_block); - - user_write_access_end(); - - err |=3D setup_tm_sigcontexts(&frame->uc.uc_mcontext, - &frame->uc_transact.uc_mcontext, - tsk, ksig->sig, NULL, - (unsigned long)ksig->ka.sa.sa_handler, - msr); - - if (!user_write_access_begin(&frame->uc.uc_sigmask, - sizeof(frame->uc.uc_sigmask))) - goto badframe; - #endif } else { unsafe_put_user(0, &frame->uc.uc_link, badframe_block); --=20 2.54.0 From nobody Mon Jun 8 04:11:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9A35C3BB68F for ; Tue, 2 Jun 2026 08:46:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390020; cv=none; b=h1ss9LlHeqm6EVyJcsPwuufA620GLUZLKId4lHUJwmHV5RVA3ZvYi72QDWQyo5PdzkHrNfU7wxcJl82Gx3PY0mySym7CSB4CFWr/po2610i/AHc4A0OCKrsK1cmTg6G75eIMmywEJjkKkZy6XgcG9+JT0Yl17iiUX5RVosJqXB8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390020; c=relaxed/simple; bh=OpFmrb3bSYZS9X19MBN/xU9riD52+8hcb0/eLT/XCyo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HX6/D6rkRYGsxS8cvkS8ue+L2G8e3lkoCKXT+TCPRH0HGtEymOQBTdEk8mXUjixVtmFibDOPb+8I0yWyAsGIyubv7nBNlXXMZLTdkvePpd/5k5ZHIlIeCM0eW6pLA51/+HAZiqEZn3F67aaN2j4fpFHyQq4s1x3BnKHHvuIhHvw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=orUCBSAk; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="orUCBSAk" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 1ABA11F00898; Tue, 2 Jun 2026 08:46:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780390017; bh=wGSAVChKX7kDKb9uSv3bGyNaq2eKRQOosLSzz0S4tzA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=orUCBSAkntoeaANeMHX7thmAPPStf5fPxc9ERuGY8gWwhtGxlaaIF1O3UzDYkxc3W 1lLmXutHXdo1as+TB/5qdD7W8Umia9kDfjOzZzCtszrwzDw6PjdeiiVDZIMuwTPQRK B5VVGf2l8R1pm3o7nNKdvVqzusZ4q2Kwm2LGPe4sx0yf8B9tgTud0f9ymzzyGBOMnp /m8JTMe3iAq5vVQwVYZV19avjJtVS0ETknQGXABXIibbLFHvIoUiwvVkRInmVHDegP IXPBlGSOVFH2nbb7BYXAbfd5HVXwf5f+QhDnR4hr4RlJL2hqdrzX5B8CZ/B/ISW1Dl rG09uLHfjCkdg== From: "Christophe Leroy (CS GROUP)" To: Michael Ellerman , Nicholas Piggin , Madhavan Srinivasan Cc: "Christophe Leroy (CS GROUP)" , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 3/8] powerpc/signal64: Convert to scoped user access Date: Tue, 2 Jun 2026 10:46:32 +0200 Message-ID: <5a4104a540b6cfa70fb12d06390e411a6dcd87ef.1780389863.git.chleroy@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=5674; i=chleroy@kernel.org; h=from:subject:message-id; bh=OpFmrb3bSYZS9X19MBN/xU9riD52+8hcb0/eLT/XCyo=; b=owGbwMvMwCV2d0KB2p7V54MZT6slMWTJzcjVOHZg9WqdfEvLXeEnlzFMb1k74VqT3Uq7b3Myz W7MV5xf31HKwiDGxSArpshy/D/3rhldX1Lzp+7Sh5nDygQyhIGLUwAmUtjF8N835NXWB4FJ0xdU dhz5L+UQ1PDywCZj+QdxptceT9P1/a/AyDBn0+L9C1YtnZqsFjennisngSUqa//v1Fe8PdUlfGH XU9kB X-Developer-Key: i=chleroy@kernel.org; a=openpgp; fpr=10FFE6F8B390DE17ACC2632368A92FEB01B8DD78 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Commit 861574d51bbd ("powerpc/uaccess: Implement masked user access") provides optimised user access by avoiding the cost of access_ok(). Convert signal64 functions to scoped user access. Scoped user access also make the code simpler. Signed-off-by: Christophe Leroy (CS GROUP) --- arch/powerpc/kernel/signal_64.c | 81 +++++++++++++-------------------- 1 file changed, 32 insertions(+), 49 deletions(-) diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_6= 4.c index 9b4cd0bbf4a7..4ff8ad5d60d0 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -693,15 +693,12 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *= , old_ctx, =20 if (old_ctx !=3D NULL) { prepare_setup_sigcontext(current); - if (!user_write_access_begin(old_ctx, ctx_size)) - return -EFAULT; - - unsafe_setup_sigcontext(&old_ctx->uc_mcontext, current, 0, NULL, - 0, ctx_has_vsx_region, efault_out); - unsafe_copy_to_user(&old_ctx->uc_sigmask, ¤t->blocked, - sizeof(sigset_t), efault_out); - - user_write_access_end(); + scoped_user_write_access_size(old_ctx, ctx_size, efault_out) { + unsafe_setup_sigcontext(&old_ctx->uc_mcontext, current, 0, NULL, + 0, ctx_has_vsx_region, efault_out); + unsafe_copy_to_user(&old_ctx->uc_sigmask, ¤t->blocked, + sizeof(sigset_t), efault_out); + } } if (new_ctx =3D=3D NULL) return 0; @@ -727,14 +724,12 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *= , old_ctx, } set_current_blocked(&set); =20 - if (!user_read_access_begin(new_ctx, ctx_size)) - return -EFAULT; - if (__unsafe_restore_sigcontext(current, NULL, 0, &new_ctx->uc_mcontext))= { - user_read_access_end(); - force_exit_sig(SIGSEGV); - return -EFAULT; + scoped_user_read_access_size(new_ctx, ctx_size, efault_out) { + if (__unsafe_restore_sigcontext(current, NULL, 0, &new_ctx->uc_mcontext)= ) { + force_exit_sig(SIGSEGV); + return -EFAULT; + } } - user_read_access_end(); =20 /* This returns like rt_sigreturn */ set_thread_flag(TIF_RESTOREALL); @@ -742,7 +737,6 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, = old_ctx, return 0; =20 efault_out: - user_write_access_end(); return -EFAULT; } =20 @@ -825,6 +819,7 @@ SYSCALL_DEFINE0(rt_sigreturn) &uc_transact->uc_mcontext)) goto badframe; } else { + struct sigcontext __user *uc_mcontext =3D &uc->uc_mcontext; /* * Fall through, for non-TM restore * @@ -839,13 +834,8 @@ SYSCALL_DEFINE0(rt_sigreturn) */ regs_set_return_msr(current->thread.regs, current->thread.regs->msr & ~MSR_TS_MASK); - if (!user_read_access_begin(&uc->uc_mcontext, sizeof(uc->uc_mcontext))) - goto badframe; - - unsafe_restore_sigcontext(current, NULL, 1, &uc->uc_mcontext, - badframe_block); - - user_read_access_end(); + scoped_user_read_access(uc_mcontext, badframe) + unsafe_restore_sigcontext(current, NULL, 1, uc_mcontext, badframe); } =20 if (restore_altstack(&uc->uc_stack)) @@ -855,8 +845,6 @@ SYSCALL_DEFINE0(rt_sigreturn) =20 return 0; =20 -badframe_block: - user_read_access_end(); badframe: signal_fault(current, regs, "rt_sigreturn", uc); =20 @@ -886,32 +874,29 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t= *set, err |=3D setup_tm_sigcontexts(frame, tsk, ksig->sig, NULL, (unsigned long)ksig->ka.sa.sa_handler, msr); =20 - if (!user_write_access_begin(frame, sizeof(*frame))) - goto badframe; + scoped_user_write_access(frame, badframe) { + unsafe_put_user(&frame->info, &frame->pinfo, badframe); + unsafe_put_user(&frame->uc, &frame->puc, badframe); =20 - unsafe_put_user(&frame->info, &frame->pinfo, badframe_block); - unsafe_put_user(&frame->uc, &frame->puc, badframe_block); + /* Create the ucontext. */ + unsafe_put_user(0, &frame->uc.uc_flags, badframe); + unsafe_save_altstack(&frame->uc.uc_stack, regs->gpr[1], badframe); =20 - /* Create the ucontext. */ - unsafe_put_user(0, &frame->uc.uc_flags, badframe_block); - unsafe_save_altstack(&frame->uc.uc_stack, regs->gpr[1], badframe_block); - - if (MSR_TM_ACTIVE(msr)) { + if (MSR_TM_ACTIVE(msr)) { #ifdef CONFIG_PPC_TRANSACTIONAL_MEM - /* The ucontext_t passed to userland points to the second - * ucontext_t (for transactional state) with its uc_link ptr. - */ - unsafe_put_user(&frame->uc_transact, &frame->uc.uc_link, badframe_block); + /* The ucontext_t passed to userland points to the second + * ucontext_t (for transactional state) with its uc_link ptr. + */ + unsafe_put_user(&frame->uc_transact, &frame->uc.uc_link, badframe); #endif - } else { - unsafe_put_user(0, &frame->uc.uc_link, badframe_block); - unsafe_setup_sigcontext(&frame->uc.uc_mcontext, tsk, ksig->sig, - NULL, (unsigned long)ksig->ka.sa.sa_handler, - 1, badframe_block); - } + } else { + unsafe_put_user(0, &frame->uc.uc_link, badframe); + unsafe_setup_sigcontext(&frame->uc.uc_mcontext, tsk, ksig->sig, NULL, + (unsigned long)ksig->ka.sa.sa_handler, 1, badframe); + } =20 - unsafe_copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set), badframe_bl= ock); - user_write_access_end(); + unsafe_copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set), badframe); + } =20 /* Save the siginfo outside of the unsafe block. */ if (copy_siginfo_to_user(&frame->info, &ksig->info)) @@ -968,8 +953,6 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *= set, =20 return 0; =20 -badframe_block: - user_write_access_end(); badframe: signal_fault(current, regs, "handle_rt_signal64", frame); =20 --=20 2.54.0 From nobody Mon Jun 8 04:11:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C61152C11EE for ; Tue, 2 Jun 2026 08:46:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390020; cv=none; b=SUiB2PdfmbLGlUhXFCoa8O1l6wC3j3uofxfHkaWcrFbz+DM+Fs3Z9b7GkZy0eQguQXZnYdvWlHSgVfnicdTQ43I0V9UaLo6+/txOGff1gaetOEY+E6mKVDJa26bisNnrJBt+9OuyYcBDqPkAWECDPCb2CsYtFviv6EsqnDH/c4I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390020; c=relaxed/simple; bh=4aksLooy4XCvM5n/sIPCKsUfuKkAa5e7DCDqbcxCFz4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YeRytQ0oUCcskkjQrGjLObyIql3aZiZOxZTBwn+5j9WEKuHsLy3LHj3NOCXIwsui3MY3K/rjwU6HG0wwVdYtIazcAgmBiRex148YdstjYebe9adpNJ3mY0kxOv+L3xoA34vpoLAGpshmVl9E6SmU3RbRwqHO7dDUAHOxNM9N5sc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=TChqJwKI; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="TChqJwKI" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0548C1F00893; Tue, 2 Jun 2026 08:46:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780390019; bh=sMG/2rxZYMjEPPBvwv4bSmWW/2cnEvqzHzFFMwcW/54=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=TChqJwKIsLx5o6EZivYMTNC1TWMC37L1gx+GW4rJSYfwykZvJLBT292S+1X5NFTGs Jk+fnS19J99iQz90W7a3/bu+hXZfrC2OQRaufm6xSbl6KTRE7p/3NISpX4LPfW5cpb zXnY1Siy9WKZ7ZF37CqJoaGttxRAatkV/JsLG1DguyIkmJhB5W9dHvQHgDujWI4vXo fmH/ry14vvn58H5bDSEv2KxtUgAQawzZh+GvlZbequNj+JaXTH11ogN1SYPUvpiRBS 1jXoi283PCVIfOgExKJXItUZSV4MLA0B4adS9zGUV1UO3zAiAvWM3i8X/0/JRD69Qp Ymm4HYO5tzXnw== From: "Christophe Leroy (CS GROUP)" To: Michael Ellerman , Nicholas Piggin , Madhavan Srinivasan Cc: "Christophe Leroy (CS GROUP)" , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 4/8] powerpc/signal64: Access function descriptor with scoped user access Date: Tue, 2 Jun 2026 10:46:33 +0200 Message-ID: <6492f5d9ace4ae9dd39ce45b509cd3790285b44a.1780389863.git.chleroy@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1246; i=chleroy@kernel.org; h=from:subject:message-id; bh=4aksLooy4XCvM5n/sIPCKsUfuKkAa5e7DCDqbcxCFz4=; b=owGbwMvMwCV2d0KB2p7V54MZT6slMWTJzcid6Fsj7a7J5Jpve0L/UfWq71tnJbrOWsWzb4HsQ 6fZi/4XdZSyMIhxMciKKbIc/8+9a0bXl9T8qbv0YeawMoEMYeDiFICJGEow/E/q8Jn7Oqq6nd89 L8xl1yMRz1lZb4o55u4XOP1i1+4jU34xMvy80rVfp/C+0csds/ZL6b9s8DF5I9WTcbfy08OHG5y cLjMBAA== X-Developer-Key: i=chleroy@kernel.org; a=openpgp; fpr=10FFE6F8B390DE17ACC2632368A92FEB01B8DD78 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Access the function descriptor of the handler within a scoped user access block. Signed-off-by: Christophe Leroy (CS GROUP) --- arch/powerpc/kernel/signal_64.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_6= 4.c index 4ff8ad5d60d0..d23a980b32a8 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -932,8 +932,10 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t = *set, struct func_desc __user *ptr =3D (struct func_desc __user *)ksig->ka.sa.sa_handler; =20 - err |=3D get_user(regs->ctr, &ptr->addr); - err |=3D get_user(regs->gpr[2], &ptr->toc); + scoped_user_read_access(ptr, badfunc) { + unsafe_get_user(regs->ctr, &ptr->addr, badfunc); + unsafe_get_user(regs->gpr[2], &ptr->toc, badfunc); + } } =20 /* enter the signal handler in native-endian mode */ @@ -956,5 +958,10 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t = *set, badframe: signal_fault(current, regs, "handle_rt_signal64", frame); =20 + return 1; + +badfunc: + signal_fault(current, regs, __func__, (void __user *)ksig->ka.sa.sa_handl= er); + return 1; } --=20 2.54.0 From nobody Mon Jun 8 04:11:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 81F5239448F for ; Tue, 2 Jun 2026 08:47:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390023; cv=none; b=jKGVz9ijukEOt7ERGnszdLQt8B1aKAstMwAK7CzctdrYTOeJu+syrE5lYUBzvYXLf2EmN7Zn3Ga91vguzilqkpuvXSli8iOhfO6C+oFtRnHbfHuUIKtLQRg6FFvhBd71SyxNtqobMzOK7OlrEwOWRi5SoBznagkhCUlvi/37KEY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390023; c=relaxed/simple; bh=R4q9+C6lESokrWVF7HF59GXu7c8YM08ZU6LfSFgcbic=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=V9pdjqhMAwPby4utyCdYKSVmP024e5MM8+LeETqK3XL1vHEMiTmAjwLItxgWeV3riHJem5AKoDIFUwZzNQE+U+QdvxQh79ztJ7yzrYGYB4tX79gBbcrr81kxkGLy9/VAL9Ey9bOPyWtj40jmPwyKolByk/hTQ9vfdwKlF1mc3a8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eFPpvLNt; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eFPpvLNt" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 3DF1E1F00899; Tue, 2 Jun 2026 08:47:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780390022; bh=pIqCsuLLewsksHrVdB7iGloQkWquv0tm2KHbomaht3s=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=eFPpvLNthEGvphD2HSQffo4Y81BDPZE9rC2ebusV/9Nit3Xepu3OYYlWiMk6/STV1 LY93tegpc5ZkBci5n+2Y39AODjlFe+ufnEQdwQXdEWv87KmF4xSKU/3zMxVX+mS+Xv Wfmfuq5AHIoGYqV5kzn1HxDchMh0SelLSRMUohidJnOjBFqcy5oNKGxT+ZIJxMW84t YQxHwExO3WPT4sDJOTLSlVuEY/2EdRG7ZPrk9g+3HVwcoWqAEimBO+EsMOuarKaS6O TtIBawjJ/1+BsbtBtJCkH9iQgHPrceHGgJP04tioLvgxxZlYEw66CBjqjEKQFwS0YL u5m2VNuHb8Iew== From: "Christophe Leroy (CS GROUP)" To: Michael Ellerman , Nicholas Piggin , Madhavan Srinivasan Cc: "Christophe Leroy (CS GROUP)" , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 5/8] powerpc/signal: Include the new stack frame inside the user access block Date: Tue, 2 Jun 2026 10:46:34 +0200 Message-ID: <16242a61b12f2920ba4eba7a705272a6e475bede.1780389863.git.chleroy@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=6824; i=chleroy@kernel.org; h=from:subject:message-id; bh=R4q9+C6lESokrWVF7HF59GXu7c8YM08ZU6LfSFgcbic=; b=owGbwMvMwCV2d0KB2p7V54MZT6slMWTJzcjlamY2y//BJ5Kxf7PcbWEhuXilCScuy7bf4JHbe 5j7oIJcRykLgxgXg6yYIsvx/9y7ZnR9Sc2fuksfZg4rE8gQBi5OAZhIlTIjw/pN2wK37hZX2rnv VqX9E84HnnsWnvVY0Oh97o3pbtmpfqwM/wO7uBemL8p49+LcOZ+DWsFPi+bU7BY8yWKdekbPoe/ /FF4A X-Developer-Key: i=chleroy@kernel.org; a=openpgp; fpr=10FFE6F8B390DE17ACC2632368A92FEB01B8DD78 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Include the new stack frame inside the user access block and set it up using unsafe_put_user(). On an mpc 8321 (book3s/32) the improvment is about 4% on a process sending a signal to itself. Signed-off-by: Christophe Leroy (CS GROUP) --- arch/powerpc/kernel/signal_32.c | 28 ++++++++++++---------------- arch/powerpc/kernel/signal_64.c | 13 ++++++------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_3= 2.c index f5d5139a1426..6b1fbd95b07d 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -730,7 +730,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *= oldset, struct task_struct *tsk) { struct rt_sigframe __user *frame; - unsigned long newsp =3D 0; + unsigned long __user *newsp; unsigned long tramp; struct pt_regs *regs =3D tsk->thread.regs; /* Save the thread's msr before get_tm_stackpointer() changes it */ @@ -738,12 +738,13 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t= *oldset, =20 /* Set up Signal Frame */ frame =3D get_sigframe(ksig, tsk, sizeof(*frame), 1); + newsp =3D (unsigned long __user *)((unsigned long)frame - (__SIGNAL_FRAME= SIZE + 16)); if (MSR_TM_ACTIVE(msr)) prepare_save_tm_user_regs(); else prepare_save_user_regs(1); =20 - scoped_user_rw_access(frame, badframe) { + scoped_user_rw_access_size(newsp, __SIGNAL_FRAMESIZE + 16 + sizeof(*frame= ), badframe) { struct mcontext __user *mctx; struct mcontext __user *tm_mctx =3D NULL; =20 @@ -784,6 +785,9 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *= oldset, asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0])); } unsafe_put_sigset_t(&frame->uc.uc_sigmask, oldset, badframe); + + /* create a stack frame for the caller of the handler */ + unsafe_put_user(regs->gpr[1], newsp, badframe); } =20 if (copy_siginfo_to_user(&frame->info, &ksig->info)) @@ -795,13 +799,8 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t = *oldset, tsk->thread.fp_state.fpscr =3D 0; /* turn off all fp exceptions */ #endif =20 - /* create a stack frame for the caller of the handler */ - newsp =3D ((unsigned long)frame) - (__SIGNAL_FRAMESIZE + 16); - if (put_user(regs->gpr[1], (u32 __user *)newsp)) - goto badframe; - /* Fill registers for signal handler */ - regs->gpr[1] =3D newsp; + regs->gpr[1] =3D (unsigned long)newsp; regs->gpr[3] =3D ksig->sig; regs->gpr[4] =3D (unsigned long)&frame->info; regs->gpr[5] =3D (unsigned long)&frame->uc; @@ -826,7 +825,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *old= set, { struct sigcontext __user *sc; struct sigframe __user *frame; - unsigned long newsp =3D 0; + unsigned long __user *newsp; unsigned long tramp; struct pt_regs *regs =3D tsk->thread.regs; /* Save the thread's msr before get_tm_stackpointer() changes it */ @@ -834,12 +833,13 @@ int handle_signal32(struct ksignal *ksig, sigset_t *o= ldset, =20 /* Set up Signal Frame */ frame =3D get_sigframe(ksig, tsk, sizeof(*frame), 1); + newsp =3D (unsigned long __user *)((unsigned long)frame - __SIGNAL_FRAMES= IZE); if (MSR_TM_ACTIVE(msr)) prepare_save_tm_user_regs(); else prepare_save_user_regs(1); =20 - scoped_user_rw_access(frame, badframe) { + scoped_user_rw_access_size(newsp, __SIGNAL_FRAMESIZE + sizeof(*frame), ba= dframe) { struct mcontext __user *mctx; struct mcontext __user *tm_mctx =3D NULL; =20 @@ -876,6 +876,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *old= set, 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_user(regs->gpr[1], newsp, badframe); } =20 regs->link =3D tramp; @@ -884,12 +885,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *ol= dset, tsk->thread.fp_state.fpscr =3D 0; /* turn off all fp exceptions */ #endif =20 - /* create a stack frame for the caller of the handler */ - newsp =3D ((unsigned long)frame) - __SIGNAL_FRAMESIZE; - if (put_user(regs->gpr[1], (u32 __user *)newsp)) - goto badframe; - - regs->gpr[1] =3D newsp; + regs->gpr[1] =3D (unsigned long)newsp; regs->gpr[3] =3D ksig->sig; regs->gpr[4] =3D (unsigned long) sc; regs_set_return_ip(regs, (unsigned long) ksig->ka.sa.sa_handler); diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_6= 4.c index d23a980b32a8..19f320218ed1 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -856,13 +856,14 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t= *set, struct task_struct *tsk) { struct rt_sigframe __user *frame; - unsigned long newsp =3D 0; + unsigned long __user *newsp; long err =3D 0; struct pt_regs *regs =3D tsk->thread.regs; /* Save the thread's msr before get_tm_stackpointer() changes it */ unsigned long msr =3D regs->msr; =20 frame =3D get_sigframe(ksig, tsk, sizeof(*frame), 0); + newsp =3D (unsigned long __user *)((unsigned long)frame - __SIGNAL_FRAMES= IZE); =20 /* * This only applies when calling unsafe_setup_sigcontext() and must be @@ -874,7 +875,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *= set, err |=3D setup_tm_sigcontexts(frame, tsk, ksig->sig, NULL, (unsigned long)ksig->ka.sa.sa_handler, msr); =20 - scoped_user_write_access(frame, badframe) { + scoped_user_write_access_size(newsp, __SIGNAL_FRAMESIZE + sizeof(*frame),= badframe) { unsafe_put_user(&frame->info, &frame->pinfo, badframe); unsafe_put_user(&frame->uc, &frame->puc, badframe); =20 @@ -896,6 +897,8 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *= set, } =20 unsafe_copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set), badframe); + /* Allocate a dummy caller frame for the signal handler. */ + unsafe_put_user(regs->gpr[1], newsp, badframe); } =20 /* Save the siginfo outside of the unsafe block. */ @@ -915,10 +918,6 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t = *set, regs_set_return_ip(regs, (unsigned long) &frame->tramp[0]); } =20 - /* Allocate a dummy caller frame for the signal handler. */ - newsp =3D ((unsigned long)frame) - __SIGNAL_FRAMESIZE; - err |=3D put_user(regs->gpr[1], (unsigned long __user *)newsp); - /* Set up "regs" so we "return" to the signal handler. */ if (is_elf2_task()) { regs->ctr =3D (unsigned long) ksig->ka.sa.sa_handler; @@ -940,7 +939,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *= set, =20 /* enter the signal handler in native-endian mode */ regs_set_return_msr(regs, (regs->msr & ~MSR_LE) | (MSR_KERNEL & MSR_LE)); - regs->gpr[1] =3D newsp; + regs->gpr[1] =3D (unsigned long)newsp; regs->gpr[3] =3D ksig->sig; regs->result =3D 0; if (ksig->ka.sa.sa_flags & SA_SIGINFO) { --=20 2.54.0 From nobody Mon Jun 8 04:11:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 00CB633D4E9 for ; Tue, 2 Jun 2026 08:47:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390028; cv=none; b=uA3Zlad4wwYIxcluHKMRmLyHeQn+lzCblDNqDbVNNoH1TntOWNyz2Oot+DkUfBKKxa3o+jcIL6o0eOfyw0s8AaPYtNA14ShP/lNxk+dkEOh3TalYQRxzna2pSGPUofsTMc1TmGj1G7M3Y0foD54+vuWLvEbbMxk3N4ukJoy4RxI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390028; c=relaxed/simple; bh=CxukwNaaHfPCgLLuHd8f2xWMx67xuC8tWT39iKS4wZo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=B7VS+N98gBhBOxUqDd7ue7TFFmqdBYrG+SgOwJDSreqSdpm9U/fSvlG1Vg2n57Zl8OXCmBwAgtXdJjKFlNnk22Us1v59LPYj7Na7HinbK0WipqZnp8m/PghYiwnRFzkzLd06fYu1FqLvfhVFull5Zeo2+1DS2IBt6GXDY0n0U7M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=j3yh+9ql; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="j3yh+9ql" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A98DB1F00898; Tue, 2 Jun 2026 08:47:02 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780390024; bh=qIFh0EHf36xuaiQUrsEboCGTYqr33D+g0zvT7LVweRs=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=j3yh+9qljNOGvMJg2vjR4qqPnlP9WDre9stzGTtmF/drPyf1BBSbJ0/CfzvDlDBv0 wR0Jk0sSLAsz4Os1NthdWFpgQvCaE3kGcv7mRLyPPD1krz5P5SO+BLo/gHi+6N/SAx xxUk3pNiLi5dhp1UqIewE2g0mDkfNrMmCQqteAFeCP1NrxixFdO8tmQlY8W3zjKZo8 USPQYbrIyrjBy3yj4N1RwnQfmNCyKqjUNNrAAEufVD4xWSt/SRc7vakmEzryWGsboa lm5YamYmdrkgnOy3Ig2SUZZ6+vHKjjz9RMyoF5HAOB3l0RAxF7XZB+tyOw0HKrIAOi YKahPcXI6EY5Q== From: "Christophe Leroy (CS GROUP)" To: Michael Ellerman , Nicholas Piggin , Madhavan Srinivasan Cc: "Christophe Leroy (CS GROUP)" , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 6/8] signal: Add unsafe_copy_siginfo_to_user() Date: Tue, 2 Jun 2026 10:46:35 +0200 Message-ID: <026832f540ef269cf8693e3c3b58c759d0f63544.1780389863.git.chleroy@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=2953; i=chleroy@kernel.org; h=from:subject:message-id; bh=CxukwNaaHfPCgLLuHd8f2xWMx67xuC8tWT39iKS4wZo=; b=owGbwMvMwCV2d0KB2p7V54MZT6slMWTJzcjb+N5K92ag76ubrK0FRWzqipmM7zaLRT7+ZRnF3 z0p4G17RykLgxgXg6yYIsvx/9y7ZnR9Sc2fuksfZg4rE8gQBi5OAZjIDk9GhoMJ3Y/YzIMiPt/d LnpFrevwgd2HlvZOnRbR3Mc4Q4pFRJGRYYHZzE+JjnyFOk6Kv3g6HzFuXJMhVmC06QfnAvErHoH fmQA= X-Developer-Key: i=chleroy@kernel.org; a=openpgp; fpr=10FFE6F8B390DE17ACC2632368A92FEB01B8DD78 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In the same spirit as commit fb05121fd6a2 ("signal: Add unsafe_get_compat_sigset()"), implement an 'unsafe' version of copy_siginfo_to_user() in order to use it within user access blocks. For that, also add an 'unsafe' version of clear_user(). This commit adds the generic fallback for unsafe_clear_user(). Architectures wanting to use unsafe_copy_siginfo_to_user() within a user_access_begin() section have to make sure they have their own unsafe_clear_user(). Signed-off-by: Christophe Leroy (CS GROUP) --- include/linux/signal.h | 15 +++++++++++++++ include/linux/uaccess.h | 1 + kernel/signal.c | 5 ----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/include/linux/signal.h b/include/linux/signal.h index f19816832f05..3ee6c9463f8b 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -36,6 +36,21 @@ static inline void copy_siginfo_to_external(siginfo_t *t= o, int copy_siginfo_to_user(siginfo_t __user *to, const kernel_siginfo_t *fro= m); int copy_siginfo_from_user(kernel_siginfo_t *to, const siginfo_t __user *f= rom); =20 +static __always_inline char __user *si_expansion(const siginfo_t __user *i= nfo) +{ + return ((char __user *)info) + sizeof(struct kernel_siginfo); +} + +#define unsafe_copy_siginfo_to_user(to, from, label) do { \ + siginfo_t __user *__ucs_to =3D to; \ + const kernel_siginfo_t *__ucs_from =3D from; \ + char __user *__ucs_expansion =3D si_expansion(__ucs_to); \ + \ + unsafe_copy_to_user(__ucs_to, __ucs_from, \ + sizeof(struct kernel_siginfo), label); \ + unsafe_clear_user(__ucs_expansion, SI_EXPANSION_SIZE, label); \ +} while (0) + enum siginfo_layout { SIL_KILL, SIL_TIMER, diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index 56328601218c..43e573b172a2 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -636,6 +636,7 @@ do { \ #define unsafe_put_user(x,p,e) unsafe_op_wrap(__put_user(x,p),e) #define unsafe_copy_to_user(d,s,l,e) unsafe_op_wrap(__copy_to_user(d,s,l),= e) #define unsafe_copy_from_user(d,s,l,e) unsafe_op_wrap(__copy_from_user(d,s= ,l),e) +#define unsafe_clear_user(d, l, e) unsafe_op_wrap(__clear_user(d, l), e) static inline unsigned long user_access_save(void) { return 0UL; } static inline void user_access_restore(unsigned long flags) { } #endif /* !user_access_begin */ diff --git a/kernel/signal.c b/kernel/signal.c index 2d102e025883..2c5eb741fe8c 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -3493,11 +3493,6 @@ enum siginfo_layout siginfo_layout(unsigned sig, int= si_code) return layout; } =20 -static inline char __user *si_expansion(const siginfo_t __user *info) -{ - return ((char __user *)info) + sizeof(struct kernel_siginfo); -} - int copy_siginfo_to_user(siginfo_t __user *to, const kernel_siginfo_t *fro= m) { char __user *expansion =3D si_expansion(to); --=20 2.54.0 From nobody Mon Jun 8 04:11:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 35A2736E489 for ; Tue, 2 Jun 2026 08:47:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390028; cv=none; b=X0/CZ9URVZqZtSttZIiKftW+95Ic074sLHN5Pz6XtOknUyPKaXfJdhWSxcgegB4fZkENRTUM0PsHZ9HmwkLuzUyhyvQ5vh1kONg/s6x/M+RNEmPPMU3HXLbjnBGYNVR0cCtDLIGO24F6y10O8xB34kd2bcWg7mU+0om8ihRv7jQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390028; c=relaxed/simple; bh=XuOAOSYDASIkE8k1DcwiObr6/h55lx5h+RiNNYy8aAY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Np37UkuIOA/xV628oCnXJt4boIiVgLqKJRxn1SbYSTvpMN8tT1TS1tqjhaHtovgjFqFLUirMD3jhNP5DzEdaiDtPDMAgA+cZ20XMBN/B0zIUBM0sdAszuqwKBx5jyBTPJrAzeRYc0DzyqtpGpK+eiKRlDE75d5xpc3vl6zPJmko= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=LuD2k+yR; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="LuD2k+yR" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 111B71F00893; Tue, 2 Jun 2026 08:47:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780390026; bh=KetQGnpihDD2vxXf7LRusXJw3y8BnoktxOIVo1JkiuE=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=LuD2k+yRlJPZt8nXdTJbqG6KC2W+Dke3s/q3g84fgMAsgCHOlv/HHiDB548ujh1xr 3rVpsuk0GvyWAWOk1iOYj530GpfzudRL9onsjLw10+vrV9bwuUGx6tFgPETvwm16l6 J6LwCmDwQmP377adwJWaHunJr4CJ2NIEODTWTLhi0WyCZJQO4HZdUZs64Ecp0LUZIG X/RhL0fNJLePJuEj+zb46h38tCqD1bdbvgxyKalD3XIm+3nGDPrwGLSr24k4zxMR7z ooxRsfSyqGlhWUg22EusR7oTkymzzs/wjfkXcNziWdi54hYfg7zG/T8U6cHr1+yC5Z WnLksJM5+C+qA== From: "Christophe Leroy (CS GROUP)" To: Michael Ellerman , Nicholas Piggin , Madhavan Srinivasan Cc: "Christophe Leroy (CS GROUP)" , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 7/8] powerpc/uaccess: Add unsafe_clear_user() Date: Tue, 2 Jun 2026 10:46:36 +0200 Message-ID: <1a4f0e7ef4d1c6b794fb95cb88c4ce65c1fd5f6a.1780389863.git.chleroy@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=1532; i=chleroy@kernel.org; h=from:subject:message-id; bh=XuOAOSYDASIkE8k1DcwiObr6/h55lx5h+RiNNYy8aAY=; b=owGbwMvMwCV2d0KB2p7V54MZT6slMWTJzcgLSU9+9t018cOqeqtNJtpPW3UPbtAzu1qw7Vj9M +kX69pSO0pZGMS4GGTFFFmO/+feNaPrS2r+1F36MHNYmUCGMHBxCsBEYlwYGeac+/MiTS3z7rvz Zf2RareFL1vxLLJyOFLGL7khyNxpbQ0jQ//UIxXxF3vYIjd+ehxR9uDMry93Jt9okBH1Y1hw+2j VFQ4A X-Developer-Key: i=chleroy@kernel.org; a=openpgp; fpr=10FFE6F8B390DE17ACC2632368A92FEB01B8DD78 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Implement unsafe_clear_user() for powerpc. It's a copy/paste of unsafe_copy_to_user() with value 0 as source. It may be improved in a later patch by using 'dcbz' instruction to zeroize full cache lines at once. Signed-off-by: Christophe Leroy (CS GROUP) --- arch/powerpc/include/asm/uaccess.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/= uaccess.h index e98c628e3899..ef6711d1278b 100644 --- a/arch/powerpc/include/asm/uaccess.h +++ b/arch/powerpc/include/asm/uaccess.h @@ -588,6 +588,26 @@ do { \ unsafe_put_user(*(u8*)(_src + _i), (u8 __user *)(_dst + _i), e); \ } while (0) =20 +#define unsafe_clear_user(d, l, e) \ +do { \ + u8 __user *_dst =3D (u8 __user *)(d); \ + size_t _len =3D (l); \ + int _i; \ + \ + for (_i =3D 0; _i < (_len & ~(sizeof(u64) - 1)); _i +=3D sizeof(u64)) \ + unsafe_put_user(0, (u64 __user *)(_dst + _i), e); \ + if (_len & 4) { \ + unsafe_put_user(0, (u32 __user *)(_dst + _i), e); \ + _i +=3D 4; \ + } \ + if (_len & 2) { \ + unsafe_put_user(0, (u16 __user *)(_dst + _i), e); \ + _i +=3D 2; \ + } \ + if (_len & 1) \ + unsafe_put_user(0, (u8 __user *)(_dst + _i), e); \ +} while (0) + #define arch_get_kernel_nofault(dst, src, type, err_label) \ __get_user_size_goto(*((type *)(dst)), \ (__force type __user *)(src), sizeof(type), err_label) --=20 2.54.0 From nobody Mon Jun 8 04:11:22 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-alma10-1.taild15c8.ts.net [100.103.45.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E3E783B388B for ; Tue, 2 Jun 2026 08:47:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=100.103.45.18 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390031; cv=none; b=Zj80JOv4jJGGyDIGUz6XCHdl7SsjK1ABOPd1VWHz5xsI7dxwiCElm6vlup0XBOYXeYwoonfZ7EAiWa2T1tcbv1aqU9QJBXHE7CoIiNJn50E9vwfHWvqyBdWqRaRQEcgawzOnrff01ACjNNZ2OlZU8PlxQCm18Wxa+XJVHJxJVqs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780390031; c=relaxed/simple; bh=ixKhjvehlfnvFNRHYvNkVWnFjQVOC0Kh+ZCiRKQI12c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=hbHGvL7JtSyV1BL1kSkCm97vGK3o7LAkhqXOxs9M7i7s2FCa408mdH7URLDsOSnjeBiW07Ed5VsQ4u9945SrrykHIy8bqAV4tOPNrBK+o6O4DbirqtHWZ2/wX30HIt0ghPgXUrh8LMXGlgVQnEXRKLCAF2wk9A6GItKOARPh2SY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=K9jsKhni; arc=none smtp.client-ip=100.103.45.18 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="K9jsKhni" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 64BEA1F00899; Tue, 2 Jun 2026 08:47:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kernel.org; s=k20260515; t=1780390029; bh=hB8KcKOOaDxrq0X6EkuXwqEZ/uT4eAU964Z3866+uHY=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=K9jsKhni8d/dKEGeCmkJJhfDcV9bDJjQUqVNPDAD6CXtVLa5GCek4977YI4JpMEa8 7BnWwaXSrY8OX/mJTA6X2lLJ30+WjNiJvSdNZTg25Ni52EutbfCDv+srNa2Op6Opnn cbH4O1gpChXs18k5WSfXY16mjrOOT8m/2wJMDXqo4PS4SbHMTQwBI2y3p74V5Ys8Cz /MrDA7vHJcr5xYnaP1eMPehM+2Q7UjmekTtQ7IOnoM7tBxt4z6xxwuns9Lu9cg1++1 FeTmOxektzGfWwTsK9yUVgJx05jh+cSFkSxBhxxonVdVcSevNh0KfCDXcaMim97LU8 2eW8mtYNZ3dGA== From: "Christophe Leroy (CS GROUP)" To: Michael Ellerman , Nicholas Piggin , Madhavan Srinivasan Cc: "Christophe Leroy (CS GROUP)" , linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v2 8/8] powerpc/signal: Use unsafe_copy_siginfo_to_user() Date: Tue, 2 Jun 2026 10:46:37 +0200 Message-ID: <250c80bb6155b625d0625459234caa17794b12c0.1780389863.git.chleroy@kernel.org> X-Mailer: git-send-email 2.54.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Developer-Signature: v=1; a=openpgp-sha256; l=3199; i=chleroy@kernel.org; h=from:subject:message-id; bh=ixKhjvehlfnvFNRHYvNkVWnFjQVOC0Kh+ZCiRKQI12c=; b=owGbwMvMwCV2d0KB2p7V54MZT6slMWTJzcgrf94lGfyhJ3I7c4TL6xdqVibZEiLTmpZvn/C4r HSTwIqkjlIWBjEuBlkxRZbj/7l3zej6kpo/dZc+zBxWJpAhDFycAjCR9P0M/xP/WV2dc7Nv5YzK Kuv1bCvO/3whamfazG3Sppz2cx971Q6G/2HzSibvTj25w0irjPNd27cH30KY2m5NKjrTuC16n/7 0AH4A X-Developer-Key: i=chleroy@kernel.org; a=openpgp; fpr=10FFE6F8B390DE17ACC2632368A92FEB01B8DD78 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Use unsafe_copy_siginfo_to_user() in order to do the copy within the user access block. On an mpc 8321 (book3s/32) the improvment is about 5% on a process sending a signal to itself. Signed-off-by: Christophe Leroy (CS GROUP) --- arch/powerpc/kernel/signal_32.c | 18 +++++++++--------- arch/powerpc/kernel/signal_64.c | 5 +---- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_3= 2.c index 6b1fbd95b07d..99a3efa874eb 100644 --- a/arch/powerpc/kernel/signal_32.c +++ b/arch/powerpc/kernel/signal_32.c @@ -716,12 +716,6 @@ static long restore_tm_user_regs(struct pt_regs *regs,= struct mcontext __user *s } #endif =20 -#ifdef CONFIG_PPC64 - -#define copy_siginfo_to_user copy_siginfo_to_user32 - -#endif /* CONFIG_PPC64 */ - /* * Set up a signal frame for a "real-time" signal handler * (one which gets siginfo). @@ -735,6 +729,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *= oldset, struct pt_regs *regs =3D tsk->thread.regs; /* Save the thread's msr before get_tm_stackpointer() changes it */ unsigned long msr =3D regs->msr; + compat_siginfo_t uinfo; =20 /* Set up Signal Frame */ frame =3D get_sigframe(ksig, tsk, sizeof(*frame), 1); @@ -744,6 +739,9 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *= oldset, else prepare_save_user_regs(1); =20 + if (IS_ENABLED(CONFIG_COMPAT)) + copy_siginfo_to_external32(&uinfo, &ksig->info); + scoped_user_rw_access_size(newsp, __SIGNAL_FRAMESIZE + 16 + sizeof(*frame= ), badframe) { struct mcontext __user *mctx; struct mcontext __user *tm_mctx =3D NULL; @@ -785,14 +783,16 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t= *oldset, asm("dcbst %y0; sync; icbi %y0; sync" :: "Z" (mctx->mc_pad[0])); } unsafe_put_sigset_t(&frame->uc.uc_sigmask, oldset, badframe); + if (IS_ENABLED(CONFIG_COMPAT)) + unsafe_copy_to_user(&frame->info, &uinfo, sizeof(frame->info), badframe= ); + else + unsafe_copy_siginfo_to_user((void __user *)&frame->info, &ksig->info, + badframe); =20 /* create a stack frame for the caller of the handler */ unsafe_put_user(regs->gpr[1], newsp, badframe); } =20 - if (copy_siginfo_to_user(&frame->info, &ksig->info)) - goto badframe; - regs->link =3D tramp; =20 #ifdef CONFIG_PPC_FPU_REGS diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_6= 4.c index 19f320218ed1..e85c430305a1 100644 --- a/arch/powerpc/kernel/signal_64.c +++ b/arch/powerpc/kernel/signal_64.c @@ -897,14 +897,11 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t= *set, } =20 unsafe_copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set), badframe); + unsafe_copy_siginfo_to_user(&frame->info, &ksig->info, badframe); /* Allocate a dummy caller frame for the signal handler. */ unsafe_put_user(regs->gpr[1], newsp, badframe); } =20 - /* Save the siginfo outside of the unsafe block. */ - if (copy_siginfo_to_user(&frame->info, &ksig->info)) - goto badframe; - /* Make sure signal handler doesn't get spurious FP exceptions */ tsk->thread.fp_state.fpscr =3D 0; =20 --=20 2.54.0