diff options
Diffstat (limited to 'arch/sparc/kernel/sys_sparc.c')
-rw-r--r-- | arch/sparc/kernel/sys_sparc.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/arch/sparc/kernel/sys_sparc.c b/arch/sparc/kernel/sys_sparc.c index dd011c143..498fdb26f 100644 --- a/arch/sparc/kernel/sys_sparc.c +++ b/arch/sparc/kernel/sys_sparc.c @@ -1,4 +1,4 @@ -/* $Id: sys_sparc.c,v 1.66 2000/07/10 20:57:35 davem Exp $ +/* $Id: sys_sparc.c,v 1.67 2000/11/30 08:37:31 anton Exp $ * linux/arch/sparc/kernel/sys_sparc.c * * This file contains various random system calls that @@ -34,6 +34,8 @@ asmlinkage unsigned long sys_getpagesize(void) return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */ } +#define COLOUR_ALIGN(addr) (((addr)+SHMLBA-1)&~(SHMLBA-1)) + unsigned long get_unmapped_area(unsigned long addr, unsigned long len) { struct vm_area_struct * vmm; @@ -45,7 +47,11 @@ unsigned long get_unmapped_area(unsigned long addr, unsigned long len) return 0; if (!addr) addr = TASK_UNMAPPED_BASE; - addr = PAGE_ALIGN(addr); + + if (current->thread.flags & SPARC_FLAG_MMAPSHARED) + addr = COLOUR_ALIGN(addr); + else + addr = PAGE_ALIGN(addr); for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { /* At this point: (!vmm || addr < vmm->vm_end). */ @@ -58,6 +64,8 @@ unsigned long get_unmapped_area(unsigned long addr, unsigned long len) if (!vmm || addr + len <= vmm->vm_start) return addr; addr = vmm->vm_end; + if (current->thread.flags & SPARC_FLAG_MMAPSHARED) + addr = COLOUR_ALIGN(addr); } } @@ -224,10 +232,16 @@ static unsigned long do_mmap2(unsigned long addr, unsigned long len, goto out_putf; flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); + + if (flags & MAP_SHARED) + current->thread.flags |= SPARC_FLAG_MMAPSHARED; + down(¤t->mm->mmap_sem); retval = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); up(¤t->mm->mmap_sem); + current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED); + out_putf: if (file) fput(file); @@ -259,6 +273,7 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr, unsigned long old_len, unsigned long new_len, unsigned long flags, unsigned long new_addr) { + struct vm_area_struct *vma; unsigned long ret = -EINVAL; if (ARCH_SUN4C_SUN4) { if (old_len > 0x20000000 || new_len > 0x20000000) @@ -270,6 +285,9 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr, new_len > TASK_SIZE - PAGE_SIZE) goto out; down(¤t->mm->mmap_sem); + vma = find_vma(current->mm, addr); + if (vma && (vma->vm_flags & VM_SHARED)) + current->thread.flags |= SPARC_FLAG_MMAPSHARED; if (flags & MREMAP_FIXED) { if (ARCH_SUN4C_SUN4 && new_addr < 0xe0000000 && @@ -290,6 +308,7 @@ asmlinkage unsigned long sparc_mremap(unsigned long addr, } ret = do_mremap(addr, old_len, new_len, flags, new_addr); out_sem: + current->thread.flags &= ~(SPARC_FLAG_MMAPSHARED); up(¤t->mm->mmap_sem); out: return ret; @@ -302,12 +321,10 @@ c_sys_nis_syscall (struct pt_regs *regs) static int count = 0; if (count++ > 5) return -ENOSYS; - lock_kernel(); printk ("%s[%d]: Unimplemented SPARC system call %d\n", current->comm, current->pid, (int)regs->u_regs[1]); #ifdef DEBUG_UNIMP_SYSCALL show_regs (regs); #endif - unlock_kernel(); return -ENOSYS; } |