diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71-e3000/0072-KVM-SVM-Add-support-for-KVM_SEV_LAUNCH_START-command.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71-e3000/0072-KVM-SVM-Add-support-for-KVM_SEV_LAUNCH_START-command.patch | 248 |
1 files changed, 248 insertions, 0 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71-e3000/0072-KVM-SVM-Add-support-for-KVM_SEV_LAUNCH_START-command.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71-e3000/0072-KVM-SVM-Add-support-for-KVM_SEV_LAUNCH_START-command.patch new file mode 100644 index 00000000..1e7c7735 --- /dev/null +++ b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71-e3000/0072-KVM-SVM-Add-support-for-KVM_SEV_LAUNCH_START-command.patch @@ -0,0 +1,248 @@ +From fbb9ae1da5aef85415efc29ae3a90d3662cb937b Mon Sep 17 00:00:00 2001 +From: Sudheesh Mavila <sudheesh.mavila@amd.com> +Date: Tue, 14 Aug 2018 22:14:32 +0530 +Subject: [PATCH 72/95] KVM: SVM: Add support for KVM_SEV_LAUNCH_START command +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + + commit 59414c989220825f970f38dbcbf11f18e817d73c + + The KVM_SEV_LAUNCH_START command is used to create a memory encryption + context within the SEV firmware. In order to do so, the guest owner + should provide the guest's policy, its public Diffie-Hellman (PDH) key + and session information. The command implements the LAUNCH_START flow + defined in SEV spec Section 6.2. + + Cc: Thomas Gleixner <tglx@linutronix.de> + Cc: Ingo Molnar <mingo@redhat.com> + Cc: "H. Peter Anvin" <hpa@zytor.com> + Cc: Paolo Bonzini <pbonzini@redhat.com> + Cc: "Radim Krčmář" <rkrcmar@redhat.com> + Cc: Joerg Roedel <joro@8bytes.org> + Cc: Borislav Petkov <bp@suse.de> + Cc: Tom Lendacky <thomas.lendacky@amd.com> + Cc: x86@kernel.org + Cc: kvm@vger.kernel.org + Cc: linux-kernel@vger.kernel.org + Improvements-by: Borislav Petkov <bp@suse.de> + Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> + Reviewed-by: Borislav Petkov <bp@suse.de> + +Signed-off-by: Sudheesh Mavila <sudheesh.mavila@amd.com> +--- + arch/x86/include/asm/kvm_host.h | 2 + + arch/x86/kvm/svm.c | 157 +++++++++++++++++++++++++++++++++++++++- + 2 files changed, 158 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index 9cc7c30..03ba288 100755 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -755,6 +755,8 @@ enum kvm_irqchip_mode { + struct kvm_sev_info { + bool active; /* SEV enabled guest */ + unsigned int asid; /* ASID used for this guest */ ++ unsigned int handle; /* SEV firmware handle */ ++ int fd; /* SEV device fd */ + }; + + struct kvm_arch { +diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c +index f4fc0b2..2f6aa95 100755 +--- a/arch/x86/kvm/svm.c ++++ b/arch/x86/kvm/svm.c +@@ -1469,8 +1469,10 @@ static void init_vmcb(struct vcpu_svm *svm) + svm->vmcb->control.int_ctl |= V_GIF_ENABLE_MASK; + } + +- if (sev_guest(svm->vcpu.kvm)) ++ if (sev_guest(svm->vcpu.kvm)) { + svm->vmcb->control.nested_ctl |= SVM_NESTED_CTL_SEV_ENABLE; ++ clr_exception_intercept(svm, UD_VECTOR); ++ } + + mark_all_dirty(svm->vmcb); + +@@ -1575,11 +1577,45 @@ static void sev_asid_free(struct kvm *kvm) + __sev_asid_free(sev->asid); + } + ++static void sev_unbind_asid(struct kvm *kvm, unsigned int handle) ++{ ++ struct sev_data_decommission *decommission; ++ struct sev_data_deactivate *data; ++ ++ if (!handle) ++ return; ++ ++ data = kzalloc(sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return; ++ ++ /* deactivate handle */ ++ data->handle = handle; ++ sev_guest_deactivate(data, NULL); ++ ++ wbinvd_on_all_cpus(); ++ sev_guest_df_flush(NULL); ++ kfree(data); ++ ++ decommission = kzalloc(sizeof(*decommission), GFP_KERNEL); ++ if (!decommission) ++ return; ++ ++ /* decommission handle */ ++ decommission->handle = handle; ++ sev_guest_decommission(decommission, NULL); ++ ++ kfree(decommission); ++} ++ + static void sev_vm_destroy(struct kvm *kvm) + { ++ struct kvm_sev_info *sev = &kvm->arch.sev_info; ++ + if (!sev_guest(kvm)) + return; + ++ sev_unbind_asid(kvm, sev->handle); + sev_asid_free(kvm); + } + +@@ -5812,6 +5848,122 @@ static int sev_guest_init(struct kvm *kvm, struct kvm_sev_cmd *argp) + return ret; + } + ++static int sev_bind_asid(struct kvm *kvm, unsigned int handle, int *error) ++{ ++ struct sev_data_activate *data; ++ int asid = sev_get_asid(kvm); ++ int ret; ++ ++ wbinvd_on_all_cpus(); ++ ++ ret = sev_guest_df_flush(error); ++ if (ret) ++ return ret; ++ ++ data = kzalloc(sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return -ENOMEM; ++ ++ /* activate ASID on the given handle */ ++ data->handle = handle; ++ data->asid = asid; ++ ret = sev_guest_activate(data, error); ++ kfree(data); ++ ++ return ret; ++} ++ ++static int sev_issue_cmd(int fd, int id, void *data, int *error) ++{ ++ struct fd f; ++ int ret; ++ ++ f = fdget(fd); ++ if (!f.file) ++ return -EBADF; ++ ++ ret = sev_issue_cmd_external_user(f.file, id, data, error); ++ ++ fdput(f); ++ return ret; ++} ++ ++static int sev_launch_start(struct kvm *kvm, struct kvm_sev_cmd *argp) ++{ ++ struct kvm_sev_info *sev = &kvm->arch.sev_info; ++ struct sev_data_launch_start *start; ++ struct kvm_sev_launch_start params; ++ void *dh_blob, *session_blob; ++ int *error = &argp->error; ++ int ret; ++ ++ if (!sev_guest(kvm)) ++ return -ENOTTY; ++ ++ if (copy_from_user(¶ms, (void __user *)(uintptr_t)argp->data, sizeof(params))) ++ return -EFAULT; ++ ++ start = kzalloc(sizeof(*start), GFP_KERNEL); ++ if (!start) ++ return -ENOMEM; ++ ++ dh_blob = NULL; ++ if (params.dh_uaddr) { ++ dh_blob = psp_copy_user_blob(params.dh_uaddr, params.dh_len); ++ if (IS_ERR(dh_blob)) { ++ ret = PTR_ERR(dh_blob); ++ goto e_free; ++ } ++ ++ start->dh_cert_address = __sme_set(__pa(dh_blob)); ++ start->dh_cert_len = params.dh_len; ++ } ++ ++ session_blob = NULL; ++ if (params.session_uaddr) { ++ session_blob = psp_copy_user_blob(params.session_uaddr, params.session_len); ++ if (IS_ERR(session_blob)) { ++ ret = PTR_ERR(session_blob); ++ goto e_free_dh; ++ } ++ ++ start->session_address = __sme_set(__pa(session_blob)); ++ start->session_len = params.session_len; ++ } ++ ++ start->handle = params.handle; ++ start->policy = params.policy; ++ ++ /* create memory encryption context */ ++ ret = sev_issue_cmd(argp->sev_fd, SEV_CMD_LAUNCH_START, start, error); ++ if (ret) ++ goto e_free_session; ++ ++ /* Bind ASID to this guest */ ++ ret = sev_bind_asid(kvm, start->handle, error); ++ if (ret) ++ goto e_free_session; ++ ++ /* return handle to userspace */ ++ params.handle = start->handle; ++ if (copy_to_user((void __user *)(uintptr_t)argp->data, ¶ms, sizeof(params))) { ++ sev_unbind_asid(kvm, start->handle); ++ ret = -EFAULT; ++ goto e_free_session; ++ } ++ ++ sev->handle = start->handle; ++ sev->fd = argp->sev_fd; ++ ++e_free_session: ++ kfree(session_blob); ++e_free_dh: ++ kfree(dh_blob); ++e_free: ++ kfree(start); ++ return ret; ++} ++ + static int svm_mem_enc_op(struct kvm *kvm, void __user *argp) + { + struct kvm_sev_cmd sev_cmd; +@@ -5829,6 +5981,9 @@ static int svm_mem_enc_op(struct kvm *kvm, void __user *argp) + case KVM_SEV_INIT: + r = sev_guest_init(kvm, &sev_cmd); + break; ++ case KVM_SEV_LAUNCH_START: ++ r = sev_launch_start(kvm, &sev_cmd); ++ break; + default: + r = -EINVAL; + goto out; +-- +2.7.4 + |