On 11/30/25 12:18, Mike Rapoport wrote:
From: "Mike Rapoport (Microsoft)" rppt@kernel.org
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_folio_noalloc() to guest_memfd vm_ops.
Reviewed-by: Liam R. Howlett Liam.Howlett@oracle.com Signed-off-by: Mike Rapoport (Microsoft) rppt@kernel.org
virt/kvm/guest_memfd.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c index ffadc5ee8e04..dca6e373937b 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" @@ -359,7 +360,15 @@ static vm_fault_t kvm_gmem_fault_user_mapping(struct vm_fault *vmf) if (!((u64)inode->i_private & GUEST_MEMFD_FLAG_INIT_SHARED)) return VM_FAULT_SIGBUS;
- folio = kvm_gmem_get_folio(inode, vmf->pgoff);
- folio = filemap_lock_folio(inode->i_mapping, vmf->pgoff);
- if (!IS_ERR_OR_NULL(folio) && userfaultfd_minor(vmf->vma)) {
Can we ever get NULL here?
ret = VM_FAULT_UFFD_MINOR;goto out_folio;- }
- if (PTR_ERR(folio) == -ENOENT)
folio = kvm_gmem_get_folio(inode, vmf->pgoff);
Was briefly wondering what the performance impact of that two-step approach is (two lookups in case we have to create it IIUC)
Wouldn't it be better to limit it to the userfaultfd_minor(vmf->vma) case?
if (userfaultfd_minor(vmf->vma)) { folio = filemap_lock_folio(inode->i_mapping, vmf->pgoff); if (!IS_ERR(folio)) { ret = VM_FAULT_UFFD_MINOR; goto out_folio; } } else { folio = kvm_gmem_get_folio(inode, vmf->pgoff); }
if (IS_ERR(folio)) { ...