From patchwork Thu Mar 2 15:18:57 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brijesh Singh X-Patchwork-Id: 9600561 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 A2EEB60522 for ; Thu, 2 Mar 2017 15:44:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 92EDA285B1 for ; Thu, 2 Mar 2017 15:44:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8725B285B5; Thu, 2 Mar 2017 15:44:58 +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.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_HI 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 0F736285B3 for ; Thu, 2 Mar 2017 15:44:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751445AbdCBPm5 (ORCPT ); Thu, 2 Mar 2017 10:42:57 -0500 Received: from mail-sn1nam01on0088.outbound.protection.outlook.com ([104.47.32.88]:46048 "EHLO NAM01-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1750947AbdCBPlh (ORCPT ); Thu, 2 Mar 2017 10:41:37 -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=U9DXAe+e2ha3P+oikAI0xHLeI/wl6tkZNwkHFgK5Pyo=; b=llsX9RX+zgpu9X2OypFLSO3GMkdOQg8WvYNhJx7eovogST5OQzAD3TN3VIIsbrWObq1ASGyptGUotLJfTFNjHJ5sTDKnec9YfAB3I7sddR8NY+e+dCKiBp0LiNAmf4Gv4YhatpFb1hlCNOA6zLKMKzKLkEzwNw4sChudZ/Cwp3M= Authentication-Results: vger.kernel.org; dkim=none (message not signed) header.d=none; vger.kernel.org; dmarc=none action=none header.from=amd.com; Received: from [127.0.1.1] (165.204.77.1) by MWHPR12MB1613.namprd12.prod.outlook.com (10.172.56.14) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.933.12; Thu, 2 Mar 2017 15:19:00 +0000 Subject: [RFC PATCH v2 32/32] x86: kvm: Pin the guest memory when SEV is active From: Brijesh Singh To: , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , Date: Thu, 2 Mar 2017 10:18:57 -0500 Message-ID: <148846793743.2349.8478208161427437950.stgit@brijesh-build-machine> In-Reply-To: <148846752022.2349.13667498174822419498.stgit@brijesh-build-machine> References: <148846752022.2349.13667498174822419498.stgit@brijesh-build-machine> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Originating-IP: [165.204.77.1] X-ClientProxiedBy: DM5PR17CA0028.namprd17.prod.outlook.com (10.173.128.142) To MWHPR12MB1613.namprd12.prod.outlook.com (10.172.56.14) X-MS-Office365-Filtering-Correlation-Id: 6b55516c-0ae5-4a2f-072f-08d4617f75ed X-MS-Office365-Filtering-HT: Tenant X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001)(48565401081); SRVR:MWHPR12MB1613; X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1613; 3:/eB8TlkXy+Kvg6gavVn5KQI6avzl8UGrXeTOTupagR9HL00gPCy5bmwBD9pWCVvGTFv671O0arGOu0PcCrZGDS0jwFpXgkuLW8gdvnz79Tnr5osNPsUhNMqTkHvOBvy5QLpgjczQjPj2/S/H3QFde+D3BjvTCnTtI+R2dt8DvCyyGeb0/boPgfWPdAAnqvazjaMaDEcW510P7IwZBc1d88XihdlLs/3wD2V/svhSiq4URbxoiWzebFNb2ppBlHzvu9Syjxid9w9J/knlwqNOiCiL6WHK6wa6AcDc5vSY3L8=; 25:RPDUxq/5D8NJa3IHDhPYl4lzXhrdsv77x0HAIuHqDpIpqD48kqDqpQEVl7baklkAR/zwBGK6T3/vCnCpHunyiZSBQCLVJ2a2slzPRV1O6+KNlZPB0t/oOZGqljSA7Jlc6twOGR3Gh4wJ+NnRGVo0nxvHkc3q/tyOsTPd5/tuft1uLH5yWYckyLeYxDG/qDRXjDtxdjj8uyLYqsn1hGhWYV54ctAQlsJoeeLsTgq82Rdg38d/oMnIHfzfCDBqwgqiO4OMpt6ycAllLuq0rKqYP06Z6Eu7VXnverMeM9z5OMF/djEuZrJdQcIS+QrUYa+UrjzWOZ187H3SRRqYCPr4W4/I36oWV0tLlOFys/SoCD2Ri02AgOG2qovFaGV21x/uG/kgR5oYYymtx3MjbkfNX5B90hKci1EizB6lwKUugfYbBqv/WjZf3Ei953N1g0kPBXhWl2PReBQRMJEOMv3gNw== X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1613; 31:7lqXz/+8lbO8ND7o3fAlE4rGmtDhirZS2mouQzYIwxrvqoS4jNzd6MvIGNmnNMvveb5WtBIlr9tSenF9qtaUfjFtMuJzWqRSXzODqk/jUio3xVd3FEQ7JdRlmW5DaQ6z8MnRJIJpvDlVovh+iF59NJnSHel77xxGWufqjzUsF/3BYyigj4r6egCBIcj7K2+ox9r0VgVX9B5DSE7W5QWm1u/Doch2MhiJuFV2uOYLt7mFAGDKoBKLr5ODKG1/vCBv; 20:vY3te8mX0CMkO6eI9C/2uziSo+vOUT/U6uTohXAPbflvLTQ5DgZE407aO6NTrw+z4cwMxG+fBXEZklTnMiQh8Iyzf9IdpPAQp9umLCY6ibNOOjw8obWqQGgJCcsxhBeS6m/EUwg/UxBSt8cFmvt6MMfXGyeiHKozPqwFc305nU6+bEnRAS48oCV8jVe6WxtBOEkAMrMfJtwhl/9yrkmLX3P0ssmPWFVJBdeLicR6CzP26u0Jj5rAsUKsYkQTauMQvTm4om12bmvBymOSGLpwPBek8DpdWMa+wBk1JIsk2m2ldjMnerYOblpLGtJQC8fbrJORB5S9IASEJbLZZ0oDl5c4702p7Utyu0AL6Qw0gNOU7n18UvwrH2L7hKnBp/J/gYpC31B7ll7uc6PnCUwGsbe/NQBzVsMZgpvM1RMlxlcywqSsVtL5+VqybzyO904U/VCRw1xF8zy7SanC7hS4wFV4Ui0muDS8fpWAajet91GXwsnZxlnPY6cs7rhrUxqf X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(767451399110); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6055026)(6041248)(20161123555025)(20161123564025)(20161123562025)(20161123558025)(20161123560025)(6072148); SRVR:MWHPR12MB1613; BCL:0; PCL:0; RULEID:; SRVR:MWHPR12MB1613; X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1613; 4:G85UuDOAJ/RCF5HVrBTSTfpS4dZH3JFNC9VHe8UtR2X14Fu8FjYgmVyIcTcoLloUYL7NIZpTKsgUaD6c6JA04Dx3ZDB7VF+BdTzKJpUWId//2iaicQkQ2y3wJpZnvhJ/5FeSMdgd0ZRyBz3LGjsCgyH2otZlDfecDZl/cx5aYHIYJ6rieP7a5m0D2UrNL/PSkogz8jz3UU6CU4FSQUMjs7Ew3tL97DCGo3BIlgwmgYK9pAlsJnyHpvFLVL1FiTG6mpGzw69m2wufuezRN7MbQ+8itHpyfJB/m+nBMtX4Jmh9d1/s1ud6R9jfxghyOMpZ3NKQhiFCTbcoUIO5XmgdlI9pkddu/eL0q6Bpr89X5nNEdxkj0EQmOQpEteEYJwHTREs5OAZyVGWwNsOZ21qAyOXudhlTO8u7FvvS+hNCmKiDUrPCD8ZpiCb6+HyKq7VbJPk/N9fCs7iq3KXH8o3/1IQA0IJ05OQf5/EG95fbHQDcv+8dhDOOM/CXFAzI/zjaNG+v7RUs83A+kjllZNwQuNMiQOgZMBF3en8OIEWJzAg5H6heJPVf/LGFqLW4MDCJYHN2p+dfRPXq2A152lVF4j9OQGpsSOGevAM7lMOy9M/5Y92vXRkI4pfPpCppI3c6S3m9iqymHea+3rpOPoWUYDN+C70Op120AzSAY8VaiEs= X-Forefront-PRVS: 023495660C X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(6049001)(7916002)(39450400003)(39840400002)(39860400002)(39410400002)(39850400002)(54356999)(230700001)(42186005)(76176999)(3846002)(2950100002)(5660300001)(2906002)(33646002)(33716001)(50986999)(6666003)(83506001)(6116002)(966004)(66066001)(8676002)(9686003)(38730400002)(25786008)(53936002)(92566002)(6306002)(77096006)(6486002)(189998001)(90366009)(2201001)(50466002)(23676002)(7406005)(1191002)(7366002)(103116003)(86362001)(7416002)(7736002)(305945005)(81166006)(47776003)(921003)(2101003)(1121003)(83996005)(217873001)(84006005); DIR:OUT; SFP:1101; SCL:1; SRVR:MWHPR12MB1613; H:[127.0.1.1]; FPR:; SPF:None; MLV:sfv; LANG:en; X-Microsoft-Exchange-Diagnostics: =?utf-8?B?MTtNV0hQUjEyTUIxNjEzOzIzOjAwU0xYNVpSbDBpTG10RmpOL3doWStqOFdi?= =?utf-8?B?d3Y0YlZUVWxBZFZXK2lzaEFnRVJVR1cxR3QrMXovYUNyMFM5MURaSVI0Q2x1?= =?utf-8?B?cm1SNlVlVUMzL2J2ZlA1cnBFR2pxOVpMQm04UVM5dUc5bmFsVHplNjBHRTFh?= =?utf-8?B?QmRocjJXYWZxaEltVnFXS1ZnNk1tZCt5cHpJYThBeFdIMHVkU0VzL1NGNEJJ?= =?utf-8?B?bWp5OEN5UE4zRzdhekR4K2V4QlhpcGtlcDRlQjRaYmYzc2pscWh2dUhiT2lZ?= =?utf-8?B?aGZaVU5WRzdaK3lOTlZLZFNlUzlSa2pPaHZvMXFyMkNBRjZHZTZoQnhJWUlq?= =?utf-8?B?d3EzdVl5MXdNcFhaczJLZ0p1NGtCMkJmc05KUW10emZ1SWc3RWpPVWFxcDVi?= =?utf-8?B?THRTcis4K0lJZnJLNnNyOFc1ZEIydG41bHZJSTM0Y0dQN1FLNGJYaU1Nd0dP?= =?utf-8?B?Yms4Z29lUW9BdEJjT3B4dDVpR3BXWWZNTDhtMEMvUEJSUUNYdkQvVWEvYXgw?= =?utf-8?B?Ri9uKzB6M2JiRU9qOVpqaVU0RUlvM2phQi9TRDRFOFhjM0liRzNYRjFmc1VB?= =?utf-8?B?bTB0QkxnUHVMcnVVTGRLei80dXNwQklEL1BxSERIbHNCUnA2MVNJbjJPRHJC?= =?utf-8?B?VXVYeDE1M0U0Z1hyRW9HUFkwR0VIcnorRzA2OWFCUi9YTXJ3NWc3Y1VqeW1T?= =?utf-8?B?aXNpcmE1V0lxbkh5VjFlV2FVc28yODJLQlBaNVBYalFselBncjF5Sk8vVUNw?= =?utf-8?B?Z21CU0IxWDA5QnNqdFhZeVlZOWFjRlpvWHZYaUVRWUhBZmtEK3BVVlZHdnU2?= =?utf-8?B?TWhibXpSbjNJY0NHZFdQMXMrdkd6MjdOTzY1K3oyczVrbC9jbjQ0R2p2TUlX?= =?utf-8?B?MFJXeUhEN2hZK3h1VmpQSFlDa3FRTzZ3cFRZOGFtSFMyd3FwQlVvaXlOZXhU?= =?utf-8?B?c1NIUjVveFhUbjVEOHRTRXVUSFNFNnV3cEhMcVZiNTFpY0EyQkhxTGpSREdV?= =?utf-8?B?MnVFb3VOK0VTcTRVTkhMLzBYb2NLdVVKTnlsbmNNd3VscWc0SFIxK0Q1Nko4?= =?utf-8?B?cTlUdldveC82T1lCZHVFT2xtdVVtWkcvUGh3ZEJScmVuZHBhSE0va1BoRExk?= =?utf-8?B?OWczZkUvem1UandqcEZJbjdxa3JIWVhYODNyWUtnWHgwR25MVGhKbm9UWnkr?= =?utf-8?B?cjk3RWNuSm1nbDAwajZRQk5EMXV5Rjl2WHpwUGM2M0IzU3ZPeVNmQ2dUZEV4?= =?utf-8?B?cFFrOHQ5Q25MeHpDUHVrUEVmcThYSlJ6alJZNVZwem50dllLTW82bE1zS09o?= =?utf-8?B?VXVrcnJJWGpSRjV1NFlyazJFc1k3dFBSV2MyaDB2bytXc2oxY2c2WVRTRytW?= =?utf-8?B?aUswcDhFSzZmL2RCZ0dQL0NiSFVHZ1RoNFJJckZML25WNE15YnJBV3RlRkxm?= =?utf-8?B?NG83dzdxK1B3V3gwRk1MR1UrWGlJRnFEczZybDgxZ3ZOZ0xoM0dhcnBnMWl2?= =?utf-8?B?bkEzbDV1WmRkSE5BTHFCVXF1ZVdDeXkydHk3Mi93UW9EOHpyVCs5dGo2RllS?= =?utf-8?B?K0RmSTJSd0FpWHA2QUYwOXVwd0VyMFYreFdMdWp6UWFJTTVSYytFREg1cjhq?= =?utf-8?B?Y2FFNkVLTjBheGdLbEl5MEJUUFdlNHdXb3hRYXgvRkVDSUFWOGxKTU5wT1N2?= =?utf-8?B?QXhjZGE5MGxMOTBJbVZ5WnJjY3ZvYlQ4YnRwU2V5OG1RWWxlSy9WUXNseXNL?= =?utf-8?Q?HwfSuYYxokPz2tNN3lWavmpL5LiN5sN5uCjCA=3D?= X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1613; 6:e2U8FTEsffB2qegaNGBC9L3u7LaHgVSbiONZPoR/PuOjzyXz/1EDfZhKJOcDwfaSAXdZtbJPWKMviqB8vr/eYXSk4CkBKyTlzVBYaZ6P6DlGp4T0Xy+j39fS6G1ISujtiKw42Dx3ML3V3ucGobZmFmhgxo7v6BJn1wNONLL0rHxX+ccQcz/1NepMNwFGWPPMHkravfO49TeuuZBssyrx7UcXP6cTfOSiHBRbeyIh35ecJCOKkqjF+uPXGjx1iOFhY3kytoPUoP5XwATNAcz8oXy5dSlxnduDd34sxxMgVJaJfXzruebD5rqxDeLnF73oIUSbUVcmLYJcj1Q6YBoIvR4gZ7ScUA0Pm1iWI4HbaGLS2/6ffUbGI3+GnySDG3t7R6TG90kifj2bV8QqYxL5MKZ4lbaoS1RCBu2RHUQhZVo=; 5:xWBVk6Rb5bp8NxfWR4o4WHDhvyQemJ1lEDXCWoHCBOGwOmNNF6OFEoPidRDUmPE3wWTZCWuGsgzmiX7yfHClGXUACYgD9ko9ZEvIVL19OWtEETEd/np5/MPTrBL7d/MTmedGYEy3lvqdnHGyOLfUDQ==; 24:xl6k53AI7TN8fvoq3zTEizSa6jJLcmMDLeyuZMPJiJm+I0LaXQy/Ek6nsK2TpaJDB1iXx1qONaaKUXUyXaZf0DW/94Q35rDb2R/LpfN7UbA= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; MWHPR12MB1613; 7:rjITebhv0eSgHbJ4hSgQQhhAM65XSFD94bVtSqdn0A2uRU9eDOBihUMO0W3+iYoTry8OZc5VMjfnJ35Ymb7hx9wbU3O/RvrajVBKdH4NtJ9VY/rH/kaRSSE+P66wwIjTCeSUv7s/h6P7RnBacQRv066dnTO3mUUbaw8Y08OGxvzpZAC6oytRPIGn33Me8xywHS4TQha5VRI6mNc0J9pKMsPZggMGZ9K9jLOSIboA2lvZU9jhrnFJ6g6zD9EKb178oxWE2DNjZ0C7cjuvvTW0K2cpoB0zVOyuGvzv6FQap82Z+OJEDUDklk4iLiMz2+lEU9MXSGgikEb5MidFkVvtYg==; 20:N2JwCwaoZGEVkFTFYUmpM8VxBGeXQcG+7a8y4udWilXr+F7zfQPT+IawYNn/hHGimdREbZP3Ja1HY+6kbBW/Q+SKy2d8nWHXPbBe3fz1OFPJs2iLIbEbtu7DoM/QptslB8W52u6guwUtOQ7bNX8VU/pVCOTvxEgbFdUGslX7Nc7dluQwqSD9Ql9RuUg7OltKXGMKgtwJXrE1ffyToR6d9H0qz6AhoS449h/mEScImoeDgF3KI7JnJngAP3JbPC43 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Mar 2017 15:19:00.1416 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: MWHPR12MB1613 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The SEV memory encryption engine uses a tweak such that two identical plaintexts at different location will have a different ciphertexts. So swapping or moving ciphertexts of two pages will not result in plaintexts being swapped. Relocating (or migrating) a physical backing pages for SEV guest will require some additional steps. The current SEV key management spec [1] does not provide commands to swap or migrate (move) ciphertexts. For now we pin the memory allocated for the SEV guest. In future when SEV key management spec provides the commands to support the page migration we can update the KVM code to remove the pinning logical without making any changes into userspace (qemu). The patch pins userspace memory when a new slot is created and unpin the memory when slot is removed. [1] http://support.amd.com/TechDocs/55766_SEV-KM%20API_Spec.pdf Signed-off-by: Brijesh Singh --- arch/x86/include/asm/kvm_host.h | 6 +++ arch/x86/kvm/svm.c | 93 +++++++++++++++++++++++++++++++++++++++ arch/x86/kvm/x86.c | 3 + 3 files changed, 102 insertions(+) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index fcc4710..9dc59f0 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -723,6 +723,7 @@ struct kvm_sev_info { unsigned int handle; /* firmware handle */ unsigned int asid; /* asid for this guest */ int sev_fd; /* SEV device fd */ + struct list_head pinned_memory_slot; }; struct kvm_arch { @@ -1043,6 +1044,11 @@ struct kvm_x86_ops { void (*setup_mce)(struct kvm_vcpu *vcpu); int (*memory_encryption_op)(struct kvm *kvm, void __user *argp); + + void (*prepare_memory_region)(struct kvm *kvm, + struct kvm_memory_slot *memslot, + const struct kvm_userspace_memory_region *mem, + enum kvm_mr_change change); }; struct kvm_arch_async_pf { diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 13996d6..ab973f9 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c @@ -498,12 +498,21 @@ static inline bool gif_set(struct vcpu_svm *svm) } /* Secure Encrypted Virtualization */ +struct kvm_sev_pinned_memory_slot { + struct list_head list; + unsigned long npages; + struct page **pages; + unsigned long userspace_addr; + short id; +}; + static unsigned int max_sev_asid; static unsigned long *sev_asid_bitmap; static void sev_deactivate_handle(struct kvm *kvm); static void sev_decommission_handle(struct kvm *kvm); static int sev_asid_new(void); static void sev_asid_free(int asid); +static void sev_unpin_memory(struct page **pages, unsigned long npages); #define __sev_page_pa(x) ((page_to_pfn(x) << PAGE_SHIFT) | sme_me_mask) static bool kvm_sev_enabled(void) @@ -1544,9 +1553,25 @@ static inline int avic_free_vm_id(int id) static void sev_vm_destroy(struct kvm *kvm) { + struct list_head *pos, *q; + struct kvm_sev_pinned_memory_slot *pinned_slot; + struct list_head *head = &kvm->arch.sev_info.pinned_memory_slot; + if (!sev_guest(kvm)) return; + /* if guest memory is pinned then unpin it now */ + if (!list_empty(head)) { + list_for_each_safe(pos, q, head) { + pinned_slot = list_entry(pos, + struct kvm_sev_pinned_memory_slot, list); + sev_unpin_memory(pinned_slot->pages, + pinned_slot->npages); + list_del(pos); + kfree(pinned_slot); + } + } + /* release the firmware resources */ sev_deactivate_handle(kvm); sev_decommission_handle(kvm); @@ -5663,6 +5688,8 @@ static int sev_pre_start(struct kvm *kvm, int *asid) } *asid = ret; ret = 0; + + INIT_LIST_HEAD(&kvm->arch.sev_info.pinned_memory_slot); } return ret; @@ -6189,6 +6216,71 @@ static int sev_launch_measure(struct kvm *kvm, struct kvm_sev_cmd *argp) return ret; } +static struct kvm_sev_pinned_memory_slot *sev_find_pinned_memory_slot( + struct kvm *kvm, struct kvm_memory_slot *slot) +{ + struct kvm_sev_pinned_memory_slot *i; + struct list_head *head = &kvm->arch.sev_info.pinned_memory_slot; + + list_for_each_entry(i, head, list) { + if (i->userspace_addr == slot->userspace_addr && + i->id == slot->id) + return i; + } + + return NULL; +} + +static void amd_prepare_memory_region(struct kvm *kvm, + struct kvm_memory_slot *memslot, + const struct kvm_userspace_memory_region *mem, + enum kvm_mr_change change) +{ + struct kvm_sev_pinned_memory_slot *pinned_slot; + struct list_head *head = &kvm->arch.sev_info.pinned_memory_slot; + + mutex_lock(&kvm->lock); + + if (!sev_guest(kvm)) + goto unlock; + + if (change == KVM_MR_CREATE) { + + if (!mem->memory_size) + goto unlock; + + pinned_slot = kmalloc(sizeof(*pinned_slot), GFP_KERNEL); + if (pinned_slot == NULL) + goto unlock; + + pinned_slot->pages = sev_pin_memory(mem->userspace_addr, + mem->memory_size, &pinned_slot->npages); + if (pinned_slot->pages == NULL) { + kfree(pinned_slot); + goto unlock; + } + + sev_clflush_pages(pinned_slot->pages, pinned_slot->npages); + + pinned_slot->id = memslot->id; + pinned_slot->userspace_addr = mem->userspace_addr; + list_add_tail(&pinned_slot->list, head); + + } else if (change == KVM_MR_DELETE) { + + pinned_slot = sev_find_pinned_memory_slot(kvm, memslot); + if (!pinned_slot) + goto unlock; + + sev_unpin_memory(pinned_slot->pages, pinned_slot->npages); + list_del(&pinned_slot->list); + kfree(pinned_slot); + } + +unlock: + mutex_unlock(&kvm->lock); +} + static int amd_memory_encryption_cmd(struct kvm *kvm, void __user *argp) { int r = -ENOTTY; @@ -6355,6 +6447,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = { .update_pi_irte = svm_update_pi_irte, .memory_encryption_op = amd_memory_encryption_cmd, + .prepare_memory_region = amd_prepare_memory_region, }; static int __init svm_init(void) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 6a737e9..e05069d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -8195,6 +8195,9 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, const struct kvm_userspace_memory_region *mem, enum kvm_mr_change change) { + if (kvm_x86_ops->prepare_memory_region) + kvm_x86_ops->prepare_memory_region(kvm, memslot, mem, change); + return 0; }