diff mbox series

[RFC,4/5] mm: userfaultfd: support continue for guest_memfd

Message ID 20250303133011.44095-5-kalyazin@amazon.com (mailing list archive)
State New
Headers show
Series KVM: guest_memfd: support for uffd missing | expand

Commit Message

Nikita Kalyazin March 3, 2025, 1:30 p.m. UTC
When userspace receives a page missing event, it is supposed to populate
the missing page in guest_memfd pagecache via the write syscall and
unblock the faulting process via UFFDIO_CONTINUE.

Signed-off-by: Nikita Kalyazin <kalyazin@amazon.com>
---
 mm/userfaultfd.c | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c
index af3dfc3633db..aaff66a7f15b 100644
--- a/mm/userfaultfd.c
+++ b/mm/userfaultfd.c
@@ -19,6 +19,10 @@ 
 #include <asm/tlb.h>
 #include "internal.h"
 
+#ifdef CONFIG_KVM_PRIVATE_MEM
+bool kvm_gmem_vma_is_gmem(struct vm_area_struct *vma);
+#endif
+
 static __always_inline
 bool validate_dst_vma(struct vm_area_struct *dst_vma, unsigned long dst_end)
 {
@@ -391,6 +395,16 @@  static int mfill_atomic_pte_continue(pmd_t *dst_pmd,
 	struct page *page;
 	int ret;
 
+#ifdef CONFIG_KVM_PRIVATE_MEM
+	if (kvm_gmem_vma_is_gmem(dst_vma)) {
+		ret = 0;
+		folio = filemap_get_entry(inode->i_mapping, pgoff);
+		if (IS_ERR(folio))
+			ret = PTR_ERR(folio);
+		else
+			folio_lock(folio);
+	} else
+#endif
 	ret = shmem_get_folio(inode, pgoff, 0, &folio, SGP_NOALLOC);
 	/* Our caller expects us to return -EFAULT if we failed to find folio */
 	if (ret == -ENOENT)
@@ -769,9 +783,16 @@  static __always_inline ssize_t mfill_atomic(struct userfaultfd_ctx *ctx,
 		return  mfill_atomic_hugetlb(ctx, dst_vma, dst_start,
 					     src_start, len, flags);
 
-	if (!vma_is_anonymous(dst_vma) && !vma_is_shmem(dst_vma))
+	if (!vma_is_anonymous(dst_vma) && !vma_is_shmem(dst_vma)
+#ifdef CONFIG_KVM_PRIVATE_MEM
+		&& !kvm_gmem_vma_is_gmem(dst_vma)
+#endif
+	)
 		goto out_unlock;
 	if (!vma_is_shmem(dst_vma) &&
+#ifdef CONFIG_KVM_PRIVATE_MEM
+		!kvm_gmem_vma_is_gmem(dst_vma) &&
+#endif
 	    uffd_flags_mode_is(flags, MFILL_ATOMIC_CONTINUE))
 		goto out_unlock;