|
@@ -376,7 +376,6 @@ cache_flush_060 (unsigned long addr, int scope, int cache, unsigned long len)
|
|
|
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 ||
|
|
@@ -389,17 +388,21 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
|
|
|
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) {
|
|
@@ -429,7 +432,7 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
|
|
|
__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
|
|
@@ -446,6 +449,8 @@ sys_cacheflush (unsigned long addr, int scope, int cache, unsigned long len)
|
|
|
ret = cache_flush_060 (addr, scope, cache, len);
|
|
|
}
|
|
|
}
|
|
|
+out_unlock:
|
|
|
+ up_read(¤t->mm->mmap_sem);
|
|
|
out:
|
|
|
return ret;
|
|
|
}
|