[PATCH v4 07/10] KVM: SEV: Disallow setting SNP-only features for non-SNP guests via a single mask
Kim Phillips <[email protected]> Tue, 4 Aug 2026 18:56:08 -0500
| Newsgroups | org.kernel.vger.kvm,dev.linux.lists.linux-coco,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
As SNP-only features get added, adding them to the valid_vmsa_features mask in __sev_guest_init() often gets neglected. Add SVM_SEV_FEAT_SNP_ONLY_MASK to help group these common features together. Also establish SNP_ONLY_FEATURES in the sev_init2 selftest as the corresponding mask for features that must be rejected for non-SNP guests, populate it with SVM_SEV_FEAT_SECURE_TSC, and exercise the rejection path by masking those bits out of the features passed for SEV-ES guests. Define the selftest's SNP_ONLY_FEATURES as ULL so future bits can use BIT_ULL() there without truncation against the u64 supported_vmsa_features. Suggested-by: Sean Christopherson <[email protected]> Cc: Borislav Petkov (AMD) <[email protected]> Link: https://lore.kernel.org/kvm/[email protected]/ Signed-off-by: Kim Phillips <[email protected]> Assisted-by: ClaudeCode:claude-opus-4-7 --- arch/x86/include/asm/svm.h | 2 ++ arch/x86/kvm/svm/sev.c | 2 +- tools/testing/selftests/kvm/x86/sev_init2_tests.c | 12 +++++++----- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index 52c900bf7e20..a206a0ed2c58 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -311,6 +311,8 @@ static_assert((X2AVIC_4K_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AV #define SVM_SEV_FEAT_DEBUG_SWAP BIT_ULL(5) #define SVM_SEV_FEAT_SECURE_TSC BIT_ULL(9) +#define SVM_SEV_FEAT_SNP_ONLY_MASK (SVM_SEV_FEAT_SECURE_TSC) + #define VMCB_ALLOWED_SEV_FEATURES_VALID BIT_ULL(63) struct vmcb_seg { diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 944aaea6501f..951f0e6be9e5 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -504,7 +504,7 @@ static int __sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp, return -EINVAL; if (!snp_active) - valid_vmsa_features &= ~SVM_SEV_FEAT_SECURE_TSC; + valid_vmsa_features &= ~SVM_SEV_FEAT_SNP_ONLY_MASK; if (data->vmsa_features & ~valid_vmsa_features) return -EINVAL; diff --git a/tools/testing/selftests/kvm/x86/sev_init2_tests.c b/tools/testing/selftests/kvm/x86/sev_init2_tests.c index 7b0643bf7ca1..5f4032239f7f 100644 --- a/tools/testing/selftests/kvm/x86/sev_init2_tests.c +++ b/tools/testing/selftests/kvm/x86/sev_init2_tests.c @@ -14,16 +14,18 @@ #include "kselftest.h" #define SVM_SEV_FEAT_DEBUG_SWAP BIT_ULL(5) +#define SVM_SEV_FEAT_SECURE_TSC BIT_ULL(9) + +/* Features valid only for SNP guests, rejected for SEV-ES and below. */ +#define SNP_ONLY_FEATURES (SVM_SEV_FEAT_SECURE_TSC) /* * Some features may have hidden dependencies, or may only work * for certain VM types. Err on the side of safety and don't * expect that all supported features can be passed one by one * to KVM_SEV_INIT2. - * - * (Well, right now there's only one...) */ -#define KNOWN_FEATURES SVM_SEV_FEAT_DEBUG_SWAP +#define KNOWN_FEATURES (SVM_SEV_FEAT_DEBUG_SWAP | SNP_ONLY_FEATURES) int kvm_fd; u64 supported_vmsa_features; @@ -112,7 +114,7 @@ void test_features(u32 vm_type, u64 supported_features) if (!(supported_features & BIT_ULL(i))) test_init2_invalid(vm_type, &(struct kvm_sev_init){ .vmsa_features = BIT_ULL(i) }, - "unknown feature"); + "unknown or unsupported feature for VM type"); else if (KNOWN_FEATURES & BIT_ULL(i)) test_init2(vm_type, &(struct kvm_sev_init){ .vmsa_features = BIT_ULL(i) }); @@ -161,7 +163,7 @@ int main(int argc, char *argv[]) test_features(KVM_X86_SEV_VM, 0); if (have_sev_es) - test_features(KVM_X86_SEV_ES_VM, supported_vmsa_features); + test_features(KVM_X86_SEV_ES_VM, supported_vmsa_features & ~SNP_ONLY_FEATURES); if (have_snp) test_features(KVM_X86_SNP_VM, supported_vmsa_features); -- 2.43.0