The KVM_SNP_INIT command is used by the hypervisor to initialize the SEV-SNP platform context. In a typical workflow, this command should be the first command issued. When creating SEV-SNP guest, the VMM must use this command instead of the KVM_SEV_INIT or KVM_SEV_ES_INIT. Signed-off-by: Brijesh Singh <brijesh.singh@xxxxxxx> --- arch/x86/include/asm/svm.h | 2 ++ arch/x86/kvm/svm/sev.c | 18 ++++++++++++++++-- include/uapi/linux/kvm.h | 3 +++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/svm.h b/arch/x86/include/asm/svm.h index b6f358d6b975..65407b6d35a0 100644 --- a/arch/x86/include/asm/svm.h +++ b/arch/x86/include/asm/svm.h @@ -212,6 +212,8 @@ struct __attribute__ ((__packed__)) vmcb_control_area { #define SVM_NESTED_CTL_SEV_ENABLE BIT(1) #define SVM_NESTED_CTL_SEV_ES_ENABLE BIT(2) +#define SVM_SEV_FEATURES_SNP_ACTIVE BIT(0) + struct vmcb_seg { u16 selector; u16 attrib; diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index abca2b9dee83..0cd0078baf75 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -230,8 +230,9 @@ static void sev_unbind_asid(struct kvm *kvm, unsigned int handle) static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) { + bool es_active = (argp->id == KVM_SEV_ES_INIT || argp->id == KVM_SEV_SNP_INIT); struct kvm_sev_info *sev = &to_kvm_svm(kvm)->sev_info; - bool es_active = argp->id == KVM_SEV_ES_INIT; + bool snp_active = argp->id == KVM_SEV_SNP_INIT; int asid, ret; if (kvm->created_vcpus) @@ -242,12 +243,16 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) return ret; sev->es_active = es_active; + sev->snp_active = snp_active; asid = sev_asid_new(sev); if (asid < 0) goto e_no_asid; sev->asid = asid; - ret = sev_platform_init(&argp->error); + if (snp_active) + ret = sev_snp_init(&argp->error); + else + ret = sev_platform_init(&argp->error); if (ret) goto e_free; @@ -591,6 +596,9 @@ static int sev_es_sync_vmsa(struct vcpu_svm *svm) save->pkru = svm->vcpu.arch.pkru; save->xss = svm->vcpu.arch.ia32_xss; + if (sev_snp_guest(svm->vcpu.kvm)) + save->sev_features |= SVM_SEV_FEATURES_SNP_ACTIVE; + return 0; } @@ -1523,6 +1531,12 @@ int svm_mem_enc_op(struct kvm *kvm, void __user *argp) } switch (sev_cmd.id) { + case KVM_SEV_SNP_INIT: + if (!sev_snp_enabled) { + r = -ENOTTY; + goto out; + } + fallthrough; case KVM_SEV_ES_INIT: if (!sev_es_enabled) { r = -ENOTTY; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 3fd9a7e9d90c..f3a86d3a8f04 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1678,6 +1678,9 @@ enum sev_cmd_id { /* Guest Migration Extension */ KVM_SEV_SEND_CANCEL, + /* SNP specific commands */ + KVM_SEV_SNP_INIT = 255, + KVM_SEV_NR_MAX, }; -- 2.17.1