From patchwork Mon Aug 5 09:32:35 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gowans, James" X-Patchwork-Id: 13753327 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4D69EC3DA4A for ; Mon, 5 Aug 2024 09:33:26 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id C63006B0082; Mon, 5 Aug 2024 05:33:25 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id BEB7C6B0085; Mon, 5 Aug 2024 05:33:25 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id A655C6B0088; Mon, 5 Aug 2024 05:33:25 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 882786B0082 for ; Mon, 5 Aug 2024 05:33:25 -0400 (EDT) Received: from smtpin30.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay05.hostedemail.com (Postfix) with ESMTP id 0BACB41BFF for ; Mon, 5 Aug 2024 09:33:25 +0000 (UTC) X-FDA: 82417678770.30.A4577A9 Received: from smtp-fw-9106.amazon.com (smtp-fw-9106.amazon.com [207.171.188.206]) by imf04.hostedemail.com (Postfix) with ESMTP id E1EEC40009 for ; Mon, 5 Aug 2024 09:33:22 +0000 (UTC) Authentication-Results: imf04.hostedemail.com; dkim=pass header.d=amazon.com header.s=amazon201209 header.b=RplKCoy9; spf=pass (imf04.hostedemail.com: domain of "prvs=940e15008=jgowans@amazon.com" designates 207.171.188.206 as permitted sender) smtp.mailfrom="prvs=940e15008=jgowans@amazon.com"; dmarc=pass (policy=quarantine) header.from=amazon.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1722850341; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:in-reply-to: references:dkim-signature; bh=ysZOagAN9K1zsPHQ0+3bGUwQuaz+/zRHk10ZM4UgRVw=; b=WhLWJhWXzEII6czzuM8LaXxC5lLFJtEPQf3Zt9dWJM+bmi+FG/mQi3chBSuA+RIEUNI006 1CyORfAFvP6N1iriCiOUgJ8H/ajqIq2FV7AYen4ceevNMnPzskIfsglMZbSrrs3NqL19RJ adNEpNJSC7ayhPW0oTP3oEpxvSkUSFI= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1722850341; a=rsa-sha256; cv=none; b=PoOvg9tuPKmIKS5E8O5FQXhK7yWqKSJVNxzzWw2mUHnzqMlD6IUW9Ijt7HztojX+15oS1s CjTfhhYPVBAFZMTt4wHGf8TgcmbLdGudB0iNhVRkWbpdcO+d3ppbORpW2ogw5BzJmallDz KmJAPw0TJIS8bL82up7d7PRjo+WcQzc= ARC-Authentication-Results: i=1; imf04.hostedemail.com; dkim=pass header.d=amazon.com header.s=amazon201209 header.b=RplKCoy9; spf=pass (imf04.hostedemail.com: domain of "prvs=940e15008=jgowans@amazon.com" designates 207.171.188.206 as permitted sender) smtp.mailfrom="prvs=940e15008=jgowans@amazon.com"; dmarc=pass (policy=quarantine) header.from=amazon.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1722850403; x=1754386403; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=ysZOagAN9K1zsPHQ0+3bGUwQuaz+/zRHk10ZM4UgRVw=; b=RplKCoy9uHEbAKNkH/OaJptB9xTss2wCmKTwT6hZsadRMa2MkY0lVqCr kKEaO7BhrJH0OHn3tY94US/Y+EfqG6q8isY/hT5VovNHRdWTcZYy4u7V3 wsgOXHhZkPGzKgkhZbsW6hWGXORYC3hUlEPi47Mg0y5kY/9g9WLa9//qD c=; X-IronPort-AV: E=Sophos;i="6.09,264,1716249600"; d="scan'208";a="747198291" Received: from pdx4-co-svc-p1-lb2-vlan2.amazon.com (HELO smtpout.prod.us-east-1.prod.farcaster.email.amazon.dev) ([10.25.36.210]) by smtp-border-fw-9106.sea19.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Aug 2024 09:33:15 +0000 Received: from EX19MTAEUA001.ant.amazon.com [10.0.43.254:40744] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.14.164:2525] with esmtp (Farcaster) id 42289a65-0a12-41c0-a96c-f792eb8c9be8; Mon, 5 Aug 2024 09:33:13 +0000 (UTC) X-Farcaster-Flow-ID: 42289a65-0a12-41c0-a96c-f792eb8c9be8 Received: from EX19D014EUC004.ant.amazon.com (10.252.51.182) by EX19MTAEUA001.ant.amazon.com (10.252.50.192) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Mon, 5 Aug 2024 09:33:09 +0000 Received: from u5d18b891348c5b.ant.amazon.com (10.146.13.113) by EX19D014EUC004.ant.amazon.com (10.252.51.182) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA) id 15.2.1258.34; Mon, 5 Aug 2024 09:32:59 +0000 From: James Gowans To: CC: James Gowans , Sean Christopherson , Paolo Bonzini , Alexander Viro , Steve Sistare , Christian Brauner , Jan Kara , "Anthony Yznaga" , Mike Rapoport , "Andrew Morton" , , Jason Gunthorpe , , Usama Arif , , Alexander Graf , David Woodhouse , Paul Durrant , Nicolas Saenz Julienne Subject: [PATCH 00/10] Introduce guestmemfs: persistent in-memory filesystem Date: Mon, 5 Aug 2024 11:32:35 +0200 Message-ID: <20240805093245.889357-1-jgowans@amazon.com> X-Mailer: git-send-email 2.34.1 MIME-Version: 1.0 X-Originating-IP: [10.146.13.113] X-ClientProxiedBy: EX19D033UWC004.ant.amazon.com (10.13.139.225) To EX19D014EUC004.ant.amazon.com (10.252.51.182) X-Stat-Signature: dok6gk4awzunoqkarmiq8k3u8aay8mtq X-Rspamd-Queue-Id: E1EEC40009 X-Rspam-User: X-Rspamd-Server: rspam08 X-HE-Tag: 1722850402-769570 X-HE-Meta: U2FsdGVkX1/6+3h2z1S1J0AxgAXHHVVF9TqUofOmyD4mQSFaZ8fb7kaQ2VxAIBVK/k7GwKJuiTPXhhdgavQbMEfn4NtwVswuEfo47wbzmqHzZieUZo622AwfW6zjHUogxaoWOC3oCoRiJzRCvQtoJWd832/7rrWr+KcZpmsMpOiF13JeL7xk2JbxX/P40nUwTwtyOVbNhpvAsJ9fBEIdDpUnOOjdQliv6glmAVr0DuyqWOtSq55vC5LpA1SbhI0oUQEZtdwAwJfy6q1Dv85LqTXk24g9e2jUOfiyTyu5bve0JabvtDuB6QXNTEjQ9y1O7T+IZikB8qSioOLsOiLW0xRHaNxgVJqar152L86sekgD6AzdtmMPpfy7VoycvPWLk/GJ8V2/izFrwYqc232peMkdKrlRTSf29AK6FdA35/aZHu4Qu6xRx6UnM2m9cOlGeARKd5G4f6UMJK6ar7dO6DPSoLCML/xsYESeDOElASnnBVQuBInJZ/t5M6UkfmDRz2RBz2NuV/GBlEfQK3WFErboAnO2wWLm5GDIbhqYZJeAA/VA3KEWJLsF4Vk4C5eqX0Di+hhaWjXpwVtsdSrMYVAlG1SNniquOvDwxnJKgn9Wi34989oLuKGV0DKfAAQeH4YjQ+oBTnQ54SYDmWz7YFpwSoPu6KZxihK+wdy+t/7D16r9RgP+svBOzD61dT1hGEg6g51vKhsQEglbBYZHATXUWYALrpnO+NM0wcnsh7lx7V1j3mEdrwuqX/O3N9wW0jsUazAeA60y2eMM4UkpCRNgIR3fNmGp7ThdJt8/N71LmYozYDp0FiZVXtIYy5dS1bu4IeaZvAn4/b8km5wXHFlpWIUfK/sDzHckAKggln+2WiPdFxW+Ug+0UqJbWSlawEv7sOzWcnYfMg+VHPsBHEhAyIb78n5d7/xxUNsRmYvcE/rbzpzvzJ3HFzEWn5+gprabb44uUlCCfmJLiD6 n1AzhEHX jTet3Tf7WUqojBr4VcIGRkSiqe/6twCiWbVxF2VrzweI6XYMQdD+Y3IW/EKJdEEXze73T5aGOSGDonsoH7xS30si1I4M9yp+X1wR46p4UkJl86G7lNkDSJG8ESe+A5RAd+U2tLnskyZed+IeflPoKGA02Rlj4iXtTFtZWwUBblxLygCkixx1+KVT6wMtEjvDsG5YZnEYd5G70xzHddNXh+vnln9RbalaO/+WqxaHnm+65Pax5z4EwlyXJNc0Dq48zTamDKuM5fNlycH6avkHINkYvBvFm30QjumcT5Cj5awh3mK+z37K0yJM8JY+BjdBW/NW0QvDPGwMhUIjMNcrVvQbqRGupB1xiyPfRPLGJG+RIQdQelZwCkBP73THUnUHe/Jgei/YMRAorBsF2yW5R0C6L2dFwU5zfTVP7DwRimFxrZp02q3aXdOHue3Lt8UEUFV6RrHxpRp+SxUhK31b81PHN3cxvJtH8jZ3RJ+DtQzK9hqV3P866gUJpSlEh/pzTGit+922Z26GsJuRCuqncFgtc9s8O3kwcyP29RVRh5VS3YnebSBXnzqZlevPX6rqcNH+eFGNkbhT3t8E4cEmSoWB2cK+MuKyGJo/WoS2WkSBu97s9lQ4Xn4RrOKjeKgH52UYt119IBXoNGM4A1MrldLXRm5p6tKVhyrn/lHEmn6DjimQitbr7j+TcEH6Ic99GNlr+yFF0G64Ou/iqX6mxYGqqbA== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: In this patch series a new in-memory filesystem designed specifically for live update is implemented. Live update is a mechanism to support updating a hypervisor in a way that has limited impact to running virtual machines. This is done by pausing/serialising running VMs, kexec-ing into a new kernel, starting new VMM processes and then deserialising/resuming the VMs so that they continue running from where they were. To support this, guest memory needs to be preserved. Guestmemfs implements preservation acrosss kexec by carving out a large contiguous block of host system RAM early in boot which is then used as the data for the guestmemfs files. As well as preserving that large block of data memory across kexec, the filesystem metadata is preserved via the Kexec Hand Over (KHO) framework (still under review): https://lore.kernel.org/all/20240117144704.602-1-graf@amazon.com/ Filesystem metadata is structured to make preservation across kexec easy: inodes are one large contiguous array, and each inode has a "mappings" block which defines which block from the filesystem data memory corresponds to which offset in the file. There are additional constraints/requirements which guestmemfs aims to meet: 1. Secret hiding: all filesystem data is removed from the kernel direct map so immune from speculative access. read()/write() are not supported; the only way to get at the data is via mmap. 2. Struct page overhead elimination: the memory is not managed by the buddy allocator and hence has no struct pages. 3. PMD and PUD level allocations for TLB performance: guestmemfs allocates PMD-sized pages to back files which improves TLB perf (caveat below!). PUD size allocations are a next step. 4. Device assignment: being able to use guestmemfs memory for VFIO/iommufd mappings, and allow those mappings to survive and continue to be used across kexec. Next steps ========= The idea is that this patch series implements a minimal filesystem to provide the foundations for in-memory persistent across kexec files. One this foundation is in place it will be extended: 1. Improve the filesystem to be more comprehensive - currently it's just functional enough to demonstrate the main objective of reserved memory and persistence via KHO. 2. Build support for iommufd IOAS and HWPT persistence, and integrate that with guestmemfs. The idea is that if VMs have DMA devices assigned to them, DMA should continue running across kexec. A future patch series will add support for this in iommufd and connect iommufd to guestmemfs so that guestmemfs files can remain mapped into the IOMMU during kexec. 3. Support a guest_memfd interface to files so that they can be used for confidential computing without needing to mmap into userspace. 3. Gigantic PUD level mappings for even better TLB perf. Caveats ======= There are a issues with the current implementation which should be solved either in this patch series or soon in follow-on work: 1. Although PMD-size allocations are done, PTE-level page tables are still created. This is because guestmemfs uses remap_pfn_range() to set up userspace pgtables. Currently remap_pfn_range() only creates PTE-level mappings. I suggest enhancing remap_pfn_range() to support creating higher level mappings where possible, by adding pmd_special and pud_special flags. 2. NUMA support is currently non-existent. To make this more generally useful it's necessary to have NUMA-awareness. One thought on how to do this is to be able to specify multiple allocations with wNUMA affinity on the kernel cmdline and have multiple mount points, one per NUMA node. Currently, for simplicity, only a single contiguous filesystem data allocation and a single mount point is supported. 3. MCEs are currently not handled - we need to add functionality for this to be able to track block ownership and deliver an MCE correctly. 4. Looking for reviews from filesystem experts to see if necessary callbacks, refcounting, locking, etc, is done correctly. Open questions ============== It is not too clear if or how guestmemfs should use DAX as a source of memory. Seeing as guestmemfs has an in-memory design, it seems that it is not necessary to use DAX as a source of memory, but I am keen for guidance/input on whether DAX should be used here. The filesystem data memory is removed from the direct map for secret hiding, but it is still necessary to mmap it to be accessible to KVM. For improving secret hiding even more a guest_memfd-style interface could be used to remove the need to mmap. That introduces a new problem of the memory being completely inaccessible to KVM for this like MMIO instruction emulation. How can this be handled? Related Work ============ There are similarities to a few attempts at solving aspects of this problem previously. The original was probably PKRAM from Oracle; a tempfs filesystem with persistence: https://lore.kernel.org/kexec/1682554137-13938-1-git-send-email-anthony.yznaga@oracle.com/ guestmemfs will additionally provide secret hiding, PMD/PUD allocations and a path to DMA persistence and NUMA support. Dmemfs from Tencent aimed to remove the need for struct page overhead: https://lore.kernel.org/kvm/cover.1602093760.git.yuleixzhang@tencent.com/ Guestmemfs provides this benefit too, along with persistence across kexec and secret hiding. Pkernfs attempted to solve guest memory persistence and IOMMU persistence all in one: https://lore.kernel.org/all/20240205120203.60312-1-jgowans@amazon.com/ Guestmemfs is a re-work of that to only persist guest RAM in the filesystem, and to use KHO for filesystem metadata. IOMMU persistence will be implemented independently with persistent iommufd domains via KHO. Testing ======= The testing for this can be seen in the Documentation file in this patch series. Essentially it is using a guestmemfs file for a QEMU VM's RAM, doing a kexec, restoring the QEMU VM and confirming that the VM picked up from where it left off. James Gowans (10): guestmemfs: Introduce filesystem skeleton guestmemfs: add inode store, files and dirs guestmemfs: add persistent data block allocator guestmemfs: support file truncation guestmemfs: add file mmap callback kexec/kho: Add addr flag to not initialise memory guestmemfs: Persist filesystem metadata via KHO guestmemfs: Block modifications when serialised guestmemfs: Add documentation and usage instructions MAINTAINERS: Add maintainers for guestmemfs Documentation/filesystems/guestmemfs.rst | 87 +++++++ MAINTAINERS | 8 + arch/x86/mm/init_64.c | 2 + fs/Kconfig | 1 + fs/Makefile | 1 + fs/guestmemfs/Kconfig | 11 + fs/guestmemfs/Makefile | 8 + fs/guestmemfs/allocator.c | 40 +++ fs/guestmemfs/dir.c | 43 ++++ fs/guestmemfs/file.c | 106 ++++++++ fs/guestmemfs/guestmemfs.c | 160 ++++++++++++ fs/guestmemfs/guestmemfs.h | 60 +++++ fs/guestmemfs/inode.c | 189 ++++++++++++++ fs/guestmemfs/serialise.c | 302 +++++++++++++++++++++++ include/linux/guestmemfs.h | 16 ++ include/uapi/linux/kexec.h | 6 + kernel/kexec_kho_in.c | 12 +- kernel/kexec_kho_out.c | 4 + 18 files changed, 1055 insertions(+), 1 deletion(-) create mode 100644 Documentation/filesystems/guestmemfs.rst create mode 100644 fs/guestmemfs/Kconfig create mode 100644 fs/guestmemfs/Makefile create mode 100644 fs/guestmemfs/allocator.c create mode 100644 fs/guestmemfs/dir.c create mode 100644 fs/guestmemfs/file.c create mode 100644 fs/guestmemfs/guestmemfs.c create mode 100644 fs/guestmemfs/guestmemfs.h create mode 100644 fs/guestmemfs/inode.c create mode 100644 fs/guestmemfs/serialise.c create mode 100644 include/linux/guestmemfs.h