Skip to content

Commit a311fce

Browse files
nikunjadsean-jc
authored andcommitted
KVM: SVM: Enable Secure TSC for SNP guests
Add support for Secure TSC, allowing userspace to configure the Secure TSC feature for SNP guests. Use the SNP specification's desired TSC frequency parameter during the SNP_LAUNCH_START command to set the mean TSC frequency in KHz for Secure TSC enabled guests. Always use kvm->arch.arch.default_tsc_khz as the TSC frequency that is passed to SNP guests in the SNP_LAUNCH_START command. The default value is the host TSC frequency. The userspace can optionally change the TSC frequency via the KVM_SET_TSC_KHZ ioctl before calling the SNP_LAUNCH_START ioctl. Introduce the read-only MSR GUEST_TSC_FREQ (0xc0010134) that returns guest's effective frequency in MHZ when Secure TSC is enabled for SNP guests. Disable interception of this MSR when Secure TSC is enabled. Note that GUEST_TSC_FREQ MSR is accessible only to the guest and not from the hypervisor context. Co-developed-by: Ketan Chaturvedi <Ketan.Chaturvedi@amd.com> Signed-off-by: Ketan Chaturvedi <Ketan.Chaturvedi@amd.com> Reviewed-by: Kai Huang <kai.huang@intel.com> Reviewed-by: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: Nikunj A Dadhania <nikunj@amd.com> [sean: contain Secure TSC to sev.c] Link: https://lore.kernel.org/r/20250819234833.3080255-9-seanjc@google.com [sean: return -EINVAL if TSC frequency is '0'] Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent f7b1f0c commit a311fce

2 files changed

Lines changed: 29 additions & 0 deletions

File tree

arch/x86/include/asm/svm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ static_assert((X2AVIC_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AVIC_
299299
#define SVM_SEV_FEAT_RESTRICTED_INJECTION BIT(3)
300300
#define SVM_SEV_FEAT_ALTERNATE_INJECTION BIT(4)
301301
#define SVM_SEV_FEAT_DEBUG_SWAP BIT(5)
302+
#define SVM_SEV_FEAT_SECURE_TSC BIT(9)
302303

303304
#define VMCB_ALLOWED_SEV_FEATURES_VALID BIT_ULL(63)
304305

arch/x86/kvm/svm/sev.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ static bool sev_vcpu_has_debug_swap(struct vcpu_svm *svm)
146146
return sev->vmsa_features & SVM_SEV_FEAT_DEBUG_SWAP;
147147
}
148148

149+
static bool snp_is_secure_tsc_enabled(struct kvm *kvm)
150+
{
151+
struct kvm_sev_info *sev = to_kvm_sev_info(kvm);
152+
153+
return (sev->vmsa_features & SVM_SEV_FEAT_SECURE_TSC) &&
154+
!WARN_ON_ONCE(!sev_snp_guest(kvm));
155+
}
156+
149157
/* Must be called with the sev_bitmap_lock held */
150158
static bool __sev_recycle_asids(unsigned int min_asid, unsigned int max_asid)
151159
{
@@ -415,6 +423,9 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp,
415423
if (data->flags)
416424
return -EINVAL;
417425

426+
if (!snp_active)
427+
valid_vmsa_features &= ~SVM_SEV_FEAT_SECURE_TSC;
428+
418429
if (data->vmsa_features & ~valid_vmsa_features)
419430
return -EINVAL;
420431

@@ -2187,6 +2198,13 @@ static int snp_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
21872198
if (!(params.policy & SNP_POLICY_MASK_RSVD_MBO))
21882199
return -EINVAL;
21892200

2201+
if (snp_is_secure_tsc_enabled(kvm)) {
2202+
if (WARN_ON_ONCE(!kvm->arch.default_tsc_khz))
2203+
return -EINVAL;
2204+
2205+
start.desired_tsc_khz = kvm->arch.default_tsc_khz;
2206+
}
2207+
21902208
sev->policy = params.policy;
21912209

21922210
sev->snp_context = snp_context_create(kvm, argp);
@@ -2195,6 +2213,7 @@ static int snp_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp)
21952213

21962214
start.gctx_paddr = __psp_pa(sev->snp_context);
21972215
start.policy = params.policy;
2216+
21982217
memcpy(start.gosvw, params.gosvw, sizeof(params.gosvw));
21992218
rc = __sev_issue_cmd(argp->sev_fd, SEV_CMD_SNP_LAUNCH_START, &start, &argp->error);
22002219
if (rc) {
@@ -3085,6 +3104,9 @@ void __init sev_hardware_setup(void)
30853104
sev_supported_vmsa_features = 0;
30863105
if (sev_es_debug_swap_enabled)
30873106
sev_supported_vmsa_features |= SVM_SEV_FEAT_DEBUG_SWAP;
3107+
3108+
if (sev_snp_enabled && tsc_khz && cpu_feature_enabled(X86_FEATURE_SNP_SECURE_TSC))
3109+
sev_supported_vmsa_features |= SVM_SEV_FEAT_SECURE_TSC;
30883110
}
30893111

30903112
void sev_hardware_unsetup(void)
@@ -4452,6 +4474,9 @@ void sev_es_recalc_msr_intercepts(struct kvm_vcpu *vcpu)
44524474
!guest_cpu_cap_has(vcpu, X86_FEATURE_RDTSCP) &&
44534475
!guest_cpu_cap_has(vcpu, X86_FEATURE_RDPID));
44544476

4477+
svm_set_intercept_for_msr(vcpu, MSR_AMD64_GUEST_TSC_FREQ, MSR_TYPE_R,
4478+
!snp_is_secure_tsc_enabled(vcpu->kvm));
4479+
44554480
/*
44564481
* For SEV-ES, accesses to MSR_IA32_XSS should not be intercepted if
44574482
* the host/guest supports its use.
@@ -4591,6 +4616,9 @@ int sev_vcpu_create(struct kvm_vcpu *vcpu)
45914616
return -ENOMEM;
45924617

45934618
svm->sev_es.vmsa = page_address(vmsa_page);
4619+
4620+
vcpu->arch.guest_tsc_protected = snp_is_secure_tsc_enabled(vcpu->kvm);
4621+
45944622
return 0;
45954623
}
45964624

0 commit comments

Comments
 (0)