On 11.08.25 11:06, Shivank Garg wrote:
From: Ackerley Tng <ackerley...@google.com>

guest_memfd's inode represents memory the guest_memfd is
providing. guest_memfd's file represents a struct kvm's view of that
memory.

Using a custom inode allows customization of the inode teardown
process via callbacks. For example, ->evict_inode() allows
customization of the truncation process on file close, and
->destroy_inode() and ->free_inode() allow customization of the inode
freeing process.

Customizing the truncation process allows flexibility in management of
guest_memfd memory and customization of the inode freeing process
allows proper cleanup of memory metadata stored on the inode.

Memory metadata is more appropriately stored on the inode (as opposed
to the file), since the metadata is for the memory and is not unique
to a specific binding and struct kvm.

Co-developed-by: Fuad Tabba <ta...@google.com>
Signed-off-by: Fuad Tabba <ta...@google.com>
Signed-off-by: Ackerley Tng <ackerley...@google.com>
Signed-off-by: Shivank Garg <shiva...@amd.com>
---

[...]

static int kvm_gmem_migrate_folio(struct address_space *mapping,
@@ -463,11 +503,71 @@ bool __weak kvm_arch_supports_gmem_mmap(struct kvm *kvm)
        return true;
  }
+static struct inode *kvm_gmem_inode_make_secure_inode(const char *name,
+                                                     loff_t size, u64 flags)
+{
+       struct inode *inode;
+
+       inode = anon_inode_make_secure_inode(kvm_gmem_mnt->mnt_sb, name, NULL);
+       if (IS_ERR(inode))
+               return inode;
+
+       inode->i_private = (void *)(unsigned long)flags;
+       inode->i_op = &kvm_gmem_iops;
+       inode->i_mapping->a_ops = &kvm_gmem_aops;
+       inode->i_mode |= S_IFREG;
+       inode->i_size = size;
+       mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER);
+       mapping_set_inaccessible(inode->i_mapping);
+       /* Unmovable mappings are supposed to be marked unevictable as well. */
+       WARN_ON_ONCE(!mapping_unevictable(inode->i_mapping));
+
+       return inode;
+}
+
+static struct file *kvm_gmem_inode_create_getfile(void *priv, loff_t size,
+                                                 u64 flags)
+{
+       static const char *name = "[kvm-gmem]";
+       struct inode *inode;
+       struct file *file;
+       int err;
+
+       err = -ENOENT;

Maybe add a comment here when the module reference will get
dropped. And maybe we should just switch to fops_get() + fops_put?

/* __fput() will take care of fops_put(). */
if (!fops_get(&kvm_gmem_fops))
        goto err;

+
+       inode = kvm_gmem_inode_make_secure_inode(name, size, flags);
+       if (IS_ERR(inode)) {
+               err = PTR_ERR(inode);
+               goto err_put_module;
+       }
+
+       file = alloc_file_pseudo(inode, kvm_gmem_mnt, name, O_RDWR,
+                                &kvm_gmem_fops);
+       if (IS_ERR(file)) {
+               err = PTR_ERR(file);
+               goto err_put_inode;
+       }
+
+       file->f_flags |= O_LARGEFILE;
+       file->private_data = priv;
+
+out:
+       return file;
+
+err_put_inode:
+       iput(inode);
+err_put_module:
+       module_put(kvm_gmem_fops.owner);

fops_put(&kvm_gmem_fops);

?


Acked-by: David Hildenbrand <da...@redhat.com>

--
Cheers,

David / dhildenb


Reply via email to