linux-old/arch/s390/kernel/sys_s390.c
<<
>>
Prefs
   1/*
   2 *  arch/s390/kernel/sys_s390.c
   3 *
   4 *  S390 version
   5 *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
   6 *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
   7 *
   8 *  Derived from "arch/i386/kernel/sys_i386.c"
   9 *
  10 *  This file contains various random system calls that
  11 *  have a non-standard calling sequence on the Linux/s390
  12 *  platform.
  13 */
  14
  15#include <linux/errno.h>
  16#include <linux/sched.h>
  17#include <linux/mm.h>
  18#include <linux/smp.h>
  19#include <linux/smp_lock.h>
  20#include <linux/sem.h>
  21#include <linux/msg.h>
  22#include <linux/shm.h>
  23#include <linux/stat.h>
  24#include <linux/mman.h>
  25#include <linux/file.h>
  26#include <linux/utsname.h>
  27
  28#include <asm/uaccess.h>
  29#include <asm/ipc.h>
  30
  31/*
  32 * sys_pipe() is the normal C calling standard for creating
  33 * a pipe. It's not the way Unix traditionally does this, though.
  34 */
  35asmlinkage int sys_pipe(unsigned long * fildes)
  36{
  37        int fd[2];
  38        int error;
  39
  40        error = do_pipe(fd);
  41        if (!error) {
  42                if (copy_to_user(fildes, fd, 2*sizeof(int)))
  43                        error = -EFAULT;
  44        }
  45        return error;
  46}
  47
  48/* common code for old and new mmaps */
  49static inline long do_mmap2(
  50        unsigned long addr, unsigned long len,
  51        unsigned long prot, unsigned long flags,
  52        unsigned long fd, unsigned long pgoff)
  53{
  54        int error = -EBADF;
  55        struct file * file = NULL;
  56
  57        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  58        if (!(flags & MAP_ANONYMOUS)) {
  59                file = fget(fd);
  60                if (!file)
  61                        goto out;
  62        }
  63
  64        down_write(&current->mm->mmap_sem);
  65        error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  66        up_write(&current->mm->mmap_sem);
  67
  68        if (file)
  69                fput(file);
  70out:
  71        return error;
  72}
  73
  74/*
  75 * Perform the select(nd, in, out, ex, tv) and mmap() system
  76 * calls. Linux for S/390 isn't able to handle more than 5
  77 * system call parameters, so these system calls used a memory
  78 * block for parameter passing..
  79 */
  80
  81struct mmap_arg_struct {
  82        unsigned long addr;
  83        unsigned long len;
  84        unsigned long prot;
  85        unsigned long flags;
  86        unsigned long fd;
  87        unsigned long offset;
  88};
  89
  90asmlinkage long sys_mmap2(struct mmap_arg_struct *arg)
  91{
  92        struct mmap_arg_struct a;
  93        int error = -EFAULT;
  94
  95        if (copy_from_user(&a, arg, sizeof(a)))
  96                goto out;
  97        error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
  98out:
  99        return error;
 100}
 101
 102asmlinkage int old_mmap(struct mmap_arg_struct *arg)
 103{
 104        struct mmap_arg_struct a;
 105        int error = -EFAULT;
 106
 107        if (copy_from_user(&a, arg, sizeof(a)))
 108                goto out;
 109
 110        error = -EINVAL;
 111        if (a.offset & ~PAGE_MASK)
 112                goto out;
 113
 114        error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
 115out:
 116        return error;
 117}
 118
 119extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 120
 121struct sel_arg_struct {
 122        unsigned long n;
 123        fd_set *inp, *outp, *exp;
 124        struct timeval *tvp;
 125};
 126
 127asmlinkage int old_select(struct sel_arg_struct *arg)
 128{
 129        struct sel_arg_struct a;
 130
 131        if (copy_from_user(&a, arg, sizeof(a)))
 132                return -EFAULT;
 133        /* sys_select() does the appropriate kernel locking */
 134        return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
 135}
 136
 137/*
 138 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
 139 *
 140 * This is really horribly ugly.
 141 */
 142asmlinkage int sys_ipc (uint call, int first, int second, 
 143                        int third, void *ptr)
 144{
 145        struct ipc_kludge tmp;
 146        int ret;
 147
 148        switch (call) {
 149        case SEMOP:
 150                return sys_semop (first, (struct sembuf *)ptr, second);
 151        case SEMGET:
 152                return sys_semget (first, second, third);
 153        case SEMCTL: {
 154                union semun fourth;
 155                if (!ptr)
 156                        return -EINVAL;
 157                if (get_user(fourth.__pad, (void **) ptr))
 158                        return -EFAULT;
 159                return sys_semctl (first, second, third, fourth);
 160        } 
 161        case MSGSND:
 162                return sys_msgsnd (first, (struct msgbuf *) ptr, 
 163                                   second, third);
 164                break;
 165        case MSGRCV:
 166                if (!ptr)
 167                        return -EINVAL;
 168                if (copy_from_user (&tmp, (struct ipc_kludge *) ptr,
 169                                    sizeof (struct ipc_kludge)))
 170                        return -EFAULT;
 171                return sys_msgrcv (first, tmp.msgp,
 172                                   second, tmp.msgtyp, third);
 173        case MSGGET:
 174                return sys_msgget ((key_t) first, second);
 175        case MSGCTL:
 176                return sys_msgctl (first, second, (struct msqid_ds *) ptr);
 177                
 178        case SHMAT: {
 179                ulong raddr;
 180                ret = sys_shmat (first, (char *) ptr, second, &raddr);
 181                if (ret)
 182                        return ret;
 183                return put_user (raddr, (ulong *) third);
 184                break;
 185        }
 186        case SHMDT: 
 187                return sys_shmdt ((char *)ptr);
 188        case SHMGET:
 189                return sys_shmget (first, second, third);
 190        case SHMCTL:
 191                return sys_shmctl (first, second,
 192                                   (struct shmid_ds *) ptr);
 193        default:
 194                return -EINVAL;
 195
 196        }
 197        
 198        return -EINVAL;
 199}
 200
 201/*
 202 * Old cruft
 203 */
 204asmlinkage int sys_uname(struct old_utsname * name)
 205{
 206        int err;
 207        if (!name)
 208                return -EFAULT;
 209        down_read(&uts_sem);
 210        err=copy_to_user(name, &system_utsname, sizeof (*name));
 211        up_read(&uts_sem);
 212        return err?-EFAULT:0;
 213}
 214
 215asmlinkage int sys_olduname(struct oldold_utsname * name)
 216{
 217        int error;
 218
 219        if (!name)
 220                return -EFAULT;
 221        if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
 222                return -EFAULT;
 223  
 224        down_read(&uts_sem);
 225        
 226        error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
 227        error |= __put_user(0,name->sysname+__OLD_UTS_LEN);
 228        error |= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
 229        error |= __put_user(0,name->nodename+__OLD_UTS_LEN);
 230        error |= __copy_to_user(&name->release,&system_utsname.release,__OLD_UTS_LEN);
 231        error |= __put_user(0,name->release+__OLD_UTS_LEN);
 232        error |= __copy_to_user(&name->version,&system_utsname.version,__OLD_UTS_LEN);
 233        error |= __put_user(0,name->version+__OLD_UTS_LEN);
 234        error |= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
 235        error |= __put_user(0,name->machine+__OLD_UTS_LEN);
 236        
 237        up_read(&uts_sem);
 238        
 239        error = error ? -EFAULT : 0;
 240
 241        return error;
 242}
 243
 244asmlinkage int sys_pause(void)
 245{
 246        set_current_state(TASK_INTERRUPTIBLE);
 247        schedule();
 248        return -ERESTARTNOHAND;
 249}
 250
 251asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
 252{
 253  return -ENOSYS;
 254}
 255
 256
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.