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