Re: [PATCH 2/2] mm/hmm: hmm_range_fault() infinite loop

2019-08-28 Thread Jason Gunthorpe
On Tue, Aug 27, 2019 at 01:16:13PM -0700, Ralph Campbell wrote:
> 
> On 8/27/19 11:41 AM, Jason Gunthorpe wrote:
> > On Fri, Aug 23, 2019 at 03:17:53PM -0700, Ralph Campbell wrote:
> > 
> > > Signed-off-by: Ralph Campbell 
> > >   mm/hmm.c | 3 +++
> > >   1 file changed, 3 insertions(+)
> > > 
> > > diff --git a/mm/hmm.c b/mm/hmm.c
> > > index 29371485fe94..4882b83aeccb 100644
> > > +++ b/mm/hmm.c
> > > @@ -292,6 +292,9 @@ static int hmm_vma_walk_hole_(unsigned long addr, 
> > > unsigned long end,
> > >   hmm_vma_walk->last = addr;
> > >   i = (addr - range->start) >> PAGE_SHIFT;
> > > + if (write_fault && walk->vma && !(walk->vma->vm_flags & VM_WRITE))
> > > + return -EPERM;
> > 
> > Can walk->vma be NULL here? hmm_vma_do_fault() touches it
> > unconditionally.
> > 
> > Jason
> > 
> walk->vma can be NULL. hmm_vma_do_fault() no longer touches it
> unconditionally, that is what the preceding patch fixes.
> I suppose I could change hmm_vma_walk_hole_() to check for NULL
> and fill in the pfns[] array, I just chose to handle it in
> hmm_vma_do_fault().

Okay, yes maybe long term it would be clearer to do the vma null check
closer to the start of the callback, but this is a good enough bug fix

Reviewed-by: Jason Gunthorpe 

Jason
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH 2/2] mm/hmm: hmm_range_fault() infinite loop

2019-08-27 Thread Ralph Campbell


On 8/27/19 11:41 AM, Jason Gunthorpe wrote:

On Fri, Aug 23, 2019 at 03:17:53PM -0700, Ralph Campbell wrote:


Signed-off-by: Ralph Campbell 
  mm/hmm.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/mm/hmm.c b/mm/hmm.c
index 29371485fe94..4882b83aeccb 100644
+++ b/mm/hmm.c
@@ -292,6 +292,9 @@ static int hmm_vma_walk_hole_(unsigned long addr, unsigned 
long end,
hmm_vma_walk->last = addr;
i = (addr - range->start) >> PAGE_SHIFT;
  
+	if (write_fault && walk->vma && !(walk->vma->vm_flags & VM_WRITE))

+   return -EPERM;


Can walk->vma be NULL here? hmm_vma_do_fault() touches it
unconditionally.

Jason


walk->vma can be NULL. hmm_vma_do_fault() no longer touches it
unconditionally, that is what the preceding patch fixes.
I suppose I could change hmm_vma_walk_hole_() to check for NULL
and fill in the pfns[] array, I just chose to handle it in
hmm_vma_do_fault().
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH 2/2] mm/hmm: hmm_range_fault() infinite loop

2019-08-27 Thread Jason Gunthorpe
On Fri, Aug 23, 2019 at 03:17:53PM -0700, Ralph Campbell wrote:

> Signed-off-by: Ralph Campbell 
>  mm/hmm.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/mm/hmm.c b/mm/hmm.c
> index 29371485fe94..4882b83aeccb 100644
> +++ b/mm/hmm.c
> @@ -292,6 +292,9 @@ static int hmm_vma_walk_hole_(unsigned long addr, 
> unsigned long end,
>   hmm_vma_walk->last = addr;
>   i = (addr - range->start) >> PAGE_SHIFT;
>  
> + if (write_fault && walk->vma && !(walk->vma->vm_flags & VM_WRITE))
> + return -EPERM;

Can walk->vma be NULL here? hmm_vma_do_fault() touches it
unconditionally.

Jason
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

Re: [PATCH 2/2] mm/hmm: hmm_range_fault() infinite loop

2019-08-26 Thread Christoph Hellwig
On Fri, Aug 23, 2019 at 03:17:53PM -0700, Ralph Campbell wrote:
> Normally, callers to handle_mm_fault() are supposed to check the
> vma->vm_flags first. hmm_range_fault() checks for VM_READ but doesn't
> check for VM_WRITE if the caller requests a page to be faulted in
> with write permission (via the hmm_range.pfns[] value).
> If the vma is write protected, this can result in an infinite loop:
>   hmm_range_fault()
> walk_page_range()
>   ...
>   hmm_vma_walk_hole()
> hmm_vma_walk_hole_()
>   hmm_vma_do_fault()
> handle_mm_fault(FAULT_FLAG_WRITE)
> /* returns VM_FAULT_WRITE */
>   /* returns -EBUSY */
> /* returns -EBUSY */
>   /* returns -EBUSY */
> /* loops on -EBUSY and range->valid */
> Prevent this by checking for vma->vm_flags & VM_WRITE before calling
> handle_mm_fault().
> 
> Signed-off-by: Ralph Campbell 

Looks good,

Reviewed-by: Christoph Hellwig 
___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

[PATCH 2/2] mm/hmm: hmm_range_fault() infinite loop

2019-08-23 Thread Ralph Campbell
Normally, callers to handle_mm_fault() are supposed to check the
vma->vm_flags first. hmm_range_fault() checks for VM_READ but doesn't
check for VM_WRITE if the caller requests a page to be faulted in
with write permission (via the hmm_range.pfns[] value).
If the vma is write protected, this can result in an infinite loop:
  hmm_range_fault()
walk_page_range()
  ...
  hmm_vma_walk_hole()
hmm_vma_walk_hole_()
  hmm_vma_do_fault()
handle_mm_fault(FAULT_FLAG_WRITE)
/* returns VM_FAULT_WRITE */
  /* returns -EBUSY */
/* returns -EBUSY */
  /* returns -EBUSY */
/* loops on -EBUSY and range->valid */
Prevent this by checking for vma->vm_flags & VM_WRITE before calling
handle_mm_fault().

Signed-off-by: Ralph Campbell 
---
 mm/hmm.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/mm/hmm.c b/mm/hmm.c
index 29371485fe94..4882b83aeccb 100644
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -292,6 +292,9 @@ static int hmm_vma_walk_hole_(unsigned long addr, unsigned 
long end,
hmm_vma_walk->last = addr;
i = (addr - range->start) >> PAGE_SHIFT;
 
+   if (write_fault && walk->vma && !(walk->vma->vm_flags & VM_WRITE))
+   return -EPERM;
+
for (; addr < end; addr += PAGE_SIZE, i++) {
pfns[i] = range->values[HMM_PFN_NONE];
if (fault || write_fault) {
-- 
2.20.1

___
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx