diff options
Diffstat (limited to 'meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71-e3000/0078-KVM-SVM-Add-support-for-SEV-DEBUG_DECRYPT-command.patch')
-rw-r--r-- | meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71-e3000/0078-KVM-SVM-Add-support-for-SEV-DEBUG_DECRYPT-command.patch | 202 |
1 files changed, 0 insertions, 202 deletions
diff --git a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71-e3000/0078-KVM-SVM-Add-support-for-SEV-DEBUG_DECRYPT-command.patch b/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71-e3000/0078-KVM-SVM-Add-support-for-SEV-DEBUG_DECRYPT-command.patch deleted file mode 100644 index 5f7419db..00000000 --- a/meta-amd-bsp/recipes-kernel/linux/linux-yocto-4.14.71-e3000/0078-KVM-SVM-Add-support-for-SEV-DEBUG_DECRYPT-command.patch +++ /dev/null @@ -1,202 +0,0 @@ -From b087a322574fc94f760c1150b344191996543733 Mon Sep 17 00:00:00 2001 -From: Brijesh Singh <brijesh.singh@amd.com> -Date: Mon, 4 Dec 2017 10:57:37 -0600 -Subject: [PATCH 78/95] KVM: SVM: Add support for SEV DEBUG_DECRYPT command -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The command is used for decrypting a guest memory region for debug -purposes. - -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 -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/kvm/svm.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 152 insertions(+) - -diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c -index f9eb8fa..9c5962a 100755 ---- a/arch/x86/kvm/svm.c -+++ b/arch/x86/kvm/svm.c -@@ -6269,6 +6269,155 @@ static int sev_guest_status(struct kvm *kvm, struct kvm_sev_cmd *argp) - return ret; - } - -+static int __sev_issue_dbg_cmd(struct kvm *kvm, unsigned long src, -+ unsigned long dst, int size, -+ int *error, bool enc) -+{ -+ struct kvm_sev_info *sev = &kvm->arch.sev_info; -+ struct sev_data_dbg *data; -+ int ret; -+ -+ data = kzalloc(sizeof(*data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ data->handle = sev->handle; -+ data->dst_addr = dst; -+ data->src_addr = src; -+ data->len = size; -+ -+ ret = sev_issue_cmd(kvm, -+ enc ? SEV_CMD_DBG_ENCRYPT : SEV_CMD_DBG_DECRYPT, -+ data, error); -+ kfree(data); -+ return ret; -+} -+ -+static int __sev_dbg_decrypt(struct kvm *kvm, unsigned long src_paddr, -+ unsigned long dst_paddr, int sz, int *err) -+{ -+ int offset; -+ -+ /* -+ * Its safe to read more than we are asked, caller should ensure that -+ * destination has enough space. -+ */ -+ src_paddr = round_down(src_paddr, 16); -+ offset = src_paddr & 15; -+ sz = round_up(sz + offset, 16); -+ -+ return __sev_issue_dbg_cmd(kvm, src_paddr, dst_paddr, sz, err, false); -+} -+ -+static int __sev_dbg_decrypt_user(struct kvm *kvm, unsigned long paddr, -+ unsigned long __user dst_uaddr, -+ unsigned long dst_paddr, -+ int size, int *err) -+{ -+ struct page *tpage = NULL; -+ int ret, offset; -+ -+ /* if inputs are not 16-byte then use intermediate buffer */ -+ if (!IS_ALIGNED(dst_paddr, 16) || -+ !IS_ALIGNED(paddr, 16) || -+ !IS_ALIGNED(size, 16)) { -+ tpage = (void *)alloc_page(GFP_KERNEL); -+ if (!tpage) -+ return -ENOMEM; -+ -+ dst_paddr = __sme_page_pa(tpage); -+ } -+ -+ ret = __sev_dbg_decrypt(kvm, paddr, dst_paddr, size, err); -+ if (ret) -+ goto e_free; -+ -+ if (tpage) { -+ offset = paddr & 15; -+ if (copy_to_user((void __user *)(uintptr_t)dst_uaddr, -+ page_address(tpage) + offset, size)) -+ ret = -EFAULT; -+ } -+ -+e_free: -+ if (tpage) -+ __free_page(tpage); -+ -+ return ret; -+} -+ -+static int sev_dbg_crypt(struct kvm *kvm, struct kvm_sev_cmd *argp, bool dec) -+{ -+ unsigned long vaddr, vaddr_end, next_vaddr; -+ unsigned long dst_vaddr, dst_vaddr_end; -+ struct page **src_p, **dst_p; -+ struct kvm_sev_dbg debug; -+ unsigned long n; -+ int ret, size; -+ -+ if (!sev_guest(kvm)) -+ return -ENOTTY; -+ -+ if (copy_from_user(&debug, (void __user *)(uintptr_t)argp->data, sizeof(debug))) -+ return -EFAULT; -+ -+ vaddr = debug.src_uaddr; -+ size = debug.len; -+ vaddr_end = vaddr + size; -+ dst_vaddr = debug.dst_uaddr; -+ dst_vaddr_end = dst_vaddr + size; -+ -+ for (; vaddr < vaddr_end; vaddr = next_vaddr) { -+ int len, s_off, d_off; -+ -+ /* lock userspace source and destination page */ -+ src_p = sev_pin_memory(kvm, vaddr & PAGE_MASK, PAGE_SIZE, &n, 0); -+ if (!src_p) -+ return -EFAULT; -+ -+ dst_p = sev_pin_memory(kvm, dst_vaddr & PAGE_MASK, PAGE_SIZE, &n, 1); -+ if (!dst_p) { -+ sev_unpin_memory(kvm, src_p, n); -+ return -EFAULT; -+ } -+ -+ /* -+ * The DBG_{DE,EN}CRYPT commands will perform {dec,en}cryption of the -+ * memory content (i.e it will write the same memory region with C=1). -+ * It's possible that the cache may contain the data with C=0, i.e., -+ * unencrypted so invalidate it first. -+ */ -+ sev_clflush_pages(src_p, 1); -+ sev_clflush_pages(dst_p, 1); -+ -+ /* -+ * Since user buffer may not be page aligned, calculate the -+ * offset within the page. -+ */ -+ s_off = vaddr & ~PAGE_MASK; -+ d_off = dst_vaddr & ~PAGE_MASK; -+ len = min_t(size_t, (PAGE_SIZE - s_off), size); -+ -+ ret = __sev_dbg_decrypt_user(kvm, -+ __sme_page_pa(src_p[0]) + s_off, -+ dst_vaddr, -+ __sme_page_pa(dst_p[0]) + d_off, -+ len, &argp->error); -+ -+ sev_unpin_memory(kvm, src_p, 1); -+ sev_unpin_memory(kvm, dst_p, 1); -+ -+ if (ret) -+ goto err; -+ -+ next_vaddr = vaddr + len; -+ dst_vaddr = dst_vaddr + len; -+ size -= len; -+ } -+err: -+ return ret; -+} -+ - static int svm_mem_enc_op(struct kvm *kvm, void __user *argp) - { - struct kvm_sev_cmd sev_cmd; -@@ -6301,6 +6450,9 @@ static int svm_mem_enc_op(struct kvm *kvm, void __user *argp) - case KVM_SEV_GUEST_STATUS: - r = sev_guest_status(kvm, &sev_cmd); - break; -+ case KVM_SEV_DBG_DECRYPT: -+ r = sev_dbg_crypt(kvm, &sev_cmd, true); -+ break; - default: - r = -EINVAL; - goto out; --- -2.7.4 - |