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. Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx> Cc: Borislav Petkov <bp@xxxxxxxxx> Cc: Joerg Roedel <jroedel@xxxxxxx> Cc: "H. Peter Anvin" <hpa@xxxxxxxxx> Cc: Tony Luck <tony.luck@xxxxxxxxx> Cc: Dave Hansen <dave.hansen@xxxxxxxxx> Cc: "Peter Zijlstra (Intel)" <peterz@xxxxxxxxxxxxx> Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx> Cc: Tom Lendacky <thomas.lendacky@xxxxxxx> Cc: David Rientjes <rientjes@xxxxxxxxxx> Cc: Sean Christopherson <seanjc@xxxxxxxxxx> Cc: x86@xxxxxxxxxx Cc: kvm@xxxxxxxxxxxxxxx Signed-off-by: Brijesh Singh <brijesh.singh@xxxxxxx> --- arch/x86/kvm/svm/sev.c | 17 +++++++++++++++++ arch/x86/kvm/svm/svm.c | 5 +++++ arch/x86/kvm/svm/svm.h | 13 +++++++++++++ 3 files changed, 35 insertions(+) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 48017fef1cd9..b720837faf5a 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -19,6 +19,7 @@ #include <asm/fpu/internal.h> #include <asm/trapnr.h> +#include <asm/sev-snp.h> #include "x86.h" #include "svm.h" @@ -1249,6 +1250,7 @@ void sev_vm_destroy(struct kvm *kvm) void __init sev_hardware_setup(void) { unsigned int eax, ebx, ecx, edx; + bool sev_snp_supported = false; bool sev_es_supported = false; bool sev_supported = false; @@ -1298,9 +1300,24 @@ void __init sev_hardware_setup(void) pr_info("SEV-ES supported: %u ASIDs\n", min_sev_asid - 1); sev_es_supported = true; + /* SEV-SNP support requested? */ + if (!sev_snp) + goto out; + + /* Does the CPU support SEV-SNP? */ + if (!boot_cpu_has(X86_FEATURE_SEV_SNP)) + goto out; + + if (!snp_key_active()) + goto out; + + pr_info("SEV-SNP supported: %u ASIDs\n", min_sev_asid - 1); + sev_snp_supported = true; + out: sev = sev_supported; sev_es = sev_es_supported; + sev_snp = sev_snp_supported; } void sev_hardware_teardown(void) diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c index 3442d44ca53b..aa7ff4685c87 100644 --- a/arch/x86/kvm/svm/svm.c +++ b/arch/x86/kvm/svm/svm.c @@ -197,6 +197,10 @@ module_param(sev, int, 0444); int sev_es = IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT); module_param(sev_es, int, 0444); +/* enable/disable SEV-SNP support */ +int sev_snp = IS_ENABLED(CONFIG_AMD_MEM_ENCRYPT_ACTIVE_BY_DEFAULT); +module_param(sev_snp, int, 0444); + bool __read_mostly dump_invalid_vmcb; module_param(dump_invalid_vmcb, bool, 0644); @@ -986,6 +990,7 @@ static __init int svm_hardware_setup(void) } else { sev = false; sev_es = false; + sev_snp = false; } svm_adjust_mmio_mask(); diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h index 6e7d070f8b86..3dd60d2a567a 100644 --- a/arch/x86/kvm/svm/svm.h +++ b/arch/x86/kvm/svm/svm.h @@ -73,6 +73,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 */ @@ -241,6 +242,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; @@ -407,6 +419,7 @@ static inline bool gif_set(struct vcpu_svm *svm) extern int sev; extern int sev_es; +extern int sev_snp; extern bool dump_invalid_vmcb; u32 svm_msrpm_offset(u32 msr); -- 2.17.1