[PATCH 06/60] KVM: SVM: Enable Restricted Injection for an SEV-SNP guest
From: Jörg Rödel <joro@8bytes.org>
Date: 2026-06-08 14:43:14
Also in:
kvm, kvm-riscv, kvmarm, linux-mips, lkml, loongarch
Subsystem:
kernel virtual machine for x86 (kvm/x86), the rest, x86 architecture (32-bit and 64-bit) · Maintainers:
Sean Christopherson, Paolo Bonzini, Linus Torvalds, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen
From: Melody Wang <redacted> Enable Restricted Injection in an SEV-SNP guest by setting the corresponding bit in the VMSA SEV features field (SEV_FEATURES[3]) from QEMU. Add Restricted Injection to the supported hypervisor features. Co-developed-by: Thomas Lendacky <thomas.lendacky@amd.com> Signed-off-by: Thomas Lendacky <thomas.lendacky@amd.com> Signed-off-by: Melody Wang <redacted> Signed-off-by: Joerg Roedel <redacted> --- arch/x86/include/asm/cpufeatures.h | 1 + arch/x86/include/asm/sev-common.h | 1 + arch/x86/kvm/svm/sev.c | 26 +++++++++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpufeatures.h
index 1d506e5d6f46..41af7bd2473c 100644
--- a/arch/x86/include/asm/cpufeatures.h
+++ b/arch/x86/include/asm/cpufeatures.h@@ -453,6 +453,7 @@ #define X86_FEATURE_SNP_SECURE_TSC (19*32+ 8) /* SEV-SNP Secure TSC */ #define X86_FEATURE_V_TSC_AUX (19*32+ 9) /* Virtual TSC_AUX */ #define X86_FEATURE_SME_COHERENT (19*32+10) /* hardware-enforced cache coherency */ +#define X86_FEATURE_RESTRICTED_INJECTION (19*32+12) /* Restricted Injection */ #define X86_FEATURE_DEBUG_SWAP (19*32+14) /* "debug_swap" SEV-ES full debug state swap support */ #define X86_FEATURE_RMPREAD (19*32+21) /* RMPREAD instruction */ #define X86_FEATURE_SEGMENTED_RMP (19*32+23) /* Segmented RMP support */
diff --git a/arch/x86/include/asm/sev-common.h b/arch/x86/include/asm/sev-common.h
index 01a6e4dbe423..ee17a3541b55 100644
--- a/arch/x86/include/asm/sev-common.h
+++ b/arch/x86/include/asm/sev-common.h@@ -136,6 +136,7 @@ enum psc_op { #define GHCB_HV_FT_SNP BIT_ULL(0) #define GHCB_HV_FT_SNP_AP_CREATION BIT_ULL(1) +#define GHCB_HV_FT_SNP_RINJ (BIT_ULL(2) | GHCB_HV_FT_SNP_AP_CREATION) #define GHCB_HV_FT_SNP_MULTI_VMPL BIT_ULL(5) /*
diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c
index 6d5d66563b0d..369fb1e36f58 100644
--- a/arch/x86/kvm/svm/sev.c
+++ b/arch/x86/kvm/svm/sev.c@@ -39,7 +39,9 @@ #define GHCB_VERSION_MAX 2ULL #define GHCB_VERSION_MIN 1ULL -#define GHCB_HV_FT_SUPPORTED (GHCB_HV_FT_SNP | GHCB_HV_FT_SNP_AP_CREATION) +#define GHCB_HV_FT_SUPPORTED (GHCB_HV_FT_SNP | \ + GHCB_HV_FT_SNP_AP_CREATION | \ + GHCB_HV_FT_SNP_RINJ) /* * The GHCB spec essentially states that all non-zero error codes other than
@@ -63,6 +65,10 @@ module_param_named(sev_es, sev_es_enabled, bool, 0444); static bool __ro_after_init sev_snp_enabled = true; module_param_named(sev_snp, sev_snp_enabled, bool, 0444); +/* enable/disable SEV-SNP Restricted Injection support */ +static bool sev_snp_restricted_injection_enabled = true; +module_param_named(restricted_injection, sev_snp_restricted_injection_enabled, bool, 0444); + static unsigned int __ro_after_init nr_ciphertext_hiding_asids; module_param_named(ciphertext_hiding_asids, nr_ciphertext_hiding_asids, uint, 0444);
@@ -3223,6 +3229,12 @@ void __init sev_hardware_setup(void) if (sev_snp_enabled && tsc_khz && cpu_feature_enabled(X86_FEATURE_SNP_SECURE_TSC)) sev_supported_vmsa_features |= SVM_SEV_FEAT_SECURE_TSC; + + if (!sev_snp_enabled || !cpu_feature_enabled(X86_FEATURE_RESTRICTED_INJECTION)) + sev_snp_restricted_injection_enabled = false; + + if (sev_snp_restricted_injection_enabled) + sev_supported_vmsa_features |= SVM_SEV_FEAT_RESTRICTED_INJECTION; } void sev_hardware_unsetup(void)
@@ -4773,10 +4785,20 @@ void sev_vcpu_after_set_cpuid(struct vcpu_svm *svm) vcpu->arch.reserved_gpa_bits &= ~(1UL << (best->ebx & 0x3f)); } +static void sev_snp_init_vmcb(struct vcpu_svm *svm) +{ + struct kvm_sev_info *sev = &to_kvm_svm(svm->vcpu.kvm)->sev_info; + + /* V_NMI is not supported when Restricted Injection is enabled */ + if (sev->vmsa_features & SVM_SEV_FEAT_RESTRICTED_INJECTION) + svm->vmcb->control.int_ctl &= ~V_NMI_ENABLE_MASK; +} + static void sev_es_init_vmcb(struct vcpu_svm *svm, bool init_event) { struct kvm_sev_info *sev = to_kvm_sev_info(svm->vcpu.kvm); struct vmcb *vmcb = svm->vmcb01.ptr; + struct kvm_vcpu *vcpu = &svm->vcpu; svm->vmcb->control.misc_ctl |= SVM_MISC_ENABLE_SEV_ES;
@@ -4843,6 +4865,8 @@ static void sev_es_init_vmcb(struct vcpu_svm *svm, bool init_event) set_ghcb_msr(svm, GHCB_MSR_SEV_INFO((__u64)sev->ghcb_version, GHCB_VERSION_MIN, sev_enc_bit)); + if (is_sev_snp_guest(vcpu)) + sev_snp_init_vmcb(svm); } void sev_init_vmcb(struct vcpu_svm *svm, bool init_event)
--
2.53.0