* Mike Rapoport <[email protected]> [251125 13:39]: > From: "Mike Rapoport (Microsoft)" <[email protected]> > > userfaultfd notifications about minor page faults used for live migration > and snapshotting of VMs with memory backed by shared hugetlbfs or tmpfs > mappings as described in detail in commit 7677f7fd8be7 ("userfaultfd: add > minor fault registration mode"). > > To use the same mechanism for VMs that use guest_memfd to map their memory, > guest_memfd should support userfaultfd minor mode. > > Extend ->fault() method of guest_memfd with ability to notify core page > fault handler that a page fault requires handle_userfault(VM_UFFD_MINOR) to > complete and add implementation of ->get_shared_folio() to guest_memfd > vm_ops. > > Signed-off-by: Mike Rapoport (Microsoft) <[email protected]>
Reviewed-by: Liam R. Howlett <[email protected]> > --- > virt/kvm/guest_memfd.c | 28 ++++++++++++++++++++++++++++ > 1 file changed, 28 insertions(+) > > diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c > index ffadc5ee8e04..2a2b076293f9 100644 > --- a/virt/kvm/guest_memfd.c > +++ b/virt/kvm/guest_memfd.c > @@ -4,6 +4,7 @@ > #include <linux/kvm_host.h> > #include <linux/pagemap.h> > #include <linux/anon_inodes.h> > +#include <linux/userfaultfd_k.h> > > #include "kvm_mm.h" > > @@ -369,6 +370,12 @@ static vm_fault_t kvm_gmem_fault_user_mapping(struct > vm_fault *vmf) > return vmf_error(err); > } > > + if (userfaultfd_minor(vmf->vma)) { > + folio_unlock(folio); > + folio_put(folio); > + return VM_FAULT_UFFD_MINOR; > + } > + > if (WARN_ON_ONCE(folio_test_large(folio))) { > ret = VM_FAULT_SIGBUS; > goto out_folio; > @@ -390,8 +397,29 @@ static vm_fault_t kvm_gmem_fault_user_mapping(struct > vm_fault *vmf) > return ret; > } > > +#ifdef CONFIG_USERFAULTFD > +static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t pgoff) > +{ > + struct folio *folio; > + > + folio = kvm_gmem_get_folio(inode, pgoff); > + if (IS_ERR_OR_NULL(folio)) > + return folio; > + > + if (!folio_test_uptodate(folio)) { > + clear_highpage(folio_page(folio, 0)); > + kvm_gmem_mark_prepared(folio); > + } > + > + return folio; > +} > +#endif > + > static const struct vm_operations_struct kvm_gmem_vm_ops = { > .fault = kvm_gmem_fault_user_mapping, > +#ifdef CONFIG_USERFAULTFD > + .get_folio = kvm_gmem_get_folio, > +#endif > }; > > static int kvm_gmem_mmap(struct file *file, struct vm_area_struct *vma) > -- > 2.50.1 >

