Commit c2579c9c authored by Jason Gunthorpe's avatar Jason Gunthorpe

mm/hmm: add missing call to hmm_range_need_fault() before returning EFAULT

All return paths that do EFAULT must call hmm_range_need_fault() to
determine if the user requires this page to be valid.

If the page cannot be made valid if the user later requires it, due to vma
flags in this case, then the return should be HMM_PFN_ERROR.

Fixes: a3e0d41c ("mm/hmm: improve driver API to work and wait over a range")
Reviewed-by: default avatarRalph Campbell <rcampbell@nvidia.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 7d082987
...@@ -604,18 +604,15 @@ static int hmm_vma_walk_test(unsigned long start, unsigned long end, ...@@ -604,18 +604,15 @@ static int hmm_vma_walk_test(unsigned long start, unsigned long end,
struct vm_area_struct *vma = walk->vma; struct vm_area_struct *vma = walk->vma;
/* /*
* Skip vma ranges that don't have struct page backing them or * Skip vma ranges that don't have struct page backing them or map I/O
* map I/O devices directly. * devices directly.
*/ *
if (vma->vm_flags & (VM_IO | VM_PFNMAP | VM_MIXEDMAP))
return -EFAULT;
/*
* If the vma does not allow read access, then assume that it does not * If the vma does not allow read access, then assume that it does not
* allow write access either. HMM does not support architectures * allow write access either. HMM does not support architectures that
* that allow write without read. * allow write without read.
*/ */
if (!(vma->vm_flags & VM_READ)) { if ((vma->vm_flags & (VM_IO | VM_PFNMAP | VM_MIXEDMAP)) ||
!(vma->vm_flags & VM_READ)) {
bool fault, write_fault; bool fault, write_fault;
/* /*
...@@ -629,7 +626,7 @@ static int hmm_vma_walk_test(unsigned long start, unsigned long end, ...@@ -629,7 +626,7 @@ static int hmm_vma_walk_test(unsigned long start, unsigned long end,
if (fault || write_fault) if (fault || write_fault)
return -EFAULT; return -EFAULT;
hmm_pfns_fill(start, end, range, HMM_PFN_NONE); hmm_pfns_fill(start, end, range, HMM_PFN_ERROR);
hmm_vma_walk->last = end; hmm_vma_walk->last = end;
/* Skip this vma and continue processing the next vma. */ /* Skip this vma and continue processing the next vma. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment