@@ -998,6 +998,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;
}
@@ -1359,8 +1371,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: