KVM: PPC: Book3S PR: Add guard code to prevent returning to guest with PR=0 and Trans...
authorSimon Guo <wei.guo.simon@gmail.com>
Wed, 23 May 2018 07:02:06 +0000 (15:02 +0800)
committerPaul Mackerras <paulus@ozlabs.org>
Fri, 1 Jun 2018 00:30:39 +0000 (10:30 +1000)
Currently PR KVM doesn't support transaction memory in guest privileged
state.

This patch adds a check at setting guest msr, so that we can never return
to guest with PR=0 and TS=0b10. A tabort will be emulated to indicate
this and fail transaction immediately.

[paulus@ozlabs.org - don't change the TM_CAUSE_MISC definition, instead
 use TM_CAUSE_KVM_FAC_UNAV.]

Signed-off-by: Simon Guo <wei.guo.simon@gmail.com>
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
arch/powerpc/kvm/book3s.h
arch/powerpc/kvm/book3s_emulate.c
arch/powerpc/kvm/book3s_pr.c

index 4ad5e287b8bc68f1267cfc163a1c07793e530b4e..14ef03501d2191c42b9dcbd23d6200728b2113db 100644 (file)
@@ -31,4 +31,10 @@ extern int kvmppc_core_emulate_mfspr_pr(struct kvm_vcpu *vcpu,
 extern int kvmppc_book3s_init_pr(void);
 extern void kvmppc_book3s_exit_pr(void);
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+extern void kvmppc_emulate_tabort(struct kvm_vcpu *vcpu, int ra_val);
+#else
+static inline void kvmppc_emulate_tabort(struct kvm_vcpu *vcpu, int ra_val) {}
+#endif
+
 #endif
index 34f910e039723db600d66e18df4bf6fb01e523cf..67d0fb40e8b285170d4ca11a8f5757279a318b98 100644 (file)
@@ -199,7 +199,7 @@ static void kvmppc_emulate_trchkpt(struct kvm_vcpu *vcpu)
 }
 
 /* emulate tabort. at guest privilege state */
-static void kvmppc_emulate_tabort(struct kvm_vcpu *vcpu, int ra_val)
+void kvmppc_emulate_tabort(struct kvm_vcpu *vcpu, int ra_val)
 {
        /* currently we only emulate tabort. but no emulation of other
         * tabort variants since there is no kernel usage of them at
index a275f8b3a4a09ed018bf88f6df437078d7ca8b68..ad0a2ee8d8b1df76cecc054ca781bae23d63b715 100644 (file)
@@ -446,12 +446,23 @@ static void kvm_set_spte_hva_pr(struct kvm *kvm, unsigned long hva, pte_t pte)
 
 static void kvmppc_set_msr_pr(struct kvm_vcpu *vcpu, u64 msr)
 {
-       ulong old_msr = kvmppc_get_msr(vcpu);
+       ulong old_msr;
 
 #ifdef EXIT_DEBUG
        printk(KERN_INFO "KVM: Set MSR to 0x%llx\n", msr);
 #endif
 
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+       /* We should never target guest MSR to TS=10 && PR=0,
+        * since we always fail transaction for guest privilege
+        * state.
+        */
+       if (!(msr & MSR_PR) && MSR_TM_TRANSACTIONAL(msr))
+               kvmppc_emulate_tabort(vcpu,
+                       TM_CAUSE_KVM_FAC_UNAV | TM_CAUSE_PERSISTENT);
+#endif
+
+       old_msr = kvmppc_get_msr(vcpu);
        msr &= to_book3s(vcpu)->msr_mask;
        kvmppc_set_msr_fast(vcpu, msr);
        kvmppc_recalc_shadow_msr(vcpu);