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

Reply via email to