@@ -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)
@@ -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();
@@ -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);
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@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Joerg Roedel <jroedel@suse.de> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Tony Luck <tony.luck@intel.com> Cc: Dave Hansen <dave.hansen@intel.com> Cc: "Peter Zijlstra (Intel)" <peterz@infradead.org> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Cc: David Rientjes <rientjes@google.com> Cc: Sean Christopherson <seanjc@google.com> Cc: x86@kernel.org Cc: kvm@vger.kernel.org Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> --- 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(+)