Message ID | 20190823221753.2514-2-rcampbell@nvidia.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mm/hmm: two bug fixes for hmm_range_fault() | expand |
On 8/24/19 3:37 PM, Christoph Hellwig wrote: > On Fri, Aug 23, 2019 at 03:17:52PM -0700, Ralph Campbell wrote: >> Although hmm_range_fault() calls find_vma() to make sure that a vma exists >> before calling walk_page_range(), hmm_vma_walk_hole() can still be called >> with walk->vma == NULL if the start and end address are not contained >> within the vma range. > > Should we convert to walk_vma_range instead? Or keep walk_page_range > but drop searching the vma ourselves? > > Except for that the patch looks good to me: > > Reviewed-by: Christoph Hellwig <hch@lst.de> > I think keeping the call to walk_page_range() makes sense. Jason is hoping to be able to snapshot a range with & without vmas and have the pfns[] filled with empty/valid entries as appropriate. I plan to repost my patch changing hmm_range_fault() to use walk.test_walk which will remove the call to find_vma(). Jason had some concerns about testing it so that's why I have been working on some HMM self tests before resending it.
On Mon, Aug 26, 2019 at 11:02:12AM -0700, Ralph Campbell wrote: > > On 8/24/19 3:37 PM, Christoph Hellwig wrote: > > On Fri, Aug 23, 2019 at 03:17:52PM -0700, Ralph Campbell wrote: > > > Although hmm_range_fault() calls find_vma() to make sure that a vma exists > > > before calling walk_page_range(), hmm_vma_walk_hole() can still be called > > > with walk->vma == NULL if the start and end address are not contained > > > within the vma range. > > > > Should we convert to walk_vma_range instead? Or keep walk_page_range > > but drop searching the vma ourselves? > > > > Except for that the patch looks good to me: > > > > Reviewed-by: Christoph Hellwig <hch@lst.de> > > > > I think keeping the call to walk_page_range() makes sense. > Jason is hoping to be able to snapshot a range with & without vmas > and have the pfns[] filled with empty/valid entries as appropriate. > > I plan to repost my patch changing hmm_range_fault() to use > walk.test_walk which will remove the call to find_vma(). > Jason had some concerns about testing it so that's why I have > been working on some HMM self tests before resending it. I'm really excited to see tests for hmm_range_fault()! Did you find this bug with the tests?? Jason
On 8/26/19 11:09 AM, Jason Gunthorpe wrote: > On Mon, Aug 26, 2019 at 11:02:12AM -0700, Ralph Campbell wrote: >> >> On 8/24/19 3:37 PM, Christoph Hellwig wrote: >>> On Fri, Aug 23, 2019 at 03:17:52PM -0700, Ralph Campbell wrote: >>>> Although hmm_range_fault() calls find_vma() to make sure that a vma exists >>>> before calling walk_page_range(), hmm_vma_walk_hole() can still be called >>>> with walk->vma == NULL if the start and end address are not contained >>>> within the vma range. >>> >>> Should we convert to walk_vma_range instead? Or keep walk_page_range >>> but drop searching the vma ourselves? >>> >>> Except for that the patch looks good to me: >>> >>> Reviewed-by: Christoph Hellwig <hch@lst.de> >>> >> >> I think keeping the call to walk_page_range() makes sense. >> Jason is hoping to be able to snapshot a range with & without vmas >> and have the pfns[] filled with empty/valid entries as appropriate. >> >> I plan to repost my patch changing hmm_range_fault() to use >> walk.test_walk which will remove the call to find_vma(). >> Jason had some concerns about testing it so that's why I have >> been working on some HMM self tests before resending it. > > I'm really excited to see tests for hmm_range_fault()! > > Did you find this bug with the tests?? > > Jason > Yes, I found both bugs with the tests. I started with Jerome's hmm_dummy driver and user level test code. Hopefully I can send it out this week.
diff --git a/mm/hmm.c b/mm/hmm.c index fc05c8fe78b4..29371485fe94 100644 --- a/mm/hmm.c +++ b/mm/hmm.c @@ -229,6 +229,9 @@ static int hmm_vma_do_fault(struct mm_walk *walk, unsigned long addr, struct vm_area_struct *vma = walk->vma; vm_fault_t ret; + if (!vma) + goto err; + if (hmm_vma_walk->flags & HMM_FAULT_ALLOW_RETRY) flags |= FAULT_FLAG_ALLOW_RETRY; if (write_fault) @@ -239,12 +242,14 @@ static int hmm_vma_do_fault(struct mm_walk *walk, unsigned long addr, /* Note, handle_mm_fault did up_read(&mm->mmap_sem)) */ return -EAGAIN; } - if (ret & VM_FAULT_ERROR) { - *pfn = range->values[HMM_PFN_ERROR]; - return -EFAULT; - } + if (ret & VM_FAULT_ERROR) + goto err; return -EBUSY; + +err: + *pfn = range->values[HMM_PFN_ERROR]; + return -EFAULT; } static int hmm_pfns_bad(unsigned long addr,
Although hmm_range_fault() calls find_vma() to make sure that a vma exists before calling walk_page_range(), hmm_vma_walk_hole() can still be called with walk->vma == NULL if the start and end address are not contained within the vma range. hmm_range_fault() /* calls find_vma() but no range check */ walk_page_range() /* calls find_vma(), sets walk->vma = NULL */ __walk_page_range() walk_pgd_range() walk_p4d_range() walk_pud_range() hmm_vma_walk_hole() hmm_vma_walk_hole_() hmm_vma_do_fault() handle_mm_fault(vma=0) Signed-off-by: Ralph Campbell <rcampbell@nvidia.com> --- mm/hmm.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)