[RFC PATCH v3 06/27] KVM: SVM: Add helper to check if Secure AVIC is enabled for a guest
From: Naveen N Rao (AMD)
Date: Wed Jul 08 2026 - 02:43:42 EST
Add a helper snp_is_secure_avic_enabled() along the lines of the similar
helper for Secure TSC to check if Secure AVIC is enabled in the VMSA SEV
Features for a SEV-SNP guest.
Note: Enabling Secure AVIC in the VMSA SEV Features puts the SEV-SNP
guest in Secure AVIC "mode", and it is up to the guest to then "enable"
Secure AVIC through the Secure AVIC Control MSR. While the use of
"enabled" in the helper might sound like a misnomer, it reflects the
fact that KVM has no visibility into whether the guest has actually
enabled Secure AVIC or not. For all practical purposes, KVM assumes that
the guest has Secure AVIC enabled. Since a Secure AVIC mode guest is
extremely restricted, it is in the best interest of the guest to enable
Secure AVIC at the earliest.
Signed-off-by: Naveen N Rao (AMD) <naveen@xxxxxxxxxx>
---
arch/x86/include/asm/svm.h | 1 +
arch/x86/kvm/svm/svm.h | 2 ++
arch/x86/kvm/svm/sev.c | 8 ++++++++
3 files changed, 11 insertions(+)
diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h
index 42ececa8963d..5857b942957b 100644
--- a/arch/x86/include/asm/svm.h
+++ b/arch/x86/include/asm/svm.h
@@ -311,6 +311,7 @@ static_assert((X2AVIC_4K_MAX_PHYSICAL_ID & AVIC_PHYSICAL_MAX_INDEX_MASK) == X2AV
#define SVM_SEV_FEAT_ALTERNATE_INJECTION BIT(4)
#define SVM_SEV_FEAT_DEBUG_SWAP BIT(5)
#define SVM_SEV_FEAT_SECURE_TSC BIT(9)
+#define SVM_SEV_FEAT_SECURE_AVIC BIT(16)
#define VMCB_ALLOWED_SEV_FEATURES_VALID BIT_ULL(63)
diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h
index 616e45624f4c..1157d022bac1 100644
--- a/arch/x86/kvm/svm/svm.h
+++ b/arch/x86/kvm/svm/svm.h
@@ -1013,6 +1013,7 @@ void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end);
int sev_gmem_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, bool is_private);
struct vmcb_save_area *sev_decrypt_vmsa(struct kvm_vcpu *vcpu);
void sev_free_decrypted_vmsa(struct kvm_vcpu *vcpu, struct vmcb_save_area *vmsa);
+bool snp_is_secure_avic_enabled(struct kvm *kvm);
#else
static inline struct page *snp_safe_alloc_page_node(int node, gfp_t gfp)
{
@@ -1050,6 +1051,7 @@ static inline struct vmcb_save_area *sev_decrypt_vmsa(struct kvm_vcpu *vcpu)
return NULL;
}
static inline void sev_free_decrypted_vmsa(struct kvm_vcpu *vcpu, struct vmcb_save_area *vmsa) {}
+static inline bool snp_is_secure_avic_enabled(struct kvm *kvm) { return false; }
#endif
/* vmenter.S */
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 74fb15551e83..686227a15328 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c
@@ -211,6 +211,14 @@ static bool snp_is_secure_tsc_enabled(struct kvm *kvm)
!WARN_ON_ONCE(!sev_snp_guest(kvm));
}
+bool snp_is_secure_avic_enabled(struct kvm *kvm)
+{
+ struct kvm_sev_info *sev = to_kvm_sev_info(kvm);
+
+ return (sev->vmsa_features & SVM_SEV_FEAT_SECURE_AVIC) &&
+ !WARN_ON_ONCE(!sev_snp_guest(kvm));
+}
+
/* Must be called with the sev_bitmap_lock held */
static bool __sev_recycle_asids(unsigned int min_asid, unsigned int max_asid)
{
--
2.54.0