[RFC PATCH v3 1/5] KVM: guest_memfd: Refactor out kvm_gmem_alloc_file()

From: Tao Gong

Date: Mon Oct 26 2026 - 02:44:49 EST


From: Ackerley Tng <ackerleytng@xxxxxxxxxx>

The file represents a KVM instance's view into the underlying memory
that is managed by the guest_memfd inode. Refactoring out the file
creation enables this function to be reused when creating multiple views
into the same guest_memfd inode.

Signed-off-by: Ackerley Tng <ackerleytng@xxxxxxxxxx>
Co-developed-by: Ryan Afranji <afranji@xxxxxxxxxx>
Signed-off-by: Ryan Afranji <afranji@xxxxxxxxxx>
Co-developed-by: Tao Gong <gongtao@xxxxxxxxxx>
Signed-off-by: Tao Gong <gongtao@xxxxxxxxxx>
---
virt/kvm/guest_memfd.c | 67 +++++++++++++++++++++++++-----------------
1 file changed, 40 insertions(+), 27 deletions(-)

diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c
index 93f3d29d5751a..3ca6f64d48040 100644
--- a/virt/kvm/guest_memfd.c
+++ b/virt/kvm/guest_memfd.c
@@ -937,10 +937,47 @@ static int kvm_gmem_init_inode(struct inode *inode, loff_t size, u64 flags)
return r;
}

+/*
+ * Allocate a new guest_memfd file for @kvm that refers to @inode. On success,
+ * the returned file takes over the caller's reference to @inode.
+ */
+static struct file *kvm_gmem_alloc_file(struct kvm *kvm, struct inode *inode,
+ const char *name)
+{
+ struct gmem_file *f;
+ struct file *file;
+
+ f = kzalloc_obj(*f);
+ if (!f)
+ return ERR_PTR(-ENOMEM);
+
+ /* __fput() will take care of fops_put(). */
+ if (!fops_get(&kvm_gmem_fops)) {
+ kfree(f);
+ return ERR_PTR(-ENOENT);
+ }
+
+ file = alloc_file_pseudo(inode, kvm_gmem_mnt, name, O_RDWR, &kvm_gmem_fops);
+ if (IS_ERR(file)) {
+ fops_put(&kvm_gmem_fops);
+ kfree(f);
+ return file;
+ }
+
+ file->f_flags |= O_LARGEFILE;
+ file->private_data = f;
+
+ kvm_get_kvm(kvm);
+ f->kvm = kvm;
+ xa_init(&f->bindings);
+ list_add(&f->entry, &GMEM_I(inode)->gmem_file_list);
+
+ return file;
+}
+
static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags)
{
static const char *name = "[kvm-gmem]";
- struct gmem_file *f;
struct inode *inode;
struct file *file;
int fd, err;
@@ -949,51 +986,27 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags)
if (fd < 0)
return fd;

- f = kzalloc_obj(*f);
- if (!f) {
- err = -ENOMEM;
- goto err_fd;
- }
-
- /* __fput() will take care of fops_put(). */
- if (!fops_get(&kvm_gmem_fops)) {
- err = -ENOENT;
- goto err_gmem;
- }
-
inode = anon_inode_make_secure_inode(kvm_gmem_mnt->mnt_sb, name, NULL);
if (IS_ERR(inode)) {
err = PTR_ERR(inode);
- goto err_fops;
+ goto err_fd;
}

err = kvm_gmem_init_inode(inode, size, flags);
if (err)
goto err_inode;

- file = alloc_file_pseudo(inode, kvm_gmem_mnt, name, O_RDWR, &kvm_gmem_fops);
+ file = kvm_gmem_alloc_file(kvm, inode, name);
if (IS_ERR(file)) {
err = PTR_ERR(file);
goto err_inode;
}

- file->f_flags |= O_LARGEFILE;
- file->private_data = f;
-
- kvm_get_kvm(kvm);
- f->kvm = kvm;
- xa_init(&f->bindings);
- list_add(&f->entry, &GMEM_I(inode)->gmem_file_list);
-
fd_install(fd, file);
return fd;

err_inode:
iput(inode);
-err_fops:
- fops_put(&kvm_gmem_fops);
-err_gmem:
- kfree(f);
err_fd:
put_unused_fd(fd);
return err;
--
2.56.0.257.gf7497c7d27-goog