Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 529a86e0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents ff33952e 044215d1
Loading
Loading
Loading
Loading
+23 −1
Original line number Original line Diff line number Diff line
@@ -734,7 +734,29 @@ EXC_REAL(program_check, 0x700, 0x100)
EXC_VIRT(program_check, 0x4700, 0x100, 0x700)
EXC_VIRT(program_check, 0x4700, 0x100, 0x700)
TRAMP_KVM(PACA_EXGEN, 0x700)
TRAMP_KVM(PACA_EXGEN, 0x700)
EXC_COMMON_BEGIN(program_check_common)
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
	bl	save_nvgprs
	RECONCILE_IRQ_STATE(r10, r11)
	RECONCILE_IRQ_STATE(r10, r11)
	addi	r3,r1,STACK_FRAME_OVERHEAD
	addi	r3,r1,STACK_FRAME_OVERHEAD
+12 −1
Original line number Original line Diff line number Diff line
@@ -452,9 +452,20 @@ static long restore_tm_sigcontexts(struct task_struct *tsk,
	if (MSR_TM_RESV(msr))
	if (MSR_TM_RESV(msr))
		return -EINVAL;
		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);
	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 */
	/* pull in MSR LE from user context */
	regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);
	regs->msr = (regs->msr & ~MSR_LE) | (msr & MSR_LE);