@@ -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;
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(-)