diff options
Diffstat (limited to 'mm/mmap.c')
| -rw-r--r-- | mm/mmap.c | 26 | 
1 files changed, 12 insertions, 14 deletions
| diff --git a/mm/mmap.c b/mm/mmap.c index d91ecb00d38c..5c8b4485860d 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -1808,6 +1808,17 @@ unsigned long mmap_region(struct file *file, unsigned long addr,  		if (error)  			goto unmap_and_free_vma; +		/* Can addr have changed?? +		 * +		 * Answer: Yes, several device drivers can do it in their +		 *         f_op->mmap method. -DaveM +		 * Bug: If addr is changed, prev, rb_link, rb_parent should +		 *      be updated for vma_link() +		 */ +		WARN_ON_ONCE(addr != vma->vm_start); + +		addr = vma->vm_start; +  		/* If vm_flags changed after call_mmap(), we should try merge vma again  		 * as we may succeed this time.  		 */ @@ -1822,25 +1833,12 @@ unsigned long mmap_region(struct file *file, unsigned long addr,  				fput(vma->vm_file);  				vm_area_free(vma);  				vma = merge; -				/* Update vm_flags and possible addr to pick up the change. We don't -				 * warn here if addr changed as the vma is not linked by vma_link(). -				 */ -				addr = vma->vm_start; +				/* Update vm_flags to pick up the change. */  				vm_flags = vma->vm_flags;  				goto unmap_writable;  			}  		} -		/* Can addr have changed?? -		 * -		 * Answer: Yes, several device drivers can do it in their -		 *         f_op->mmap method. -DaveM -		 * Bug: If addr is changed, prev, rb_link, rb_parent should -		 *      be updated for vma_link() -		 */ -		WARN_ON_ONCE(addr != vma->vm_start); - -		addr = vma->vm_start;  		vm_flags = vma->vm_flags;  	} else if (vm_flags & VM_SHARED) {  		error = shmem_zero_setup(vma); |