diff options
Diffstat (limited to 'arch/microblaze/kernel/sys_microblaze.c')
| -rw-r--r-- | arch/microblaze/kernel/sys_microblaze.c | 200 |
1 files changed, 15 insertions, 185 deletions
diff --git a/arch/microblaze/kernel/sys_microblaze.c b/arch/microblaze/kernel/sys_microblaze.c index 31905ff590b..f1e1f666ddd 100644 --- a/arch/microblaze/kernel/sys_microblaze.c +++ b/arch/microblaze/kernel/sys_microblaze.c @@ -13,9 +13,9 @@ */ #include <linux/errno.h> +#include <linux/export.h> #include <linux/mm.h> #include <linux/smp.h> -#include <linux/smp_lock.h> #include <linux/syscalls.h> #include <linux/sem.h> #include <linux/msg.h> @@ -24,202 +24,32 @@ #include <linux/mman.h> #include <linux/sys.h> #include <linux/ipc.h> -#include <linux/utsname.h> #include <linux/file.h> -#include <linux/module.h> #include <linux/err.h> #include <linux/fs.h> #include <linux/semaphore.h> #include <linux/uaccess.h> #include <linux/unistd.h> - +#include <linux/slab.h> #include <asm/syscalls.h> -/* - * sys_ipc() is the de-multiplexer for the SysV IPC calls.. - * - * This is really horribly ugly. This will be remove with new toolchain. - */ -asmlinkage int -sys_ipc(uint call, int first, int second, int third, void *ptr, long fifth) -{ - int version, ret; - - version = call >> 16; /* hack for backward compatibility */ - call &= 0xffff; - - ret = -EINVAL; - switch (call) { - case SEMOP: - ret = sys_semop(first, (struct sembuf *)ptr, second); - break; - case SEMGET: - ret = sys_semget(first, second, third); - break; - case SEMCTL: - { - union semun fourth; - if (!ptr) - break; - ret = (access_ok(VERIFY_READ, ptr, sizeof(long)) ? 0 : -EFAULT) - || (get_user(fourth.__pad, (void **)ptr)) ; - if (ret) - break; - ret = sys_semctl(first, second, third, fourth); - break; - } - case MSGSND: - ret = sys_msgsnd(first, (struct msgbuf *) ptr, second, third); - break; - case MSGRCV: - switch (version) { - case 0: { - struct ipc_kludge tmp; - - if (!ptr) - break; - ret = (access_ok(VERIFY_READ, ptr, sizeof(tmp)) - ? 0 : -EFAULT) || copy_from_user(&tmp, - (struct ipc_kludge *) ptr, sizeof(tmp)); - if (ret) - break; - ret = sys_msgrcv(first, tmp.msgp, second, tmp.msgtyp, - third); - break; - } - default: - ret = sys_msgrcv(first, (struct msgbuf *) ptr, - second, fifth, third); - break; - } - break; - case MSGGET: - ret = sys_msgget((key_t) first, second); - break; - case MSGCTL: - ret = sys_msgctl(first, second, (struct msqid_ds *) ptr); - break; - case SHMAT: - switch (version) { - default: { - ulong raddr; - ret = access_ok(VERIFY_WRITE, (ulong *) third, - sizeof(ulong)) ? 0 : -EFAULT; - if (ret) - break; - ret = do_shmat(first, (char *) ptr, second, &raddr); - if (ret) - break; - ret = put_user(raddr, (ulong *) third); - break; - } - case 1: /* iBCS2 emulator entry point */ - if (!segment_eq(get_fs(), get_ds())) - break; - ret = do_shmat(first, (char *) ptr, second, - (ulong *) third); - break; - } - break; - case SHMDT: - ret = sys_shmdt((char *)ptr); - break; - case SHMGET: - ret = sys_shmget(first, second, third); - break; - case SHMCTL: - ret = sys_shmctl(first, second, (struct shmid_ds *) ptr); - break; - } - return ret; -} - -asmlinkage int sys_vfork(struct pt_regs *regs) +SYSCALL_DEFINE6(mmap, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, unsigned long, fd, + off_t, pgoff) { - return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1, - regs, 0, NULL, NULL); -} + if (pgoff & ~PAGE_MASK) + return -EINVAL; -asmlinkage int sys_clone(int flags, unsigned long stack, struct pt_regs *regs) -{ - if (!stack) - stack = regs->r1; - return do_fork(flags, stack, regs, 0, NULL, NULL); + return sys_mmap_pgoff(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); } -asmlinkage int sys_execve(char __user *filenamei, char __user *__user *argv, - char __user *__user *envp, struct pt_regs *regs) +SYSCALL_DEFINE6(mmap2, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, unsigned long, fd, + unsigned long, pgoff) { - int error; - char *filename; - - filename = getname(filenamei); - error = PTR_ERR(filename); - if (IS_ERR(filename)) - goto out; - error = do_execve(filename, argv, envp, regs); - putname(filename); -out: - return error; -} + if (pgoff & (~PAGE_MASK >> 12)) + return -EINVAL; -asmlinkage unsigned long -sys_mmap2(unsigned long addr, size_t len, - unsigned long prot, unsigned long flags, - unsigned long fd, unsigned long pgoff) -{ - struct file *file = NULL; - int ret = -EBADF; - - flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); - if (!(flags & MAP_ANONYMOUS)) { - file = fget(fd); - if (!file) { - printk(KERN_INFO "no fd in mmap\r\n"); - goto out; - } - } - - down_write(¤t->mm->mmap_sem); - ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); - up_write(¤t->mm->mmap_sem); - if (file) - fput(file); -out: - return ret; -} - -asmlinkage unsigned long sys_mmap(unsigned long addr, size_t len, - unsigned long prot, unsigned long flags, - unsigned long fd, off_t offset) -{ - int err = -EINVAL; - - if (offset & ~PAGE_MASK) { - printk(KERN_INFO "no pagemask in mmap\r\n"); - goto out; - } - - err = sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); -out: - return err; -} - -/* - * Do a system call from kernel instead of calling sys_execve so we - * end up with proper pt_regs. - */ -int kernel_execve(const char *filename, char *const argv[], char *const envp[]) -{ - register const char *__a __asm__("r5") = filename; - register const void *__b __asm__("r6") = argv; - register const void *__c __asm__("r7") = envp; - register unsigned long __syscall __asm__("r12") = __NR_execve; - register unsigned long __ret __asm__("r3"); - __asm__ __volatile__ ("brki r14, 0x8" - : "=r" (__ret), "=r" (__syscall) - : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c) - : "r4", "r8", "r9", - "r10", "r11", "r14", "cc", "memory"); - return __ret; + return sys_mmap_pgoff(addr, len, prot, flags, fd, + pgoff >> (PAGE_SHIFT - 12)); } |
