diff options
Diffstat (limited to 'arch/sparc/kernel/sys_sparc.c')
-rw-r--r-- | arch/sparc/kernel/sys_sparc.c | 51 |
1 files changed, 6 insertions, 45 deletions
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index f188b5dc9fd0..3c6b49a53ae8 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c | |||
@@ -219,12 +219,11 @@ out: | |||
219 | return err; | 219 | return err; |
220 | } | 220 | } |
221 | 221 | ||
222 | int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) | 222 | int sparc_mmap_check(unsigned long addr, unsigned long len) |
223 | { | 223 | { |
224 | if (ARCH_SUN4C_SUN4 && | 224 | if (ARCH_SUN4C_SUN4 && |
225 | (len > 0x20000000 || | 225 | (len > 0x20000000 || |
226 | ((flags & MAP_FIXED) && | 226 | (addr < 0xe0000000 && addr + len > 0x20000000))) |
227 | addr < 0xe0000000 && addr + len > 0x20000000))) | ||
228 | return -EINVAL; | 227 | return -EINVAL; |
229 | 228 | ||
230 | /* See asm-sparc/uaccess.h */ | 229 | /* See asm-sparc/uaccess.h */ |
@@ -296,52 +295,14 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr, | |||
296 | unsigned long old_len, unsigned long new_len, | 295 | unsigned long old_len, unsigned long new_len, |
297 | unsigned long flags, unsigned long new_addr) | 296 | unsigned long flags, unsigned long new_addr) |
298 | { | 297 | { |
299 | struct vm_area_struct *vma; | ||
300 | unsigned long ret = -EINVAL; | 298 | unsigned long ret = -EINVAL; |
301 | if (ARCH_SUN4C_SUN4) { | 299 | |
302 | if (old_len > 0x20000000 || new_len > 0x20000000) | 300 | if (unlikely(sparc_mmap_check(addr, old_len))) |
303 | goto out; | 301 | goto out; |
304 | if (addr < 0xe0000000 && addr + old_len > 0x20000000) | 302 | if (unlikely(sparc_mmap_check(new_addr, new_len))) |
305 | goto out; | ||
306 | } | ||
307 | if (old_len > TASK_SIZE - PAGE_SIZE || | ||
308 | new_len > TASK_SIZE - PAGE_SIZE) | ||
309 | goto out; | 303 | goto out; |
310 | down_write(¤t->mm->mmap_sem); | 304 | down_write(¤t->mm->mmap_sem); |
311 | if (flags & MREMAP_FIXED) { | ||
312 | if (ARCH_SUN4C_SUN4 && | ||
313 | new_addr < 0xe0000000 && | ||
314 | new_addr + new_len > 0x20000000) | ||
315 | goto out_sem; | ||
316 | if (new_addr + new_len > TASK_SIZE - PAGE_SIZE) | ||
317 | goto out_sem; | ||
318 | } else if ((ARCH_SUN4C_SUN4 && addr < 0xe0000000 && | ||
319 | addr + new_len > 0x20000000) || | ||
320 | addr + new_len > TASK_SIZE - PAGE_SIZE) { | ||
321 | unsigned long map_flags = 0; | ||
322 | struct file *file = NULL; | ||
323 | |||
324 | ret = -ENOMEM; | ||
325 | if (!(flags & MREMAP_MAYMOVE)) | ||
326 | goto out_sem; | ||
327 | |||
328 | vma = find_vma(current->mm, addr); | ||
329 | if (vma) { | ||
330 | if (vma->vm_flags & VM_SHARED) | ||
331 | map_flags |= MAP_SHARED; | ||
332 | file = vma->vm_file; | ||
333 | } | ||
334 | |||
335 | new_addr = get_unmapped_area(file, addr, new_len, | ||
336 | vma ? vma->vm_pgoff : 0, | ||
337 | map_flags); | ||
338 | ret = new_addr; | ||
339 | if (new_addr & ~PAGE_MASK) | ||
340 | goto out_sem; | ||
341 | flags |= MREMAP_FIXED; | ||
342 | } | ||
343 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); | 305 | ret = do_mremap(addr, old_len, new_len, flags, new_addr); |
344 | out_sem: | ||
345 | up_write(¤t->mm->mmap_sem); | 306 | up_write(¤t->mm->mmap_sem); |
346 | out: | 307 | out: |
347 | return ret; | 308 | return ret; |