[PATCH gmem FIXUP] kvm: guestmem: do not use a file system

From: Paolo Bonzini
Date: Thu Sep 28 2023 - 14:07:50 EST


Use a run-of-the-mill anonymous inode, there is nothing useful
being provided by kvm_gmem_fs.

Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
include/uapi/linux/magic.h | 1 -
virt/kvm/guest_mem.c | 110 ++++++++++---------------------------
virt/kvm/kvm_main.c | 6 --
3 files changed, 30 insertions(+), 87 deletions(-)

diff --git a/include/uapi/linux/magic.h b/include/uapi/linux/magic.h
index afe9c376c9a5..6325d1d0e90f 100644
--- a/include/uapi/linux/magic.h
+++ b/include/uapi/linux/magic.h
@@ -101,6 +101,5 @@
#define DMA_BUF_MAGIC 0x444d4142 /* "DMAB" */
#define DEVMEM_MAGIC 0x454d444d /* "DMEM" */
#define SECRETMEM_MAGIC 0x5345434d /* "SECM" */
-#define KVM_GUEST_MEMORY_MAGIC 0x474d454d /* "GMEM" */

#endif /* __LINUX_MAGIC_H__ */
diff --git a/virt/kvm/guest_mem.c b/virt/kvm/guest_mem.c
index a819367434e9..73b841a2e1b1 100644
--- a/virt/kvm/guest_mem.c
+++ b/virt/kvm/guest_mem.c
@@ -3,14 +3,10 @@
#include <linux/falloc.h>
#include <linux/kvm_host.h>
#include <linux/pagemap.h>
-#include <linux/pseudo_fs.h>
-
-#include <uapi/linux/magic.h>
+#include <linux/anon_inodes.h>

#include "kvm_mm.h"

-static struct vfsmount *kvm_gmem_mnt;
-
struct kvm_gmem {
struct kvm *kvm;
struct xarray bindings;
@@ -356,23 +352,40 @@ static const struct inode_operations kvm_gmem_iops = {
.setattr = kvm_gmem_setattr,
};

-static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags,
- struct vfsmount *mnt)
+static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags)
{
const char *anon_name = "[kvm-gmem]";
- const struct qstr qname = QSTR_INIT(anon_name, strlen(anon_name));
struct kvm_gmem *gmem;
struct inode *inode;
struct file *file;
int fd, err;

- inode = alloc_anon_inode(mnt->mnt_sb);
- if (IS_ERR(inode))
- return PTR_ERR(inode);
+ fd = get_unused_fd_flags(0);
+ if (fd < 0)
+ return fd;

- err = security_inode_init_security_anon(inode, &qname, NULL);
- if (err)
- goto err_inode;
+ gmem = kzalloc(sizeof(*gmem), GFP_KERNEL);
+ if (!gmem) {
+ err = -ENOMEM;
+ goto err_fd;
+ }
+
+ file = anon_inode_getfile(anon_name, &kvm_gmem_fops, gmem,
+ O_RDWR);
+ if (IS_ERR(file)) {
+ err = PTR_ERR(file);
+ goto err_gmem;
+ }
+
+ file->f_flags |= O_LARGEFILE;
+
+ kvm_get_kvm(kvm);
+ gmem->kvm = kvm;
+ xa_init(&gmem->bindings);
+ list_add(&gmem->entry, &file->f_mapping->private_list);
+
+ inode = file->f_inode;
+ WARN_ON(file->f_mapping != inode->i_mapping);

inode->i_private = (void *)(unsigned long)flags;
inode->i_op = &kvm_gmem_iops;
@@ -385,44 +398,13 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags,
/* Unmovable mappings are supposed to be marked unevictable as well. */
WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping));

- fd = get_unused_fd_flags(0);
- if (fd < 0) {
- err = fd;
- goto err_inode;
- }
-
- file = alloc_file_pseudo(inode, mnt, "kvm-gmem", O_RDWR, &kvm_gmem_fops);
- if (IS_ERR(file)) {
- err = PTR_ERR(file);
- goto err_fd;
- }
-
- file->f_flags |= O_LARGEFILE;
- file->f_mapping = inode->i_mapping;
-
- gmem = kzalloc(sizeof(*gmem), GFP_KERNEL);
- if (!gmem) {
- err = -ENOMEM;
- goto err_file;
- }
-
- kvm_get_kvm(kvm);
- gmem->kvm = kvm;
- xa_init(&gmem->bindings);
-
- file->private_data = gmem;
-
- list_add(&gmem->entry, &inode->i_mapping->private_list);
-
fd_install(fd, file);
return fd;

-err_file:
- fput(file);
+err_gmem:
+ kfree(gmem);
err_fd:
put_unused_fd(fd);
-err_inode:
- iput(inode);
return err;
}

@@ -455,7 +437,7 @@ int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args)
if (!kvm_gmem_is_valid_size(size, flags))
return -EINVAL;

- return __kvm_gmem_create(kvm, size, flags, kvm_gmem_mnt);
+ return __kvm_gmem_create(kvm, size, flags);
}

int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot,
@@ -603,35 +585,3 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot,
return r;
}
EXPORT_SYMBOL_GPL(kvm_gmem_get_pfn);
-
-static int kvm_gmem_init_fs_context(struct fs_context *fc)
-{
- if (!init_pseudo(fc, KVM_GUEST_MEMORY_MAGIC))
- return -ENOMEM;
-
- return 0;
-}
-
-static struct file_system_type kvm_gmem_fs = {
- .name = "kvm_guest_memory",
- .init_fs_context = kvm_gmem_init_fs_context,
- .kill_sb = kill_anon_super,
-};
-
-int kvm_gmem_init(void)
-{
- kvm_gmem_mnt = kern_mount(&kvm_gmem_fs);
- if (IS_ERR(kvm_gmem_mnt))
- return PTR_ERR(kvm_gmem_mnt);
-
- /* For giggles. Userspace can never map this anyways. */
- kvm_gmem_mnt->mnt_flags |= MNT_NOEXEC;
-
- return 0;
-}
-
-void kvm_gmem_exit(void)
-{
- kern_unmount(kvm_gmem_mnt);
- kvm_gmem_mnt = NULL;
-}
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index a83dfef1316e..4a1ded1faf84 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -6424,10 +6424,6 @@ int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module)
if (r)
goto err_async_pf;

- r = kvm_gmem_init();
- if (r)
- goto err_gmem;
-
kvm_chardev_ops.owner = module;

kvm_preempt_ops.sched_in = kvm_sched_in;
@@ -6454,8 +6450,6 @@ int kvm_init(unsigned vcpu_size, unsigned vcpu_align, struct module *module)
err_register:
kvm_vfio_ops_exit();
err_vfio:
- kvm_gmem_exit();
-err_gmem:
kvm_async_pf_deinit();
err_async_pf:
kvm_irqfd_exit();
--
2.39.1