diff options
Diffstat (limited to 'arch/sh/kernel/sys_sh.c')
-rw-r--r-- | arch/sh/kernel/sys_sh.c | 168 |
1 files changed, 36 insertions, 132 deletions
diff --git a/arch/sh/kernel/sys_sh.c b/arch/sh/kernel/sys_sh.c index 90d00e47264..8c6a350df75 100644 --- a/arch/sh/kernel/sys_sh.c +++ b/arch/sh/kernel/sys_sh.c @@ -25,30 +25,8 @@ #include <asm/syscalls.h> #include <asm/uaccess.h> #include <asm/unistd.h> - -static inline long -do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, - unsigned long flags, int fd, unsigned long pgoff) -{ - int error = -EBADF; - struct file *file = NULL; - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - if (!(flags & MAP_ANONYMOUS)) { - file = fget(fd); - if (!file) - goto out; - } - - down_write(¤t->mm->mmap_sem); - error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up_write(¤t->mm->mmap_sem); - - if (file) - fput(file); -out: - return error; -} +#include <asm/cacheflush.h> +#include <asm/cachectl.h> asmlinkage int old_mmap(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, @@ -56,7 +34,7 @@ asmlinkage int old_mmap(unsigned long addr, unsigned long len, { if (off & ~PAGE_MASK) return -EINVAL; - return do_mmap2(addr, len, prot, flags, fd, off>>PAGE_SHIFT); + return sys_mmap_pgoff(addr, len, prot, flags, fd, off>>PAGE_SHIFT); } asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, @@ -72,120 +50,46 @@ asmlinkage long sys_mmap2(unsigned long addr, unsigned long len, pgoff >>= PAGE_SHIFT - 12; - return do_mmap2(addr, len, prot, flags, fd, pgoff); + return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff); } -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. - */ -asmlinkage int sys_ipc(uint call, int first, int second, - int third, void __user *ptr, long fifth) +/* sys_cacheflush -- flush (part of) the processor cache. */ +asmlinkage int sys_cacheflush(unsigned long addr, unsigned long len, int op) { - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; + struct vm_area_struct *vma; - if (call <= SEMTIMEDOP) - switch (call) { - case SEMOP: - return sys_semtimedop(first, - (struct sembuf __user *)ptr, - second, NULL); - case SEMTIMEDOP: - return sys_semtimedop(first, - (struct sembuf __user *)ptr, second, - (const struct timespec __user *)fifth); - case SEMGET: - return sys_semget (first, second, third); - case SEMCTL: { - union semun fourth; - if (!ptr) - return -EINVAL; - if (get_user(fourth.__pad, (void __user * __user *) ptr)) - return -EFAULT; - return sys_semctl (first, second, third, fourth); - } - default: - return -EINVAL; - } - - if (call <= MSGCTL) - switch (call) { - case MSGSND: - return sys_msgsnd (first, (struct msgbuf __user *) ptr, - second, third); - case MSGRCV: - switch (version) { - case 0: - { - struct ipc_kludge tmp; + if ((op <= 0) || (op > (CACHEFLUSH_D_PURGE|CACHEFLUSH_I))) + return -EINVAL; - if (!ptr) - return -EINVAL; + /* + * Verify that the specified address region actually belongs + * to this process. + */ + if (addr + len < addr) + return -EFAULT; - if (copy_from_user(&tmp, - (struct ipc_kludge __user *) ptr, - sizeof (tmp))) - return -EFAULT; + down_read(¤t->mm->mmap_sem); + vma = find_vma (current->mm, addr); + if (vma == NULL || addr < vma->vm_start || addr + len > vma->vm_end) { + up_read(¤t->mm->mmap_sem); + return -EFAULT; + } - return sys_msgrcv (first, tmp.msgp, second, - tmp.msgtyp, third); - } - default: - return sys_msgrcv (first, - (struct msgbuf __user *) ptr, - second, fifth, third); - } - case MSGGET: - return sys_msgget ((key_t) first, second); - case MSGCTL: - return sys_msgctl (first, second, - (struct msqid_ds __user *) ptr); - default: - return -EINVAL; - } - if (call <= SHMCTL) - switch (call) { - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = do_shmat (first, (char __user *) ptr, - second, &raddr); - if (ret) - return ret; - return put_user (raddr, (ulong __user *) third); - } - case 1: /* iBCS2 emulator entry point */ - if (!segment_eq(get_fs(), get_ds())) - return -EINVAL; - return do_shmat (first, (char __user *) ptr, - second, (ulong *) third); - } - case SHMDT: - return sys_shmdt ((char __user *)ptr); - case SHMGET: - return sys_shmget (first, second, third); - case SHMCTL: - return sys_shmctl (first, second, - (struct shmid_ds __user *) ptr); - default: - return -EINVAL; - } + switch (op & CACHEFLUSH_D_PURGE) { + case CACHEFLUSH_D_INVAL: + __flush_invalidate_region((void *)addr, len); + break; + case CACHEFLUSH_D_WB: + __flush_wback_region((void *)addr, len); + break; + case CACHEFLUSH_D_PURGE: + __flush_purge_region((void *)addr, len); + break; + } - return -EINVAL; -} + if (op & CACHEFLUSH_I) + flush_icache_range(addr, addr+len); -asmlinkage int sys_uname(struct old_utsname __user *name) -{ - int err; - if (!name) - return -EFAULT; - down_read(&uts_sem); - err = copy_to_user(name, utsname(), sizeof(*name)); - up_read(&uts_sem); - return err?-EFAULT:0; + up_read(¤t->mm->mmap_sem); + return 0; } |