Merge branch 'topic/paca' into next
[linux-2.6-block.git] / arch / powerpc / kvm / book3s_hv.c
index 9b48d4a191ff9769c22e35759ff9bd442eaa568a..1e1211c66b26d3dca14cc9568eb90ce45ed0f923 100644 (file)
@@ -742,6 +742,8 @@ static int kvmppc_h_set_mode(struct kvm_vcpu *vcpu, unsigned long mflags,
        case H_SET_MODE_RESOURCE_SET_DAWR:
                if (!kvmppc_power8_compatible(vcpu))
                        return H_P2;
+               if (!ppc_breakpoint_available())
+                       return H_P2;
                if (mflags)
                        return H_UNSUPPORTED_FLAG_START;
                if (value2 & DABRX_HYP)
@@ -1207,6 +1209,19 @@ static int kvmppc_handle_exit_hv(struct kvm_run *run, struct kvm_vcpu *vcpu,
                        r = RESUME_GUEST;
                }
                break;
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       case BOOK3S_INTERRUPT_HV_SOFTPATCH:
+               /*
+                * This occurs for various TM-related instructions that
+                * we need to emulate on POWER9 DD2.2.  We have already
+                * handled the cases where the guest was in real-suspend
+                * mode and was transitioning to transactional state.
+                */
+               r = kvmhv_p9_tm_emulation(vcpu);
+               break;
+#endif
+
        case BOOK3S_INTERRUPT_HV_RM_HARD:
                r = RESUME_PASSTHROUGH;
                break;
@@ -1979,7 +1994,9 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm,
         * turn off the HFSCR bit, which causes those instructions to trap.
         */
        vcpu->arch.hfscr = mfspr(SPRN_HFSCR);
-       if (!cpu_has_feature(CPU_FTR_TM))
+       if (cpu_has_feature(CPU_FTR_P9_TM_HV_ASSIST))
+               vcpu->arch.hfscr |= HFSCR_TM;
+       else if (!cpu_has_feature(CPU_FTR_TM_COMP))
                vcpu->arch.hfscr &= ~HFSCR_TM;
        if (cpu_has_feature(CPU_FTR_ARCH_300))
                vcpu->arch.hfscr &= ~HFSCR_MSGP;
@@ -2243,6 +2260,7 @@ static void kvmppc_start_thread(struct kvm_vcpu *vcpu, struct kvmppc_vcore *vc)
        tpaca = paca_ptrs[cpu];
        tpaca->kvm_hstate.kvm_vcpu = vcpu;
        tpaca->kvm_hstate.ptid = cpu - vc->pcpu;
+       tpaca->kvm_hstate.fake_suspend = 0;
        /* Order stores to hstate.kvm_vcpu etc. before store to kvm_vcore */
        smp_wmb();
        tpaca->kvm_hstate.kvm_vcore = vc;