aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@ozlabs.org>2018-06-07 04:06:21 -0400
committerPaul Mackerras <paulus@ozlabs.org>2018-06-12 19:45:28 -0400
commita50623fb57002207b9b2636e1d3bd5cf17a3e74f (patch)
treeb1b4b959bc8f66300d0636ba0ff6f753e6a1f7d4
parent916ccadccdcd8a0b7184dce37066a9fb2f9b4195 (diff)
KVM: PPC: Book3S PR: Fix failure status setting in treclaim. emulation
The treclaim. emulation needs to record failure status in the TEXASR register if the transaction had not previously failed. However, the current code first does kvmppc_save_tm_pr() (which does a treclaim. itself) and then checks the failure summary bit in TEXASR after that. Since treclaim. itself causes transaction failure, the FS bit is always set, so we were never updating TEXASR with the failure cause supplied by the guest as the RA parameter to the treclaim. instruction. This caused the tm-unavailable test in tools/testing/selftests/powerpc/tm to fail. To fix this, we need to read TEXASR before calling kvmppc_save_tm_pr(), and base the final value of TEXASR on that value. Fixes: 03c81682a90b ("KVM: PPC: Book3S PR: Add emulation for treclaim.") Reviewed-by: Simon Guo <wei.guo.simon@gmail.com> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
-rw-r--r--arch/powerpc/kvm/book3s_emulate.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/arch/powerpc/kvm/book3s_emulate.c b/arch/powerpc/kvm/book3s_emulate.c
index fdbc695038dc..05cac5ea79c5 100644
--- a/arch/powerpc/kvm/book3s_emulate.c
+++ b/arch/powerpc/kvm/book3s_emulate.c
@@ -138,6 +138,7 @@ static void kvmppc_emulate_treclaim(struct kvm_vcpu *vcpu, int ra_val)
138{ 138{
139 unsigned long guest_msr = kvmppc_get_msr(vcpu); 139 unsigned long guest_msr = kvmppc_get_msr(vcpu);
140 int fc_val = ra_val ? ra_val : 1; 140 int fc_val = ra_val ? ra_val : 1;
141 uint64_t texasr;
141 142
142 /* CR0 = 0 | MSR[TS] | 0 */ 143 /* CR0 = 0 | MSR[TS] | 0 */
143 vcpu->arch.cr = (vcpu->arch.cr & ~(CR0_MASK << CR0_SHIFT)) | 144 vcpu->arch.cr = (vcpu->arch.cr & ~(CR0_MASK << CR0_SHIFT)) |
@@ -145,25 +146,26 @@ static void kvmppc_emulate_treclaim(struct kvm_vcpu *vcpu, int ra_val)
145 << CR0_SHIFT); 146 << CR0_SHIFT);
146 147
147 preempt_disable(); 148 preempt_disable();
149 tm_enable();
150 texasr = mfspr(SPRN_TEXASR);
148 kvmppc_save_tm_pr(vcpu); 151 kvmppc_save_tm_pr(vcpu);
149 kvmppc_copyfrom_vcpu_tm(vcpu); 152 kvmppc_copyfrom_vcpu_tm(vcpu);
150 153
151 tm_enable();
152 vcpu->arch.texasr = mfspr(SPRN_TEXASR);
153 /* failure recording depends on Failure Summary bit */ 154 /* failure recording depends on Failure Summary bit */
154 if (!(vcpu->arch.texasr & TEXASR_FS)) { 155 if (!(texasr & TEXASR_FS)) {
155 vcpu->arch.texasr &= ~TEXASR_FC; 156 texasr &= ~TEXASR_FC;
156 vcpu->arch.texasr |= ((u64)fc_val << TEXASR_FC_LG); 157 texasr |= ((u64)fc_val << TEXASR_FC_LG) | TEXASR_FS;
157 158
158 vcpu->arch.texasr &= ~(TEXASR_PR | TEXASR_HV); 159 texasr &= ~(TEXASR_PR | TEXASR_HV);
159 if (kvmppc_get_msr(vcpu) & MSR_PR) 160 if (kvmppc_get_msr(vcpu) & MSR_PR)
160 vcpu->arch.texasr |= TEXASR_PR; 161 texasr |= TEXASR_PR;
161 162
162 if (kvmppc_get_msr(vcpu) & MSR_HV) 163 if (kvmppc_get_msr(vcpu) & MSR_HV)
163 vcpu->arch.texasr |= TEXASR_HV; 164 texasr |= TEXASR_HV;
164 165
166 vcpu->arch.texasr = texasr;
165 vcpu->arch.tfiar = kvmppc_get_pc(vcpu); 167 vcpu->arch.tfiar = kvmppc_get_pc(vcpu);
166 mtspr(SPRN_TEXASR, vcpu->arch.texasr); 168 mtspr(SPRN_TEXASR, texasr);
167 mtspr(SPRN_TFIAR, vcpu->arch.tfiar); 169 mtspr(SPRN_TFIAR, vcpu->arch.tfiar);
168 } 170 }
169 tm_disable(); 171 tm_disable();