The next generation of SEV is called SEV-SNP (Secure Nested Paging). SEV-SNP builds upon existing SEV and SEV-ES functionality while adding new hardware based security protection. SEV-SNP adds strong memory encryption integrity protection to help prevent malicious hypervisor-based attacks such as data replay, memory re-mapping, and more, to create an isolated execution environment. The SNP feature can be enabled in the KVM by passing the sev-snp module parameter. Signed-off-by: Brijesh Singh <brijesh.singh@xxxxxxx> --- arch/x86/kvm/svm/sev.c | 18 ++++++++++++++++++ arch/x86/kvm/svm/svm.h | 12 ++++++++++++ 2 files changed, 30 insertions(+) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index b750e435626a..200d227f9232 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -52,9 +52,14 @@ module_param_named(sev, sev_enabled, bool, 0444); /* enable/disable SEV-ES support */ static bool sev_es_enabled = true; module_param_named(sev_es, sev_es_enabled, bool, 0444); + +/* enable/disable SEV-SNP support */ +static bool sev_snp_enabled = true; +module_param_named(sev_snp, sev_snp_enabled, bool, 0444); #else #define sev_enabled false #define sev_es_enabled false +#define sev_snp_enabled false #endif /* CONFIG_KVM_AMD_SEV */ #define AP_RESET_HOLD_NONE 0 @@ -1826,6 +1831,7 @@ void __init sev_hardware_setup(void) { #ifdef CONFIG_KVM_AMD_SEV unsigned int eax, ebx, ecx, edx, sev_asid_count, sev_es_asid_count; + bool sev_snp_supported = false; bool sev_es_supported = false; bool sev_supported = false; @@ -1889,9 +1895,21 @@ void __init sev_hardware_setup(void) pr_info("SEV-ES supported: %u ASIDs\n", sev_es_asid_count); sev_es_supported = true; + /* SEV-SNP support requested? */ + if (!sev_snp_enabled) + goto out; + + /* Is SEV-SNP enabled? */ + if (!cpu_feature_enabled(X86_FEATURE_SEV_SNP)) + goto out; + + pr_info("SEV-SNP supported: %u ASIDs\n", min_sev_asid - 1); + sev_snp_supported = true; + out: sev_enabled = sev_supported; sev_es_enabled = sev_es_supported; + sev_snp_enabled = sev_snp_supported; #endif } diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 894e828227d9..85a2d5857ffb 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -58,6 +58,7 @@ enum { struct kvm_sev_info { bool active; /* SEV enabled guest */ bool es_active; /* SEV-ES enabled guest */ + bool snp_active; /* SEV-SNP enabled guest */ unsigned int asid; /* ASID used for this guest */ unsigned int handle; /* SEV firmware handle */ int fd; /* SEV device fd */ @@ -232,6 +233,17 @@ static inline bool sev_es_guest(struct kvm *kvm) #endif } +static inline bool sev_snp_guest(struct kvm *kvm) +{ +#ifdef CONFIG_KVM_AMD_SEV + struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; + + return sev_es_guest(kvm) && sev->snp_active; +#else + return false; +#endif +} + static inline void vmcb_mark_all_dirty(struct vmcb *vmcb) { vmcb->control.clean = 0; -- 2.17.1