From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933620AbdKAVRf (ORCPT ); Wed, 1 Nov 2017 17:17:35 -0400 Received: from mail-bn3nam01on0059.outbound.protection.outlook.com ([104.47.33.59]:44352 "EHLO NAM01-BN3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S933570AbdKAVRX (ORCPT ); Wed, 1 Nov 2017 17:17:23 -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 27/38] KVM: SVM: Add support for KVM_SEV_LAUNCH_START command Date: Wed, 1 Nov 2017 16:16:12 -0500 Message-Id: <20171101211623.71496-28-brijesh.singh@amd.com> X-Mailer: git-send-email 2.9.5 In-Reply-To: <20171101211623.71496-1-brijesh.singh@amd.com> References: <20171101211623.71496-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: DM5PR06CA0064.namprd06.prod.outlook.com (2603:10b6:3:37::26) To DM2PR12MB0155.namprd12.prod.outlook.com (2a01:111:e400:50ce::18) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 54ca0f5c-1a4e-401e-8e23-08d5216de0fd X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001)(48565401081)(4534020)(4602075)(2017052603199);SRVR:DM2PR12MB0155; X-Microsoft-Exchange-Diagnostics: 1;DM2PR12MB0155;3:NaCCruvTy7w5z6OMni0ktZ+MilY+qFG6PDkOea6ZTf8+kH6bPxEE8jueWEa3PB9XlZTkY/les6UNpaUi37vy7HE4XvhOkyY4jDvxYULICF4vHlwYhSMDSjVXttJ/MeVcH0suxW3Zn5o/bPC6nSxomG5F6mKGkF7GDdz+s78ofXQ0cIgoCKBBBmTkEMQkCx+cdCc35LOCI1qXT/ic+RR3a6NaowAX4Qma6UQLmk7G8P5DLBlxlVawGkDJ0vUeghjd;25:lJE6th4BAJ1Poh6XU1ShT+FH7wRpNSTlSAX1CSSVh54niukUmBHRQwkQFyl1OmeLw05OzUwYJwDih/1fr+HE9tgWZ0rzvtIiMtqYjungcOmH6qRZzkQgphiLbjjcibxjaYjzL1sjj3z8tCL+ftoMCTBfWu2I7Dfpq2/6qgQ1AB24X7w1qDviqGYsjBTsILoABEaSID2qcTjZ1Wqk5QpChmiAlDRFAh7X5gGWyGPxqInyQcIIYiR1eO4GeBVGw67B2Azkk+tLKNMre2Rff6wyjGzAkgoUALkGPUD6bt0BXFg2CXePPDC/UpjiadOIOUgZdi1h6T61eivgA8IwMaj5NA==;31:FyWIX0gOFZSoga+UwkByQSIrhGE5oSOnORb9vuADhJt8hqHqtjAnR+C1tf3N767NKp8SAhHHJLOL0fRgdCTHsTelkhAZZL10UVjP6O7a+a4xb+PqorD9QWgH2p9fVuKlbV1VoFK9MElcwsKQrlNfOK/5fYVqdwtPY+xGUSxp16JUhWdDcre6yrrOS47a3zDgupmEc6PRDqd8YWxt/Y88GswztSoogylAFK/Gy0vBh9E= X-MS-TrafficTypeDiagnostic: DM2PR12MB0155: X-Microsoft-Exchange-Diagnostics: 1;DM2PR12MB0155;20:0aJbf3pau8PVH4/gKlP7JI8GiB2T5GW9Tb//mUMw5cdBoH6G1lebay8XktkS+zzuLiJc327rQyjNiYCjwkEGJ3/INgBbslJ5eUK2qA/GQTUYCjbwc6yBLm++HNTww0BT61eNbuFEBxf1+4p8/g1lN5UWuKlDiDfecwaDWecZ4XiKx1UMBVYoPVA1W9KMK5XH0L4w6MFWkEqLv9BZAkA9IWtoJse3ECM1yMlnAnncLeX3KdbR+t5T4dEd4ZStC8g3dhwyXyBuRTHoIJ1PaE3rk2+SSE4Hl61qoWWrGApm+PbXt5I/m1ddmZByA3LXxKBufOhsRcLaE1X8Oz6tsRhaNVj5aMmCJrjF00YixZJj5Ei7ij9m+KhZzsUnMEpFiGCFBwzt+FQcqY4lKvG5zNQwFQ2G9AKpFiM2nJ3VwZZVgiJtSM+XWD76hFa4vf1W9LelQzziDUy9H4FKyHm9MrdQcX8KDqhrcoLyoCk8eCdeLX+VR2hrB29I3KMrKYXHLHhS;4:Yac8F14GUfc3f46JOEDU1wwBDPI5QwI665L6n9E7P0kCd+14WcVY2BA2RFFRGlRr+3nOVi7tVRm1zCsyBM8f/GoGA7REAF1rop8KY85KfaMvAGpsxKe3pw8kAdQJBHjRAhupPxUGnANLy7ApX1bBtRm4lrY7rypY4WWBMvCINC8NtZopBHHpph1tNeUxlnhlE1rQTL8a1EdjkHkqUWbzNhqw+WHRaDDYDYc2oVB/lkynaFOkDY6Mp7KK72/X/TfXW29mkWHSXlUyVN18vrts+kQgmJ/KX6dkvq+DTH88USxBD23tKIWwY8uGSQ0BiYmk+HJZr0IuzPgp3nBjaRurYg== 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)(100000703101)(100105400095)(3231020)(10201501046)(93006095)(93001095)(3002001)(6055026)(6041248)(20161123560025)(20161123555025)(20161123564025)(201703131423075)(201702281528075)(201703061421075)(201703061406153)(20161123562025)(20161123558100)(6072148)(201708071742011)(100000704101)(100105200095)(100000705101)(100105500095);SRVR:DM2PR12MB0155;BCL:0;PCL:0;RULEID:(100000800101)(100110000095)(100000801101)(100110300095)(100000802101)(100110100095)(100000803101)(100110400095)(100000804101)(100110200095)(100000805101)(100110500095);SRVR:DM2PR12MB0155; X-Forefront-PRVS: 0478C23FE0 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6009001)(39860400002)(376002)(346002)(189002)(199003)(1076002)(6116002)(97736004)(66066001)(50466002)(3846002)(25786009)(4326008)(54906003)(316002)(8676002)(47776003)(36756003)(23676003)(50986999)(478600001)(7416002)(81156014)(81166006)(105586002)(53416004)(53936002)(189998001)(106356001)(2906002)(16526018)(2870700001)(76176999)(33646002)(305945005)(7736002)(86362001)(5660300001)(6486002)(101416001)(50226002)(68736007)(8936002)(2950100002)(6666003);DIR:OUT;SFP:1101;SCL:1;SRVR:DM2PR12MB0155;H:wsp141597wss.amd.com;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtETTJQUjEyTUIwMTU1OzIzOlE2N1R5ZDlpdGNPbzlrcHdjRWtoNUZsUnZT?= =?utf-8?B?WTJNVmd6UlVMUFlCY2w5REE1SVpjcWszd3pwaUVZZllQSUxuN3FlU21sOXdL?= =?utf-8?B?WmI5NTJIZzFKbU16UEpLRmtXS2VNUStEdVh2QXdzKytwMjdpWW1pS1djUDdR?= =?utf-8?B?eDhRMmY4SDlOL1NDNHRrZE0yYzlxVFVyaVBmUnlOd2IwR0x6VDJIUXgybnpI?= =?utf-8?B?ZGJqekR5elVQN3VFcWRyU2tkOUh5R3hJZHZiNjRlczhXaTVibjFNYUdCZWdV?= =?utf-8?B?RTU5eXVIcFUwSkdoZCtNYXdkNTNIbVVVSk56bDZrckh2OWdiNWphRFlYaXNl?= =?utf-8?B?SGgvdmt2bjdMd2JyalBodm9zNGdrcUhMaVozT096Vnd4dHFsQWxCTGZTd0ho?= =?utf-8?B?bDMvWnEyNGgzS09vQ1Y3K2dnb2JOVTEyREVHZEc5ZGYreWZvTU1sTlMwbSty?= =?utf-8?B?Vkh1a3FwRkxNR29XU1ozcjlEaysyWFZEVlJtbjRPKy9YT3k5ekdvQTBIR1p1?= =?utf-8?B?QTRPNVQvSjBNbkljMlVsYVNsQ2ZJNlNsUUpjZjFiWVdoMG1pMFVNaEFxdEFR?= =?utf-8?B?TE4rNk9xZUFSSlE5RVhrY0pVWm84elRGUnlBZE9TcXUyUlRBR2JrQ1VDM3o3?= =?utf-8?B?UjRTMk9Ca1YrNVpuc0NnbTlCZTJMRlBKV3FtRFZSNURDOUVrZU5iQlhibHJN?= =?utf-8?B?OUdFSzZZTkkyZXJJdnczUjNoODdZN0c0Q3I1Rmlac2Z1a20xOWpvenQxS3Mr?= =?utf-8?B?NXdDelhINjlkdW9VOVFmVVlQdVNpT0VCeGMvaS9meUVYM0xrUWFTVHNvb04v?= =?utf-8?B?L0dJVStNakFudEVHV1JvZk1NYlRseGpJUERSVVpDSVRHbFVYSFhtdTJxOUhK?= =?utf-8?B?NExnM3NBYlVaMXQvQS8wRVB0K1dyc01leVF6NDY0aHZKYkl6WHpaMUFJNEZU?= =?utf-8?B?RlU5NWM0VTlUR2FlQlhCNWtIMkZDNURlRVR2TFFZM01KTnhlZ0xVb2tERWJS?= =?utf-8?B?QnlwcXlBTVlIeTlIZmY0YndkMFlaT3dRUmZnOFNWRFNKandXeDNyTzltazgv?= =?utf-8?B?dHJ0ZkNtMmJGV2VkTnBoQmdkTDJMNFlPbVNtK0RWZVE1dkF3UFRNSWdLRU82?= =?utf-8?B?Ry9QQXZaa3VNcDJrbmpWSjBDdG9CMDltbmRTRzdjZmp5UE5NbzRqOEJMcEtu?= =?utf-8?B?bWE3bXZUZHpSQ0ZkWHlLcUZtWWd3T3RNalRVWi9JVi9ybTAvd25pbFF3Sjgw?= =?utf-8?B?Q1FVODZ2QmF3YWxwcDRzK0hmcytETzlGZ0VjT2gyMHJBVzZ5UmVCWm5kWVZS?= =?utf-8?B?dDNCM2w3OFdhakxNWmoxRnNza1RNSFVQc2QxSlVTWTc3YlZ5ZVlIZWNOZTh2?= =?utf-8?B?dFQ1SHE1QTd5OGxLZ08yYXVqaGFWUmhLVnlsNEtwaTdqUGltY05DR3Q4Tlk1?= =?utf-8?Q?OnKluYypLPK5Ql69Dsdx60k94Tr?= X-Microsoft-Exchange-Diagnostics: 1;DM2PR12MB0155;6:FOxKwHJ+O1BqV0VYLyysx1ZXOp0Q0RfRZlfbehEHrJkKmoupvLD43zbpV49ftfBdbA/7zN5WqxMucN9wAVscxlrcwSuZ+7TgY6Z4nuC7ZDt/IMrKKHpobPyVcQFmHHgsSh6lbDfNTo/RE8QDnwYskfmyFfCJ6sielDHK2FZUeKmP+1KlSb+ZY5CiREW9+5RptIp9pFxJ3WzTO13ATywPaqkU9jSaYuxrZBfCKcXMRa98WGieBFYkh3ItwpFUbuAU+OGQfJGIR696ANE7dD+Y5H6mNaf8Og//BbKUtrpcQMbsNw6nKRHhbRImwYXJeuMxShRZODE8Xd34jp6XSaGFxBM74Xa9OQQsJqJvKNDrSdU=;5:QRV7SIpp/JoECoU2pblH7ChnAtzZsM37d/xJWgjqhefHSrxbL+3cGRwHwI2VkrLa1K2CJBXQ0b9IFYVYRbAt/VAT6mHQvlrIzrQ5w/qNI4ItXa5w6dnpt9hDMcRhZcVsYqsWtQHzoynU+FvfXO86pNSWJPgNz/FEnWcasGKqVJY=;24:e+M4aVfWF4lRQfA5lpSeYGntaW7Un+7yAFCRZXDOr6jWdKCQMJ5xXNvfCe+V/8pBX8gWmQdtw0qDoEzjB7ny/el/FmyBVfOi/Oal1vZCLSw=;7:pCnAOCGdZuM3Yqbtmw6810b16TgNIPBBffzyvK5Df/tE+71qbw06uZGQeDdro7PNwVZn8ibQo9R2ZtJHbdyBVUwzp77Ofrqtd4CryrvyBSozL5VQg5hWdoCCwy3WmrYd//tJundK34DoP9NyJ2xUu2bJMWqovi5guVjbEkwYStRRPkT9mdsE1tzv6J99l323rlCQjC+wNlvxiCvSzRnZ7Gh3PC32aMeaZnUD6keSLv8xt6LhHDwMcs62Yuxc0oYS SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;DM2PR12MB0155;20:rY2v6Kvl3OVG5lre+gxC4dD3ajI4bzdgAXAMy8Un5juX+Sz35vCMDg0uFGjRPqj4BYF7myjfuZiPLGNW5x+GfbWQOX0NEIo0bA0XK+XuW6DITmBU3H5p24P+o6ZIu0odEkD6KRJNlSRPJAunC8aHKZimgyrEAL43KnVuVnbLjBK+XERUm83oh0GWthhVWsdRO95rhPlbsnCK2zUrt993TO42no59DTgrfrOxSF3Jb16LMEa18A+pSv+8nCAN+Rfo X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Nov 2017 21:16:54.7814 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 54ca0f5c-1a4e-401e-8e23-08d5216de0fd X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM2PR12MB0155 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 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 Improvements-by: Borislav Petkov Signed-off-by: Brijesh Singh Reviewed-by: Borislav Petkov --- arch/x86/include/asm/kvm_host.h | 2 + arch/x86/kvm/svm.c | 153 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index b8837cff22ec..f2654486b9a6 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -750,6 +750,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 18af702f783a..56df6d64359b 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -1516,11 +1516,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); } @@ -5577,6 +5611,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; @@ -5594,6 +5744,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.9.5