diff options
Diffstat (limited to 'arch/x86/kvm/svm/svm.c')
| -rw-r--r-- | arch/x86/kvm/svm/svm.c | 53 | 
1 files changed, 28 insertions, 25 deletions
diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 200045f71df0..44bbf25dfeb9 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -465,11 +465,24 @@ static int has_svm(void)  	return 1;  } +void __svm_write_tsc_multiplier(u64 multiplier) +{ +	preempt_disable(); + +	if (multiplier == __this_cpu_read(current_tsc_ratio)) +		goto out; + +	wrmsrl(MSR_AMD64_TSC_RATIO, multiplier); +	__this_cpu_write(current_tsc_ratio, multiplier); +out: +	preempt_enable(); +} +  static void svm_hardware_disable(void)  {  	/* Make sure we clean up behind us */  	if (tsc_scaling) -		wrmsrl(MSR_AMD64_TSC_RATIO, SVM_TSC_RATIO_DEFAULT); +		__svm_write_tsc_multiplier(SVM_TSC_RATIO_DEFAULT);  	cpu_svm_disable(); @@ -515,8 +528,7 @@ static int svm_hardware_enable(void)  		 * Set the default value, even if we don't use TSC scaling  		 * to avoid having stale value in the msr  		 */ -		wrmsrl(MSR_AMD64_TSC_RATIO, SVM_TSC_RATIO_DEFAULT); -		__this_cpu_write(current_tsc_ratio, SVM_TSC_RATIO_DEFAULT); +		__svm_write_tsc_multiplier(SVM_TSC_RATIO_DEFAULT);  	} @@ -909,7 +921,7 @@ static void grow_ple_window(struct kvm_vcpu *vcpu)  	struct vmcb_control_area *control = &svm->vmcb->control;  	int old = control->pause_filter_count; -	if (kvm_pause_in_guest(vcpu->kvm) || !old) +	if (kvm_pause_in_guest(vcpu->kvm))  		return;  	control->pause_filter_count = __grow_ple_window(old, @@ -930,7 +942,7 @@ static void shrink_ple_window(struct kvm_vcpu *vcpu)  	struct vmcb_control_area *control = &svm->vmcb->control;  	int old = control->pause_filter_count; -	if (kvm_pause_in_guest(vcpu->kvm) || !old) +	if (kvm_pause_in_guest(vcpu->kvm))  		return;  	control->pause_filter_count = @@ -999,11 +1011,12 @@ static void svm_write_tsc_offset(struct kvm_vcpu *vcpu, u64 offset)  	vmcb_mark_dirty(svm->vmcb, VMCB_INTERCEPTS);  } -void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier) +static void svm_write_tsc_multiplier(struct kvm_vcpu *vcpu, u64 multiplier)  { -	wrmsrl(MSR_AMD64_TSC_RATIO, multiplier); +	__svm_write_tsc_multiplier(multiplier);  } +  /* Evaluate instruction intercepts that depend on guest CPUID features. */  static void svm_recalc_instruction_intercepts(struct kvm_vcpu *vcpu,  					      struct vcpu_svm *svm) @@ -1199,15 +1212,8 @@ static void init_vmcb(struct kvm_vcpu *vcpu)  		svm->vmcb->control.int_ctl |= V_GIF_ENABLE_MASK;  	} -	if (sev_guest(vcpu->kvm)) { -		svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ENABLE; -		clr_exception_intercept(svm, UD_VECTOR); - -		if (sev_es_guest(vcpu->kvm)) { -			/* Perform SEV-ES specific VMCB updates */ -			sev_es_init_vmcb(svm); -		} -	} +	if (sev_guest(vcpu->kvm)) +		sev_init_vmcb(svm);  	svm_hv_init_vmcb(vmcb);  	init_vmcb_after_set_cpuid(vcpu); @@ -1363,13 +1369,8 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)  		sev_es_prepare_switch_to_guest(hostsa);  	} -	if (tsc_scaling) { -		u64 tsc_ratio = vcpu->arch.tsc_scaling_ratio; -		if (tsc_ratio != __this_cpu_read(current_tsc_ratio)) { -			__this_cpu_write(current_tsc_ratio, tsc_ratio); -			wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio); -		} -	} +	if (tsc_scaling) +		__svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio);  	if (likely(tsc_aux_uret_slot >= 0))  		kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull); @@ -1392,13 +1393,13 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)  		indirect_branch_prediction_barrier();  	}  	if (kvm_vcpu_apicv_active(vcpu)) -		__avic_vcpu_load(vcpu, cpu); +		avic_vcpu_load(vcpu, cpu);  }  static void svm_vcpu_put(struct kvm_vcpu *vcpu)  {  	if (kvm_vcpu_apicv_active(vcpu)) -		__avic_vcpu_put(vcpu); +		avic_vcpu_put(vcpu);  	svm_prepare_host_switch(vcpu); @@ -4255,6 +4256,8 @@ out:  static void svm_handle_exit_irqoff(struct kvm_vcpu *vcpu)  { +	if (to_svm(vcpu)->vmcb->control.exit_code == SVM_EXIT_INTR) +		vcpu->arch.at_instruction_boundary = true;  }  static void svm_sched_in(struct kvm_vcpu *vcpu, int cpu)  |