From: Michael Neuling <mi...@neuling.org>

commit 3fefd1cd95df04da67c83c1cb93b663f04b3324f upstream.

When emulating tsr, treclaim and trechkpt, we incorrectly set CR0. The
code currently sets:
    CR0 <- 00 || MSR[TS]
but according to the ISA it should be:
    CR0 <-  0 || MSR[TS] || 0

This fixes the bit shift to put the bits in the correct location.

This is a data integrity issue as CR0 is corrupted.

Fixes: 4bb3c7a0208f ("KVM: PPC: Book3S HV: Work around transactional memory 
bugs in POWER9")
Cc: sta...@vger.kernel.org # v4.17+
Tested-by: Suraj Jitindar Singh <sjitindarsi...@gmail.com>
Signed-off-by: Michael Neuling <mi...@neuling.org>
Signed-off-by: Michael Ellerman <m...@ellerman.id.au>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 arch/powerpc/kvm/book3s_hv_tm.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

--- a/arch/powerpc/kvm/book3s_hv_tm.c
+++ b/arch/powerpc/kvm/book3s_hv_tm.c
@@ -128,7 +128,7 @@ int kvmhv_p9_tm_emulation(struct kvm_vcp
                }
                /* Set CR0 to indicate previous transactional state */
                vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) |
-                       (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 28);
+                       (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29);
                /* L=1 => tresume, L=0 => tsuspend */
                if (instr & (1 << 21)) {
                        if (MSR_TM_SUSPENDED(msr))
@@ -172,7 +172,7 @@ int kvmhv_p9_tm_emulation(struct kvm_vcp
 
                /* Set CR0 to indicate previous transactional state */
                vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) |
-                       (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 28);
+                       (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29);
                vcpu->arch.shregs.msr &= ~MSR_TS_MASK;
                return RESUME_GUEST;
 
@@ -202,7 +202,7 @@ int kvmhv_p9_tm_emulation(struct kvm_vcp
 
                /* Set CR0 to indicate previous transactional state */
                vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) |
-                       (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 28);
+                       (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29);
                vcpu->arch.shregs.msr = msr | MSR_TS_S;
                return RESUME_GUEST;
        }


Reply via email to