Commit 68ab07b9 authored by Simon Guo's avatar Simon Guo Committed by Paul Mackerras
Browse files

KVM: PPC: Book3S PR: Add guard code to prevent returning to guest with PR=0 and Transactional state



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: default avatarSimon Guo <wei.guo.simon@gmail.com>
Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
parent 26798f88
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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
+1 −1
Original line number Diff line number Diff line
@@ -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
+12 −1
Original line number Diff line number Diff line
@@ -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);