From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933655AbdKAVUZ (ORCPT ); Wed, 1 Nov 2017 17:20:25 -0400 Received: from mail-by2nam01on0041.outbound.protection.outlook.com ([104.47.34.41]:43936 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S933351AbdKAVRp (ORCPT ); Wed, 1 Nov 2017 17:17:45 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; From: Brijesh Singh To: kvm@vger.kernel.org, linux-kernel@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 Subject: [Part2 PATCH v7 32/38] KVM: SVM: Add support for SEV DEBUG_DECRYPT command Date: Wed, 1 Nov 2017 16:17:17 -0500 Message-Id: <20171101211723.71594-3-brijesh.singh@amd.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20171101211723.71594-1-brijesh.singh@amd.com> References: <20171101211723.71594-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: CY4PR02CA0025.namprd02.prod.outlook.com (10.175.57.139) To BY2PR12MB0145.namprd12.prod.outlook.com (10.162.82.18) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 7ea4b943-87f0-49b0-a9ff-08d5216dfcb7 X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(48565401081)(4534020)(4602075)(2017052603199);SRVR:BY2PR12MB0145; X-Microsoft-Exchange-Diagnostics: 1;BY2PR12MB0145;3:MXJRdQCnzFgW+1FiW8/Dsr+ljavsrFI7w6R2OIjUuqSG+NfiKs0B2H6wZpHbgEwm9k9X9FmwMC5ioyTxIgAtmsbhEMdumQ0aliInJVgME12/auPzz3K7sLJAlfd5i+bl346YkPs5aBmUzK0pauxbv28spw8edhFK2nZlur2I4AVWWqPJyEBZxtLA3+J/EeSTrnR/QzYloNh+12E1FtwACce2GoejffW2K9tRXf81nAsHjEc5IkBmSBuW8+J+GlhI;25:Ru2Q6PV56cmbl+MebV04na0v5aXKo4MKkz4iTs62ExK4LrL3HqCr/6+Y+hw9U+AvNdYl0qAhwE+1xN3Fs5DsKefwQIw5AWmAqj5inPKnpH8hGoyOE7hUJZoDPFWtx5+61Fp0qRvJT0p2BrwttOBLnqnbRSWG5LmRqEwGtiy/VhF7bTe5eO7AHECJEOcw3GYYS+TQkb7PbkF4NZWRh68cG3uBkxM/9qjkJuvNXefjkj8SYeej4sQY4+NxYyuXmxp5lG/V2ECwaiLeukDKoUoqiRxM8Sdj4zSqha5+7W/LG/P2/QCvBIUSEA2d6FEFdhW6qb/yNMqI/NGtvPfsI7VUUA==;31:1hePXLAe18CWizY5hCmI/5ikJgEkKnLDhj9eFIu3aPedh6nnhRVeRXxcTZ2C7i1cw3mcsJuiCwRZXFbs6JRE7Urz7FvTjazcboz4e1vsIvehQYGPVHuCqr7rQXKFxoFiahpyux6L9MzoxNuGtT9NNKW2mPvSIAprxZioC+bc89lmYvUck0gNpKOIBwgP/lfMcv4/6YJIQu5LoI87Z2pTtXsymvu2572s9LpFhKI+rk4= X-MS-TrafficTypeDiagnostic: BY2PR12MB0145: X-Microsoft-Exchange-Diagnostics: 1;BY2PR12MB0145;20:EkpQ0ytS2+b/K2ukfZB4ttjKA0DoKRGcMxCeW/8txRx76MXbOrkdI1VtxoYncyh1zuSt7Q1TKRevU5kg17b01wxCEMU91KSXrMaN4UrYnL0tO5qCVIh6Jf+LacG6Dv6vNxh0B32/GbkybD0SnkVhr4Gm4GJBGiq+XWQEEBT/IWJ39ese7GkTM10AbSLysrSVr3HzGIRNH+IevQhs7YDo8VTpExTnEXDgZdiRAq2FsVWroVjaxRvC1i5nZIUPFaoxtsmWY7n46sEmnaNZ4yrNx5l8YLk8c2sYJS1hmsO6B69z6MnqBz9GyO2McSYN/7Tp9OmlqUJXK16aihyUAi/xDTLkY8XE6c5FQvttm0QzyZWXHIJdQThhrgjc8vlvuwqe5mgUkOjtYCJHxYJYXNgEmkt32vE3kV/loQs4R0nnY0lz+qkEeD4EafYgoYkMhfOZTaNTrFrElNgQxD1YQplbr6qRqi0i1U1e3mNPEIGICIH+ZscsnirgUnYQULupeX51;4:dI7Db3sICx4LNVYyDDgWZxBIhP7l/0gxwdAFLr4vNwBketVZFnbOiBu+y7AC8IX6iCA9TtPjgzQlnLf3kWMkfqdJe8NkgE8nSZ01XeiPMAKt7Jqv8CdRAkgaklnuk83ehR0jpLH00yVC/3Sw5lJkvq5pqU1jIuUVxRROhPiR2BGNRQtWt840cZHop947OxFxOekvkrpslFjouAlIAsf9Mnwk6wFTdddevxxu7cy+P76K5vIKbw+zdyY4KGu2uBbkvAv45vcBn2C3a4HDC+q4uEZYa8mqX1NWNqIoirLOxSmKYQZJ3MMJgXKKXHuPQk07Qk/T+ODhVXMEm/7Dv5SuDg== 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)(5005006)(8121501046)(10201501046)(93006095)(93001095)(3002001)(100000703101)(100105400095)(3231020)(6055026)(6041248)(20161123555025)(20161123560025)(20161123562025)(20161123564025)(20161123558100)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:BY2PR12MB0145;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:BY2PR12MB0145; X-Forefront-PRVS: 0478C23FE0 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(39860400002)(346002)(376002)(199003)(189002)(23676003)(25786009)(2950100002)(4326008)(36756003)(8936002)(81156014)(81166006)(8676002)(33646002)(2906002)(68736007)(2870700001)(6116002)(86362001)(3846002)(54906003)(97736004)(1076002)(53936002)(50226002)(316002)(47776003)(50986999)(53416004)(66066001)(76176999)(50466002)(478600001)(101416001)(6486002)(105586002)(5660300001)(6666003)(189998001)(106356001)(7416002)(7736002)(305945005)(16526018);DIR:OUT;SFP:1101;SCL:1;SRVR:BY2PR12MB0145;H:wsp141597wss.amd.com;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtCWTJQUjEyTUIwMTQ1OzIzOmdBVU1OZ1V4ZDh3Nm9TbFZobjFIdmVyVk1R?= =?utf-8?B?OEcrbXZHMXRqNzRucGxha0sxbzdwRGZwMzN1V3d0SmJoam9OSVhibUJQZEZU?= =?utf-8?B?V3NoSVVmS2oyT0RUTTJ4U2Z6ZXVwRGs3MjVrTVp4RlI1amljRGRnVWlNUHVJ?= =?utf-8?B?TStycjQ4QUdWZGpsSkNsWGw0MVBidGtnc284QjIyZUJwaG5leXlZZGdXaWV1?= =?utf-8?B?Y2FsUGtEMGxGdnFXdm9rOTVmdFk5VVQ5eFROd25ZamJOTC9HL2NIbCthMk9q?= =?utf-8?B?TG1DSm1pUmJFNmtsWUNUMHl6ZXBmLzgwUklRcGtMRERsKzdvekFGNjdKSGhy?= =?utf-8?B?d1p4dEFvR21mdEtjeEZWcjZGR0o5amYwcEJ3SGhoSno4Qm9UWlp3bnp5akdq?= =?utf-8?B?SnovSXYyekMyaVd1Zmt3SVlPYkJ6b1luTTVZT09MOW9vMm1VTlFndHYwVlhP?= =?utf-8?B?SnRYMzBmMXlNMlhlVzRwSzB4T3d3QllRZmFoUitFZHpPejhPSnZsZWJqYmth?= =?utf-8?B?cTg3d3Q3NFB1WnRrRzlCMlI3a1A5R1VzUVN5ZThaMjk5QkIya1ZYUTVxWVUz?= =?utf-8?B?TVNIejRRSnh2STJ2T01mQWZMQ1hxOE00dGhvMlZZUERLQkwzY3NUd014ZUQy?= =?utf-8?B?OVdRdDJmTHN4c3lvR1pyRmZQNWkrUlVIb2h4enBsRXlteGYwbkZJZU9LSTFu?= =?utf-8?B?M2p5ZnNzZjlGZmNJWWgzY0ZPZ3Awd1E0VTcxMTJYSlY5N05YWEdwZGd5TWNh?= =?utf-8?B?QllqajJ2STRNZXpxZEw0YThleWQ4NUQ5QWZBTlYvMVI3VTREb09aU3BvTGlw?= =?utf-8?B?NXVmU25aajNldzRtWG9MUFoyY2h0cUw1YW5EYTZ2d0lEYXVxaTEvOXRQZGtG?= =?utf-8?B?bFFTSHpIaGVLVVZhU25STklJYS9BaiszM0RXZXFwdlBPTUF0cXppdUlIeGhv?= =?utf-8?B?dEdtTHQwR081Y1UxZkpoemlaeWZOVVFDUUlTNjQ0MWVUeGhVTWZQUGh0andx?= =?utf-8?B?UWszUENqTXc0cEFuSU0rNDhzM29kNmlTektiWENpRnFXU1ArcnNISnlCcHY4?= =?utf-8?B?NWNLUzFKaGxOYzJSSWR3ZlFVOUNsRXptaTY1dk5Xa28zOWxlRTd2RndNdHhI?= =?utf-8?B?MVlTaG5pQ1FSL1pON1lOdFJKTTE2dnVxbEQrQkQwTkpUMkh1cXhhS3M5b3FX?= =?utf-8?B?TzB0SWV6bjN3WVU2NHRMVDlPSC9EdTNxS1RFSnVNR3ZCVWFFVkt0dmRIN1pj?= =?utf-8?B?ZnBHblloVzNUSXB4SmwyKzVXd3JaL0lORzhmRzBXL1YrZUNnZG10NFovRWpo?= =?utf-8?B?WmZLVnNVdWxNR2kzOWN6YUt5WStRengrMjNhRkppSlM2RHdUQlVUWjllUW91?= =?utf-8?B?dk5OS2hvRzVrL0NNUHBSQkg3UzgrYlNESzdvWjUwYUhkMnhrNFcwK3ppUUNB?= =?utf-8?Q?co7N46Ciq/qqHbFFFPtLebzRI8G?= X-Microsoft-Exchange-Diagnostics: 1;BY2PR12MB0145;6:w/Eqw100jTrsO99UQUpSZdJGvK248FcOGqEijso9O3xbykhgpDCKPwWH2NJ9FFnDnyzLjjeNGYZW7xQBHyx1O8usYkh3G4CX1xvt//8G5VhNPHNJyZCVCDTC9zoVQahpYRXou6cjN2f69g7eKTz8weMgi8NJq8sG6g3bI+yUw+fe2Ry6QfT0ATYoz7VzzaPlP+SvU8TcifgfpBha7MYPneNKOHGhjnRea0cYrjWlWqu2NNoMINEXALjZDkNrKUuTXsWTu6z9xF8mNgptPePk2Yrq6mjekuKH0fW+M1SoHvmEEcGvSegrs3ioF0J1Vv1V68w4AzoyGgDlIra1+aKPpFuG4gUObNSlz6ToK2C/584=;5:DdiD61tNDgXhoZrvlzTU9F72kjOgi+hDSNOlqaiwp7QLDUltT6f/AbtiIqvVd5eRl3gV/tmn7yD80NZd9eMorgtH6MKeoj08bHdDD7SeREx1iEzxNrfAmU3GC0pISrPuCeY1mocOTflG1gPhawPPFlVw35YheYf98Lap9ai9FLY=;24:dwUyudufh1El+FmdHi5bD6ObGYUS+90wYU74PKvob8AXHLbLIv3n/fQu+50ECGBcViB4O02Ploa/eN0g3fqAjJGWhd+Ih3UzH3tIf3fNPTc=;7:2cSbQElATZp6RvYSUOKK21+yVj8OwhNYCPvyy/P9H4QUXxvZCWUNac0SW5ilinWLWinAoVme/CKLCiKB14RTaJEA9LEGxX4eFKi8AGTdNpy9UYx+9kslenSdkN17qPV4BPilN849m7GkYAmTJJdithS7sdB3dr41imdOpAj+gJrYKhHqzNIydKf+J5bA4jYo3YgB6l6xiJrbaODLlvuU7NrP2grUidnGzi98ntkMQgf/Ls2lGwr5zF/XRFMFPRrI SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;BY2PR12MB0145;20:pSnii3h3Wb0du+M6u2UBdcD1N2GYNB95wtAD1S26Ql90qA3jiCjthvZKpxdfsLUV5tzqvoh50n7JoK+I/ToZ1M+BRHDvBB8MJVg7ZaERX8cwcw2LAmSb7DQgvwCxOkmGOTjb0Z0If+df8ROf9MxgOIr5TvcdkbCUnKQZaBUu/vdL2oVNs+X/cibb8e/UGRMO/oBqi+IB1rdCLEczDmKHPbfX3MiTdPwzktoRVZqAd2xNiu0HIvWJwRmFnp5Wg1tC X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Nov 2017 21:17:40.7527 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 7ea4b943-87f0-49b0-a9ff-08d5216dfcb7 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR12MB0145 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 | 157 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 65ef2a72b8e8..adf4d80caee4 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -6032,6 +6032,160 @@ 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 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; @@ -6064,6 +6218,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