KVM: PPC: Book3S HV: Skip treclaim if non-transactional in kvmppc_save_tm

Message ID 20180111025347.1460-1-sjitindarsingh@gmail.com
State New
Headers show
Series
  • KVM: PPC: Book3S HV: Skip treclaim if non-transactional in kvmppc_save_tm
Related show

Commit Message

Suraj Jitindar Singh Jan. 11, 2018, 2:53 a.m.
Before entering a guest in fake suspend mode, we perform the setup in
such a way that the hrfid instruction will put the processor in the
(fake) suspend state. Then on guest exit a treclaim is used to return
the processor to the non-transactional state. However if we branch to
the exit path before transitioning to guest state (such as hdec_soon)
then we come into kvmppc_save_tm in non-transactional state already.
The treclaim then causes a tm bad-thing type program exception.

To avoid this, when in fake suspend check that the processor is not
already in non-transactional state before performing the treclaim, and
skip it if that is the case. We perform the treclaim irrespective if not
in fake suspend as getting here in non-transactional state would be a
bug.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---

Patch applies on top of series:
KVM: PPC: Book3S HV: Transactional memory bug workarounds for POWER9

 arch/powerpc/kvm/book3s_hv_rmhandlers.S | 48 +++++++++++++++------------------
 1 file changed, 22 insertions(+), 26 deletions(-)

Patch

diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
index adf2da6b2211..e600ef505d20 100644
--- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S
@@ -3010,15 +3010,34 @@  kvmppc_save_tm:
 	rldicl. r5, r5, 64 - MSR_TS_S_LG, 62
 	beq	1f	/* TM not active in guest. */
 
-	std	r1, HSTATE_HOST_R1(r13)
-	li	r3, TM_CAUSE_KVM_RESCHED
-
 BEGIN_FTR_SECTION
 	/* Emulation of the treclaim instruction needs TEXASR before treclaim */
 	mfspr	r6, SPRN_TEXASR
 	std	r6, VCPU_ORIG_TEXASR(r9)
+	/* If doing TM emulation on POWER9 DD2.2, check for fake suspend mode */
+	lbz     r0, HSTATE_FAKE_SUSPEND(r13)
+	cmpwi   r0, 0
+	beq	3f
+	/* Check if transactional or suspended, skip the treclaim if not */
+	rldicl.	r8, r8, 64 - MSR_TS_S_LG, 62
+	beq 	2f
+	/* Gets us to N trans-state. Fake suspend so registers unmodified */
+	li	r3, TM_CAUSE_KVM_RESCHED
+	TRECLAIM(R3)
+2:	li	r0, 0
+	stb	r0, HSTATE_FAKE_SUSPEND(r13)
+	mfspr	r3, SPRN_PSSCR
+	/* PSSCR_FAKE_SUSPEND is a write-only bit, but clear it anyway */
+	li	r0, PSSCR_FAKE_SUSPEND
+	andc	r3, r3, r0
+	mtspr	SPRN_PSSCR, r3
+	b	1f
+3:
 END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_EMUL)
 
+	std	r1, HSTATE_HOST_R1(r13)
+	li	r3, TM_CAUSE_KVM_RESCHED
+
 	/* Clear the MSR RI since r1, r13 are all going to be foobar. */
 	li	r5, 0
 	mtmsrd	r5, 1
@@ -3031,29 +3050,6 @@  END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_EMUL)
 	GET_PACA(r13)
 	std	r9, PACATMSCRATCH(r13)
 
-	/* If doing TM emulation on POWER9 DD2.2, check for fake suspend mode */
-BEGIN_FTR_SECTION
-	lbz	r9, HSTATE_FAKE_SUSPEND(r13)
-	cmpwi	r9, 0
-	beq	2f
-	/*
-	 * We were in fake suspend, so the treclaim above didn't
-	 * change any registers, therefore we can now use any volatile GPR.
-	 */
-	li	r5, MSR_RI
-	mtmsrd	r5, 1
-	li	r0, 0
-	stb	r0, HSTATE_FAKE_SUSPEND(r13)
-	mfspr	r3, SPRN_PSSCR
-	/* PSSCR_FAKE_SUSPEND is a write-only bit, but clear it anyway */
-	li	r0, PSSCR_FAKE_SUSPEND
-	andc	r3, r3, r0
-	mtspr	SPRN_PSSCR, r3
-	ld	r9, HSTATE_KVM_VCPU(r13)
-	b	1f
-2:
-END_FTR_SECTION_IFSET(CPU_FTR_P9_TM_EMUL)
-
 	ld	r9, HSTATE_KVM_VCPU(r13)
 
 	/* Get a few more GPRs free. */