From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752175AbdJTCih (ORCPT ); Thu, 19 Oct 2017 22:38:37 -0400 Received: from mail-bl2nam02on0071.outbound.protection.outlook.com ([104.47.38.71]:59884 "EHLO NAM02-BL2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752295AbdJTCfw (ORCPT ); Thu, 19 Oct 2017 22:35:52 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; From: Brijesh Singh To: kvm@vger.kernel.org Cc: bp@alien8.de, Brijesh Singh , Thomas Gleixner , Ingo Molnar , "H. Peter Anvin" , Paolo Bonzini , =?UTF-8?q?Radim=20Kr=C4=8Dm=C3=A1=C5=99?= , Joerg Roedel , Borislav Petkov , Tom Lendacky , x86@kernel.org, linux-kernel@vger.kernel.org Subject: [Part2 PATCH v6 32/38] KVM: SVM: Add support for SEV DEBUG_DECRYPT command Date: Thu, 19 Oct 2017 21:34:07 -0500 Message-Id: <20171020023413.122280-33-brijesh.singh@amd.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20171020023413.122280-1-brijesh.singh@amd.com> References: <20171020023413.122280-1-brijesh.singh@amd.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Originating-IP: [165.204.78.1] X-ClientProxiedBy: MWHPR1701CA0020.namprd17.prod.outlook.com (10.172.58.30) To SN1PR12MB0157.namprd12.prod.outlook.com (10.162.3.144) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9db7f529-e865-4420-aa39-08d517634035 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(48565401081)(4534020)(4602075)(4627075)(201703031133081)(201702281549075)(2017052603199);SRVR:SN1PR12MB0157; X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0157;3:/FA3AR6HpblU17bg20nVpAl40vjuUV7uvO8InTrmXUPvFBsPMU1ovG//kCd60ftFccCiHdufTkajXxp2x84IaRDW5Mx78FWDYUOL+hBiizrTKgFzNOwq/06BJS+wOvet99yX36U37efJYznE3WmNN3qQc+b1l0TdLf147AE1fPwLgPOupsR6vHOgAYxpHrDA9bwshjQ191gi8yfcyvyJ0pJW4Azdacw65sz9q+mNQYqTeN6teMaq79GQLpY/TRZ2;25:JjBrLHq9BItkqCIha2l9YkeSScAYeI5wzW7oR8gQt9sU09kkOD99fGonr00vzveGaewpNbVCAiH6X8C87lhZxsZTO2Qq/gW0GdpqhZZ3OunEdSGRY69cpnSHZRNkqWXFL7bDGsUkSo7990L8yeSNvoDxrRAG76cdXQsWKqZVCZz0/6K0FgsSXzz6Q9GE0cieGW5Ei4qrZJ+N85116eDpYYmssLZw6mr2U/SJCv5cUWOJgQxELzI8uuEbuK5wkg9L8KjVRjqSv9texa4y7xVneLriU98LgMhRx+OowLq0qHEoFt11CwXIwYdUh8/jEm4jAegbAD/2pixSm3rAI+2igA==;31:eRV4l+tbPhw4wsJBT9Uh0VWIx+nG0bef8kyhl1oQS8JXh7EDdp1zfQtjOf75TcfbEmmd49ulRWPYw/aHYBzT4iePPhrnLcju8LYJVIImoNGGXga+JtyLQuUzGJyfXFtvFHSxr1BEL6Bv1h/VHoFA6tAsG3E8begTm6eYQNzRazuAOv6yLHMcOmGRHqTSW4MlB9u/o6/RjrQzlYeSRoATpVCje173K2HiLyFdfIU3LO8= X-MS-TrafficTypeDiagnostic: SN1PR12MB0157: X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0157;20:tQXzy+jDAMInR4Pf6NfGIhESsRZ+CucEwgd11+BRyCAzGvm2XdChoLxI8LB2yAzqISKdhQfQjuqegfWhudyyLfomkhvXcjATDwyn0j2VbTBZHgGPkWhWxKILTVnxTMk0YqZKVfMB/m1V+jjYj2S2tVd7F1PUBLEun+IMi6kpkYVxcVmx1kZFDIMPLqFC689UBbN/nSDe0nY7qztT8DGddcE/CfhLiLIXv3Djw9LWWtCZ9LEg7g0Nf68+IB+kjkw3dgjarMMulsIPkrjc7o402hDYBQuIRtONAnhEjZIBR2hibq/le8eXPxTNSXE9xW835FFIVuraUjP9bNq3xikkdEP+1jHVs2DAn+SxeUxldEUkMsmCOQ5HZShNA3fiiK7c9tZ1sVlfzqUNn3iwUDJtx1z30PswcY1BjES5SWQGbVHjGpJQsdJKNPwVBIxhXhVb9lLdvQMqdG+GE8V4cNAPl57ZEUOXXHBEW4AYc+RSnxBrK+0H8GTZJDeM81OikGEg;4:BdOMtaZE7fDcN8OB6211s283waD8qEBhrN4MNVsA3ar0QlRbGY5JDtezeinXW0x63dmQz1iknC4RaMR1Fs/9Le4jpItWSc2ibptVUXptd7oX38MYTeKcWO2FKxRfl58IcyMk0gJUxPvxgf0gCRYYCIU5dsUJg+y1Uh4GkzXUH4dxWKwQ03h5SB1x57+eMLMp/WfMIIq/MGP+w0x7fjJ/G65b2Gd/z4VLIw/Vn1P4iz8zFFjTZxPsaJi3+zaHrLG7JTcu7Qp0JSJPeWhyc3N9blZSKaPd3KNjgDonmAYfraH+OHcxVOGb76mgBZVHTMef X-Exchange-Antispam-Report-Test: UriScan:(9452136761055)(767451399110); X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(100000700101)(100105000095)(100000701101)(100105300095)(100000702101)(100105100095)(6040450)(2401047)(8121501046)(5005006)(3231020)(100000703101)(100105400095)(10201501046)(93006095)(93001095)(3002001)(6055026)(6041248)(20161123555025)(20161123564025)(20161123558100)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(20161123560025)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:SN1PR12MB0157;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:SN1PR12MB0157; X-Forefront-PRVS: 0466CA5A45 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(346002)(376002)(39860400002)(199003)(189002)(36756003)(7736002)(68736007)(50466002)(1076002)(478600001)(4326008)(16526018)(316002)(53936002)(6486002)(86362001)(305945005)(53416004)(54906003)(50226002)(2351001)(106356001)(101416001)(81166006)(105586002)(8676002)(2361001)(76176999)(2870700001)(2906002)(50986999)(6916009)(23676002)(66066001)(47776003)(6666003)(97736004)(6116002)(2950100002)(189998001)(8936002)(3846002)(33646002)(81156014)(7416002)(5660300001)(25786009);DIR:OUT;SFP:1101;SCL:1;SRVR:SN1PR12MB0157;H:ubuntu-010236106000.amd.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtTTjFQUjEyTUIwMTU3OzIzOi9ZQVU5OHM1SHNwRWNYdEhFajBZQmxkSzNU?= =?utf-8?B?MDh2QVk3SXVDRm9WNFlhVGdOY3JBV1lnSGRGNUVBY1dDdWprOTNlOHdGaU40?= =?utf-8?B?UWIyK2RnMnBNZk1TdDh3Nnp3YXVZT0h2N1hDbWEyUjFkRUR4N1c4emdjUEp2?= =?utf-8?B?VlplTnVmYlIrbnplWkRJKzJiL01ibkpaVXFaNjQwUGxDTkFDdFo2Tis5cVFV?= =?utf-8?B?bVBGa1N0WjYwREdIaGdzZ3FrK2k3RGRZM21ac2ppK09WaXZkWWM1REhSdkJu?= =?utf-8?B?RG94MVdTcXJTMm55Qk13ZnlZbGJKaXdidWp1QTFBNjVEMm5pZHRjZ2Y2bXNV?= =?utf-8?B?cU1DSWllVDlhSGpNckVXT21DaktUVTFFdXRCRXMrWXp4L0paK0RPYUhRZUhw?= =?utf-8?B?RUFvOFd0NHVFVFkra2psOTVxYllMOGxZTmFkWHBLdklwWktMSXdwNVdRT2dv?= =?utf-8?B?cEVuRzFZRmRycDFmcVhncmVOYkxOcVNmSi9sWEUrbHRrZnN3RmNpMFBUKzFN?= =?utf-8?B?L2NJSDdhZnlmQ0hjMVpxVXlKRzlRbVNoQXNMNitsY0d6VkU2NlhmTzNicU1p?= =?utf-8?B?cUpEQkVaNmVDcXEzNHQxQVBLVGZDZWNvNlFHeFhGS1ZTOGtjZG1BWlUzaUIv?= =?utf-8?B?YkJqc25zVXJ2LzU0VmJMRkdvMzR4Yk9PelNvYWh1S0phYkd2bkh1bDdzaXBG?= =?utf-8?B?TlVsQmZCOTlJdDRsS01BT0dTYmY1dWhaa3g3V1VVNExmM05hQzJmYXZOZVBt?= =?utf-8?B?VGgwTTlYUDlQUmpZd0ZMZFZiMVNTYStlYmJOWnBkbm0vUlh4ZE9ON1VDaWlm?= =?utf-8?B?WWE3cmZjRlc1L3ZZdGtTbzh1L1JaZ013am84ZjAzbStsOC9BRnljVzRZcWhJ?= =?utf-8?B?eVRsNkxRaGoxUkloelRrYTdKZDBGZUsxb3RuSFJHTXZ1OStsVU91aXRRcXBO?= =?utf-8?B?RyszRWlobGFGa3BxWUJGNDdtanh0SFF1WnpvamFGMVNMRkdtWFdkd09FcjJ4?= =?utf-8?B?QU5ERGMzWEJRUC9QbmZ5UTNXUkR1d2djd1YzTE1iYmVhUGQ3WW9DMk8rbWVz?= =?utf-8?B?SXVzRUJaYTJ5OUJVUG93cGZEZWNJTVBCTWdjTnlDT0R3dWNmdWpxV1k0MHlD?= =?utf-8?B?bDdmQWhhaVVJQnNIYmE5QzBLZlcvQ0F4QUNyZ1NwMUkveThVTVk3aDQ3Tmpo?= =?utf-8?B?eElqRFlSSXlodDBibnI2dm5YcE12MldDWm10Qmt3MnpEQjhUbEsyaElvekgw?= =?utf-8?B?UTRqT0xjTWFjb1lDZkgySGRvQlhNWmk0K2ExRkFQZXZQOXJZZ2p1ZTNyK0ZP?= =?utf-8?B?V3hCZWFLQ2d3Sms1MXBybzRCblBOd1E1TS9wOTJyanFHQ012bEhQb3J4bENK?= =?utf-8?B?N0FveFFieDE5UVdqOG5nS2dtZmdRTi9ySFVFQStHeXh4dS90M29lR0FiMDhp?= =?utf-8?B?TzRKempBZzB4MHNmNHVkS28xR09XcmNwNUwrcDNsb2lmUFBFdXRLcWNTWW9p?= =?utf-8?Q?6Afjt0MXwL9R1ifBSz7LHraJkYDivpNMk7n4GjoIRnisXZ?= X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0157;6:Yw507psKwPXW+xWgYkUezMYlDxo8CIKQIhXPFZe9yhGG0zyqENcv1W3BZrc/AzFNHbiEHvvb0c7+PUJiDTLl/ihDcPl/jx0+hYenmhpWQKMAzuY2nezHiUnIShuBHxzU2jTDxyy5jf1oYKNXoiKbjZ4JqYLxOaYLeuunL8BpvaL56kpST6jcxL+0+ee622kq7sCrbmxYoalEgzp48Dfk3SGDur0zRvto+ZdPEuqISQr2zPwe4fLg5ffmC1cevn+Vla8EnwUGnZPlqos1Sah3lQvPV0CPaF9nn4Ur0LoLuelmoukDQZSHg/vgNkUOVETtpmn9DFN4TAmICpl/jlq5Zg==;5:93jvyn/l1xzqaMhOzdV8W0AYaQbqAvKEAVA8aQLFnhHZgVwEI9Xu2XZt7udRh/40WaoUdbeUJj86kTVk0xB6uOG3YiTfnMTU+ZBaEYDIoSnN1AjwqaDCr0+aINTMiYZCdtkfuo/mZ9h4/fmHAQvDvA==;24:bRlKHC8zLCBEu386BEtZzzdkcN+pYvDi5uE/JInH2sf9oMbXi1iOj5gRW/QuBQdjLlfzBXf0IHoZj5kiyPz60bZwj1m56n198yXbkeHaOWc=;7:vdmO9PtN+4HH1B35rOv3LsMq21k3DyQqo3AAwDK108SNVpq3jdkWnXoQUqM5oV4etgvRwnFQ8yGPKqck8lwaEbFt9qNhnujTd8adNfNv/7lN+uQJeUPw9F0xJTi3IerlUJU7Lmuz7n9tEnxMh1GO72gy1xaBN7JWvIEQBgTpCw55U5pNaC0zBM6G9C06jVFRcRiNP7kJ5XRBBK9yGiwkzGNBqUCkmPJOCysxCpNVXGs= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;SN1PR12MB0157;20:n9TzjKAuLVNQoAklRNuZe03UqEHUY68fnRa0G6Qez/DNKem0sINOA8nJr20VxM2Vuxnsm8rrSL7aoGCLvkdc53rLZJQPTuhgY5N953/gyRtI9e1WTjbtxRdLQKcSCVyTUdW/l33PDiDw1ZQD95Shav08Vg+wnOdP7a4JhOFkSXij7fJcQssM+5QuyF7GF165zVxcE7sEC/9PQ2LDSLOwl4Pjf/UzKn9Fr54aRbf84oFjP28t6X7OAv4xSvySDZ43 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Oct 2017 02:35:37.2221 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 9db7f529-e865-4420-aa39-08d517634035 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB0157 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The command is used for decrypting a guest memory region for debug purposes. Cc: Thomas Gleixner Cc: Ingo Molnar Cc: "H. Peter Anvin" Cc: Paolo Bonzini Cc: "Radim Krčmář" Cc: Joerg Roedel Cc: Borislav Petkov Cc: Tom Lendacky Cc: x86@kernel.org Cc: kvm@vger.kernel.org Cc: linux-kernel@vger.kernel.org Signed-off-by: Brijesh Singh --- arch/x86/kvm/svm.c | 179 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 83a4d0406a4b..f19c4fb2fdc8 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -6023,6 +6023,182 @@ 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; +} + +/* + * Decrypt source memory into userspace or kernel buffer. If destination buffer + * or len is not aligned to 16-byte boundary then it uses intermediate buffer. + */ +static int __sev_dbg_decrypt(struct kvm *kvm, unsigned long paddr, + unsigned long __user dst_uaddr, + unsigned long dst_kaddr, unsigned long dst_paddr, + int size, int *error) +{ + int ret, offset = 0, len = size; + struct page *tpage = NULL; + + /* + * Debug command works with 16-byte aligned inputs, check if all inputs + * (src, dst and len) are 16-byte aligned. If one of the input is not + * aligned then we decrypt more than requested into a temporary buffer + * and copy the porition of data into destination buffer. + */ + if (!IS_ALIGNED(paddr, 16) || + !IS_ALIGNED(dst_paddr, 16) || + !IS_ALIGNED(size, 16)) { + tpage = (void *)alloc_page(GFP_KERNEL); + if (!tpage) + return -ENOMEM; + + dst_paddr = __sme_page_pa(tpage); + + /* + * if source buffer is not aligned then offset will be used + * when copying the data from the temporary buffer into + * destination buffer. + */ + offset = paddr & 15; + + /* its safe to read more than requested size. */ + len = round_up(size + offset, 16); + + paddr = round_down(paddr, 16); + + /* + * The temporary buffer may have mapping with C=0 or C=1 on x86 + * side but PSP will will write the memory region with C=0. + * Lets make sure x86 cache for this memory range is flushed so + * that we can see the recent contents after the command + * completes. + */ + clflush_cache_range(page_address(tpage), PAGE_SIZE); + } + + ret = __sev_issue_dbg_cmd(kvm, paddr, dst_paddr, len, error, false); + + /* + * If temporary buffer is used then copy the data from temporary buffer + * into destination buffer. + */ + if (!ret && tpage) { + /* + * If destination buffer is a userspace buffer then use + * copy_to_user otherwise memcpy. + */ + if (dst_uaddr) { + if (copy_to_user((void __user *)(uintptr_t)dst_uaddr, + page_address(tpage) + offset, size)) + ret = -EFAULT; + } else { + memcpy((void *)dst_kaddr, page_address(tpage) + offset, size); + } + } + + 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; + } + + /* + * Depending on the operation type (encrypt or decrypt), PSP + * will access the source and destination buffer with C=0 or + * C=1. Lets make sure that caches are flushed so that data gets + * accessed with correct C-bit. + */ + 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(kvm, + __sme_page_pa(src_p[0]) + s_off, + dst_vaddr, 0, + __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 sev_dbg_decrypt(struct kvm *kvm, struct kvm_sev_cmd *argp) +{ + return sev_dbg_crypt(kvm, argp, true); +} + static int svm_mem_enc_op(struct kvm *kvm, void __user *argp) { struct kvm_sev_cmd sev_cmd; @@ -6055,6 +6231,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_decrypt(kvm, &sev_cmd); + break; default: r = -EINVAL; goto out; -- 2.9.5