forked from Minki/linux
powerpc fixes for 4.4 #2
- tm: Block signal return from setting invalid MSR state from Michael Neuling - tm: Check for already reclaimed tasks from Michael Neuling -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWVul+AAoJEFHr6jzI4aWAUZAQAK2s+E4WTtcExXSG1bqq05o6 5wCLtIq6M91h5HDpgBfN7S5OXpRd72ZeIVdzC0HkFeLBF3y7NSHSEezUw4g/GGfz K2xGV1CCXC3Rb3qyHSdyi6+c1AnLVRPBVzVxPVmlXigrXeFiQ4613YW9rzf9b8fs oktUciwW9aHbrIv7g8f82gpuk9jwwhp/sF+1H/7fGOozT4CFsKo4wj4HOOCBwH4y ODEjs6Z+9Uwb6Kfvi/rn3k4XA1wC36WFq3ORI6KrmK/ZB1eR0Kwf0IELYpMj8cOX q5ZtCH7t68f9vmEK2B34AUijf/amm+2vLwvF6xAuZJFPUPZtgMBdRcqkLalbtPAO 8hlyPPgoZcgR/Of+lEYxUobcL0SMNufXwmfwRO35ktkm9Z9Ee96C8NNbpybBSDXL YRa6is5MeO4GL8Gbcc0TA50hGjok7o3acGE6HSAReyzf0guQ4xqcif7+6lfWZPkk P3aM02ajp2qoqyjhT/Ei6JlMptAiuQY+HvELFneqn5s9nDbv6cGuYZNNap0c1fK+ 74W0p7MiZh7+IF5HpyUIeYV836inXMDIoKzjA6H3OWitk/1lbcrbF34Qpz9zAWZn YF3w786ZzzQLw0jcALaqZejm58MLGIakO4MNDB0/ZBh0nKKfEV8WvPOjev78OAp1 +pDrJh0iQzrujN6OMKQ0 =IL8A -----END PGP SIGNATURE----- Merge tag 'powerpc-4.4-3' into next Merge the two TM fixes we merged in 4.4. We are about to merge selftests for these, and without the fixes the selftests will oops. powerpc fixes for 4.4 #2 - tm: Block signal return from setting invalid MSR state from Michael Neuling - tm: Check for already reclaimed tasks from Michael Neuling
This commit is contained in:
commit
1901d8bb45
@ -108,6 +108,7 @@
|
||||
#define MSR_TS_T __MASK(MSR_TS_T_LG) /* Transaction Transactional */
|
||||
#define MSR_TS_MASK (MSR_TS_T | MSR_TS_S) /* Transaction State bits */
|
||||
#define MSR_TM_ACTIVE(x) (((x) & MSR_TS_MASK) != 0) /* Transaction active? */
|
||||
#define MSR_TM_RESV(x) (((x) & MSR_TS_MASK) == MSR_TS_MASK) /* Reserved */
|
||||
#define MSR_TM_TRANSACTIONAL(x) (((x) & MSR_TS_MASK) == MSR_TS_T)
|
||||
#define MSR_TM_SUSPENDED(x) (((x) & MSR_TS_MASK) == MSR_TS_S)
|
||||
|
||||
|
@ -640,6 +640,24 @@ static void tm_reclaim_thread(struct thread_struct *thr,
|
||||
msr_diff &= MSR_FP | MSR_VEC | MSR_VSX | MSR_FE0 | MSR_FE1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the current MSR TM suspended bit to track if we have
|
||||
* checkpointed state outstanding.
|
||||
* On signal delivery, we'd normally reclaim the checkpointed
|
||||
* state to obtain stack pointer (see:get_tm_stackpointer()).
|
||||
* This will then directly return to userspace without going
|
||||
* through __switch_to(). However, if the stack frame is bad,
|
||||
* we need to exit this thread which calls __switch_to() which
|
||||
* will again attempt to reclaim the already saved tm state.
|
||||
* Hence we need to check that we've not already reclaimed
|
||||
* this state.
|
||||
* We do this using the current MSR, rather tracking it in
|
||||
* some specific thread_struct bit, as it has the additional
|
||||
* benifit of checking for a potential TM bad thing exception.
|
||||
*/
|
||||
if (!MSR_TM_SUSPENDED(mfmsr()))
|
||||
return;
|
||||
|
||||
tm_reclaim(thr, thr->regs->msr, cause);
|
||||
|
||||
/* Having done the reclaim, we now have the checkpointed
|
||||
|
@ -857,6 +857,15 @@ static long restore_tm_user_regs(struct pt_regs *regs,
|
||||
return 1;
|
||||
#endif /* CONFIG_SPE */
|
||||
|
||||
/* Get the top half of the MSR from the user context */
|
||||
if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
|
||||
return 1;
|
||||
msr_hi <<= 32;
|
||||
/* If TM bits are set to the reserved value, it's an invalid context */
|
||||
if (MSR_TM_RESV(msr_hi))
|
||||
return 1;
|
||||
/* Pull in the MSR TM bits from the user context */
|
||||
regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr_hi & MSR_TS_MASK);
|
||||
/* Now, recheckpoint. This loads up all of the checkpointed (older)
|
||||
* registers, including FP and V[S]Rs. After recheckpointing, the
|
||||
* transactional versions should be loaded.
|
||||
@ -866,11 +875,6 @@ static long restore_tm_user_regs(struct pt_regs *regs,
|
||||
current->thread.tm_texasr |= TEXASR_FS;
|
||||
/* This loads the checkpointed FP/VEC state, if used */
|
||||
tm_recheckpoint(¤t->thread, msr);
|
||||
/* Get the top half of the MSR */
|
||||
if (__get_user(msr_hi, &tm_sr->mc_gregs[PT_MSR]))
|
||||
return 1;
|
||||
/* Pull in MSR TM from user context */
|
||||
regs->msr = (regs->msr & ~MSR_TS_MASK) | ((msr_hi<<32) & MSR_TS_MASK);
|
||||
|
||||
/* This loads the speculative FP/VEC state, if used */
|
||||
if (msr & MSR_FP) {
|
||||
|
@ -429,6 +429,10 @@ static long restore_tm_sigcontexts(struct pt_regs *regs,
|
||||
|
||||
/* get MSR separately, transfer the LE bit if doing signal return */
|
||||
err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
|
||||
/* Don't allow reserved mode. */
|
||||
if (MSR_TM_RESV(msr))
|
||||
return -EINVAL;
|
||||
|
||||
/* pull in MSR TM from user context */
|
||||
regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user