Skip to content

Commit 46896c7

Browse files
committed
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 <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 9dbe6cf commit 46896c7

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

arch/x86/kvm/svm.c

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ static const u32 host_save_user_msrs[] = {
8686
MSR_FS_BASE,
8787
#endif
8888
MSR_IA32_SYSENTER_CS, MSR_IA32_SYSENTER_ESP, MSR_IA32_SYSENTER_EIP,
89+
MSR_TSC_AUX,
8990
};
9091

9192
#define NR_HOST_SAVE_USER_MSRS ARRAY_SIZE(host_save_user_msrs)
@@ -135,6 +136,7 @@ struct vcpu_svm {
135136
uint64_t asid_generation;
136137
uint64_t sysenter_esp;
137138
uint64_t sysenter_eip;
139+
uint64_t tsc_aux;
138140

139141
u64 next_rip;
140142

@@ -1238,6 +1240,9 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
12381240
wrmsrl(MSR_AMD64_TSC_RATIO, tsc_ratio);
12391241
}
12401242
}
1243+
/* This assumes that the kernel never uses MSR_TSC_AUX */
1244+
if (static_cpu_has(X86_FEATURE_RDTSCP))
1245+
wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
12411246
}
12421247

12431248
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)
30243029
case MSR_IA32_SYSENTER_ESP:
30253030
msr_info->data = svm->sysenter_esp;
30263031
break;
3032+
case MSR_TSC_AUX:
3033+
if (!boot_cpu_has(X86_FEATURE_RDTSCP))
3034+
return 1;
3035+
msr_info->data = svm->tsc_aux;
3036+
break;
30273037
/*
30283038
* Nobody will change the following 5 values in the VMCB so we can
30293039
* 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)
31453155
svm->sysenter_esp = data;
31463156
svm->vmcb->save.sysenter_esp = data;
31473157
break;
3158+
case MSR_TSC_AUX:
3159+
if (!boot_cpu_has(X86_FEATURE_RDTSCP))
3160+
return 1;
3161+
3162+
/*
3163+
* This is rare, so we update the MSR here instead of using
3164+
* direct_access_msrs. Doing that would require a rdmsr in
3165+
* svm_vcpu_put.
3166+
*/
3167+
svm->tsc_aux = data;
3168+
wrmsrl(MSR_TSC_AUX, svm->tsc_aux);
3169+
break;
31483170
case MSR_IA32_DEBUGCTLMSR:
31493171
if (!boot_cpu_has(X86_FEATURE_LBRV)) {
31503172
vcpu_unimpl(vcpu, "%s: MSR_IA32_DEBUGCTL 0x%llx, nop\n",
@@ -4041,7 +4063,7 @@ static int svm_get_lpage_level(void)
40414063

40424064
static bool svm_rdtscp_supported(void)
40434065
{
4044-
return false;
4066+
return boot_cpu_has(X86_FEATURE_RDTSCP);
40454067
}
40464068

40474069
static bool svm_invpcid_supported(void)

0 commit comments

Comments
 (0)