1*1da177e4SLinus Torvalds /* 2*1da177e4SLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 3*1da177e4SLinus Torvalds * License. See the file "COPYING" in the main directory of this archive 4*1da177e4SLinus Torvalds * for more details. 5*1da177e4SLinus Torvalds * 6*1da177e4SLinus Torvalds * Copyright (C) 1995, 1996, 1997, 2000, 2001, 05 by Ralf Baechle 7*1da177e4SLinus Torvalds * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 8*1da177e4SLinus Torvalds * Copyright (C) 2001 MIPS Technologies, Inc. 9*1da177e4SLinus Torvalds */ 10*1da177e4SLinus Torvalds #include <linux/a.out.h> 11*1da177e4SLinus Torvalds #include <linux/errno.h> 12*1da177e4SLinus Torvalds #include <linux/linkage.h> 13*1da177e4SLinus Torvalds #include <linux/mm.h> 14*1da177e4SLinus Torvalds #include <linux/smp.h> 15*1da177e4SLinus Torvalds #include <linux/smp_lock.h> 16*1da177e4SLinus Torvalds #include <linux/mman.h> 17*1da177e4SLinus Torvalds #include <linux/ptrace.h> 18*1da177e4SLinus Torvalds #include <linux/sched.h> 19*1da177e4SLinus Torvalds #include <linux/string.h> 20*1da177e4SLinus Torvalds #include <linux/syscalls.h> 21*1da177e4SLinus Torvalds #include <linux/file.h> 22*1da177e4SLinus Torvalds #include <linux/slab.h> 23*1da177e4SLinus Torvalds #include <linux/utsname.h> 24*1da177e4SLinus Torvalds #include <linux/unistd.h> 25*1da177e4SLinus Torvalds #include <linux/sem.h> 26*1da177e4SLinus Torvalds #include <linux/msg.h> 27*1da177e4SLinus Torvalds #include <linux/shm.h> 28*1da177e4SLinus Torvalds #include <linux/compiler.h> 29*1da177e4SLinus Torvalds 30*1da177e4SLinus Torvalds #include <asm/branch.h> 31*1da177e4SLinus Torvalds #include <asm/cachectl.h> 32*1da177e4SLinus Torvalds #include <asm/cacheflush.h> 33*1da177e4SLinus Torvalds #include <asm/ipc.h> 34*1da177e4SLinus Torvalds #include <asm/offset.h> 35*1da177e4SLinus Torvalds #include <asm/signal.h> 36*1da177e4SLinus Torvalds #include <asm/sim.h> 37*1da177e4SLinus Torvalds #include <asm/shmparam.h> 38*1da177e4SLinus Torvalds #include <asm/sysmips.h> 39*1da177e4SLinus Torvalds #include <asm/uaccess.h> 40*1da177e4SLinus Torvalds 41*1da177e4SLinus Torvalds asmlinkage int sys_pipe(nabi_no_regargs volatile struct pt_regs regs) 42*1da177e4SLinus Torvalds { 43*1da177e4SLinus Torvalds int fd[2]; 44*1da177e4SLinus Torvalds int error, res; 45*1da177e4SLinus Torvalds 46*1da177e4SLinus Torvalds error = do_pipe(fd); 47*1da177e4SLinus Torvalds if (error) { 48*1da177e4SLinus Torvalds res = error; 49*1da177e4SLinus Torvalds goto out; 50*1da177e4SLinus Torvalds } 51*1da177e4SLinus Torvalds regs.regs[3] = fd[1]; 52*1da177e4SLinus Torvalds res = fd[0]; 53*1da177e4SLinus Torvalds out: 54*1da177e4SLinus Torvalds return res; 55*1da177e4SLinus Torvalds } 56*1da177e4SLinus Torvalds 57*1da177e4SLinus Torvalds unsigned long shm_align_mask = PAGE_SIZE - 1; /* Sane caches */ 58*1da177e4SLinus Torvalds 59*1da177e4SLinus Torvalds #define COLOUR_ALIGN(addr,pgoff) \ 60*1da177e4SLinus Torvalds ((((addr) + shm_align_mask) & ~shm_align_mask) + \ 61*1da177e4SLinus Torvalds (((pgoff) << PAGE_SHIFT) & shm_align_mask)) 62*1da177e4SLinus Torvalds 63*1da177e4SLinus Torvalds unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, 64*1da177e4SLinus Torvalds unsigned long len, unsigned long pgoff, unsigned long flags) 65*1da177e4SLinus Torvalds { 66*1da177e4SLinus Torvalds struct vm_area_struct * vmm; 67*1da177e4SLinus Torvalds int do_color_align; 68*1da177e4SLinus Torvalds unsigned long task_size; 69*1da177e4SLinus Torvalds 70*1da177e4SLinus Torvalds task_size = STACK_TOP; 71*1da177e4SLinus Torvalds 72*1da177e4SLinus Torvalds if (flags & MAP_FIXED) { 73*1da177e4SLinus Torvalds /* 74*1da177e4SLinus Torvalds * We do not accept a shared mapping if it would violate 75*1da177e4SLinus Torvalds * cache aliasing constraints. 76*1da177e4SLinus Torvalds */ 77*1da177e4SLinus Torvalds if ((flags & MAP_SHARED) && (addr & shm_align_mask)) 78*1da177e4SLinus Torvalds return -EINVAL; 79*1da177e4SLinus Torvalds return addr; 80*1da177e4SLinus Torvalds } 81*1da177e4SLinus Torvalds 82*1da177e4SLinus Torvalds if (len > task_size) 83*1da177e4SLinus Torvalds return -ENOMEM; 84*1da177e4SLinus Torvalds do_color_align = 0; 85*1da177e4SLinus Torvalds if (filp || (flags & MAP_SHARED)) 86*1da177e4SLinus Torvalds do_color_align = 1; 87*1da177e4SLinus Torvalds if (addr) { 88*1da177e4SLinus Torvalds if (do_color_align) 89*1da177e4SLinus Torvalds addr = COLOUR_ALIGN(addr, pgoff); 90*1da177e4SLinus Torvalds else 91*1da177e4SLinus Torvalds addr = PAGE_ALIGN(addr); 92*1da177e4SLinus Torvalds vmm = find_vma(current->mm, addr); 93*1da177e4SLinus Torvalds if (task_size - len >= addr && 94*1da177e4SLinus Torvalds (!vmm || addr + len <= vmm->vm_start)) 95*1da177e4SLinus Torvalds return addr; 96*1da177e4SLinus Torvalds } 97*1da177e4SLinus Torvalds addr = TASK_UNMAPPED_BASE; 98*1da177e4SLinus Torvalds if (do_color_align) 99*1da177e4SLinus Torvalds addr = COLOUR_ALIGN(addr, pgoff); 100*1da177e4SLinus Torvalds else 101*1da177e4SLinus Torvalds addr = PAGE_ALIGN(addr); 102*1da177e4SLinus Torvalds 103*1da177e4SLinus Torvalds for (vmm = find_vma(current->mm, addr); ; vmm = vmm->vm_next) { 104*1da177e4SLinus Torvalds /* At this point: (!vmm || addr < vmm->vm_end). */ 105*1da177e4SLinus Torvalds if (task_size - len < addr) 106*1da177e4SLinus Torvalds return -ENOMEM; 107*1da177e4SLinus Torvalds if (!vmm || addr + len <= vmm->vm_start) 108*1da177e4SLinus Torvalds return addr; 109*1da177e4SLinus Torvalds addr = vmm->vm_end; 110*1da177e4SLinus Torvalds if (do_color_align) 111*1da177e4SLinus Torvalds addr = COLOUR_ALIGN(addr, pgoff); 112*1da177e4SLinus Torvalds } 113*1da177e4SLinus Torvalds } 114*1da177e4SLinus Torvalds 115*1da177e4SLinus Torvalds /* common code for old and new mmaps */ 116*1da177e4SLinus Torvalds static inline unsigned long 117*1da177e4SLinus Torvalds do_mmap2(unsigned long addr, unsigned long len, unsigned long prot, 118*1da177e4SLinus Torvalds unsigned long flags, unsigned long fd, unsigned long pgoff) 119*1da177e4SLinus Torvalds { 120*1da177e4SLinus Torvalds unsigned long error = -EBADF; 121*1da177e4SLinus Torvalds struct file * file = NULL; 122*1da177e4SLinus Torvalds 123*1da177e4SLinus Torvalds flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); 124*1da177e4SLinus Torvalds if (!(flags & MAP_ANONYMOUS)) { 125*1da177e4SLinus Torvalds file = fget(fd); 126*1da177e4SLinus Torvalds if (!file) 127*1da177e4SLinus Torvalds goto out; 128*1da177e4SLinus Torvalds } 129*1da177e4SLinus Torvalds 130*1da177e4SLinus Torvalds down_write(¤t->mm->mmap_sem); 131*1da177e4SLinus Torvalds error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); 132*1da177e4SLinus Torvalds up_write(¤t->mm->mmap_sem); 133*1da177e4SLinus Torvalds 134*1da177e4SLinus Torvalds if (file) 135*1da177e4SLinus Torvalds fput(file); 136*1da177e4SLinus Torvalds out: 137*1da177e4SLinus Torvalds return error; 138*1da177e4SLinus Torvalds } 139*1da177e4SLinus Torvalds 140*1da177e4SLinus Torvalds asmlinkage unsigned long 141*1da177e4SLinus Torvalds old_mmap(unsigned long addr, unsigned long len, int prot, 142*1da177e4SLinus Torvalds int flags, int fd, off_t offset) 143*1da177e4SLinus Torvalds { 144*1da177e4SLinus Torvalds unsigned long result; 145*1da177e4SLinus Torvalds 146*1da177e4SLinus Torvalds result = -EINVAL; 147*1da177e4SLinus Torvalds if (offset & ~PAGE_MASK) 148*1da177e4SLinus Torvalds goto out; 149*1da177e4SLinus Torvalds 150*1da177e4SLinus Torvalds result = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT); 151*1da177e4SLinus Torvalds 152*1da177e4SLinus Torvalds out: 153*1da177e4SLinus Torvalds return result; 154*1da177e4SLinus Torvalds } 155*1da177e4SLinus Torvalds 156*1da177e4SLinus Torvalds asmlinkage unsigned long 157*1da177e4SLinus Torvalds sys_mmap2(unsigned long addr, unsigned long len, unsigned long prot, 158*1da177e4SLinus Torvalds unsigned long flags, unsigned long fd, unsigned long pgoff) 159*1da177e4SLinus Torvalds { 160*1da177e4SLinus Torvalds return do_mmap2(addr, len, prot, flags, fd, pgoff); 161*1da177e4SLinus Torvalds } 162*1da177e4SLinus Torvalds 163*1da177e4SLinus Torvalds save_static_function(sys_fork); 164*1da177e4SLinus Torvalds __attribute_used__ noinline static int 165*1da177e4SLinus Torvalds _sys_fork(nabi_no_regargs struct pt_regs regs) 166*1da177e4SLinus Torvalds { 167*1da177e4SLinus Torvalds return do_fork(SIGCHLD, regs.regs[29], ®s, 0, NULL, NULL); 168*1da177e4SLinus Torvalds } 169*1da177e4SLinus Torvalds 170*1da177e4SLinus Torvalds save_static_function(sys_clone); 171*1da177e4SLinus Torvalds __attribute_used__ noinline static int 172*1da177e4SLinus Torvalds _sys_clone(nabi_no_regargs struct pt_regs regs) 173*1da177e4SLinus Torvalds { 174*1da177e4SLinus Torvalds unsigned long clone_flags; 175*1da177e4SLinus Torvalds unsigned long newsp; 176*1da177e4SLinus Torvalds int *parent_tidptr, *child_tidptr; 177*1da177e4SLinus Torvalds 178*1da177e4SLinus Torvalds clone_flags = regs.regs[4]; 179*1da177e4SLinus Torvalds newsp = regs.regs[5]; 180*1da177e4SLinus Torvalds if (!newsp) 181*1da177e4SLinus Torvalds newsp = regs.regs[29]; 182*1da177e4SLinus Torvalds parent_tidptr = (int *) regs.regs[6]; 183*1da177e4SLinus Torvalds child_tidptr = (int *) regs.regs[7]; 184*1da177e4SLinus Torvalds return do_fork(clone_flags, newsp, ®s, 0, 185*1da177e4SLinus Torvalds parent_tidptr, child_tidptr); 186*1da177e4SLinus Torvalds } 187*1da177e4SLinus Torvalds 188*1da177e4SLinus Torvalds /* 189*1da177e4SLinus Torvalds * sys_execve() executes a new program. 190*1da177e4SLinus Torvalds */ 191*1da177e4SLinus Torvalds asmlinkage int sys_execve(nabi_no_regargs struct pt_regs regs) 192*1da177e4SLinus Torvalds { 193*1da177e4SLinus Torvalds int error; 194*1da177e4SLinus Torvalds char * filename; 195*1da177e4SLinus Torvalds 196*1da177e4SLinus Torvalds filename = getname((char *) (long)regs.regs[4]); 197*1da177e4SLinus Torvalds error = PTR_ERR(filename); 198*1da177e4SLinus Torvalds if (IS_ERR(filename)) 199*1da177e4SLinus Torvalds goto out; 200*1da177e4SLinus Torvalds error = do_execve(filename, (char **) (long)regs.regs[5], 201*1da177e4SLinus Torvalds (char **) (long)regs.regs[6], ®s); 202*1da177e4SLinus Torvalds putname(filename); 203*1da177e4SLinus Torvalds 204*1da177e4SLinus Torvalds out: 205*1da177e4SLinus Torvalds return error; 206*1da177e4SLinus Torvalds } 207*1da177e4SLinus Torvalds 208*1da177e4SLinus Torvalds /* 209*1da177e4SLinus Torvalds * Compacrapability ... 210*1da177e4SLinus Torvalds */ 211*1da177e4SLinus Torvalds asmlinkage int sys_uname(struct old_utsname * name) 212*1da177e4SLinus Torvalds { 213*1da177e4SLinus Torvalds if (name && !copy_to_user(name, &system_utsname, sizeof (*name))) 214*1da177e4SLinus Torvalds return 0; 215*1da177e4SLinus Torvalds return -EFAULT; 216*1da177e4SLinus Torvalds } 217*1da177e4SLinus Torvalds 218*1da177e4SLinus Torvalds /* 219*1da177e4SLinus Torvalds * Compacrapability ... 220*1da177e4SLinus Torvalds */ 221*1da177e4SLinus Torvalds asmlinkage int sys_olduname(struct oldold_utsname * name) 222*1da177e4SLinus Torvalds { 223*1da177e4SLinus Torvalds int error; 224*1da177e4SLinus Torvalds 225*1da177e4SLinus Torvalds if (!name) 226*1da177e4SLinus Torvalds return -EFAULT; 227*1da177e4SLinus Torvalds if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) 228*1da177e4SLinus Torvalds return -EFAULT; 229*1da177e4SLinus Torvalds 230*1da177e4SLinus Torvalds error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN); 231*1da177e4SLinus Torvalds error -= __put_user(0,name->sysname+__OLD_UTS_LEN); 232*1da177e4SLinus Torvalds error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN); 233*1da177e4SLinus Torvalds error -= __put_user(0,name->nodename+__OLD_UTS_LEN); 234*1da177e4SLinus Torvalds error -= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN); 235*1da177e4SLinus Torvalds error -= __put_user(0,name->release+__OLD_UTS_LEN); 236*1da177e4SLinus Torvalds error -= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN); 237*1da177e4SLinus Torvalds error -= __put_user(0,name->version+__OLD_UTS_LEN); 238*1da177e4SLinus Torvalds error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN); 239*1da177e4SLinus Torvalds error = __put_user(0,name->machine+__OLD_UTS_LEN); 240*1da177e4SLinus Torvalds error = error ? -EFAULT : 0; 241*1da177e4SLinus Torvalds 242*1da177e4SLinus Torvalds return error; 243*1da177e4SLinus Torvalds } 244*1da177e4SLinus Torvalds 245*1da177e4SLinus Torvalds asmlinkage int _sys_sysmips(int cmd, long arg1, int arg2, int arg3) 246*1da177e4SLinus Torvalds { 247*1da177e4SLinus Torvalds int tmp, len; 248*1da177e4SLinus Torvalds char *name; 249*1da177e4SLinus Torvalds 250*1da177e4SLinus Torvalds switch(cmd) { 251*1da177e4SLinus Torvalds case SETNAME: { 252*1da177e4SLinus Torvalds char nodename[__NEW_UTS_LEN + 1]; 253*1da177e4SLinus Torvalds 254*1da177e4SLinus Torvalds if (!capable(CAP_SYS_ADMIN)) 255*1da177e4SLinus Torvalds return -EPERM; 256*1da177e4SLinus Torvalds 257*1da177e4SLinus Torvalds name = (char *) arg1; 258*1da177e4SLinus Torvalds 259*1da177e4SLinus Torvalds len = strncpy_from_user(nodename, name, __NEW_UTS_LEN); 260*1da177e4SLinus Torvalds if (len < 0) 261*1da177e4SLinus Torvalds return -EFAULT; 262*1da177e4SLinus Torvalds 263*1da177e4SLinus Torvalds down_write(&uts_sem); 264*1da177e4SLinus Torvalds strncpy(system_utsname.nodename, nodename, len); 265*1da177e4SLinus Torvalds nodename[__NEW_UTS_LEN] = '\0'; 266*1da177e4SLinus Torvalds strlcpy(system_utsname.nodename, nodename, 267*1da177e4SLinus Torvalds sizeof(system_utsname.nodename)); 268*1da177e4SLinus Torvalds up_write(&uts_sem); 269*1da177e4SLinus Torvalds return 0; 270*1da177e4SLinus Torvalds } 271*1da177e4SLinus Torvalds 272*1da177e4SLinus Torvalds case MIPS_ATOMIC_SET: 273*1da177e4SLinus Torvalds printk(KERN_CRIT "How did I get here?\n"); 274*1da177e4SLinus Torvalds return -EINVAL; 275*1da177e4SLinus Torvalds 276*1da177e4SLinus Torvalds case MIPS_FIXADE: 277*1da177e4SLinus Torvalds tmp = current->thread.mflags & ~3; 278*1da177e4SLinus Torvalds current->thread.mflags = tmp | (arg1 & 3); 279*1da177e4SLinus Torvalds return 0; 280*1da177e4SLinus Torvalds 281*1da177e4SLinus Torvalds case FLUSH_CACHE: 282*1da177e4SLinus Torvalds __flush_cache_all(); 283*1da177e4SLinus Torvalds return 0; 284*1da177e4SLinus Torvalds 285*1da177e4SLinus Torvalds case MIPS_RDNVRAM: 286*1da177e4SLinus Torvalds return -EIO; 287*1da177e4SLinus Torvalds } 288*1da177e4SLinus Torvalds 289*1da177e4SLinus Torvalds return -EINVAL; 290*1da177e4SLinus Torvalds } 291*1da177e4SLinus Torvalds 292*1da177e4SLinus Torvalds /* 293*1da177e4SLinus Torvalds * sys_ipc() is the de-multiplexer for the SysV IPC calls.. 294*1da177e4SLinus Torvalds * 295*1da177e4SLinus Torvalds * This is really horribly ugly. 296*1da177e4SLinus Torvalds */ 297*1da177e4SLinus Torvalds asmlinkage int sys_ipc (uint call, int first, int second, 298*1da177e4SLinus Torvalds unsigned long third, void *ptr, long fifth) 299*1da177e4SLinus Torvalds { 300*1da177e4SLinus Torvalds int version, ret; 301*1da177e4SLinus Torvalds 302*1da177e4SLinus Torvalds version = call >> 16; /* hack for backward compatibility */ 303*1da177e4SLinus Torvalds call &= 0xffff; 304*1da177e4SLinus Torvalds 305*1da177e4SLinus Torvalds switch (call) { 306*1da177e4SLinus Torvalds case SEMOP: 307*1da177e4SLinus Torvalds return sys_semtimedop (first, (struct sembuf *)ptr, second, 308*1da177e4SLinus Torvalds NULL); 309*1da177e4SLinus Torvalds case SEMTIMEDOP: 310*1da177e4SLinus Torvalds return sys_semtimedop (first, (struct sembuf *)ptr, second, 311*1da177e4SLinus Torvalds (const struct timespec __user *)fifth); 312*1da177e4SLinus Torvalds case SEMGET: 313*1da177e4SLinus Torvalds return sys_semget (first, second, third); 314*1da177e4SLinus Torvalds case SEMCTL: { 315*1da177e4SLinus Torvalds union semun fourth; 316*1da177e4SLinus Torvalds if (!ptr) 317*1da177e4SLinus Torvalds return -EINVAL; 318*1da177e4SLinus Torvalds if (get_user(fourth.__pad, (void **) ptr)) 319*1da177e4SLinus Torvalds return -EFAULT; 320*1da177e4SLinus Torvalds return sys_semctl (first, second, third, fourth); 321*1da177e4SLinus Torvalds } 322*1da177e4SLinus Torvalds 323*1da177e4SLinus Torvalds case MSGSND: 324*1da177e4SLinus Torvalds return sys_msgsnd (first, (struct msgbuf *) ptr, 325*1da177e4SLinus Torvalds second, third); 326*1da177e4SLinus Torvalds case MSGRCV: 327*1da177e4SLinus Torvalds switch (version) { 328*1da177e4SLinus Torvalds case 0: { 329*1da177e4SLinus Torvalds struct ipc_kludge tmp; 330*1da177e4SLinus Torvalds if (!ptr) 331*1da177e4SLinus Torvalds return -EINVAL; 332*1da177e4SLinus Torvalds 333*1da177e4SLinus Torvalds if (copy_from_user(&tmp, 334*1da177e4SLinus Torvalds (struct ipc_kludge *) ptr, 335*1da177e4SLinus Torvalds sizeof (tmp))) 336*1da177e4SLinus Torvalds return -EFAULT; 337*1da177e4SLinus Torvalds return sys_msgrcv (first, tmp.msgp, second, 338*1da177e4SLinus Torvalds tmp.msgtyp, third); 339*1da177e4SLinus Torvalds } 340*1da177e4SLinus Torvalds default: 341*1da177e4SLinus Torvalds return sys_msgrcv (first, 342*1da177e4SLinus Torvalds (struct msgbuf *) ptr, 343*1da177e4SLinus Torvalds second, fifth, third); 344*1da177e4SLinus Torvalds } 345*1da177e4SLinus Torvalds case MSGGET: 346*1da177e4SLinus Torvalds return sys_msgget ((key_t) first, second); 347*1da177e4SLinus Torvalds case MSGCTL: 348*1da177e4SLinus Torvalds return sys_msgctl (first, second, (struct msqid_ds *) ptr); 349*1da177e4SLinus Torvalds 350*1da177e4SLinus Torvalds case SHMAT: 351*1da177e4SLinus Torvalds switch (version) { 352*1da177e4SLinus Torvalds default: { 353*1da177e4SLinus Torvalds ulong raddr; 354*1da177e4SLinus Torvalds ret = do_shmat (first, (char *) ptr, second, &raddr); 355*1da177e4SLinus Torvalds if (ret) 356*1da177e4SLinus Torvalds return ret; 357*1da177e4SLinus Torvalds return put_user (raddr, (ulong *) third); 358*1da177e4SLinus Torvalds } 359*1da177e4SLinus Torvalds case 1: /* iBCS2 emulator entry point */ 360*1da177e4SLinus Torvalds if (!segment_eq(get_fs(), get_ds())) 361*1da177e4SLinus Torvalds return -EINVAL; 362*1da177e4SLinus Torvalds return do_shmat (first, (char *) ptr, second, (ulong *) third); 363*1da177e4SLinus Torvalds } 364*1da177e4SLinus Torvalds case SHMDT: 365*1da177e4SLinus Torvalds return sys_shmdt ((char *)ptr); 366*1da177e4SLinus Torvalds case SHMGET: 367*1da177e4SLinus Torvalds return sys_shmget (first, second, third); 368*1da177e4SLinus Torvalds case SHMCTL: 369*1da177e4SLinus Torvalds return sys_shmctl (first, second, 370*1da177e4SLinus Torvalds (struct shmid_ds *) ptr); 371*1da177e4SLinus Torvalds default: 372*1da177e4SLinus Torvalds return -ENOSYS; 373*1da177e4SLinus Torvalds } 374*1da177e4SLinus Torvalds } 375*1da177e4SLinus Torvalds 376*1da177e4SLinus Torvalds /* 377*1da177e4SLinus Torvalds * Native ABI that is O32 or N64 version 378*1da177e4SLinus Torvalds */ 379*1da177e4SLinus Torvalds asmlinkage long sys_shmat(int shmid, char __user *shmaddr, 380*1da177e4SLinus Torvalds int shmflg, unsigned long *addr) 381*1da177e4SLinus Torvalds { 382*1da177e4SLinus Torvalds unsigned long raddr; 383*1da177e4SLinus Torvalds int err; 384*1da177e4SLinus Torvalds 385*1da177e4SLinus Torvalds err = do_shmat(shmid, shmaddr, shmflg, &raddr); 386*1da177e4SLinus Torvalds if (err) 387*1da177e4SLinus Torvalds return err; 388*1da177e4SLinus Torvalds 389*1da177e4SLinus Torvalds return put_user(raddr, addr); 390*1da177e4SLinus Torvalds } 391*1da177e4SLinus Torvalds 392*1da177e4SLinus Torvalds /* 393*1da177e4SLinus Torvalds * No implemented yet ... 394*1da177e4SLinus Torvalds */ 395*1da177e4SLinus Torvalds asmlinkage int sys_cachectl(char *addr, int nbytes, int op) 396*1da177e4SLinus Torvalds { 397*1da177e4SLinus Torvalds return -ENOSYS; 398*1da177e4SLinus Torvalds } 399*1da177e4SLinus Torvalds 400*1da177e4SLinus Torvalds /* 401*1da177e4SLinus Torvalds * If we ever come here the user sp is bad. Zap the process right away. 402*1da177e4SLinus Torvalds * Due to the bad stack signaling wouldn't work. 403*1da177e4SLinus Torvalds */ 404*1da177e4SLinus Torvalds asmlinkage void bad_stack(void) 405*1da177e4SLinus Torvalds { 406*1da177e4SLinus Torvalds do_exit(SIGSEGV); 407*1da177e4SLinus Torvalds } 408