aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/sys_sparc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc/kernel/sys_sparc.c')
-rw-r--r--arch/sparc/kernel/sys_sparc.c51
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
222int sparc_mmap_check(unsigned long addr, unsigned long len, unsigned long flags) 222int 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(&current->mm->mmap_sem); 304 down_write(&current->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);
344out_sem:
345 up_write(&current->mm->mmap_sem); 306 up_write(&current->mm->mmap_sem);
346out: 307out:
347 return ret; 308 return ret;