Commit 46896c73 authored by Paolo Bonzini's avatar Paolo Bonzini

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: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 9dbe6cf9
...@@ -86,6 +86,7 @@ static const u32 host_save_user_msrs[] = { ...@@ -86,6 +86,7 @@ static const u32 host_save_user_msrs[] = {
MSR_FS_BASE, MSR_FS_BASE,
#endif #endif
MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP, 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) #define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
...@@ -135,6 +136,7 @@ struct vcpu_svm { ...@@ -135,6 +136,7 @@ struct vcpu_svm {
uint64_t asid_generation; uint64_t asid_generation;
uint64_t sysenter_esp; uint64_t sysenter_esp;
uint64_t sysenter_eip; uint64_t sysenter_eip;
uint64_t tsc_aux;
u64 next_rip; u64 next_rip;
...@@ -1238,6 +1240,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) ...@@ -1238,6 +1240,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio); 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) 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) ...@@ -3024,6 +3029,11 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
case MSR_IA32_SYSENTER_ESP: case MSR_IA32_SYSENTER_ESP:
msr_info->data = svm->sysenter_esp; msr_info->data = svm->sysenter_esp;
break; 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 * 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 * 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) ...@@ -3145,6 +3155,18 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
svm->sysenter_esp = data; svm->sysenter_esp = data;
svm->vmcb->save.sysenter_esp = data; svm->vmcb->save.sysenter_esp = data;
break; 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: case MSR_IA32_DEBUGCTLMSR:
if (!boot_cpu_has(X86_FEATURE_LBRV)) { if (!boot_cpu_has(X86_FEATURE_LBRV)) {
vcpu_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n", vcpu_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n",
...@@ -4041,7 +4063,7 @@ static int svm_get_lpage_level(void) ...@@ -4041,7 +4063,7 @@ static int svm_get_lpage_level(void)
static bool svm_rdtscp_supported(void) static bool svm_rdtscp_supported(void)
{ {
return false; return boot_cpu_has(X86_FEATURE_RDTSCP);
} }
static bool svm_invpcid_supported(void) static bool svm_invpcid_supported(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment