Skip to content

Commit 916e3e5

Browse files
tlendackybonzini
authored andcommitted
KVM: SVM: Do not use user return MSR support for virtualized TSC_AUX
When the TSC_AUX MSR is virtualized, the TSC_AUX value is swap type "B" within the VMSA. This means that the guest value is loaded on VMRUN and the host value is restored from the host save area on #VMEXIT. Since the value is restored on #VMEXIT, the KVM user return MSR support for TSC_AUX can be replaced by populating the host save area with the current host value of TSC_AUX. And, since TSC_AUX is not changed by Linux post-boot, the host save area can be set once in svm_hardware_enable(). This eliminates the two WRMSR instructions associated with the user return MSR support. Signed-off-by: Tom Lendacky <[email protected]> Message-Id: <d381de38eb0ab6c9c93dda8503b72b72546053d7.1694811272.git.thomas.lendacky@amd.com> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent e0096d0 commit 916e3e5

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

arch/x86/kvm/svm/svm.c

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,6 +683,21 @@ static int svm_hardware_enable(void)
683683

684684
amd_pmu_enable_virt();
685685

686+
/*
687+
* If TSC_AUX virtualization is supported, TSC_AUX becomes a swap type
688+
* "B" field (see sev_es_prepare_switch_to_guest()) for SEV-ES guests.
689+
* Since Linux does not change the value of TSC_AUX once set, prime the
690+
* TSC_AUX field now to avoid a RDMSR on every vCPU run.
691+
*/
692+
if (boot_cpu_has(X86_FEATURE_V_TSC_AUX)) {
693+
struct sev_es_save_area *hostsa;
694+
u32 msr_hi;
695+
696+
hostsa = (struct sev_es_save_area *)(page_address(sd->save_area) + 0x400);
697+
698+
rdmsr(MSR_TSC_AUX, hostsa->tsc_aux, msr_hi);
699+
}
700+
686701
return 0;
687702
}
688703

@@ -1532,7 +1547,14 @@ static void svm_prepare_switch_to_guest(struct kvm_vcpu *vcpu)
15321547
if (tsc_scaling)
15331548
__svm_write_tsc_multiplier(vcpu->arch.tsc_scaling_ratio);
15341549

1535-
if (likely(tsc_aux_uret_slot >= 0))
1550+
/*
1551+
* TSC_AUX is always virtualized for SEV-ES guests when the feature is
1552+
* available. The user return MSR support is not required in this case
1553+
* because TSC_AUX is restored on #VMEXIT from the host save area
1554+
* (which has been initialized in svm_hardware_enable()).
1555+
*/
1556+
if (likely(tsc_aux_uret_slot >= 0) &&
1557+
(!boot_cpu_has(X86_FEATURE_V_TSC_AUX) || !sev_es_guest(vcpu->kvm)))
15361558
kvm_set_user_return_msr(tsc_aux_uret_slot, svm->tsc_aux, -1ull);
15371559

15381560
svm->guest_state_loaded = true;
@@ -3086,6 +3108,16 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
30863108
svm->sysenter_esp_hi = guest_cpuid_is_intel(vcpu) ? (data >> 32) : 0;
30873109
break;
30883110
case MSR_TSC_AUX:
3111+
/*
3112+
* TSC_AUX is always virtualized for SEV-ES guests when the
3113+
* feature is available. The user return MSR support is not
3114+
* required in this case because TSC_AUX is restored on #VMEXIT
3115+
* from the host save area (which has been initialized in
3116+
* svm_hardware_enable()).
3117+
*/
3118+
if (boot_cpu_has(X86_FEATURE_V_TSC_AUX) && sev_es_guest(vcpu->kvm))
3119+
break;
3120+
30893121
/*
30903122
* TSC_AUX is usually changed only during boot and never read
30913123
* directly. Intercept TSC_AUX instead of exposing it to the

0 commit comments

Comments
 (0)