Merge "mm: ashmem: Make sure vma is valid while flushing" into msm-3.0
diff --git a/mm/ashmem.c b/mm/ashmem.c
index bc977ee..e4aab56 100644
--- a/mm/ashmem.c
+++ b/mm/ashmem.c
@@ -673,10 +673,28 @@
 	void (*cache_func)(unsigned long vstart, unsigned long length,
 				unsigned long pstart))
 {
+	int ret = 0;
+	struct vm_area_struct *vma;
 #ifdef CONFIG_OUTER_CACHE
 	unsigned long vaddr;
 #endif
-	mutex_lock(&ashmem_mutex);
+	if (!asma->vm_start)
+		return -EINVAL;
+
+	down_read(&current->mm->mmap_sem);
+	vma = find_vma(current->mm, asma->vm_start);
+	if (!vma) {
+		ret = -EINVAL;
+		goto done;
+	}
+	if (vma->vm_file != asma->file) {
+		ret = -EINVAL;
+		goto done;
+	}
+	if ((asma->vm_start + asma->size) > (vma->vm_start + vma->vm_end)) {
+		ret = -EINVAL;
+		goto done;
+	}
 #ifndef CONFIG_OUTER_CACHE
 	cache_func(asma->vm_start, asma->size, 0);
 #else
@@ -689,8 +707,11 @@
 		cache_func(vaddr, PAGE_SIZE, physaddr);
 	}
 #endif
-	mutex_unlock(&ashmem_mutex);
-	return 0;
+done:
+	up_read(&current->mm->mmap_sem);
+	if (ret)
+		asma->vm_start = 0;
+	return ret;
 }
 
 static long ashmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)