From bd5d3587b218d33d70a835582dfe1d8f8498e702 Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe Date: Fri, 27 Mar 2020 17:00:21 -0300 Subject: mm/hmm: return error for non-vma snapshots The pagewalker does not call most ops with NULL vma, those are all routed to hmm_vma_walk_hole() via ops->pte_hole instead. Thus hmm_vma_fault() is only called with a NULL vma from hmm_vma_walk_hole(), so hoist the NULL vma check to there. Now it is clear that snapshotting with no vma is a HMM_PFN_ERROR as without a vma we have no path to call hmm_vma_fault(). Link: https://lore.kernel.org/r/20200327200021.29372-10-jgg@ziepe.ca Reviewed-by: Christoph Hellwig Signed-off-by: Jason Gunthorpe --- mm/hmm.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'mm/hmm.c') diff --git a/mm/hmm.c b/mm/hmm.c index 9b6a8a26a1fa..280585833adf 100644 --- a/mm/hmm.c +++ b/mm/hmm.c @@ -83,9 +83,6 @@ static int hmm_vma_fault(unsigned long addr, unsigned long end, WARN_ON_ONCE(!required_fault); hmm_vma_walk->last = addr; - if (!vma) - return -EFAULT; - if (required_fault & HMM_NEED_WRITE_FAULT) { if (!(vma->vm_flags & VM_WRITE)) return -EPERM; @@ -170,6 +167,11 @@ static int hmm_vma_walk_hole(unsigned long addr, unsigned long end, npages = (end - addr) >> PAGE_SHIFT; pfns = &range->pfns[i]; required_fault = hmm_range_need_fault(hmm_vma_walk, pfns, npages, 0); + if (!walk->vma) { + if (required_fault) + return -EFAULT; + return hmm_pfns_fill(addr, end, range, HMM_PFN_ERROR); + } if (required_fault) return hmm_vma_fault(addr, end, required_fault, walk); hmm_vma_walk->last = addr; -- cgit