Commit 036fc2cb authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman

powerpc/signal32: Reorder user reads in restore_tm_user_regs()

In restore_tm_user_regs(), regroup the reads from 'sr' and the ones
from 'tm_sr' together in order to allow two block user accesses
in following patch.
Signed-off-by: default avatarChristophe Leroy <christophe.leroy@csgroup.eu>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/7c518b9a4c8e5ae9a3bfb647bc8b20bf820233af.1616151715.git.christophe.leroy@csgroup.eu
parent 362471b3
...@@ -607,8 +607,7 @@ static long restore_tm_user_regs(struct pt_regs *regs, ...@@ -607,8 +607,7 @@ static long restore_tm_user_regs(struct pt_regs *regs,
* TFHAR is restored from the checkpointed NIP; TEXASR and TFIAR * TFHAR is restored from the checkpointed NIP; TEXASR and TFIAR
* were set by the signal delivery. * were set by the signal delivery.
*/ */
err = restore_general_regs(regs, tm_sr); err = restore_general_regs(&current->thread.ckpt_regs, sr);
err |= restore_general_regs(&current->thread.ckpt_regs, sr);
err |= __get_user(current->thread.tm_tfhar, &sr->mc_gregs[PT_NIP]); err |= __get_user(current->thread.tm_tfhar, &sr->mc_gregs[PT_NIP]);
...@@ -624,9 +623,6 @@ static long restore_tm_user_regs(struct pt_regs *regs, ...@@ -624,9 +623,6 @@ static long restore_tm_user_regs(struct pt_regs *regs,
if (msr & MSR_VEC) { if (msr & MSR_VEC) {
/* restore altivec registers from the stack */ /* restore altivec registers from the stack */
if (__copy_from_user(&current->thread.ckvr_state, &sr->mc_vregs, if (__copy_from_user(&current->thread.ckvr_state, &sr->mc_vregs,
sizeof(sr->mc_vregs)) ||
__copy_from_user(&current->thread.vr_state,
&tm_sr->mc_vregs,
sizeof(sr->mc_vregs))) sizeof(sr->mc_vregs)))
return 1; return 1;
current->thread.used_vr = true; current->thread.used_vr = true;
...@@ -639,9 +635,7 @@ static long restore_tm_user_regs(struct pt_regs *regs, ...@@ -639,9 +635,7 @@ static long restore_tm_user_regs(struct pt_regs *regs,
/* Always get VRSAVE back */ /* Always get VRSAVE back */
if (__get_user(current->thread.ckvrsave, if (__get_user(current->thread.ckvrsave,
(u32 __user *)&sr->mc_vregs[32]) || (u32 __user *)&sr->mc_vregs[32]))
__get_user(current->thread.vrsave,
(u32 __user *)&tm_sr->mc_vregs[32]))
return 1; return 1;
if (cpu_has_feature(CPU_FTR_ALTIVEC)) if (cpu_has_feature(CPU_FTR_ALTIVEC))
mtspr(SPRN_VRSAVE, current->thread.ckvrsave); mtspr(SPRN_VRSAVE, current->thread.ckvrsave);
...@@ -649,8 +643,7 @@ static long restore_tm_user_regs(struct pt_regs *regs, ...@@ -649,8 +643,7 @@ static long restore_tm_user_regs(struct pt_regs *regs,
regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1); regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
if (copy_fpr_from_user(current, &sr->mc_fregs) || if (copy_fpr_from_user(current, &sr->mc_fregs))
copy_ckfpr_from_user(current, &tm_sr->mc_fregs))
return 1; return 1;
#ifdef CONFIG_VSX #ifdef CONFIG_VSX
...@@ -660,8 +653,7 @@ static long restore_tm_user_regs(struct pt_regs *regs, ...@@ -660,8 +653,7 @@ static long restore_tm_user_regs(struct pt_regs *regs,
* Restore altivec registers from the stack to a local * Restore altivec registers from the stack to a local
* buffer, then write this out to the thread_struct * buffer, then write this out to the thread_struct
*/ */
if (copy_vsx_from_user(current, &tm_sr->mc_vsregs) || if (copy_ckvsx_from_user(current, &sr->mc_vsregs))
copy_ckvsx_from_user(current, &sr->mc_vsregs))
return 1; return 1;
current->thread.used_vsr = true; current->thread.used_vsr = true;
} else if (current->thread.used_vsr) } else if (current->thread.used_vsr)
...@@ -690,6 +682,39 @@ static long restore_tm_user_regs(struct pt_regs *regs, ...@@ -690,6 +682,39 @@ static long restore_tm_user_regs(struct pt_regs *regs,
return 1; return 1;
#endif /* CONFIG_SPE */ #endif /* CONFIG_SPE */
err = restore_general_regs(regs, tm_sr);
if (err)
return 1;
#ifdef CONFIG_ALTIVEC
/* restore altivec registers from the stack */
if (msr & MSR_VEC)
if (__copy_from_user(&current->thread.vr_state,
&tm_sr->mc_vregs,
sizeof(sr->mc_vregs)))
return 1;
/* Always get VRSAVE back */
if (__get_user(current->thread.vrsave,
(u32 __user *)&tm_sr->mc_vregs[32]))
return 1;
#endif /* CONFIG_ALTIVEC */
if (copy_ckfpr_from_user(current, &tm_sr->mc_fregs))
return 1;
#ifdef CONFIG_VSX
if (msr & MSR_VSX) {
/*
* Restore altivec registers from the stack to a local
* buffer, then write this out to the thread_struct
*/
if (copy_vsx_from_user(current, &tm_sr->mc_vsregs))
return 1;
current->thread.used_vsr = true;
}
#endif /* CONFIG_VSX */
/* Get the top half of the MSR from the user context */ /* Get the top half of the MSR from the user context */
if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR])) if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
return 1; return 1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment