From patchwork Tue Sep 13 14:47:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brijesh Singh X-Patchwork-Id: 669442 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3sYTtn4gTLz9sdm for ; Wed, 14 Sep 2016 02:01:21 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=amdcloud.onmicrosoft.com header.i=@amdcloud.onmicrosoft.com header.b=RAjCfe2a; dkim-atps=neutral Received: from localhost ([::1]:49822 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bjq99-0003hN-5a for incoming@patchwork.ozlabs.org; Tue, 13 Sep 2016 12:01:19 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:54596) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bjpW9-0003MC-Cj for qemu-devel@nongnu.org; Tue, 13 Sep 2016 11:21:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1bjpW4-0007rG-1E for qemu-devel@nongnu.org; Tue, 13 Sep 2016 11:21:00 -0400 Received: from mail-by2nam03on0085.outbound.protection.outlook.com ([104.47.42.85]:32183 helo=NAM03-BY2-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1bjpW3-0007pM-Ka for qemu-devel@nongnu.org; Tue, 13 Sep 2016 11:20:55 -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=kcnNo5YoevXY8+ynfpi5dnqPe8qPv7z7ewk1Trtr7g0=; b=RAjCfe2a6x8l0RYNqWO5pgHy62XnKlS/y8fheSLu4/KCMJU2nYTU9xTXh4I2Gb5fGumgLrqytATHVYIVZa+RwaOJ7Pn8VaRC22FmAMTJfBmxSNf6E4XD1jlPw+iySsWdntVbPw+Hq58nD38Gz1Ok1+Ws4psbJuPJe+UXvECSoy4= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; Received: from [127.0.1.1] (165.204.77.1) by SN1PR12MB0670.namprd12.prod.outlook.com (10.163.208.28) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA_P384) id 15.1.609.9; Tue, 13 Sep 2016 14:47:53 +0000 From: Brijesh Singh To: , , , , , , , , Date: Tue, 13 Sep 2016 10:47:47 -0400 Message-ID: <147377806784.11859.11149856529336910514.stgit@brijesh-build-machine> In-Reply-To: <147377800565.11859.4411044563640180545.stgit@brijesh-build-machine> References: <147377800565.11859.4411044563640180545.stgit@brijesh-build-machine> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: BY2PR1001CA0069.namprd10.prod.outlook.com (10.164.163.37) To SN1PR12MB0670.namprd12.prod.outlook.com (10.163.208.28) X-MS-Office365-Filtering-Correlation-Id: eaa11d9b-1170-41dd-b3e8-08d3dbe4f175 X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0670; 2:T0wYaIlXSVNMeIj8dvJyXQWhGhKz5c27iIl6ie+OQ2IIHxAKbSaETHD61//Ry4Y/RHo+g3KUS2F/1i69NayJDLU8kAVs1E8fGFKR4xsK/mh5iql3qkn8i6PIgHuFhS0XtbCB/jvc1Gh+yZe7Tj5kdsBL+G8bYRzPZcMjzeGAybUQfJNuaXWWlmnSgwxurV5k; 3:L6hvSnDVErwpWq/cnwxSP2GQopvdoFz69Rkc9df8cg3BPd3n/QSNUVzJcHljExuoikYJMHL61YOq+T1ynln6RYxi51hPJyYEUvinU9R6CCWsCQb6KHGudQ24+5ZQWVqU X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SN1PR12MB0670; X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0670; 25:IeH2Uy6OKfiyVTyNtv4AB3GuNnx2n/LqNspC5tjr4HWSnSJAsq1PDSnRG2xVEiz30c/5n2D9ANBYwYm9Naxjv/5ww8G6XxyqWJaCCD836RnTIkYpfxbRrgFJAw220HhFs6wSmeffiyxxyMU8f7vbEmIgizagJkLKxFDsbBLVw5QhjIODdPCHwI0cl7YVsTU95d8+Gj3GZX1Vux061J1L92swUeq8ZvVPPb1vxtdN/Gu4z7hjfKJFEzSw3My+4KKzpWTM7HRzqUihCf90me2GwXcHWVW6ncqWdlS62lhZWPofOjQtRFrhQi3Q50Uncwjmm2P2JerkUGf2ELJFhLO68hnTn4nL00VDTef+b/DLSl6rZ7Wte8/jnyvB/RY9bR7Ace6Ih4gS13WAOc+Ax6f9LMdmz+8iNwZ7b+wRrpJ5Y+nEHoXmACXKKZcvjMcGTQxfRJJa1IIlNl1F88tLZFOp5tM3fAlKZHILOzOBZkzhFPQ6DCg8UW8Cqn40ilxPziPIWc1GkWIcinRNWOwcCquFtcHeFHeUhnFz3vR/KacroN6tQwiqk3Jw75C7rPZNetxyq5mPWFZsnNoe2zyzu4q/JpUS7N0mZHv+inmXT5JMXlLNpW9yL5/mcYX15Z0L297qvgKbgS1ZDz0F8xIKQzcYa6DTc93Z5Eo3iD0xBb9YuBHBqW8DXUaXuPS+fggYZg51F3keqJP8QC7iFPbkGU1yqA==; 31:zdw0FNGdH9JWgrV8vxZqAzq61B0QLF3OAgA6yQlbtOWjeEPFkcCHNxqBbeTGE1XHAnLAVVUtDr+QClBI7aYeONDg8/6sxa4Kpo6cD83YO9XyKy5PIvecUcpyXuem7ks6o90UPr+Yp93DJBXCZU1aO2ICDTbX6dvXrQBcY4f14s/C67eYDnIBYqvEYrRlw5WO+em89erK9J3AE+lPBOPD9q4L+NRpT4C8sxhvv3rzOp0= X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0670; 20:5sWRroV11mLTf5ula1tnu5PpddIZ9MnVuwqHOt3hD5sEIDDurNv1YSdifFF6rg2658TfJh7KlhRhiJMUxdHSx8mYvPQIhDk2FIjBCq2OH0lWhh/LjmOPfG0oA6xSuhA5XA559PWYDtLLhhlKqrupTcjqgeOSBVI7nn9W+2PMb5bEahfObgkNRAItDB6eV/o2VPRqDIcw5MUvWbriReFOo+Pn6q9w1hiePR+pMcmIExVDBaMtPvYwd4pbyQy/WRTF6mk13cLAxLcRLN7NuUz/i5VWtKIz2u8jggQi2fJuc1/1jZJKabjt1nnMHWwsPnbEYhhrSF1X7ealsk5pMn4AYZXC9TWsaQEcaRClpLQZm/BNi8F/8eYYB/gEy1evIBgStEHM41Aq5bMhPuekZLIHeK0wXs7EWXj8kEcXK5ZMpUw53yjK2POmXCgxrg0lDtnI+ly8MwHS/Iu0L/8nwtkHTMdjxC9dhoU/E8iVSsofNaEkW+5S6aAJMk2wlw1FGxYq; 4:EBSPzcHqhNYunlC5FNK4E8viptA8qB9ySvNvSg6XS8YuXzNSD+4QOunnZcxqtqo+2IvXaEYMw60d+8qg4Oo/NV70cHNGcGXHK8FrVm/lrhJ352ODZhCVolk5m8rt3mOxLCcnjVMV2cbcYHNLPY7XDPSLxTjKlLg2IPdvdZw7uwPB6rkJAVRcyg/GseJLVGUjsa9ItYv5GVnE8sXUV32UiPFus4DgbWqCqodlgUz81IeTI4lMDibxOF/F4LgypNi8SWsVCsb1rchFXufegRytHav6CItrpB+M1QXADCp1EWBMMP8QkEcXyvTtkVJdnp7WgYpVN4wZGPGVmsz1GPtcwyLENL/T5EqhWflRiQzBc3OSFX5Rtn0ai9WJS4aMrgW6T+QLT4ACDVCNZsNYzP22dTN95ikEWvv0EID92OZdBMUlct8Zc7HjpwlcLwpmwU40 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)(8121501046)(5005006)(10201501046)(3002001)(6055026); SRVR:SN1PR12MB0670; BCL:0; PCL:0; RULEID:; SRVR:SN1PR12MB0670; X-Forefront-PRVS: 0064B3273C X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6049001)(6009001)(7916002)(189002)(199003)(103116003)(86362001)(7846002)(106356001)(81166006)(105586002)(2906002)(2201001)(3846002)(9686002)(81156014)(8676002)(4001350100001)(42186005)(97736004)(6116002)(305945005)(5001770100001)(23676002)(107886002)(229853001)(33646002)(76176999)(77096005)(54356999)(7736002)(50986999)(189998001)(66066001)(33716001)(2950100001)(83506001)(68736007)(47776003)(586003)(19580395003)(230700001)(50466002)(92566002)(5660300001)(19580405001)(101416001)(217873001); DIR:OUT; SFP:1101; SCL:1; SRVR:SN1PR12MB0670; H:[127.0.1.1]; FPR:; SPF:None; PTR:InfoNoRecords; MX:1; A:1; LANG:en; Received-SPF: None (protection.outlook.com: amd.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtTTjFQUjEyTUIwNjcwOzIzOk5wMEl2OHhLK0Z4Mk1tMmtXQkZiSFYvYXY3?= =?utf-8?B?bGFlZUduU2JuZFlLeENna1dOeCtlU0k2WWo1UCttWUZVVi9QSGp4djZ1WGFD?= =?utf-8?B?d3RrSzJ3MU5kUitFa3dtckxMcjMzWjNya1JoeWVKNlhRS21LelIrd3FlaE5C?= =?utf-8?B?U3k1b1UrbmJCN0NjSEt6VEFkQld1NmlkZTBuTjVWWXZtdzVzTG1xWFM2NGY1?= =?utf-8?B?dTlFem5MT3pscXFFaDYxMmE5WTEzMW80TFdUNmNtY3BRTFp1YXVVQmNoNFZ0?= =?utf-8?B?aE85Qno4dWJNTUNpRUxDRXNvRDZLZVFFc1ExUmM4VzRVekhTb0NNTnVzV3h6?= =?utf-8?B?N280U09QT3RpVUVlblBsNUs4ZXdnVDVIU2s0bGlhN0lkOWZUSHZ2bU9oRldv?= =?utf-8?B?UVpEVFlqZDhWRUh3bWFJWExYdzdSam8xV2JyZVBvV2xaSWZyQTNmWTZYQXBK?= =?utf-8?B?UXJ4S0dGWFk5TE9UT21KM3lobHBGTm51T3BXWjJKLzFkdWhaNDk2bEtMeDlp?= =?utf-8?B?V2pDR1BaTmF6Z0NJTjR1djVIUkpGbGFvbnFuQ0pWTEU5MmRrUkovemVQNHFo?= =?utf-8?B?aGErQk15RkJkWmVDZmFOaHNsZ1ZxaGxLdndCYWFNVHFpK1BQL25pTG11OXMr?= =?utf-8?B?WjFWYmF4OTRNMU5yWDNrd2J6ais2bkh5elBGWUdReEdleElRMXBOZW5wcXpv?= =?utf-8?B?VHp4ZU9QTUx5WHhRRVh0cjMzME8xbkg1TVU4c2krcWFRNy81OXpjVS9mZjRV?= =?utf-8?B?TFFtUlRLcG5iblNKUGJiOUpNOWNUcWdPTWpIOXZYSm5wQks4RFhkNDZON2hk?= =?utf-8?B?VWtXRTF2RmlPTVpxMm50eTNwUkdjR2dYR2lWTU14bFlFc0NVb1NRVmVXTTkx?= =?utf-8?B?OUc1RzRrL1g0STEyei85MlBObWkwbmVwMXYydXhNNUZvdnY3Yk1ReVVoUzhG?= =?utf-8?B?WklGT01rNm1Zb29xSUw1WDNNV0tuZG50RnhmbG9vc2h0dEdNdVZKRnlkREE4?= =?utf-8?B?S3NOQ1IrNk51cVpUSkgxUmFUdHVnM2ZvUExZVXN0RkdOL1Rtc2Nud1VmUVl2?= =?utf-8?B?UG1yZlhScnNkT2VVcWxOdGxGVTdzdi83Z1ZWYUVzKzlMa3hmOU1FM05uWGc3?= =?utf-8?B?ZHdzN2xia1VTTGdXT0FKc2pjYnhSLzQ1N0tjSGJoSUFaV0Q4QVhCK2RpSCtz?= =?utf-8?B?UkJiR1Y3cFNOdDE5NytPZlNaNW5rWUlCQ3dxcXg2eHB4a0JNOEV0MTR3ZXg1?= =?utf-8?B?Zk12Y2o4TEVnd0NjeVZ0d2lxc2lDamtvbmpFLzh3cWZCTTBHbHBXSW5LM2R0?= =?utf-8?B?SXhkUWJRTC9hZDFWMEx6cWhraFZzNFB5TWs4UGxMUjd4RHROZnlxMlhBd09K?= =?utf-8?B?bVJCOXQ4aWt2RG5SSVJnc2JtdllJWXlZOEI3TllTR2l6WVVGOVNvcEluUzNo?= =?utf-8?B?NUdWVHFnS2VxTHorM0RRemlXNUg4Rm1HdlNDcXRtS1BVc0V5a1crY3RPNnR4?= =?utf-8?B?UVIyeFRObUhBanB2b2FQcHRVWTBjNFZpRmRMRzVLclZBYTFNQ3NBS0dUVmJI?= =?utf-8?B?dytxUm5Ec0J3Ym1nWW9RRXF4RW5jNzhDMUtWQ3M1TERlUkNFQlBoWC8vZE1C?= =?utf-8?B?c0kvY09Lb3hIaDNqZ2I3Zk11NUQ5UXRycm9CbEdRbVdvY3F1WW1USkhnPT0=?= X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0670; 6:Hp5295gCHap1tVIOcdNp13443ZGlgoLm11pBvzByTOfGxzcpXdhzwZol1ynoXsz/cZS5Gla+Fn9jrMykTueefA+URwzNWsahP22IkomWGMiTbhqJ1iZ72PiCDu5xcJV9jnHDob/azF62Cb2y5zMWcvJd3az3CWwnZG4NqJpCFn6h879Dih/3825hTvQCLWY+WUJdNadoON8bJgE9jwgrVx59SCqjo2YLWCmEF1UG5MFOtrquLxeI08FZMcTIAgGE/IWt4b56b9Vy07JHi8vcw5jQor8s4AJSL0gyeevcdVy6PhESlf0N4ljv5so3xEIbxXDtlkoeG7q3sx2Y4QV2qg==; 5:gaSvyodfjPl3ELZy5SjjGniUr6QhGY4OKYShRYrZa65GFpwILkBXSonxjNqF2GrIKmsntkSBpKrDHs8C25TUx2n4zFwjqgAsrLz53GCuqR/G7zmH0E0sQpffJdue7fqACiX8tK8/nKJT1+MGRQmfhw==; 24:kuijeiROxM/gQjXmvgX0XLncjPQbAOsGa0lyoPsSEEXBtm88Q39XeCX+aGWjixTo55HGoVCv523/iGYSYGVtPgVvEMDbRGOuGQH3kh/Skz4=; 7:CTfR1qWivVXkoJYG5e2Kx13Fs2HmGlvTBSqljgv5Oe3rfoY+DKtcuFlG7eZaVWNfhfOZg2yByTtaoSqmJ5d9X9rCBQ4V7PsjQwaADxsipZEl9FCqRmbvE2rQV/qnOWdlNBsLk6iIvMjWxTMozWxDYptNCqd/HuCAGEaPCMWLyfzVfS/ONg+DvkoJjxSJOWbI4ueb5oDe7XGXqSzlZWf1rGZ/VFCsNDc3bSa6j7t+GV4qTRO7mZN8tEdoKSgHgx0n SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; SN1PR12MB0670; 20:SBzSDK0lIf0xfFOOklzWqt3hD5GMav1ZKC8ei8GFn+CggIG6HtvZEWtuSa7QSPSqx5jxIxiZboI3AHU3x1UrOG6CLnwuzH/V9WmCA9XYllQPW+fWlvhI3mzclLC8JL2jqkXxGZ+7a5rLkMKIR50EQ9WLuc6G4ZzSMbc1xi5bQiUT+CL9uev5JtgWD90AMUPN40JqvOxQg34Rn/0U4GXouMTDGoF/8QfvC9mOyoYGc5j7Izh3MIwD5JZ4rF1lfkiY X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 13 Sep 2016 14:47:53.0123 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR12MB0670 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.42.85 X-Mailman-Approved-At: Tue, 13 Sep 2016 11:45:46 -0400 Subject: [Qemu-devel] [RFC PATCH v1 06/22] sev: add initial SEV support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This patch adds the initial support required to integrate Secure Encrypted Virtualization feature, the patch include the following changes: - adds sev.c and sev.h files: the file will contain SEV APIs implemention. - add kvm_sev_enabled(): similar to kvm_enabled() this function can be used to check if sev is enabled on this guest. - implement functions to parse SEV specific configuration file. A typical SEV config file looks like this: [sev-launch] flags = "00000000" policy = "000000" dh_pub_qx = "0123456789abcdef0123456789abcdef" dh_pub_qy = "0123456789abcdef0123456789abcdef" nonce = "0123456789abcdef" vcpu_count = "1" vcpu_length = "30" vcpu_mask = "00ab" Signed-off-by: Brijesh Singh --- Makefile.target | 2 include/sysemu/kvm.h | 10 ++ include/sysemu/sev.h | 27 +++++ kvm-all.c | 6 + sev.c | 282 ++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 326 insertions(+), 1 deletion(-) create mode 100644 include/sysemu/sev.h create mode 100644 sev.c diff --git a/Makefile.target b/Makefile.target index a440bcb..74ad204 100644 --- a/Makefile.target +++ b/Makefile.target @@ -136,7 +136,7 @@ ifdef CONFIG_SOFTMMU obj-y += arch_init.o cpus.o monitor.o gdbstub.o balloon.o ioport.o numa.o obj-y += qtest.o bootdevice.o obj-y += hw/ -obj-$(CONFIG_KVM) += kvm-all.o +obj-$(CONFIG_KVM) += kvm-all.o sev.o obj-y += memory.o cputlb.o obj-y += memory_mapping.o obj-y += dump.o diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index c9c2436..7f83de0 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -40,6 +40,7 @@ #endif extern bool kvm_allowed; +extern bool kvm_sev_allowed; extern bool kvm_kernel_irqchip; extern bool kvm_split_irqchip; extern bool kvm_async_interrupts_allowed; @@ -56,6 +57,14 @@ extern bool kvm_ioeventfd_any_length_allowed; #if defined CONFIG_KVM || !defined NEED_CPU_H #define kvm_enabled() (kvm_allowed) + +/** + * kvm_sev_enabled: + * + * Returns: true if guest is running into SEV-enabled mode. + */ +#define kvm_sev_enabled() (kvm_sev_allowed) + /** * kvm_irqchip_in_kernel: * @@ -171,6 +180,7 @@ extern bool kvm_ioeventfd_any_length_allowed; #else #define kvm_enabled() (0) +#define kvm_sev_enabled() (false) #define kvm_irqchip_in_kernel() (false) #define kvm_irqchip_is_split() (false) #define kvm_async_interrupts_enabled() (false) diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h new file mode 100644 index 0000000..0ee8aff --- /dev/null +++ b/include/sysemu/sev.h @@ -0,0 +1,27 @@ +/* + * QEMU SEV support + * + * Copyright: Advanced Micro Devices, 2016 + * + * Authors: + * Brijesh Singh + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#ifndef QEMU_SEV_H +#define QEMU_SEV_H + +#include "sysemu/kvm.h" + +/** + * sev_init - initialize Secure Encrypted Virtualization on this guest + * @kvm_state - KVM handle + * Returns: 1 on error, 0 on success + */ +int sev_init(KVMState *kvm_state); + +#endif + diff --git a/kvm-all.c b/kvm-all.c index ebf35b0..e194849 100644 --- a/kvm-all.c +++ b/kvm-all.c @@ -36,6 +36,7 @@ #include "qemu/event_notifier.h" #include "trace.h" #include "hw/irq.h" +#include "sysemu/sev.h" #include "hw/boards.h" @@ -119,6 +120,7 @@ bool kvm_readonly_mem_allowed; bool kvm_vm_attributes_allowed; bool kvm_direct_msi_allowed; bool kvm_ioeventfd_any_length_allowed; +bool kvm_sev_allowed; static const KVMCapabilityInfo kvm_required_capabilites[] = { KVM_CAP_INFO(USER_MEMORY), @@ -1745,6 +1747,10 @@ static int kvm_init(MachineState *ms) kvm_state = s; + if (!sev_init(kvm_state)) { + kvm_sev_allowed = true; + } + if (kvm_eventfds_allowed) { s->memory_listener.listener.eventfd_add = kvm_mem_ioeventfd_add; s->memory_listener.listener.eventfd_del = kvm_mem_ioeventfd_del; diff --git a/sev.c b/sev.c new file mode 100644 index 0000000..2d71ca6 --- /dev/null +++ b/sev.c @@ -0,0 +1,282 @@ +/* + * QEMU SEV support + * + * Copyright Advanced Micro Devices 2016 + * + * Author: + * Brijesh Singh + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + */ + +#include "qemu/osdep.h" +#include +#include + +#include + +#include "qemu-common.h" +#include "qemu/atomic.h" +#include "qemu/option.h" +#include "qemu/config-file.h" +#include "qemu/error-report.h" +#include "hw/hw.h" +#include "hw/pci/msi.h" +#include "hw/s390x/adapter.h" +#include "exec/gdbstub.h" +#include "sysemu/kvm_int.h" +#include "sysemu/sev.h" +#include "qemu/bswap.h" +#include "exec/memory.h" +#include "exec/ram_addr.h" +#include "exec/address-spaces.h" +#include "qemu/event_notifier.h" +#include "trace.h" +#include "hw/irq.h" + +//#define DEBUG_SEV + +#ifdef DEBUG_SEV +#define DPRINTF(fmt, ...) \ + do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) +#else +#define DPRINTF(fmt, ...) \ + do { } while (0) +#endif + +struct SEVInfo { + uint8_t state; /* guest current state */ + uint8_t type; /* guest type (encrypted, unencrypted) */ + struct kvm_sev_launch_start *launch_start; + struct kvm_sev_launch_update *launch_update; + struct kvm_sev_launch_finish *launch_finish; +}; + +typedef struct SEVInfo SEVInfo; +static SEVInfo *sev_info; +static const char *cfg_file; + +enum { + LAUNCH_OPTS = 0, +}; + +enum { + PRE_ENCRYPTED_GUEST = 0, + UNENCRYPTED_GUEST, +}; + +static QemuOptsList launch_opts = { + .name = "sev-launch", + .head = QTAILQ_HEAD_INITIALIZER(launch_opts.head), + .desc = { + { + .name = "flags", + .type = QEMU_OPT_NUMBER, + }, + { + .name = "policy", + .type = QEMU_OPT_NUMBER, + }, + { + .name = "dh_pub_qx", + .type = QEMU_OPT_STRING, + }, + { + .name = "dh_pub_qy", + .type = QEMU_OPT_STRING, + }, + { + .name = "nonce", + .type = QEMU_OPT_STRING, + }, + { + .name = "vcpu_length", + .type = QEMU_OPT_NUMBER, + }, + { + .name = "vcpu_count", + .type = QEMU_OPT_NUMBER, + }, + { + .name = "vcpu_mask", + .type = QEMU_OPT_STRING, + }, + { /* end of list */ } + }, +}; + +static QemuOptsList *config_groups[] = { + &launch_opts, + NULL +}; + +struct add_rule_data { + SEVInfo *s; + int action; +}; + +static unsigned int read_config_u32(QemuOpts *opts, const char *key) +{ + unsigned int val; + + val = qemu_opt_get_number_del(opts, key, -1); + DPRINTF(" %s = %08x\n", key, val); + + return val; +} + +static int read_config_u8(QemuOpts *opts, const char *key, uint8_t *val) +{ + int i; + const char *v; + + v = qemu_opt_get(opts, key); + if (!v) { + return 0; + } + + DPRINTF(" %s = ", key); + i = 0; + while (*v) { + sscanf(v, "%2hhx", &val[i]); + DPRINTF("%02hhx", val[i]); + v += 2; + i++; + } + DPRINTF("\n"); + + return i; +} + +static int add_rule(void *opaque, QemuOpts *opts, Error **errp) +{ + struct add_rule_data *d = opaque; + + switch (d->action) { + case LAUNCH_OPTS: { + struct kvm_sev_launch_start *start; + struct kvm_sev_launch_update *update; + struct kvm_sev_launch_finish *finish; + + /* LAUNCH_START parameters */ + start = g_malloc0(sizeof(*start)); + + DPRINTF("Parsing 'sev-launch' parameters\n"); + start->flags = read_config_u32(opts, "flags"); + start->policy = read_config_u32(opts, "policy"); + read_config_u8(opts, "nonce", start->nonce); + read_config_u8(opts, "dh_pub_qx", start->dh_pub_qx); + read_config_u8(opts, "dh_pub_qy", start->dh_pub_qy); + sev_info->launch_start = start; + + /* LAUNCH_UPDATE */ + update = g_malloc0(sizeof(*update)); + sev_info->launch_update = update; + + /* LAUNCH_FINISH parameters */ + finish = g_malloc0(sizeof(*finish)); + + finish->vcpu_count = read_config_u32(opts, "vcpu_count"); + finish->vcpu_length = read_config_u32(opts, "vcpu_length"); + if (qemu_opt_get(opts, "vcpu_mask")) { + finish->vcpu_mask_length = + strlen(qemu_opt_get(opts, "vcpu_mask")) / 2; + finish->vcpu_mask_addr = (unsigned long) + g_malloc0(finish->vcpu_length); + read_config_u8(opts, "vcpu_mask", + (uint8_t *)finish->vcpu_mask_addr); + } + + sev_info->launch_finish = finish; + + break; + } + } + + return 0; +} + +static int parse_add_rules(QemuOptsList *list, struct add_rule_data *d) +{ + Error *local_err = NULL; + + qemu_opts_foreach(list, add_rule, d, &local_err); + if (local_err) { + return 1; + } + + return 0; +} + +static int parse_sev_cfg(SEVInfo *s, int type, const char *filename) +{ + FILE *f; + int ret = 0; + struct add_rule_data d; + + if (filename) { + f = fopen(filename, "r"); + if (f == NULL) { + return 1; + } + + ret = qemu_config_parse(f, config_groups, filename); + if (ret < 0) { + fprintf(stderr, "SEV: could not parse config file\n"); + exit(EXIT_FAILURE); + } + } + + switch (type) { + case LAUNCH_OPTS: + d.s = s; + d.action = type; + ret = parse_add_rules(&launch_opts, &d); + break; + } + + return ret; + +} + +int sev_init(KVMState *kvm_state) +{ + QemuOpts *opts; + const char *type; + + opts = qemu_find_opts_singleton("sev"); + cfg_file = qemu_opt_get(opts, "config"); + if (!cfg_file) { + return 1; + } + + type = qemu_opt_get(opts, "type"); + if (!type) { + return 1; + } + + sev_info = calloc(1, sizeof(*sev_info)); + if (!sev_info) { + return 1; + } + + if (!strcmp(type, "unencrypted")) { + sev_info->type = UNENCRYPTED_GUEST; + } else if (!strcmp(type, "encrypted")) { + sev_info->type = PRE_ENCRYPTED_GUEST; + } else { + fprintf(stderr, "SEV: unsupported type '%s'\n", type); + goto err; + } + + /* call SEV launch start APIs based on guest type */ + + return 0; +err: + free(sev_info); + sev_info = NULL; + return 1; +} +