asmlinkage int
 sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
 {
-       struct vm_area_struct *vma;
        int ret = -EINVAL;
 
        if (scope < FLUSH_SCOPE_LINE || scope > FLUSH_SCOPE_ALL ||
                if (!capable(CAP_SYS_ADMIN))
                        goto out;
        } else {
+               struct vm_area_struct *vma;
+
+               /* Check for overflow.  */
+               if (addr + len < addr)
+                       goto out;
+
                /*
                 * Verify that the specified address region actually belongs
                 * to this process.
                 */
-               vma = find_vma (current->mm, addr);
                ret = -EINVAL;
-               /* Check for overflow.  */
-               if (addr + len < addr)
-                       goto out;
-               if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end)
-                       goto out;
+               down_read(¤t->mm->mmap_sem);
+               vma = find_vma(current->mm, addr);
+               if (!vma || addr < vma->vm_start || addr + len > vma->vm_end)
+                       goto out_unlock;
        }
 
        if (CPU_IS_020_OR_030) {
                        __asm__ __volatile__ ("movec %0, %%cacr" : : "r" (cacr));
                }
                ret = 0;
-               goto out;
+               goto out_unlock;
        } else {
            /*
             * 040 or 060: don't blindly trust 'scope', someone could
                ret = cache_flush_060 (addr, scope, cache, len);
            }
        }
+out_unlock:
+       up_read(¤t->mm->mmap_sem);
 out:
        return ret;
 }