Message ID | 1495030779-29745-1-git-send-email-leitao@debian.org |
---|---|
State | New |
Headers | show |
On Wed, May 17, 2017 at 11:19:39AM -0300, Breno Leitao wrote: > From: Michael Neuling <mikey@neuling.org> > > BugLink: https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1691477 > > In commit dc3106690b20 ("powerpc: tm: Always use fp_state and vr_state > to store live registers"), a section of code was removed that copied > the current state to checkpointed state. That code should not have been > removed. > > When an FP (Floating Point) unavailable is taken inside a transaction, > we need to abort the transaction. This is because at the time of the > tbegin, the FP state is bogus so the state stored in the checkpointed > registers is incorrect. To fix this, we treclaim (to get the > checkpointed GPRs) and then copy the thread_struct FP live state into > the checkpointed state. We then trecheckpoint so that the FP state is > correctly restored into the CPU. > > The copying of the FP registers from live to checkpointed is what was > missing. > > This simplifies the logic slightly from the original patch. > tm_reclaim_thread() will now always write the checkpointed FP > state. Either the checkpointed FP state will be written as part of > the actual treclaim (in tm.S), or it'll be a copy of the live > state. Which one we use is based on MSR[FP] from userspace. > > Similarly for VMX. > > Fixes: dc3106690b20 ("powerpc: tm: Always use fp_state and vr_state to store live registers") > Cc: stable@vger.kernel.org # 4.9+ > Signed-off-by: Michael Neuling <mikey@neuling.org> > Reviewed-by: cyrilbur@gmail.com > Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> > (cherry picked from commit f48e91e87e67b56bef63393d1a02c6e22c1d7078) > Signed-off-by: Breno Leitao <breno.leitao@gmail.com> Applied to artful/master-next.
Applied to zesty master-next branch. Thanks. Cascardo.
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 5dd056df0baa..b58cbcae7aad 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -839,6 +839,25 @@ static void tm_reclaim_thread(struct thread_struct *thr, if (!MSR_TM_SUSPENDED(mfmsr())) return; + /* + * If we are in a transaction and FP is off then we can't have + * used FP inside that transaction. Hence the checkpointed + * state is the same as the live state. We need to copy the + * live state to the checkpointed state so that when the + * transaction is restored, the checkpointed state is correct + * and the aborted transaction sees the correct state. We use + * ckpt_regs.msr here as that's what tm_reclaim will use to + * determine if it's going to write the checkpointed state or + * not. So either this will write the checkpointed registers, + * or reclaim will. Similarly for VMX. + */ + if ((thr->ckpt_regs.msr & MSR_FP) == 0) + memcpy(&thr->ckfp_state, &thr->fp_state, + sizeof(struct thread_fp_state)); + if ((thr->ckpt_regs.msr & MSR_VEC) == 0) + memcpy(&thr->ckvr_state, &thr->vr_state, + sizeof(struct thread_vr_state)); + giveup_all(container_of(thr, struct task_struct, thread)); tm_reclaim(thr, thr->ckpt_regs.msr, cause);