forked from Minki/linux
KVM: svm: add support for RDTSCP
RDTSCP was never supported for AMD CPUs, which nobody noticed because Linux does not use it. But exactly the fact that Linux does not use it makes the implementation very simple; we can freely trash MSR_TSC_AUX while running the guest. Cc: Joerg Roedel <joro@8bytes.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
9dbe6cf941
commit
46896c73c1
@ -86,6 +86,7 @@ static const u32 host_save_user_msrs[] = {
|
||||
MSR_FS_BASE,
|
||||
#endif
|
||||
MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
|
||||
MSR_TSC_AUX,
|
||||
};
|
||||
|
||||
#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
|
||||
@ -135,6 +136,7 @@ struct vcpu_svm {
|
||||
uint64_t asid_generation;
|
||||
uint64_t sysenter_esp;
|
||||
uint64_t sysenter_eip;
|
||||
uint64_t tsc_aux;
|
||||
|
||||
u64 next_rip;
|
||||
|
||||
@ -1238,6 +1240,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||
wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio);
|
||||
}
|
||||
}
|
||||
/* This assumes that the kernel never uses MSR_TSC_AUX */
|
||||
if (static_cpu_has(X86_FEATURE_RDTSCP))
|
||||
wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
|
||||
}
|
||||
|
||||
static void svm_vcpu_put(struct kvm_vcpu *vcpu)
|
||||
@ -3024,6 +3029,11 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
|
||||
case MSR_IA32_SYSENTER_ESP:
|
||||
msr_info->data = svm->sysenter_esp;
|
||||
break;
|
||||
case MSR_TSC_AUX:
|
||||
if (!boot_cpu_has(X86_FEATURE_RDTSCP))
|
||||
return 1;
|
||||
msr_info->data = svm->tsc_aux;
|
||||
break;
|
||||
/*
|
||||
* Nobody will change the following 5 values in the VMCB so we can
|
||||
* safely return them on rdmsr. They will always be 0 until LBRV is
|
||||
@ -3145,6 +3155,18 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
|
||||
svm->sysenter_esp = data;
|
||||
svm->vmcb->save.sysenter_esp = data;
|
||||
break;
|
||||
case MSR_TSC_AUX:
|
||||
if (!boot_cpu_has(X86_FEATURE_RDTSCP))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* This is rare, so we update the MSR here instead of using
|
||||
* direct_access_msrs. Doing that would require a rdmsr in
|
||||
* svm_vcpu_put.
|
||||
*/
|
||||
svm->tsc_aux = data;
|
||||
wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
|
||||
break;
|
||||
case MSR_IA32_DEBUGCTLMSR:
|
||||
if (!boot_cpu_has(X86_FEATURE_LBRV)) {
|
||||
vcpu_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n",
|
||||
@ -4041,7 +4063,7 @@ static int svm_get_lpage_level(void)
|
||||
|
||||
static bool svm_rdtscp_supported(void)
|
||||
{
|
||||
return false;
|
||||
return boot_cpu_has(X86_FEATURE_RDTSCP);
|
||||
}
|
||||
|
||||
static bool svm_invpcid_supported(void)
|
||||
|
Loading…
Reference in New Issue
Block a user