From patchwork Wed Feb 28 21:10:11 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brijesh Singh X-Patchwork-Id: 10249863 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 63C8960362 for ; Wed, 28 Feb 2018 21:32:57 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4A88A2882B for ; Wed, 28 Feb 2018 21:32:57 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4385A28B82; Wed, 28 Feb 2018 21:32:57 +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=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED,RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable version=3.3.1 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 mail.wl.linuxfoundation.org (Postfix) with ESMTPS id C0F1F28F43 for ; Wed, 28 Feb 2018 21:31:42 +0000 (UTC) Received: from localhost ([::1]:47071 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1er9KA-0002Zu-2E for patchwork-qemu-devel@patchwork.kernel.org; Wed, 28 Feb 2018 16:31:42 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53225) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1er90I-0001JR-J3 for qemu-devel@nongnu.org; Wed, 28 Feb 2018 16:11:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1er90E-0005kE-7P for qemu-devel@nongnu.org; Wed, 28 Feb 2018 16:11:10 -0500 Received: from mail-sn1nam02on0070.outbound.protection.outlook.com ([104.47.36.70]:44829 helo=NAM02-SN1-obe.outbound.protection.outlook.com) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1er90D-0005jA-UH for qemu-devel@nongnu.org; Wed, 28 Feb 2018 16:11:06 -0500 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=M1UPcIPpiilLCBUSEmRQ8qsIlcetyf1b5ryoNs1kFUs=; b=tEarZCcr4XsVIfQVMR56RmdLSUG6sJl+dhJwa5GCWixHgeXJkqQk0PU4gmWijTdtKdqm0rtJ9XFY0ZlAvubk243LA5yO0R4DgIE1WnFl440IQDw8ky0NFPOxPnVIqTk/0/WyHvPyGcGU6tNPYR6K1BK2vpUu4RSNxgF0hTQExFA= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=brijesh.singh@amd.com; Received: from wsp141597wss.amd.com (165.204.78.1) by DM2PR12MB0155.namprd12.prod.outlook.com (2a01:111:e400:50ce::18) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.527.15; Wed, 28 Feb 2018 21:11:01 +0000 From: Brijesh Singh To: qemu-devel@nongnu.org Date: Wed, 28 Feb 2018 15:10:11 -0600 Message-Id: <20180228211028.83970-12-brijesh.singh@amd.com> X-Mailer: git-send-email 2.14.3 In-Reply-To: <20180228211028.83970-1-brijesh.singh@amd.com> References: <20180228211028.83970-1-brijesh.singh@amd.com> MIME-Version: 1.0 X-Originating-IP: [165.204.78.1] X-ClientProxiedBy: DM5PR10CA0008.namprd10.prod.outlook.com (2603:10b6:4:2::18) To DM2PR12MB0155.namprd12.prod.outlook.com (2a01:111:e400:50ce::18) X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: c87b98a1-d13b-4f3e-2e63-08d57eefc603 X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(7020095)(4652020)(4534165)(4627221)(201703031133081)(201702281549075)(48565401081)(5600026)(4604075)(2017052603307)(7153060)(7193020); SRVR:DM2PR12MB0155; X-Microsoft-Exchange-Diagnostics: 1; DM2PR12MB0155; 3:+hxo8Afgp2Ll/liPeQrqOYLBqqRq865G3+3Q8YXsRHX1t7SbSpeeydwU7V2bFI0ZxcsXg12vpKTY341/WSIEvCv6dfIhCsXcfh24LlORknHbf9+WhYY7xve3T+ojuX7GUJUbP+bAWpGUdgHPS1S/KzhDfj+0gKf2k2+7dohTk+gRxwN7pEuq/OtiKbX7LzrSMZ0+KfqoLfO/IYKYz7WFhLEJA81KdrRLnlvK1u9k03lBbfv+bI7KXp0pUs3TycSg; 25:oOBHCWKJwJBDTD4lD0ES+v+c3nDMdTi8FCXBR8wKD6dW7eUybkYJ5OWG9qLPRT7drF5AfI4YfoxJpeG+lLCqnKlB5/nCn3JU7+BP+FV2lsuY34YAAFABgNiKtz5/zhq2CrNwUrfCL6ltsplKkuC5H/70rvJZeAHr6GOIlgDgfyYh4OxqofwhSAEifYRClAzbxEl4XHFluH1oPc4u3M2n34NAzIdic0hijeBEdDO18sv0u1xJGDyBsRtkddOK2L2tJs9zVs15e9yKigGuvNRwix2+HD8VY7mhiq2e5jopwXP3bMxfEQDaMimgCzq3E2gxLQ0gmhkbnAImDo0eWYx6Og==; 31:PeBHn+zRh9ROmoxGXMpgd/Zkl9Yf3jolIDVuP+CssfO3iacWh45/3Y6SmK4THGjsIYWvdAgL8DlZTYVlckeWeuYNvdQJNViSJRGOhdat2dwPpRDCRqtuLq9xyYfDjA8extVrqfAsKkORNt51y800se7IPv+7JBn/1j8L+JEOelxFjVBSDXAG176Ds/4BHJ0mc9ZOYK3CD0J++JaiXOav7TJkC0j8kmxFOeWrgFsMr9I= X-MS-TrafficTypeDiagnostic: DM2PR12MB0155: X-Microsoft-Exchange-Diagnostics: 1; DM2PR12MB0155; 20:Yfe16EsTo4+vfAtny1UoN18Cr3/VLz6BNOJKa7Fu1ozQUbxCGoHYbgUZQ+g43/BaPbD8lxGPSYn2zDcslbzDu0DLf7NO4WJ1nUHwEXZmZ1UEv5FBDXHyBGlOWmr2zf6MpDTjwN+xSuFfgsJzdg40JtBMyjBzxYqDfn/MDW9tTAq62mYzhfThIrMH1wbupdQN8fDd+QZZ7raBIT+lrn6ZyBmx3ShwimAxRYQhlIeHCy8ykqbqTWohcL7oON8suSnIvOX2viFzuTyiqFJO+UaXWosnEvwI6rNGPTpGahCbhaC/fMSZdTy5qz/wPL4XMIuCFqeZnxm0PQc0aszoGDXZXDAA3vkeycemiK4jBLR4fRQYRqo7ez7kb/Ul4BlsSsW7UT3/jwGoTSiefpEQJ9cvb7uTdQS1QcDFJ92Q84ymNPUj9Ojlo8MaxF7fOhYfLoF7tTpiNG+H1vJIiDmSEyhUamdxjccpZ2V9kFjsdtgdf1Z30KjONiMXgb0QuUSUiKa9; 4:TU3LU26KiqOrrBd+pVdAg9TynF8hCGzqQ4uvOGztZbsbK5uG7jWD0ZMBd975tmqjHVnR16FmgIQ47uC/s1AGDTlzj/nSZM5tkmwjVYOG+nIiDmD3OsQ7hvWjoDamxA1s26CR+Wl38TvoSUlHg+W9tuKdfcuygeMgBJbJy2WzR9xNJHM39gxY/QP4Quf9DJVxagNZZP0aUzzvJnRpeFaIRJpvZT88bD+VGAf9LiiK9ftka5aan8WMsnmzmPu0joXq32nCAR9AJzBeloqaYdLO8YczHEHalLTmf77L+Pm3CBmJ5jJAz6CeSsuovuivBxpO X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(8211001083)(6040501)(2401047)(8121501046)(5005006)(3231220)(944501219)(52105095)(3002001)(93006095)(93001095)(10201501046)(6055026)(6041288)(20161123560045)(20161123564045)(20161123562045)(20161123558120)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(6072148)(201708071742011); SRVR:DM2PR12MB0155; BCL:0; PCL:0; RULEID:; SRVR:DM2PR12MB0155; X-Forefront-PRVS: 0597911EE1 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(1496009)(39860400002)(39380400002)(396003)(346002)(366004)(376002)(189003)(199004)(6486002)(6116002)(1076002)(2351001)(36756003)(16526019)(16586007)(54906003)(53416004)(26005)(53936002)(66066001)(186003)(47776003)(59450400001)(2361001)(478600001)(8666007)(316002)(81166006)(50226002)(8676002)(8936002)(386003)(106356001)(97736004)(5660300001)(2950100002)(6666003)(305945005)(4326008)(76176011)(7736002)(39060400002)(8656006)(105586002)(68736007)(50466002)(7696005)(51416003)(25786009)(48376002)(52116002)(3846002)(2906002)(86362001)(81156014)(7416002)(6916009); DIR:OUT; SFP:1101; SCL:1; SRVR:DM2PR12MB0155; H:wsp141597wss.amd.com; 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: =?us-ascii?Q?1; DM2PR12MB0155; 23:ihNqmBB2vF/y59be4pz43NIFajwDW19lh1/HUvRLn?= =?us-ascii?Q?e0W7xwQRouwQj6ga0g64/WO8Sk56x0sIvD7n8gTmgCPAWCj0/30+P9q5bIfc?= =?us-ascii?Q?oVjwZ6uE/XYUXC8Hdljv4+D9jCBvJBLn+Wg9Gmc9vQrAUVRQJSmw892C7pKx?= =?us-ascii?Q?K5s4fukEJrXKtiyCMxDwGinPwgiLwW9evP05WvpMLgLVNeJisQzdpottXa27?= =?us-ascii?Q?F/mqPnoQZg2d5i+hifnncaXKIt6MhfaI5zXp6y/NAAdi1L9zTc4mUGMa2Wpk?= =?us-ascii?Q?V7su6V9nDy4JXvm0xtBxL98mKUe3NRw2rPOqsCTHzO09YOy7cLdWcJxtUG48?= =?us-ascii?Q?spjVpgGpd15H2EAHeCXeVCuzEqsxdBMK9zgtIrbZHKlh5ZwZyedXTqEbYT2t?= =?us-ascii?Q?L7MX9T3MByVyOYqlE9XKc1N9PKlUIv0FuVH7ci25PK/weQMobfhGuMcygNL2?= =?us-ascii?Q?spd/NeTjyfNkoyHAH/Kttg1gENdo84beuyLkQwZ0Seup60uLxiJ0ZLzqIqzY?= =?us-ascii?Q?8G450W6Qlka1zOcBWVk3Ei2H2guyA3u2/kRgM6Z9oCxX8CTefsuCAs6DPJrB?= =?us-ascii?Q?lz7R0o6ArY5lquGwcLg7GQlnRPw+9pHLKAYzjoZCrE2MVNGi5kbGNpGwJxnr?= =?us-ascii?Q?L+TjxyCU/XSCnMRFDGXgBoti3Y/oNrCkgHuuvYyd0dNIPSg/6VcYBpNbrMPW?= =?us-ascii?Q?mKZxlQcsuH35OvQkZxhoPTzSKKdY+oDRND4q2DtYG4lAi7k6cyO0ByM35mCw?= =?us-ascii?Q?MH9Q8Xz0WfLO1LU9jYN1g3kVCX+OhlB5LDaPiuW4DaA6CfZXQkr2pwstvP+r?= =?us-ascii?Q?QRVGTAhlMl81SrF0gZoVsQVIaNtsSDPA8H3mAozSrFXeiwqxVmSdBVi6kXay?= =?us-ascii?Q?CS3zRE7fiYYoTCqBQKtb7cbvzydae/8mQqCuJI5QwwVmgHnexOt5ucLjH8FH?= =?us-ascii?Q?QO/QIIsLr9T4QxYJMY6o28OziT2cjOGltLL7I77v+KS9zddc+iCI1bk8y0fu?= =?us-ascii?Q?o5aMXtgAEyRxTH9142DiVq7nYfGNTuDjvCDu8Bw+mdV19izpNUJQYsLizEMi?= =?us-ascii?Q?rdSpTU5RmzFPgJeWO6Ymz0uCScJnJmxH1CjiB4hN3MvT+C/Pondf4gsaWZfN?= =?us-ascii?Q?utinOZ2NjLguLd19on3ZqAhB1Xrqc4otSZoPmvuz+/LRXvuQ+5tG5PbzLFEG?= =?us-ascii?Q?FDDrCUgO0DRyWXunkfdN6iHAGu1mO7UZB53ol5bS38F+woWk3OtdMmKvHD3q?= =?us-ascii?Q?5B55PYjP7oDqmBTuBiTiSgiXoqUyN6216H4rrID2ukGkQMU/6IqMRR0m8vqA?= =?us-ascii?Q?ERMki0trOQ7PSTlcNvzf4E=3D?= X-Microsoft-Exchange-Diagnostics: 1; DM2PR12MB0155; 6:jGFbUNynKer52QYEqR7wr6I2DXY9+mdyuRSS6sIVa2D4pZVDoV0OQJRKPvhFOBK1XMgb5A1V6Q6/fNHx1B6OJvZvLmhQX9lBlwW/DRT51u+TIKNQNGQa3PHRiBLbgLFt7TnqLVn4zQAW15iB6zY9MyzxQJiBahyErajmWlAk++oT8u/ze5pFK/oLLpAENNz0Nhpzt3JR30BWkKIkgdvYJZlA38COWOWJCuAaRG7qjnBZdx709KQJKR1TMMl41kVE3pBMpl2wwb6fS24k3ssBJQwadZuJm1pTfkpFIsTGntkj3SCvAr4FwiG6XKLpylse5CQIda44o6x+FbhEnLeaZOg4Jh+dKvuy5lmjzG8yfz0=; 5:tSlKwdPCLL1MUj8d6ntMQFcczNYUtF+yNlLHoU8vn3DyE8wTwgpoOT9FO3NjQbgbJZsmwtgsqWkI1+gaBsnvNv0Qb+WQIGzJ/yRfowmXV1KXBMyo1Oy06DqTPybDTHP7f9wvNiExxUlOMkTm5XqD2sKAGsFjgvKOONs+nYblTFs=; 24:UWDLzKdvXOJ6kG2cY3a10QwPCMmLs4ltf0x3o9aijj+Kku/h1NWj4tuhZbGXN5QxBbntBEJ4zFONqPOIQ/xNk2d7gskPkl1arc9ZHVRjtTo=; 7:bpItJvdGQ7M2WDHlXBd/b02CkgwEjvzIT8eG80fbVgzqkQlzC4qaMsGuYAKmKSkQ6J/dKNXoIGsx/LX99ZJYL0Kvn4xLkFb/tZZW+Jl4V5gxKyRM/ngpZQHUXURgOamj4TGkLD0oO2LdR39Flx9C0PMOzWQRsvf8PF3F/EvrUYP9X3xaxPdp5tBwka1gu/n4odxWYK3/WrdK8hEzFw/Y4R5uF/Oj5oxSZ+snY+cYu6s0XwoIQBEqV1kwolnsx1Zt SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; DM2PR12MB0155; 20:ML0A+0VtXMdU9OiCj49cpLJLnIhb+kBoehPZ6tehZ5Z1lVNMwTTiBdx3Rgj0wDz7adJTwmdOPhWEWTGXZ0qYAjXriwvCATl39VME2M/zd+KnFdBLx9nc1bhuAfStaUA8HBU9109w4/PBlqDvtbL9RERFLLz/OLMQ7IBBItOLdzTY37qx9zmOuG1fN3zBNMD2Cx17uUfE/eQJFhz0xow6ar+uxl7yKqW/dl/rKmb4HGtPAHFnrJOYLwpOq/A+nAPy X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Feb 2018 21:11:01.9361 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c87b98a1-d13b-4f3e-2e63-08d57eefc603 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM2PR12MB0155 X-detected-operating-system: by eggs.gnu.org: Windows 7 or 8 [fuzzy] X-Received-From: 104.47.36.70 Subject: [Qemu-devel] [PATCH v10 11/28] sev/i386: add command to initialize the memory encryption context 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: , Cc: Peter Maydell , Brijesh Singh , kvm@vger.kernel.org, "Michael S. Tsirkin" , Stefan Hajnoczi , Alexander Graf , "Edgar E. Iglesias" , Markus Armbruster , Bruce Rogers , Christian Borntraeger , Marcel Apfelbaum , Borislav Petkov , Thomas Lendacky , Eduardo Habkost , Richard Henderson , "Dr. David Alan Gilbert" , Alistair Francis , Cornelia Huck , Richard Henderson , Peter Crosthwaite , Paolo Bonzini Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP When memory encryption is enabled, KVM_SEV_INIT command is used to initialize the platform. The command loads the SEV related persistent data from non-volatile storage and initializes the platform context. This command should be first issued before invoking any other guest commands provided by the SEV firmware. Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Signed-off-by: Brijesh Singh --- accel/kvm/kvm-all.c | 15 ++++ include/sysemu/sev.h | 22 +++++ stubs/Makefile.objs | 1 + stubs/sev.c | 21 +++++ target/i386/Makefile.objs | 2 +- target/i386/monitor.c | 11 ++- target/i386/sev-stub.c | 41 +++++++++ target/i386/sev.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++ target/i386/sev_i386.h | 29 ++++++ target/i386/trace-events | 3 + 10 files changed, 364 insertions(+), 3 deletions(-) create mode 100644 include/sysemu/sev.h create mode 100644 stubs/sev.c create mode 100644 target/i386/sev-stub.c diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index b91fcb7160d3..300fc3cd44ce 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -38,6 +38,7 @@ #include "qemu/event_notifier.h" #include "trace.h" #include "hw/irq.h" +#include "sysemu/sev.h" #include "hw/boards.h" @@ -103,6 +104,9 @@ struct KVMState #endif KVMMemoryListener memory_listener; QLIST_HEAD(, KVMParkedVcpu) kvm_parked_vcpus; + + /* memory encryption */ + void *memcrypt_handle; }; KVMState *kvm_state; @@ -1636,6 +1640,17 @@ static int kvm_init(MachineState *ms) kvm_state = s; + /* + * if memory encryption object is specified then initialize the memory + * encryption context. + */ + if (ms->memory_encryption) { + kvm_state->memcrypt_handle = sev_guest_init(ms->memory_encryption); + if (!kvm_state->memcrypt_handle) { + goto err; + } + } + ret = kvm_arch_init(ms, s); if (ret < 0) { goto err; diff --git a/include/sysemu/sev.h b/include/sysemu/sev.h new file mode 100644 index 000000000000..3f6a26e92789 --- /dev/null +++ b/include/sysemu/sev.h @@ -0,0 +1,22 @@ +/* + * QEMU Secure Encrypted Virutualization (SEV) support + * + * Copyright: Advanced Micro Devices, 2016-2018 + * + * 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" + +void *sev_guest_init(const char *id); +int sev_encrypt_data(void *handle, uint8_t *ptr, uint64_t len); +void sev_set_debug_ops(void *handle, MemoryRegion *mr); +#endif diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 2d59d8409162..31b36fdfdb88 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -43,3 +43,4 @@ stub-obj-y += xen-common.o stub-obj-y += xen-hvm.o stub-obj-y += pci-host-piix.o stub-obj-y += ram-block.o +stub-obj-y += sev.o diff --git a/stubs/sev.c b/stubs/sev.c new file mode 100644 index 000000000000..4a5cc5569e5f --- /dev/null +++ b/stubs/sev.c @@ -0,0 +1,21 @@ +/* + * QEMU SEV stub + * + * Copyright Advanced Micro Devices 2018 + * + * 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. + * + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "sysemu/sev.h" + +void *sev_guest_init(const char *id) +{ + return NULL; +} diff --git a/target/i386/Makefile.objs b/target/i386/Makefile.objs index 76aeaeae2750..741cb080eb17 100644 --- a/target/i386/Makefile.objs +++ b/target/i386/Makefile.objs @@ -5,7 +5,7 @@ obj-$(CONFIG_TCG) += int_helper.o mem_helper.o misc_helper.o mpx_helper.o obj-$(CONFIG_TCG) += seg_helper.o smm_helper.o svm_helper.o obj-$(CONFIG_SOFTMMU) += machine.o arch_memory_mapping.o arch_dump.o monitor.o obj-$(CONFIG_KVM) += kvm.o hyperv.o sev.o -obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o +obj-$(call lnot,$(CONFIG_KVM)) += kvm-stub.o sev-stub.o # HAX support ifdef CONFIG_WIN32 obj-$(CONFIG_HAX) += hax-all.o hax-mem.o hax-windows.o diff --git a/target/i386/monitor.c b/target/i386/monitor.c index f429b1fc5383..e2f02c4be95c 100644 --- a/target/i386/monitor.c +++ b/target/i386/monitor.c @@ -670,6 +670,13 @@ void hmp_info_io_apic(Monitor *mon, const QDict *qdict) SevInfo *qmp_query_sev(Error **errp) { - error_setg(errp, "SEV feature is not available"); - return NULL; + SevInfo *info; + + info = sev_get_info(); + if (!info) { + error_setg(errp, "SEV feature is not available"); + return NULL; + } + + return info; } diff --git a/target/i386/sev-stub.c b/target/i386/sev-stub.c new file mode 100644 index 000000000000..c86d8c139237 --- /dev/null +++ b/target/i386/sev-stub.c @@ -0,0 +1,41 @@ +/* + * QEMU SEV stub + * + * Copyright Advanced Micro Devices 2018 + * + * 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. + * + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "sev_i386.h" + +SevInfo *sev_get_info(void) +{ + return NULL; +} + +bool sev_enabled(void) +{ + return false; +} + +uint64_t sev_get_me_mask(void) +{ + return ~0; +} + +uint32_t sev_get_cbit_position(void) +{ + return 0; +} + +uint32_t sev_get_reduced_phys_bits(void) +{ + return 0; +} diff --git a/target/i386/sev.c b/target/i386/sev.c index ab42e4a456d2..80569f4bcf49 100644 --- a/target/i386/sev.c +++ b/target/i386/sev.c @@ -18,10 +18,88 @@ #include "sysemu/kvm.h" #include "sev_i386.h" #include "sysemu/sysemu.h" +#include "trace.h" #define DEFAULT_GUEST_POLICY 0x1 /* disable debug */ #define DEFAULT_SEV_DEVICE "/dev/sev" +static SEVState *sev_state; + +static const char *const sev_fw_errlist[] = { + "", + "Platform state is invalid", + "Guest state is invalid", + "Platform configuration is invalid", + "Buffer too small", + "Platform is already owned", + "Certificate is invalid", + "Policy is not allowed", + "Guest is not active", + "Invalid address", + "Bad signature", + "Bad measurement", + "Asid is already owned", + "Invalid ASID", + "WBINVD is required", + "DF_FLUSH is required", + "Guest handle is invalid", + "Invalid command", + "Guest is active", + "Hardware error", + "Hardware unsafe", + "Feature not supported", + "Invalid parameter" +}; + +#define SEV_FW_MAX_ERROR ARRAY_SIZE(sev_fw_errlist) + +static int +sev_ioctl(int fd, int cmd, void *data, int *error) +{ + int r; + struct kvm_sev_cmd input; + + memset(&input, 0x0, sizeof(input)); + + input.id = cmd; + input.sev_fd = fd; + input.data = (__u64)data; + + r = kvm_vm_ioctl(kvm_state, KVM_MEMORY_ENCRYPT_OP, &input); + + if (error) { + *error = input.error; + } + + return r; +} + +static int +sev_platform_ioctl(int fd, int cmd, void *data, int *error) +{ + int r; + struct sev_issue_cmd arg; + + arg.cmd = cmd; + arg.data = (unsigned long)data; + r = ioctl(fd, SEV_ISSUE_CMD, &arg); + if (error) { + *error = arg.error; + } + + return r; +} + +static const char * +fw_error_to_str(int code) +{ + if (code >= SEV_FW_MAX_ERROR) { + return "unknown error"; + } + + return sev_fw_errlist[code]; +} + static void qsev_guest_finalize(Object *obj) { @@ -219,6 +297,150 @@ static const TypeInfo qsev_guest_info = { } }; +static QSevGuestInfo * +lookup_sev_guest_info(const char *id) +{ + Object *obj; + QSevGuestInfo *info; + + obj = object_resolve_path_component(object_get_objects_root(), id); + if (!obj) { + return NULL; + } + + info = (QSevGuestInfo *) + object_dynamic_cast(obj, TYPE_QSEV_GUEST_INFO); + if (!info) { + return NULL; + } + + return info; +} + +bool +sev_enabled(void) +{ + return sev_state ? true : false; +} + +uint64_t +sev_get_me_mask(void) +{ + return sev_state ? sev_state->me_mask : ~0; +} + +uint32_t +sev_get_cbit_position(void) +{ + return sev_state ? sev_state->cbitpos : 0; +} + +uint32_t +sev_get_reduced_phys_bits(void) +{ + return sev_state ? sev_state->reduced_phys_bits : 0; +} + +SevInfo * +sev_get_info(void) +{ + SevInfo *info; + + info = g_new0(SevInfo, 1); + info->enabled = sev_state ? true : false; + + if (info->enabled) { + info->api_major = sev_state->api_major; + info->api_minor = sev_state->api_minor; + info->build_id = sev_state->build_id; + info->policy = sev_state->policy; + info->state = sev_state->state; + info->handle = sev_state->handle; + } + + return info; +} + +void * +sev_guest_init(const char *id) +{ + SEVState *s; + char *devname; + int ret, fw_error; + uint32_t ebx; + uint32_t host_cbitpos; + uint32_t host_reduced_phys_bits; + struct sev_user_data_status status = {}; + + s = g_new0(SEVState, 1); + s->sev_info = lookup_sev_guest_info(id); + if (!s->sev_info) { + error_report("%s: '%s' is not a valid '%s' object", + __func__, id, TYPE_QSEV_GUEST_INFO); + goto err; + } + + sev_state = s; + s->state = SEV_STATE_UNINIT; + + host_cpuid(0x8000001F, 0, NULL, &ebx, NULL, NULL); + host_cbitpos = ebx & 0x3f; + host_reduced_phys_bits = (ebx >> 6) & 0x3f; + + s->cbitpos = object_property_get_int(OBJECT(s->sev_info), "cbitpos", NULL); + if (host_cbitpos != s->cbitpos) { + error_report("%s: cbitpos check failed, host '%d' requested '%d'", + __func__, host_cbitpos, s->cbitpos); + goto err; + } + + s->reduced_phys_bits = object_property_get_int(OBJECT(s->sev_info), + "reduced-phys-bits", NULL); + if (host_reduced_phys_bits != s->reduced_phys_bits) { + error_report("%s: reduced_phys_bits check failed," + "host '%d' requested '%d'", __func__, + host_reduced_phys_bits, s->reduced_phys_bits); + goto err; + } + + s->me_mask = ~(1UL << s->cbitpos); + + devname = object_property_get_str(OBJECT(s->sev_info), "sev-device", NULL); + s->sev_fd = open(devname, O_RDWR); + if (s->sev_fd < 0) { + error_report("%s: Failed to open %s '%s'", __func__, + devname, strerror(errno)); + goto err; + } + g_free(devname); + + ret = sev_platform_ioctl(s->sev_fd, SEV_PLATFORM_STATUS, &status, + &fw_error); + if (ret) { + error_report("%s: failed to get platform status ret=%d" + "fw_error='%d: %s'", __func__, ret, fw_error, + fw_error_to_str(fw_error)); + goto err; + } + s->build_id = status.build; + s->api_major = status.api_major; + s->api_minor = status.api_minor; + + trace_kvm_sev_init(); + ret = sev_ioctl(s->sev_fd, KVM_SEV_INIT, NULL, &fw_error); + if (ret) { + error_report("%s: failed to initialize ret=%d fw_error=%d '%s'", + __func__, ret, fw_error, fw_error_to_str(fw_error)); + goto err; + } + + return s; +err: + g_free(sev_state); + sev_state = NULL; + return NULL; +} + static void sev_register_types(void) { diff --git a/target/i386/sev_i386.h b/target/i386/sev_i386.h index caf879c3b874..68019d6f39a5 100644 --- a/target/i386/sev_i386.h +++ b/target/i386/sev_i386.h @@ -14,10 +14,17 @@ #ifndef QEMU_SEV_I386_H #define QEMU_SEV_I386_H +#include +#include + +#include + #include "qom/object.h" #include "qapi/error.h" #include "sysemu/kvm.h" +#include "sysemu/sev.h" #include "qemu/error-report.h" +#include "qapi-types.h" #define SEV_POLICY_NODBG 0x1 #define SEV_POLICY_NOKS 0x2 @@ -30,6 +37,12 @@ #define QSEV_GUEST_INFO(obj) \ OBJECT_CHECK(QSevGuestInfo, (obj), TYPE_QSEV_GUEST_INFO) +extern bool sev_enabled(void); +extern uint64_t sev_get_me_mask(void); +extern SevInfo *sev_get_info(void); +extern uint32_t sev_get_cbit_position(void); +extern uint32_t sev_get_reduced_phys_bits(void); + typedef struct QSevGuestInfo QSevGuestInfo; typedef struct QSevGuestInfoClass QSevGuestInfoClass; @@ -58,4 +71,20 @@ struct QSevGuestInfoClass { ObjectClass parent_class; }; +struct SEVState { + QSevGuestInfo *sev_info; + uint8_t api_major; + uint8_t api_minor; + uint8_t build_id; + uint32_t policy; + uint64_t me_mask; + uint32_t cbitpos; + uint32_t reduced_phys_bits; + uint32_t handle; + int sev_fd; + SevState state; +}; + +typedef struct SEVState SEVState; + #endif diff --git a/target/i386/trace-events b/target/i386/trace-events index 3153fd445488..797b716751b7 100644 --- a/target/i386/trace-events +++ b/target/i386/trace-events @@ -5,3 +5,6 @@ kvm_x86_fixup_msi_error(uint32_t gsi) "VT-d failed to remap interrupt for GSI %" kvm_x86_add_msi_route(int virq) "Adding route entry for virq %d" kvm_x86_remove_msi_route(int virq) "Removing route entry for virq %d" kvm_x86_update_msi_routes(int num) "Updated %d MSI routes" + +# target/i386/sev.c +kvm_sev_init(void) ""