Tarun Sahu <[email protected]> writes: > Extract 'struct gmem_file', 'struct gmem_inode', and GMEM_I() from > virt/kvm/guest_memfd.c into a new internal header virt/kvm/guest_memfd.h. > Also split __kvm_gmem_create() to expose a non-static > __kvm_gmem_create_file() helper that returns a 'struct file *' instead of > an fd. >
This is done basically to support a new virt/kvm/guest_memfd_luo.c file. Would like to know what Sean thinks of this! I'd like to know for future guest_memfd work too. > These internal definitions and helpers allow upcoming guest_memfd Live > Update Orchestrator (LUO) preservation code to access guest_memfd > internals and reconstruct guest_memfd file instances from preserved state > without installing them into a file descriptor table up front. > > Signed-off-by: Tarun Sahu <[email protected]> > --- > virt/kvm/guest_memfd.c | 68 +++++++++++++++++------------------------- > virt/kvm/guest_memfd.h | 39 ++++++++++++++++++++++++ > 2 files changed, 67 insertions(+), 40 deletions(-) > create mode 100644 virt/kvm/guest_memfd.h > > diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c > index db57c5766ab6..dd84bba8974b 100644 > --- a/virt/kvm/guest_memfd.c > +++ b/virt/kvm/guest_memfd.c > @@ -7,38 +7,12 @@ > #include <linux/mempolicy.h> > #include <linux/pseudo_fs.h> > #include <linux/pagemap.h> > +#include "guest_memfd.h" > > #include "kvm_mm.h" > > static struct vfsmount *kvm_gmem_mnt; > > -/* > - * A guest_memfd instance can be associated multiple VMs, each with its own > - * "view" of the underlying physical memory. > - * > - * The gmem's inode is effectively the raw underlying physical storage, and > is > - * used to track properties of the physical memory, while each gmem file is > - * effectively a single VM's view of that storage, and is used to track > assets > - * specific to its associated VM, e.g. memslots=>gmem bindings. > - */ > -struct gmem_file { > - struct kvm *kvm; > - struct xarray bindings; > - struct list_head entry; > -}; > - > -struct gmem_inode { > - struct shared_policy policy; > - struct inode vfs_inode; > - struct list_head gmem_file_list; > - > - u64 flags; > -}; > - > -static __always_inline struct gmem_inode *GMEM_I(struct inode *inode) > -{ > - return container_of(inode, struct gmem_inode, vfs_inode); > -} > > #define kvm_gmem_for_each_file(f, inode) \ > list_for_each_entry(f, &GMEM_I(inode)->gmem_file_list, entry) > @@ -557,23 +531,17 @@ bool __weak kvm_arch_supports_gmem_init_shared(struct > kvm *kvm) > return true; > } > > -static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags) > +struct file *__kvm_gmem_create_file(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; > - > - fd = get_unused_fd_flags(0); > - if (fd < 0) > - return fd; > + int err; > > f = kzalloc_obj(*f); > - if (!f) { > - err = -ENOMEM; > - goto err_fd; > - } > + if (!f) > + return ERR_PTR(-ENOMEM); > > /* __fput() will take care of fops_put(). */ > if (!fops_get(&kvm_gmem_fops)) { > @@ -612,8 +580,7 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t > size, u64 flags) > xa_init(&f->bindings); > list_add(&f->entry, &GMEM_I(inode)->gmem_file_list); > > - fd_install(fd, file); > - return fd; > + return file; > > err_inode: > iput(inode); > @@ -621,7 +588,28 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t > size, u64 flags) > fops_put(&kvm_gmem_fops); > err_gmem: > kfree(f); > -err_fd: > + return ERR_PTR(err); > +} > + > +static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags) > +{ > + struct file *file; > + int fd, err; > + > + fd = get_unused_fd_flags(0); > + if (fd < 0) > + return fd; > + > + file = __kvm_gmem_create_file(kvm, size, flags); > + if (IS_ERR(file)) { > + err = PTR_ERR(file); > + goto err_put_fd; > + } > + > + fd_install(fd, file); > + return fd; > + > +err_put_fd: > put_unused_fd(fd); > return err; > } > diff --git a/virt/kvm/guest_memfd.h b/virt/kvm/guest_memfd.h > new file mode 100644 > index 000000000000..c528b046dd69 > --- /dev/null > +++ b/virt/kvm/guest_memfd.h > @@ -0,0 +1,39 @@ > +/* SPDX-License-Identifier: GPL-2.0-only */ > +#ifndef __KVM_GUEST_MEMFD_H__ > +#define __KVM_GUEST_MEMFD_H__ 1 > + > +#include <linux/kvm_host.h> > +#include <linux/fs.h> > +#include <linux/mempolicy.h> > + > +/* > + * A guest_memfd instance can be associated multiple VMs, each with its own > + * "view" of the underlying physical memory. > + * > + * The gmem's inode is effectively the raw underlying physical storage, and > is > + * used to track properties of the physical memory, while each gmem file is > + * effectively a single VM's view of that storage, and is used to track > assets > + * specific to its associated VM, e.g. memslots=>gmem bindings. > + */ > +struct gmem_file { > + struct kvm *kvm; > + struct xarray bindings; > + struct list_head entry; > +}; > + > +struct gmem_inode { > + struct shared_policy policy; > + struct inode vfs_inode; > + struct list_head gmem_file_list; > + > + u64 flags; > +}; > + > +static inline struct gmem_inode *GMEM_I(struct inode *inode) > +{ > + return container_of(inode, struct gmem_inode, vfs_inode); > +} > + > +struct file *__kvm_gmem_create_file(struct kvm *kvm, loff_t size, u64 flags); > + > +#endif /* __KVM_GUEST_MEMFD_H__ */ > -- > 2.55.0.229.g6434b31f56-goog

