|
@@ -989,6 +989,18 @@ static int kvmppc_handle_fac(struct kvm_vcpu *vcpu, ulong fac)
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
|
|
|
+ /* Since we disabled MSR_TM at privilege state, the mfspr instruction
|
|
|
+ * for TM spr can trigger TM fac unavailable. In this case, the
|
|
|
+ * emulation is handled by kvmppc_emulate_fac(), which invokes
|
|
|
+ * kvmppc_emulate_mfspr() finally. But note the mfspr can include
|
|
|
+ * RT for NV registers. So it need to restore those NV reg to reflect
|
|
|
+ * the update.
|
|
|
+ */
|
|
|
+ if ((fac == FSCR_TM_LG) && !(kvmppc_get_msr(vcpu) & MSR_PR))
|
|
|
+ return RESUME_GUEST_NV;
|
|
|
+#endif
|
|
|
+
|
|
|
return RESUME_GUEST;
|
|
|
}
|
|
|
|
|
@@ -1350,8 +1362,7 @@ int kvmppc_handle_exit_pr(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
|
|
}
|
|
|
#ifdef CONFIG_PPC_BOOK3S_64
|
|
|
case BOOK3S_INTERRUPT_FAC_UNAVAIL:
|
|
|
- kvmppc_handle_fac(vcpu, vcpu->arch.shadow_fscr >> 56);
|
|
|
- r = RESUME_GUEST;
|
|
|
+ r = kvmppc_handle_fac(vcpu, vcpu->arch.shadow_fscr >> 56);
|
|
|
break;
|
|
|
#endif
|
|
|
case BOOK3S_INTERRUPT_MACHINE_CHECK:
|