1 /* 2 * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> 3 * Copyright (C) 2007-2009 PetaLogix 4 * Copyright (C) 2007 John Williams <john.williams@petalogix.com> 5 * 6 * Copyright (C) 2006 Atmark Techno, Inc. 7 * Yasushi SHOJI <yashi@atmark-techno.com> 8 * Tetsuya OHKAWA <tetsuya@atmark-techno.com> 9 * 10 * This file is subject to the terms and conditions of the GNU General Public 11 * License. See the file "COPYING" in the main directory of this archive 12 * for more details. 13 */ 14 15 #include <linux/errno.h> 16 #include <linux/mm.h> 17 #include <linux/smp.h> 18 #include <linux/syscalls.h> 19 #include <linux/sem.h> 20 #include <linux/msg.h> 21 #include <linux/shm.h> 22 #include <linux/stat.h> 23 #include <linux/mman.h> 24 #include <linux/sys.h> 25 #include <linux/ipc.h> 26 #include <linux/file.h> 27 #include <linux/module.h> 28 #include <linux/err.h> 29 #include <linux/fs.h> 30 #include <linux/semaphore.h> 31 #include <linux/uaccess.h> 32 #include <linux/unistd.h> 33 34 #include <asm/syscalls.h> 35 36 asmlinkage long microblaze_vfork(struct pt_regs *regs) 37 { 38 return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->r1, 39 regs, 0, NULL, NULL); 40 } 41 42 asmlinkage long microblaze_clone(int flags, unsigned long stack, struct pt_regs *regs) 43 { 44 if (!stack) 45 stack = regs->r1; 46 return do_fork(flags, stack, regs, 0, NULL, NULL); 47 } 48 49 asmlinkage long microblaze_execve(char __user *filenamei, char __user *__user *argv, 50 char __user *__user *envp, struct pt_regs *regs) 51 { 52 int error; 53 char *filename; 54 55 filename = getname(filenamei); 56 error = PTR_ERR(filename); 57 if (IS_ERR(filename)) 58 goto out; 59 error = do_execve(filename, argv, envp, regs); 60 putname(filename); 61 out: 62 return error; 63 } 64 65 asmlinkage long 66 sys_mmap2(unsigned long addr, unsigned long len, 67 unsigned long prot, unsigned long flags, 68 unsigned long fd, unsigned long pgoff) 69 { 70 struct file *file = NULL; 71 int ret = -EBADF; 72 73 flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); 74 if (!(flags & MAP_ANONYMOUS)) { 75 file = fget(fd); 76 if (!file) { 77 printk(KERN_INFO "no fd in mmap\r\n"); 78 goto out; 79 } 80 } 81 82 down_write(¤t->mm->mmap_sem); 83 ret = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); 84 up_write(¤t->mm->mmap_sem); 85 if (file) 86 fput(file); 87 out: 88 return ret; 89 } 90 91 asmlinkage long sys_mmap(unsigned long addr, unsigned long len, 92 unsigned long prot, unsigned long flags, 93 unsigned long fd, off_t pgoff) 94 { 95 int err = -EINVAL; 96 97 if (pgoff & ~PAGE_MASK) { 98 printk(KERN_INFO "no pagemask in mmap\r\n"); 99 goto out; 100 } 101 102 err = sys_mmap2(addr, len, prot, flags, fd, pgoff >> PAGE_SHIFT); 103 out: 104 return err; 105 } 106 107 /* 108 * Do a system call from kernel instead of calling sys_execve so we 109 * end up with proper pt_regs. 110 */ 111 int kernel_execve(const char *filename, char *const argv[], char *const envp[]) 112 { 113 register const char *__a __asm__("r5") = filename; 114 register const void *__b __asm__("r6") = argv; 115 register const void *__c __asm__("r7") = envp; 116 register unsigned long __syscall __asm__("r12") = __NR_execve; 117 register unsigned long __ret __asm__("r3"); 118 __asm__ __volatile__ ("brki r14, 0x8" 119 : "=r" (__ret), "=r" (__syscall) 120 : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c) 121 : "r4", "r8", "r9", 122 "r10", "r11", "r14", "cc", "memory"); 123 return __ret; 124 } 125