linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
From: Christophe Leroy <christophe.leroy@csgroup.eu>
To: Benjamin Herrenschmidt <benh@kernel.crashing.org>,
	Paul Mackerras <paulus@samba.org>,
	Michael Ellerman <mpe@ellerman.id.au>
Cc: linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org
Subject: [PATCH v2 24/25] powerpc/signal32: Isolate non-copy actions in save_user_regs() and save_tm_user_regs()
Date: Tue, 18 Aug 2020 17:19:36 +0000 (UTC)	[thread overview]
Message-ID: <f6eac65781b4a57220477c8864bca2b57f29a5d5.1597770847.git.christophe.leroy@csgroup.eu> (raw)
In-Reply-To: <cover.1597770847.git.christophe.leroy@csgroup.eu>

Reorder actions in save_user_regs() and save_tm_user_regs() to
regroup copies together in order to switch to user_access_begin()
logic in a later patch.

Move non-copy actions into new functions called
prepare_save_user_regs() and prepare_save_tm_user_regs().

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/kernel/signal_32.c | 54 +++++++++++++++++++++++++--------
 1 file changed, 41 insertions(+), 13 deletions(-)

diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 5b8a4ede142c..86539a4e0514 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -229,14 +229,31 @@ struct rt_sigframe {
  * We only save the altivec/spe registers if the process has used
  * altivec/spe instructions at some point.
  */
+static void prepare_save_user_regs(int ctx_has_vsx_region)
+{
+	/* Make sure floating point registers are stored in regs */
+	flush_fp_to_thread(current);
+#ifdef CONFIG_ALTIVEC
+	if (current->thread.used_vr)
+		flush_altivec_to_thread(current);
+	if (cpu_has_feature(CPU_FTR_ALTIVEC))
+		current->thread.vrsave = mfspr(SPRN_VRSAVE);
+#endif
+#ifdef CONFIG_VSX
+	if (current->thread.used_vsr && ctx_has_vsx_region)
+		flush_vsx_to_thread(current);
+#endif
+#ifdef CONFIG_SPE
+	if (current->thread.used_spe)
+		flush_spe_to_thread(current);
+#endif
+}
+
 static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
 			  struct mcontext __user *tm_frame, int ctx_has_vsx_region)
 {
 	unsigned long msr = regs->msr;
 
-	/* Make sure floating point registers are stored in regs */
-	flush_fp_to_thread(current);
-
 	/* save general registers */
 	if (save_general_regs(regs, frame))
 		return 1;
@@ -244,7 +261,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
 #ifdef CONFIG_ALTIVEC
 	/* save altivec registers */
 	if (current->thread.used_vr) {
-		flush_altivec_to_thread(current);
 		if (__copy_to_user(&frame->mc_vregs, &current->thread.vr_state,
 				   ELF_NVRREG * sizeof(vector128)))
 			return 1;
@@ -260,8 +276,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
 	 * most significant bits of that same vector. --BenH
 	 * Note that the current VRSAVE value is in the SPR at this point.
 	 */
-	if (cpu_has_feature(CPU_FTR_ALTIVEC))
-		current->thread.vrsave = mfspr(SPRN_VRSAVE);
 	if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
 		return 1;
 #endif /* CONFIG_ALTIVEC */
@@ -281,7 +295,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
 	 * contains valid data
 	 */
 	if (current->thread.used_vsr && ctx_has_vsx_region) {
-		flush_vsx_to_thread(current);
 		if (copy_vsx_to_user(&frame->mc_vsregs, current))
 			return 1;
 		msr |= MSR_VSX;
@@ -290,7 +303,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
 #ifdef CONFIG_SPE
 	/* save spe registers */
 	if (current->thread.used_spe) {
-		flush_spe_to_thread(current);
 		if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
 				   ELF_NEVRREG * sizeof(u32)))
 			return 1;
@@ -326,11 +338,23 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
  *
  * See save_user_regs() and signal_64.c:setup_tm_sigcontexts().
  */
-static int save_tm_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
-			     struct mcontext __user *tm_frame, unsigned long msr)
+static void prepare_save_tm_user_regs(void)
 {
 	WARN_ON(tm_suspend_disabled);
 
+#ifdef CONFIG_ALTIVEC
+	if (cpu_has_feature(CPU_FTR_ALTIVEC))
+		current->thread.ckvrsave = mfspr(SPRN_VRSAVE);
+#endif
+#ifdef CONFIG_SPE
+	if (current->thread.used_spe)
+		flush_spe_to_thread(current);
+#endif
+}
+
+static int save_tm_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
+			     struct mcontext __user *tm_frame, unsigned long msr)
+{
 	/* Save both sets of general registers */
 	if (save_general_regs(&current->thread.ckpt_regs, frame)
 	    || save_general_regs(regs, tm_frame))
@@ -374,8 +398,6 @@ static int save_tm_user_regs(struct pt_regs *regs, struct mcontext __user *frame
 	 * significant bits of a vector, we "cheat" and stuff VRSAVE in the
 	 * most significant bits of that same vector. --BenH
 	 */
-	if (cpu_has_feature(CPU_FTR_ALTIVEC))
-		current->thread.ckvrsave = mfspr(SPRN_VRSAVE);
 	if (__put_user(current->thread.ckvrsave,
 		       (u32 __user *)&frame->mc_vregs[32]))
 		return 1;
@@ -427,7 +449,6 @@ static int save_tm_user_regs(struct pt_regs *regs, struct mcontext __user *frame
 	 * simply the same as in save_user_regs().
 	 */
 	if (current->thread.used_spe) {
-		flush_spe_to_thread(current);
 		if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
 				   ELF_NEVRREG * sizeof(u32)))
 			return 1;
@@ -447,6 +468,8 @@ static int save_tm_user_regs(struct pt_regs *regs, struct mcontext __user *frame
 	return 0;
 }
 #else
+static void prepare_save_tm_user_regs(void) { }
+
 static int save_tm_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
 			     struct mcontext __user *tm_frame, unsigned long msr)
 {
@@ -790,9 +813,11 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
 		flush_icache_range(tramp, tramp + 2 * sizeof(unsigned long));
 
 	if (MSR_TM_ACTIVE(msr)) {
+		prepare_save_tm_user_regs();
 		if (save_tm_user_regs(regs, mctx, tm_mctx, msr))
 			goto badframe;
 	} else {
+		prepare_save_user_regs(1);
 		if (save_user_regs(regs, mctx, tm_mctx, 1))
 			goto badframe;
 	}
@@ -881,9 +906,11 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
 		flush_icache_range(tramp, tramp + 2 * sizeof(unsigned long));
 
 	if (MSR_TM_ACTIVE(msr)) {
+		prepare_save_tm_user_regs();
 		if (save_tm_user_regs(regs, mctx, tm_mctx, msr))
 			goto badframe;
 	} else {
+		prepare_save_user_regs(1);
 		if (save_user_regs(regs, mctx, tm_mctx, 1))
 			goto badframe;
 	}
@@ -1038,6 +1065,7 @@ 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 (save_user_regs(regs, mctx, NULL, ctx_has_vsx_region))
 			return -EFAULT;
 		if (!user_write_access_begin(old_ctx, ctx_size))
-- 
2.25.0


  parent reply	other threads:[~2020-08-18 18:11 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-18 17:19 [PATCH v2 00/25] powerpc: Switch signal 32 to using unsafe_put_user() and friends Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 01/25] powerpc/signal: Move inline functions in signal.h Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 02/25] powerpc/ptrace: Move declaration of ptrace_get_reg() and ptrace_set_reg() Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 03/25] powerpc/ptrace: Consolidate reg index calculation Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 04/25] powerpc/ptrace: Create ptrace_get_fpr() and ptrace_put_fpr() Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 05/25] powerpc/signal: Don't manage floating point regs when no FPU Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 06/25] powerpc/32s: Allow deselecting CONFIG_PPC_FPU on mpc832x Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 07/25] powerpc/signal: Remove BUG_ON() in handler_signal functions Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 08/25] powerpc/signal: Move access_ok() out of get_sigframe() Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 09/25] powerpc/signal: Remove get_clean_sp() Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 10/25] powerpc/signal: Call get_tm_stackpointer() from get_sigframe() Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 11/25] powerpc/signal: Refactor bad frame logging Christophe Leroy
2020-08-19  1:19   ` Joe Perches
2020-08-18 17:19 ` [PATCH v2 12/25] powerpc/signal32: Simplify logging in handle_rt_signal32() Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 13/25] powerpc/signal32: Move handle_signal32() close to handle_rt_signal32() Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 14/25] powerpc/signal32: Rename local pointers in handle_rt_signal32() Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 15/25] powerpc/signal32: Misc changes to make handle_[rt_]_signal32() more similar Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 16/25] powerpc/signal32: Move signal trampoline setup to handle_[rt_]signal32 Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 17/25] powerpc/signal32: Switch handle_signal32() to user_access_begin() logic Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 18/25] powerpc/signal32: Switch handle_rt_signal32() " Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 19/25] powerpc/signal32: Remove ifdefery in middle of if/else Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 20/25] signal: Add unsafe_put_compat_sigset() Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 21/25] powerpc/signal32: Add and use unsafe_put_sigset_t() Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 22/25] powerpc/signal32: Switch swap_context() to user_access_begin() logic Christophe Leroy
2020-08-18 17:19 ` [PATCH v2 23/25] powerpc/signal: Create 'unsafe' versions of copy_[ck][fpr/vsx]_to_user() Christophe Leroy
2020-09-29  2:04   ` Christopher M. Riedl
2020-09-29  5:22     ` Christophe Leroy
2020-09-29  5:33       ` Christophe Leroy
2020-08-18 17:19 ` Christophe Leroy [this message]
2020-08-18 17:19 ` [PATCH v2 25/25] powerpc/signal32: Transform save_user_regs() and save_tm_user_regs() in 'unsafe' version Christophe Leroy
     [not found]   ` <202008271728.tFAPDKU8%lkp@intel.com>
2020-08-27 15:59     ` Christophe Leroy
2020-09-29  2:55   ` Christopher M. Riedl
2020-09-29  5:21     ` Christophe Leroy
2020-12-10 11:29 ` [PATCH v2 00/25] powerpc: Switch signal 32 to using unsafe_put_user() and friends Michael Ellerman

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=f6eac65781b4a57220477c8864bca2b57f29a5d5.1597770847.git.christophe.leroy@csgroup.eu \
    --to=christophe.leroy@csgroup.eu \
    --cc=benh@kernel.crashing.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=mpe@ellerman.id.au \
    --cc=paulus@samba.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).