Merge branch 'ppc-bundle' (bundle from Michael Ellerman)
Merge powerpc transactional memory fixes from Michael Ellerman: "I figured I'd still send you the commits using a bundle to make sure it works in case I need to do it again in future" This fixes transactional memory state restore for powerpc. * bundle'd patches from Michael Ellerman: powerpc/tm: Fix illegal TM state in signal handler powerpc/64s: Use emergency stack for kernel TM Bad Thing program checks
This commit is contained in:
commit
529a86e063
|
@ -734,7 +734,29 @@ EXC_REAL(program_check, 0x700, 0x100)
|
|||
EXC_VIRT(program_check, 0x4700, 0x100, 0x700)
|
||||
TRAMP_KVM(PACA_EXGEN, 0x700)
|
||||
EXC_COMMON_BEGIN(program_check_common)
|
||||
EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
|
||||
/*
|
||||
* It's possible to receive a TM Bad Thing type program check with
|
||||
* userspace register values (in particular r1), but with SRR1 reporting
|
||||
* that we came from the kernel. Normally that would confuse the bad
|
||||
* stack logic, and we would report a bad kernel stack pointer. Instead
|
||||
* we switch to the emergency stack if we're taking a TM Bad Thing from
|
||||
* the kernel.
|
||||
*/
|
||||
li r10,MSR_PR /* Build a mask of MSR_PR .. */
|
||||
oris r10,r10,0x200000@h /* .. and SRR1_PROGTM */
|
||||
and r10,r10,r12 /* Mask SRR1 with that. */
|
||||
srdi r10,r10,8 /* Shift it so we can compare */
|
||||
cmpldi r10,(0x200000 >> 8) /* .. with an immediate. */
|
||||
bne 1f /* If != go to normal path. */
|
||||
|
||||
/* SRR1 had PR=0 and SRR1_PROGTM=1, so use the emergency stack */
|
||||
andi. r10,r12,MSR_PR; /* Set CR0 correctly for label */
|
||||
/* 3 in EXCEPTION_PROLOG_COMMON */
|
||||
mr r10,r1 /* Save r1 */
|
||||
ld r1,PACAEMERGSP(r13) /* Use emergency stack */
|
||||
subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */
|
||||
b 3f /* Jump into the macro !! */
|
||||
1: EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN)
|
||||
bl save_nvgprs
|
||||
RECONCILE_IRQ_STATE(r10, r11)
|
||||
addi r3,r1,STACK_FRAME_OVERHEAD
|
||||
|
|
|
@ -452,9 +452,20 @@ static long restore_tm_sigcontexts(struct task_struct *tsk,
|
|||
if (MSR_TM_RESV(msr))
|
||||
return -EINVAL;
|
||||
|
||||
/* pull in MSR TM from user context */
|
||||
/* pull in MSR TS bits from user context */
|
||||
regs->msr = (regs->msr & ~MSR_TS_MASK) | (msr & MSR_TS_MASK);
|
||||
|
||||
/*
|
||||
* Ensure that TM is enabled in regs->msr before we leave the signal
|
||||
* handler. It could be the case that (a) user disabled the TM bit
|
||||
* through the manipulation of the MSR bits in uc_mcontext or (b) the
|
||||
* TM bit was disabled because a sufficient number of context switches
|
||||
* happened whilst in the signal handler and load_tm overflowed,
|
||||
* disabling the TM bit. In either case we can end up with an illegal
|
||||
* TM state leading to a TM Bad Thing when we return to userspace.
|
||||
*/
|
||||
regs->msr |= MSR_TM;
|
||||
|
||||
/* pull in MSR LE from user context */
|
||||
regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
|
||||
|
||||
|
|
Loading…
Reference in New Issue