From patchwork Mon Aug 5 09:32:36 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gowans, James" X-Patchwork-Id: 13753326 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 1C8F3C3DA7F for ; Mon, 5 Aug 2024 09:33:24 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 647976B007B; Mon, 5 Aug 2024 05:33:24 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 5F7BF6B0082; Mon, 5 Aug 2024 05:33:24 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 498516B0085; Mon, 5 Aug 2024 05:33:24 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 27DA16B007B for ; Mon, 5 Aug 2024 05:33:24 -0400 (EDT) Received: from smtpin17.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id B58CB1601EA for ; Mon, 5 Aug 2024 09:33:23 +0000 (UTC) X-FDA: 82417678686.17.D8984B5 Received: from smtp-fw-52003.amazon.com (smtp-fw-52003.amazon.com [52.119.213.152]) by imf07.hostedemail.com (Postfix) with ESMTP id C865540002 for ; Mon, 5 Aug 2024 09:33:21 +0000 (UTC) Authentication-Results: imf07.hostedemail.com; dkim=pass header.d=amazon.com header.s=amazon201209 header.b="kMHfbr/j"; spf=pass (imf07.hostedemail.com: domain of "prvs=940e15008=jgowans@amazon.com" designates 52.119.213.152 as permitted sender) smtp.mailfrom="prvs=940e15008=jgowans@amazon.com"; dmarc=pass (policy=quarantine) header.from=amazon.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1722850371; a=rsa-sha256; cv=none; b=UQht70GjawbImemEQTlYbJYm/9yYFckK2soOZe9ern14hgHy0pWgQSt7NthMOg3CIbpvjU KaVOBWBd4T0iyGjtlicut12mjyf4+SPrXtyReVTdElDks+qDQ9lstEEkcpa8vxDa+qe+uz 0aPpjs9Cth/zpDGm/4gXyz1WnMS8PAk= ARC-Authentication-Results: i=1; imf07.hostedemail.com; dkim=pass header.d=amazon.com header.s=amazon201209 header.b="kMHfbr/j"; spf=pass (imf07.hostedemail.com: domain of "prvs=940e15008=jgowans@amazon.com" designates 52.119.213.152 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=1722850371; 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:in-reply-to:references:references:dkim-signature; bh=CIMC4dBHyqkF/IJtbOCSyvit7T6FcLaiifrH1Oqev8I=; b=AhtMhEFrt/7B7Db/dxZ6CuWRCEY/+nJS7LhZVgB+I0+7C1jOXO2/qbDZd0rOnBldFXcp0F Bs9TAbnxE/Bld/W5FzGpX6hh3w/8BdChLObBYBtgHLwFfiXTbttseHFREY4I9br91pKIRm RE02rtt6dJmjfDJMQBU2zOZ1ggrQhFI= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amazon.com; i=@amazon.com; q=dns/txt; s=amazon201209; t=1722850402; x=1754386402; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=CIMC4dBHyqkF/IJtbOCSyvit7T6FcLaiifrH1Oqev8I=; b=kMHfbr/jpwBdUFPda9lxD45d72LjciyQNLbdVoo8xbQEho5sIeI/hhE7 WrucxuP+39cmAPrZzzRtwyiZh8kAxbYK22VE+Op54EotYWDVbZdj07ISB iSqeZ2SlYqJH/ETeFLEqq+YaothWLygkp9EErrH+LijYS+UpO/en+vS5/ U=; X-IronPort-AV: E=Sophos;i="6.09,264,1716249600"; d="scan'208";a="16963930" Received: from iad12-co-svc-p1-lb1-vlan3.amazon.com (HELO smtpout.prod.us-east-1.prod.farcaster.email.amazon.dev) ([10.43.8.6]) by smtp-border-fw-52003.iad7.amazon.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 05 Aug 2024 09:33:20 +0000 Received: from EX19MTAEUA002.ant.amazon.com [10.0.43.254:34036] by smtpin.naws.eu-west-1.prod.farcaster.email.amazon.dev [10.0.35.73:2525] with esmtp (Farcaster) id 9a93516f-30d6-4fa2-8ce9-a895a0a56cc5; Mon, 5 Aug 2024 09:33:18 +0000 (UTC) X-Farcaster-Flow-ID: 9a93516f-30d6-4fa2-8ce9-a895a0a56cc5 Received: from EX19D014EUC004.ant.amazon.com (10.252.51.182) by EX19MTAEUA002.ant.amazon.com (10.252.50.126) 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:18 +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:33:09 +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 01/10] guestmemfs: Introduce filesystem skeleton Date: Mon, 5 Aug 2024 11:32:36 +0200 Message-ID: <20240805093245.889357-2-jgowans@amazon.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240805093245.889357-1-jgowans@amazon.com> References: <20240805093245.889357-1-jgowans@amazon.com> 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: 4znpefwb6um9wsxr8fd6yt797urppin4 X-Rspamd-Queue-Id: C865540002 X-Rspam-User: X-Rspamd-Server: rspam10 X-HE-Tag: 1722850401-40270 X-HE-Meta: U2FsdGVkX19Fe92g9PCqyXokX5gXWshxaPDT7BL2M5ak8rf4LVS+FHj2K45kti+4YqkpBvOT0G7yeMqDpJ5PQmwPgLtwioX/+LkhbcIYc7lO4L1vS0pwO1H4iWBkaPdK1EBZaz4aGv9JcFr6D29Hk0vFDGuNJzgdSeX6hdRfj9O4/HnNvhLhF8q88IuAaBLuFVuokGPGidLE4VigQ7+7l18kCTmkIVgH0fqU60y/6spV9HZKidFtBcFpTgARFzLlJ1isAN9CamXFzNom3ULMgsDAldp435gZaH42OLLpRyj4OXdiWiPT3cUpzLhCOBcjVHTnCubEctHsUhhnodRvwjVXFj6aaZ0GLxdkBr3FiffmfGtwggtis561IEyNtmvwdIUnfIEwHsztEavYez7/ONdPz/u3D+PUvqwf36f+bXuHvZbp0svzN6E4lUkRqbIBdN4QYuq2+m3pPQg8Ennq1tpIHM7MFqQeERAo8WirAyG4tGsFYgsJnZObMH9dtJUg3BzF1+u5abDH2WrCzt4dGfpUrpUrTHHZH4DaOUcYPfneCOslAyQPkfWA1Glh9p0JGmyHZUzUMUUDInBTON4CiyQsJRUCoCPlveuarqzPpXk1kq7cRgvzSpvN7VLqPt9G5vjVNh9RoxbHuNoNNZ2KdAhkiCYxu3Ov08shoX3gve1kvFqCS23hinNhO+EKh3SKnLrW/P9eqlbuhb6CoyIlOqVnEfIJy/K6iDYbsqYDASow33stCoLeyoasPdKo8ZtaZeG5QtukHXIo4AeffzIm+IFXvVTREhCUJGa0nKsrI5rFszF+sNNgq1t7gUqZ4AkyzRvTAC3LAAWo7EW3KwfZZH8fwkSHSQ4mhowUk5ft6SSO4CHEFWZCOsHOX4s6+yxg+Ad6MKujNq1ryrwFCs6dINgUnUjTF7QJPWnPsxGTuQjpjZeo9uwL76mQwhp0yg+3ned6vHUg64+MAQEi6e1 qN7cLvE/ h3DPUQu2R9i6UfIlRCDEzkfut/ZaeAx+PSzqh5e8vZIe/Fge7DVAQ7U2pcb7lgOfagM4XsqwMdMr97ZNUuaENPwPcDpIfOGqFLYrrRNb4pM3+7U/m6JVLR3oaN9w3DApz1EAWqFh5nQVAXl+kmy/5GGm/HuQfRaqKkdprHpvn4jJVKgT6nvtu+GptTKZh+7TrGExjQWB+fpc09ekXSSPsGQ+r0j8mbZdnMo6Sdh0D3pShGyQg6UukBh0VQK0r3/yv71ktTNM/g5+55UQRzWyHZ9ryGp3dZzGkxmyIyuTShNLP7SQ72vvJEVHZdZPpKWPfr91dMmQ53Q7F0Nb6oMl+O+ubOp3teuQD3zQ19Cxx6Hikic/jtaL/lp+Ar/pbt0T+X0TtO3e/sDq0JiIGOA6iI736CGBaPBofDMjplIpOiXvVdnTvsJI0Y/P79fvsn4/kR99syMW+mVeGZeOTtf4z723g85+dIR0+yTXz8bumjOA43r+/Exl96Cf2KpcxPzKuFtpYpgU6fvWLLPoP9fN578mwQpoC+m7NMAQGhAufz/gDRBcRC17Ea+ETjf4OcH5uXnObxiJ4dbAgWQE= 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: Add an in-memory filesystem: guestmemfs. Memory is donated to guestmemfs by carving it out of the normal System RAM range with the memmap= cmdline parameter and then giving that same physical range to guestmemfs with the guestmemfs= cmdline parameter. A new filesystem is added; so far it doesn't do much except persist a super block at the start of the donated memory and allows itself to be mounted. A hook to x86 mm init is added to reserve the memory really early on via memblock allocator. There is probably a better arch-independent place to do this... Signed-off-by: James Gowans --- arch/x86/mm/init_64.c | 2 + fs/Kconfig | 1 + fs/Makefile | 1 + fs/guestmemfs/Kconfig | 11 ++++ fs/guestmemfs/Makefile | 6 ++ fs/guestmemfs/guestmemfs.c | 116 +++++++++++++++++++++++++++++++++++++ fs/guestmemfs/guestmemfs.h | 9 +++ include/linux/guestmemfs.h | 16 +++++ 8 files changed, 162 insertions(+) create mode 100644 fs/guestmemfs/Kconfig create mode 100644 fs/guestmemfs/Makefile create mode 100644 fs/guestmemfs/guestmemfs.c create mode 100644 fs/guestmemfs/guestmemfs.h create mode 100644 include/linux/guestmemfs.h diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 8932ba8f5cdd..39fcf017c90c 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -1331,6 +1332,7 @@ static void __init preallocate_vmalloc_pages(void) void __init mem_init(void) { + guestmemfs_reserve_mem(); pci_iommu_alloc(); /* clear_bss() already clear the empty_zero_page */ diff --git a/fs/Kconfig b/fs/Kconfig index a46b0cbc4d8f..727359901da8 100644 --- a/fs/Kconfig +++ b/fs/Kconfig @@ -321,6 +321,7 @@ source "fs/befs/Kconfig" source "fs/bfs/Kconfig" source "fs/efs/Kconfig" source "fs/jffs2/Kconfig" +source "fs/guestmemfs/Kconfig" # UBIFS File system configuration source "fs/ubifs/Kconfig" source "fs/cramfs/Kconfig" diff --git a/fs/Makefile b/fs/Makefile index 6ecc9b0a53f2..044524b17d63 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -129,3 +129,4 @@ obj-$(CONFIG_EFIVAR_FS) += efivarfs/ obj-$(CONFIG_EROFS_FS) += erofs/ obj-$(CONFIG_VBOXSF_FS) += vboxsf/ obj-$(CONFIG_ZONEFS_FS) += zonefs/ +obj-$(CONFIG_GUESTMEMFS_FS) += guestmemfs/ diff --git a/fs/guestmemfs/Kconfig b/fs/guestmemfs/Kconfig new file mode 100644 index 000000000000..d87fca4822cb --- /dev/null +++ b/fs/guestmemfs/Kconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config GUESTMEMFS_FS + bool "Persistent Guest memory filesystem (guestmemfs)" + help + An in-memory filesystem on top of reserved memory specified via + guestmemfs= cmdline argument. Used for storing kernel state and + userspace memory which is preserved across kexec to support + live update of a hypervisor when running guest virtual machines. + Select this if you need the ability to persist memory for guest VMs + across kexec to do live update. diff --git a/fs/guestmemfs/Makefile b/fs/guestmemfs/Makefile new file mode 100644 index 000000000000..6dc820a9d4fe --- /dev/null +++ b/fs/guestmemfs/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +# +# Makefile for persistent kernel filesystem +# + +obj-y += guestmemfs.o diff --git a/fs/guestmemfs/guestmemfs.c b/fs/guestmemfs/guestmemfs.c new file mode 100644 index 000000000000..3aaada1b8df6 --- /dev/null +++ b/fs/guestmemfs/guestmemfs.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include "guestmemfs.h" +#include +#include +#include +#include +#include +#include +#include + +static phys_addr_t guestmemfs_base, guestmemfs_size; +struct guestmemfs_sb *psb; + +static int statfs(struct dentry *root, struct kstatfs *buf) +{ + simple_statfs(root, buf); + buf->f_bsize = PMD_SIZE; + buf->f_blocks = guestmemfs_size / PMD_SIZE; + buf->f_bfree = buf->f_bavail = buf->f_blocks; + return 0; +} + +static const struct super_operations guestmemfs_super_ops = { + .statfs = statfs, +}; + +static int guestmemfs_fill_super(struct super_block *sb, struct fs_context *fc) +{ + struct inode *inode; + struct dentry *dentry; + + psb = kzalloc(sizeof(*psb), GFP_KERNEL); + /* + * Keep a reference to the persistent super block in the + * ephemeral super block. + */ + sb->s_fs_info = psb; + sb->s_op = &guestmemfs_super_ops; + + inode = new_inode(sb); + if (!inode) + return -ENOMEM; + + inode->i_ino = 1; + inode->i_mode = S_IFDIR; + inode->i_op = &simple_dir_inode_operations; + inode->i_fop = &simple_dir_operations; + simple_inode_init_ts(inode); + /* directory inodes start off with i_nlink == 2 (for "." entry) */ + inc_nlink(inode); + + dentry = d_make_root(inode); + if (!dentry) + return -ENOMEM; + sb->s_root = dentry; + + return 0; +} + +static int guestmemfs_get_tree(struct fs_context *fc) +{ + return get_tree_nodev(fc, guestmemfs_fill_super); +} + +static const struct fs_context_operations guestmemfs_context_ops = { + .get_tree = guestmemfs_get_tree, +}; + +static int guestmemfs_init_fs_context(struct fs_context *const fc) +{ + fc->ops = &guestmemfs_context_ops; + return 0; +} + +static struct file_system_type guestmemfs_fs_type = { + .owner = THIS_MODULE, + .name = "guestmemfs", + .init_fs_context = guestmemfs_init_fs_context, + .kill_sb = kill_litter_super, + .fs_flags = FS_USERNS_MOUNT, +}; + +static int __init guestmemfs_init(void) +{ + int ret; + + ret = register_filesystem(&guestmemfs_fs_type); + return ret; +} + +/** + * Format: guestmemfs=: + * Just like: memmap=nn[KMG]!ss[KMG] + */ +static int __init parse_guestmemfs_extents(char *p) +{ + guestmemfs_size = memparse(p, &p); + return 0; +} + +early_param("guestmemfs", parse_guestmemfs_extents); + +void __init guestmemfs_reserve_mem(void) +{ + guestmemfs_base = memblock_phys_alloc(guestmemfs_size, 4 << 10); + if (guestmemfs_base) { + memblock_reserved_mark_noinit(guestmemfs_base, guestmemfs_size); + memblock_mark_nomap(guestmemfs_base, guestmemfs_size); + } else { + pr_warn("Failed to alloc %llu bytes for guestmemfs\n", guestmemfs_size); + } +} + +MODULE_ALIAS_FS("guestmemfs"); +module_init(guestmemfs_init); diff --git a/fs/guestmemfs/guestmemfs.h b/fs/guestmemfs/guestmemfs.h new file mode 100644 index 000000000000..37d8cf630e0a --- /dev/null +++ b/fs/guestmemfs/guestmemfs.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define pr_fmt(fmt) "guestmemfs: " KBUILD_MODNAME ": " fmt + +#include + +struct guestmemfs_sb { + /* Will be populated soon... */ +}; diff --git a/include/linux/guestmemfs.h b/include/linux/guestmemfs.h new file mode 100644 index 000000000000..60e769c8e533 --- /dev/null +++ b/include/linux/guestmemfs.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT */ + +#ifndef _LINUX_GUESTMEMFS_H +#define _LINUX_GUESTMEMFS_H + +/* + * Carves out chunks of memory from memblocks for guestmemfs. + * Must be called in early boot before memblocks are freed. + */ +# ifdef CONFIG_GUESTMEMFS_FS +void guestmemfs_reserve_mem(void); +#else +void guestmemfs_reserve_mem(void) { } +#endif + +#endif