From patchwork Mon Aug 22 23:28:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brijesh Singh X-Patchwork-Id: 9294743 X-Patchwork-Delegate: herbert@gondor.apana.org.au Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id B8BA2608A7 for ; Mon, 22 Aug 2016 23:44:30 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AAC2428B31 for ; Mon, 22 Aug 2016 23:44:30 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9F0D728B39; Mon, 22 Aug 2016 23:44:30 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1DA9A28B33 for ; Mon, 22 Aug 2016 23:44:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932807AbcHVXoG (ORCPT ); Mon, 22 Aug 2016 19:44:06 -0400 Received: from mail-cys01nam02on0055.outbound.protection.outlook.com ([104.47.37.55]:45504 "EHLO NAM02-CY1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S932520AbcHVXoB (ORCPT ); Mon, 22 Aug 2016 19:44:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amdcloud.onmicrosoft.com; s=selector1-amd-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=HYPQIXB4U4aHYsp27ESDsy8NBuJ+bVEqDlk5iODw6k8=; b=dmy9A3+DSMKqTrk3N7QMawTHFCBbRggBzdX7IbUrNlvRARRy3nVYRWRuUEviJYIJE9fytDPyzr7idazkquD1zg6CUiiNedMe5G9PL6uoIcPE47yBJnNe1rhah0QWauIYkeOnVhd1Box6uX+eLQ2zvbYyqagB8YNVyA8k4U/s2VM= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; Received: from [127.0.1.1] (165.204.77.1) by CY1PR12MB0666.namprd12.prod.outlook.com (10.163.238.151) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.557.21; Mon, 22 Aug 2016 23:28:33 +0000 Subject: [RFC PATCH v1 22/28] KVM: SVM: add SEV launch start command From: Brijesh Singh To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , Date: Mon, 22 Aug 2016 19:28:28 -0400 Message-ID: <147190850830.9523.15876380749386321765.stgit@brijesh-build-machine> In-Reply-To: <147190820782.9523.4967724730957229273.stgit@brijesh-build-machine> References: <147190820782.9523.4967724730957229273.stgit@brijesh-build-machine> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: YQXPR01CA0066.CANPRD01.PROD.OUTLOOK.COM (10.165.103.34) To CY1PR12MB0666.namprd12.prod.outlook.com (10.163.238.151) X-MS-Office365-Filtering-Correlation-Id: cf142b7a-7ed5-45e0-967d-08d3cae40b7f X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0666; 2:V+HugjGvGmr/GysmQGor7ti863E5jQBV5k/CBTYaflw7/epd6sX0KDEH2ujPG2DJ7rRHy6J8IwrlAIOGvF050ZDQJydPvWicqa9KHJGD0UdUDjpkKyD7Bpox3aiR7U8AAIlq3DGI7PlLCvd3rBdXfU0s/U5hwCpkh1qalVOPFcTKHh3F035cBVi6SXLjpNpK; 3:zhSt6XYcNPCPjuRVQrlb6QHzCg2wA3UgyzDTbPQ7mjRlM2G5+F5WBzfZTNrodrO6rFhroI3nRITG0Ez9uVC0fhK5jGcVotOkGPO75s9F8rCx77n78c9bbXknNMq/7E6i X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:CY1PR12MB0666; X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0666; 25:zuBy0Azjhwo+yO7yxo/cEu/QoCZQI2QOi2RHC193GaLiQaY+6h9tuSsBo1gK4IBZB71ATZu42l7oXGPIjebs015GlAgEg4lhc6WRRwNRmUW+CJY8LuqBIlFCK+kLPPhLKHtEzCuHPqLl10yFXOiOJ3t31As8oQZrARn0K+VhTxbYCYoQs+QOvFezp1wQFvfuMD0WNTMjDBHS2Y6psmLPRyGP/rchcbc0TpfC4OnwdoOW1j1qQagzOXugWXSjJUtEMWU6S6vHYAFnBitMnbhM5EOby3PVOesWdg9OMZ2U8rF7xqzGY7uNyU4F/wcJ6+VtVw9bFQpDceyoUR5syfPMh36ji30JU1yy/3NPKumZZIJ9HJE1oG2f7EbckkTvx1PLD42hFuqGgJh534hK/Ir89H9DP1Xg5faZ26OCUgbzrxbvocLSm8N5C2avrSZeSzhtXFzlLwE72FGJ9UwsiFhGK7m8wFSaGndu0IX0xZhjVLcOZfG7IfQu+2cL+V6YPcvf2YmaeTJbeQk3Xa4ypLZ+uxYyABVTezgMifxI3Ti94p1/mmGICyrb3M9MXowNDR8gKrqWE1zdExp/zHbj7bBFVPrCgXq/wwERjXKiH2C87HCoSI+Tqh8tJX8Y9C7Ak83U/VmSatI1N9QM28n+JnYVDPbfZvdIcyTjdGQny6Nr7N5ypi+XVzXcttjjlMRZ/QTTtbiaIIruDEXwJJee/CFG0n8LVdKdxB1ybQHakOkTLIriLRtjMxxYMsaGstmmyKo8TzRLJWpm3Ybew/KeRlMRJYcvNLE9O7FSOFA8u7mEPa8g1ClImGXKlM4jm2k7pfg2 X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0666; 31:yzDwLY3h1eiCDnpU2Rra+lzL0jVvRdEHJcP1ukcNJaODsZJyluJHvwWv7kPQD0htwSMGPKpNPI75RlCb5FmkzkTcIiv3EU27LUy+vJauYworeIjQ9P6KkypAyDXIf/b/me5OZQIa3ML6kSyORYeIDZGmCL/Kap+AbPm5sxOcjEB+ff1V8S3kg0TnEQcp3pbXBEfuCHdk24tjUpA1dzDfVHYD0cFAjJzzOkL+Q5aiLHw=; 20:RJAlQgjbeKTwxnOUetcX4tUn8CAfOoxLwus+q3G8nSwu+gEWnCPLa/gK8hKCunCL2cyqjp5+op63CqRIZIT1OP4sREZCIKgf85W58PNq6pAMSW9YEijixoah1EdO0ovV3O3lo3H5PyqREQZf5yI/hBeSWwo7yDRd5REAAIJZA98RH7119Z5fktoleZhLcuR640dxVwQa+FVlPbIPHT5CbdjnUZ85yLcXLtg76MSLjD/194T1XQVAyownw3pkLHNX0SSCR6783Uqcx0ES5wrKeQPU0bwnlLx3Obll/yTKKYt6K1/Oy9VAz9JX5sVU+Pn3ItdfgnDfSnLVci5fQ2I0eAM9pNb279prT3fVFqlbholJlcTi5p2sdlakLCb1o4rvqBvDdGLWKDkKclLfKCnHVlcmYvdTmDd+sIQYV4nww0lVwEi+tS8ElgnTH+63JHuK0KC3mqqeumQ5ltgjUwDQMNU2VX9ZowCsFaDpogZl4W57fPrDJTfmY9tijlu6Jr+d X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046)(6055026); SRVR:CY1PR12MB0666; BCL:0; PCL:0; RULEID:; SRVR:CY1PR12MB0666; X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0666; 4:61R/F7bAmARQurWIzIB2eEY/0UvpkRRyuNLFI49jwBd1NU3kdx/kPdC4bQhPoUP4FIOFglki1rzrtlc4nTuPX0F/HTBouN7IZNp6VOkS0KJPOg/SUXttD3580JpDDdKnxdJHHad5uLy7s+Aldl6hAaHlsTl9Jn9jF4UFuJk+kLdNueRSf8bIGdCudURGXuDsGhG8mUixHld5XroU9vIATJ1W1APqkjwbTVBXUdAzarugtj6N7RYG+l+ZC/ZOKb6csXQOoM0MF0zPt0kd1dhSS5saFxoynXBkX4AJ/91nchbjasLG2QlTj8GrxuTnwfyW+YEurMwmDxE8HwnK8O8Zo7TEkrqNqWMj2G3MS046nn4h8+082m9WiWGyljTres3+Iwl2xqYGf+bhEtauOo5aNjxCwWhIoizNlVG+qjTrMMFheir36gEgLEEQcBgbsw+S X-Forefront-PRVS: 00429279BA X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6049001)(6009001)(7916002)(199003)(189002)(107886002)(2906002)(77096005)(33646002)(2950100001)(230700001)(83506001)(7406005)(6116002)(103116003)(92566002)(15975445007)(106356001)(47776003)(586003)(3846002)(7416002)(81156014)(4001350100001)(189998001)(81166006)(8676002)(33716001)(97736004)(50466002)(50986999)(54356999)(76176999)(23676002)(7846002)(101416001)(5660300001)(86362001)(2201001)(7736002)(66066001)(305945005)(5001770100001)(229853001)(68736007)(105586002)(9686002)(19580395003)(19580405001)(42186005)(921003)(2101003)(1121003)(217873001)(83996005); DIR:OUT; SFP:1101; SCL:1; SRVR:CY1PR12MB0666; H:[127.0.1.1]; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtDWTFQUjEyTUIwNjY2OzIzOndrV3NHZmFyeUVoNU1SRFpzWDVmdE1JODR4?= =?utf-8?B?czd6eUJ1VUlLSDd0QnZGaWRwUDVNZUhvUzhITW4rK2Z1ei82NG90VTJ4blJm?= =?utf-8?B?K2puRmlkay9xbDZGcFF2R3pubXhBVUVlUlBzZUhEL3JnakczRmhQSGxkZUhW?= =?utf-8?B?bnRaSnlhQVpvektsQkdLeXdpc3hRelJ1b25Dd2toVEg0amdaOHVXOXFlcXJa?= =?utf-8?B?Z3lCdFp3UFNRY2gxZW53ZjFVRitSc0QyOE1XMUIzU0VzaVYyMzNYdXNNZ0xn?= =?utf-8?B?TTlCbGJKUm1hK3RKZ0UwRUNDcEFFSHVwVFp2QUIyWjVHVUZJb0JlNDlEWEVW?= =?utf-8?B?V1hJYTA2NkV0Wm5GanFMelBoNWZmcE9vT3h4aENmeUlKc29OcExVajIzOEI4?= =?utf-8?B?MkhxZkFVUlpHSytRSHI5RFBSbUhlRGNycFZlNjRaS1YrUVQzRUV0Y21EWmdD?= =?utf-8?B?WFowbGlrcFRZNVp4bVVJdmc0R0NYSnNuWVE4MEdHQTdIUjF1UDdoZFkzZERk?= =?utf-8?B?VnpJUmlES2RzK0lpZ0hqL2syc0tiS0t5ZFFGMGxLTmIyVlFCUldNQW03RVpR?= =?utf-8?B?MzBMU1hzaVJ0WFJOMkV2MXh1VE51TnVyK0liSlV0a0VhSGMxNGtZbXhRUzRB?= =?utf-8?B?cUxoV1VxUVNvVVNlWWpKVGJ4ZlhEVk9ZMWIyWHQ3ZDc5cS83OXRQSVhFd05j?= =?utf-8?B?a2lPTEQrclE2Wis5NTlxSnVjUUhMYXpKZ0Y0R1hHc0JEUUxJTDNyV3J3OFpS?= =?utf-8?B?Szdjbkg1aEk5MWIxdDM3cHJJM0x6ZDAyTjJ1aW5idVl1RWY5NW1kdEpndzNz?= =?utf-8?B?bnlVV3RKRTJUS2NGZ0lldk9vcDdBVTh4eHBha0JuQVJVdTZjUEVwOXhWWndj?= =?utf-8?B?cTlMNC8vd29LU01yS0RnQWtMZHl1ck9COUYyTzJlNEpTNDFpbHJEcTBxNTRo?= =?utf-8?B?TXRPODBDcy9yK0Rla2tuQkpjMFVzeGxFZ0lRU1JMa2NQeXU5Y1ZPTWcvWGtp?= =?utf-8?B?ZkMyK0F0V3ZWU0MvSG0yNE9SNFo4MXROZDV2OW5KY2w2OHE4Umd4RUZQZnph?= =?utf-8?B?cTczQlJrcEFBT1VUUlhzV0Q0ODNLTXcxOGhSSUQyZGpONGE0cFpvKzZHazBT?= =?utf-8?B?Nnp4YlZVZXJLbnhTVlp2cmRhOXdBWTZQVGhyOGJvQjA2a1cwckpiaXowNTdx?= =?utf-8?B?S1dmRmhuZnZYQlR6bFNXUjJ0d2s4MzNEMTlPb3hvRW9nYTVBbjd2NU1Xd3N6?= =?utf-8?B?NXlOOVBpazNzSkd4ODk1ay9PenprdFZiV00vSzJNK1pmaE1YNWVOU1FCckVP?= =?utf-8?B?b1ErTDljNXEvTUVkOGpzUGRQaFJRWlA2bVN6bi9hWWdKNXlzVmZ0YWcydEsx?= =?utf-8?B?OStLcU1HdG1jMUR2SkFOU0dEUnBtbUVva3hLWUpqeG9hYWlXL2hXaTl4VUN1?= =?utf-8?B?NElzVzJJMWtiMXB1ZUpMZHozM2x1N2tmWFBPR0s5RnVveGJUbE5qNng0TmNK?= =?utf-8?B?N0lLVUd2OHNQcTJDNnZuaVdaMWdNTlEzS0RUU1FkRlpuZTBrUDhLR2p6VGRp?= =?utf-8?B?Um9yeGowQ3FhL2x0dmFzZTAycDNXc3FoSE5TdGZiT3ZjaUtqWkI1OHZZSHdR?= =?utf-8?B?bmpCMDhTN2lRSTYzS1I1bFQ5M1FnaldsMEc5aXpnaG8wZDFrSzJMMmFIeW04?= =?utf-8?B?eGhCNXVJaGRJNGRBMGFwTUltS1lEMktxeW53Qnl4aDc0THRFdmpsWXFXcUhP?= =?utf-8?B?bmhZVGphSFFaUG9JN0NnalE3MkdsYzI1SWhZNVhnZzJmMWFwdmdsNW84MUN5?= =?utf-8?B?eVQ0T3AzVVk4WmxWRzlXYnFaWWRjTmxUVXl1ZUt2RWZRSjk2YzA4THJHUjFC?= =?utf-8?Q?t/PRcg1eo18=3D?= X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0666; 6:H3ci6lKi+r8Hnfn662T1Dfr7mgvg3IN8weskE3V1zepDQIfeJ3YpYOevLWRz+xmMvOBORfkkapZEpx3I23Lg6j22guqiKZWJhbwPCpR6/FcRmGs1lqsdWieyxxpZ0FrWLXz5Ec2EnZIEOUzP6cLaIW9GfbhksFUNsQmPNWx6chKHTe1ymNWOamJYDQzQX8mmTTSCZJB9d7cjeFOTRp31UDTlEDcsqYfeDx4Uw2NYEzBVxnuP7xCvfPoK/OyxlidgaVhskGI+cRdHXexYatNIvK+NbMLEURkNGOGUxOeAroypgK+Om2lRDYYrjgylkPeiEvnd98eg/coar9QAa36/qA==; 5:UGy7I8owwA4xMRbAOu9WMBCNq+AGjo+fVGu0RAfwHl96GjuJ8F528cXYlODIlPrLuPovFdLfKAZd/ASGrQj1/jdAJY6VqpiedXgQKskOtr5oAXKzT3a+dEnlJeES4eCd9LWqPTM9KIGqLXEwpVLadw==; 24:2qho6u9Z1zrzI+8UAJRKhYVYFtDo/rBz+OPviA0lE4ExaKSB+vk3b8/loFpiTu6ijocyu05UfpbTM7uP1k0jljev7RZBoYcI3GX7hGZZj+8=; 7:SLEurYoSPwUQCx6QKECuwjDsZAU1U8e23rZgaVMHifrZyG6RIn2UQbMcaGoxU7X9la06VjhNRxsMRGMje760fW5FFISoE/QraUANQbZHgyoPd2LpQuxfdl6dN3JA/f7xkgnf1Hv9dR/yOQUx2rQdOsWnAozP4RjrlI96J71zp1d4CAve9Yrkro7mj5kqKgrGSDeF6fOhzttmcHIeSr44s9V04G70C1EX67MHWpKeZsawBi0vqXg3s6q5GPdIRbCQ SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; CY1PR12MB0666; 20:5aopaETOhpTqMostT8S/+V3RTWjOYkDcEqwP+9ugbKOEauGqYVmHmZeEdmsHDZf9RNXMUnR15OqJO68Bj6PPzdVI+pthgoEgeYDpOnsD8/7Ief9THpKK+af3Aj8/2gxO3JB628H5yT3yHrRTSR1mU3raQsZM4coLukyVSq1bhtUueddoOJxmxW6cIYoo21S4cYY87JOV9iHHikPNZxAHovjst5589zZuxKAM2VI7gVYf220atm3Bh+oD8RFDtmqI X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 22 Aug 2016 23:28:33.4185 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR12MB0666 Sender: linux-crypto-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-crypto@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The command initate the process to launch this guest into SEV-enabled mode. For more information on command structure see [1], section 6.1 [1] http://support.amd.com/TechDocs/55766_SEV-KM%20API_Spec.pdf Signed-off-by: Brijesh Singh --- arch/x86/kvm/svm.c | 212 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 209 insertions(+), 3 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-crypto" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index dcee635..0b6da4a 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -265,6 +265,9 @@ static unsigned long *sev_asid_bitmap; static int sev_asid_new(void); static void sev_asid_free(int asid); +static void sev_deactivate_handle(unsigned int handle); +static void sev_decommission_handle(unsigned int handle); +static int sev_activate_asid(unsigned int handle, int asid, int *psp_ret); static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0); static void svm_flush_tlb(struct kvm_vcpu *vcpu); @@ -1645,9 +1648,18 @@ static void sev_uninit_vcpu(struct vcpu_svm *svm) svm_sev_unref(); - for_each_possible_cpu(cpu) { - sd = per_cpu(svm_data, cpu); - sd->sev_vmcb[asid] = NULL; + /* when reference count reaches to zero then free SEV asid and + * deactivate psp handle + */ + if (!svm_sev_ref_count()) { + sev_deactivate_handle(svm_sev_handle()); + sev_decommission_handle(svm_sev_handle()); + sev_asid_free(svm_sev_asid()); + + for_each_possible_cpu(cpu) { + sd = per_cpu(svm_data, cpu); + sd->sev_vmcb[asid] = NULL; + } } } @@ -5196,6 +5208,198 @@ static void sev_asid_free(int asid) clear_bit(asid, sev_asid_bitmap); } +static void sev_decommission_handle(unsigned int handle) +{ + int ret, psp_ret; + struct psp_data_decommission *decommission; + + decommission = kzalloc(sizeof(*decommission), GFP_KERNEL); + if (!decommission) + return; + + decommission->hdr.buffer_len = sizeof(*decommission); + decommission->handle = handle; + ret = psp_guest_decommission(decommission, &psp_ret); + if (ret) + printk(KERN_ERR "SEV: DECOMISSION ret=%d (%#010x)\n", + ret, psp_ret); + + kfree(decommission); +} + +static void sev_deactivate_handle(unsigned int handle) +{ + int ret, psp_ret; + struct psp_data_deactivate *deactivate; + + deactivate = kzalloc(sizeof(*deactivate), GFP_KERNEL); + if (!deactivate) + return; + + deactivate->hdr.buffer_len = sizeof(*deactivate); + deactivate->handle = handle; + ret = psp_guest_deactivate(deactivate, &psp_ret); + if (ret) { + printk(KERN_ERR "SEV: DEACTIVATE ret=%d (%#010x)\n", + ret, psp_ret); + goto buffer_free; + } + + wbinvd_on_all_cpus(); + + ret = psp_guest_df_flush(&psp_ret); + if (ret) + printk(KERN_ERR "SEV: DF_FLUSH ret=%d (%#010x)\n", + ret, psp_ret); + +buffer_free: + kfree(deactivate); +} + +static int sev_activate_asid(unsigned int handle, int asid, int *psp_ret) +{ + int ret; + struct psp_data_activate *activate; + + wbinvd_on_all_cpus(); + + ret = psp_guest_df_flush(psp_ret); + if (ret) { + printk(KERN_ERR "SEV: DF_FLUSH ret=%d (%#010x)\n", + ret, *psp_ret); + return ret; + } + + activate = kzalloc(sizeof(*activate), GFP_KERNEL); + if (!activate) + return -ENOMEM; + + activate->hdr.buffer_len = sizeof(*activate); + activate->handle = handle; + activate->asid = asid; + ret = psp_guest_activate(activate, psp_ret); + if (ret) + printk(KERN_ERR "SEV: ACTIVATE ret=%d (%#010x)\n", + ret, *psp_ret); + kfree(activate); + return ret; +} + +static int sev_pre_start(struct kvm *kvm, int *asid) +{ + int ret; + + /* If guest has active psp handle then deactivate before calling + * launch start. + */ + if (kvm_sev_guest()) { + sev_deactivate_handle(kvm_sev_handle()); + sev_decommission_handle(kvm_sev_handle()); + *asid = kvm->arch.sev_info.asid; /* reuse the asid */ + ret = 0; + } else { + /* Allocate new asid for this launch */ + ret = sev_asid_new(); + if (ret < 0) { + printk(KERN_ERR "SEV: failed to allocate asid\n"); + return ret; + } + *asid = ret; + ret = 0; + } + + return ret; +} + +static int sev_post_start(struct kvm *kvm, int asid, int handle, int *psp_ret) +{ + int ret; + + /* activate asid */ + ret = sev_activate_asid(handle, asid, psp_ret); + if (ret) + return ret; + + kvm->arch.sev_info.handle = handle; + kvm->arch.sev_info.asid = asid; + + return 0; +} + +static int sev_launch_start(struct kvm *kvm, + struct kvm_sev_launch_start __user *arg, + int *psp_ret) +{ + int ret, asid; + struct kvm_sev_launch_start params; + struct psp_data_launch_start *start; + + /* Get parameter from the user */ + if (copy_from_user(¶ms, arg, sizeof(*arg))) + return -EFAULT; + + start = kzalloc(sizeof(*start), GFP_KERNEL); + if (!start) + return -ENOMEM; + + ret = sev_pre_start(kvm, &asid); + if (ret) + goto err_1; + + start->hdr.buffer_len = sizeof(*start); + start->flags = params.flags; + start->policy = params.policy; + start->handle = params.handle; + memcpy(start->nonce, ¶ms.nonce, sizeof(start->nonce)); + memcpy(start->dh_pub_qx, ¶ms.dh_pub_qx, sizeof(start->dh_pub_qx)); + memcpy(start->dh_pub_qy, ¶ms.dh_pub_qy, sizeof(start->dh_pub_qy)); + + /* launch start */ + ret = psp_guest_launch_start(start, psp_ret); + if (ret) { + printk(KERN_ERR "SEV: LAUNCH_START ret=%d (%#010x)\n", + ret, *psp_ret); + goto err_2; + } + + ret = sev_post_start(kvm, asid, start->handle, psp_ret); + if (ret) + goto err_2; + + kfree(start); + return 0; + +err_2: + sev_asid_free(asid); +err_1: + kfree(start); + return ret; +} + +static int amd_sev_issue_cmd(struct kvm *kvm, + struct kvm_sev_issue_cmd __user *user_data) +{ + int r = -ENOTTY; + struct kvm_sev_issue_cmd arg; + + if (copy_from_user(&arg, user_data, sizeof(struct kvm_sev_issue_cmd))) + return -EFAULT; + + switch (arg.cmd) { + case KVM_SEV_LAUNCH_START: { + r = sev_launch_start(kvm, (void *)arg.opaque, + &arg.ret_code); + break; + } + default: + break; + } + + if (copy_to_user(user_data, &arg, sizeof(struct kvm_sev_issue_cmd))) + r = -EFAULT; + return r; +} + static struct kvm_x86_ops svm_x86_ops __ro_after_init = { .cpu_has_kvm_support = has_svm, .disabled_by_bios = is_disabled, @@ -5313,6 +5517,8 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { .pmu_ops = &amd_pmu_ops, .deliver_posted_interrupt = svm_deliver_avic_intr, + + .sev_issue_cmd = amd_sev_issue_cmd, }; static int __init svm_init(void)