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@xxxxxxxxxx> --- mm/userfaultfd.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) 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; -- 2.47.1