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@xxxxxxxxx> --- 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(-) 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. */ -- 2.13.6 -- To unsubscribe from this list: send the line "unsubscribe kvm-ppc" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html