linux/arch/mn10300/kernel/sys_mn10300.c
<<
>>
Prefs
   1/* MN10300 Weird system calls
   2 *
   3 * Copyright (C) 2007 Matsushita Electric Industrial Co., Ltd.
   4 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public Licence
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the Licence, or (at your option) any later version.
  10 */
  11#include <linux/errno.h>
  12#include <linux/sched.h>
  13#include <linux/syscalls.h>
  14#include <linux/mm.h>
  15#include <linux/smp.h>
  16#include <linux/smp_lock.h>
  17#include <linux/sem.h>
  18#include <linux/msg.h>
  19#include <linux/shm.h>
  20#include <linux/stat.h>
  21#include <linux/mman.h>
  22#include <linux/file.h>
  23#include <linux/utsname.h>
  24#include <linux/syscalls.h>
  25#include <linux/tty.h>
  26
  27#include <asm/uaccess.h>
  28
  29#define MIN_MAP_ADDR    PAGE_SIZE       /* minimum fixed mmap address */
  30
  31/*
  32 * memory mapping syscall
  33 */
  34asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
  35                          unsigned long prot, unsigned long flags,
  36                          unsigned long fd, unsigned long pgoff)
  37{
  38        struct file *file = NULL;
  39        long error = -EINVAL;
  40
  41        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  42
  43        if (flags & MAP_FIXED && addr < MIN_MAP_ADDR)
  44                goto out;
  45
  46        error = -EBADF;
  47        if (!(flags & MAP_ANONYMOUS)) {
  48                file = fget(fd);
  49                if (!file)
  50                        goto out;
  51        }
  52
  53        down_write(&current->mm->mmap_sem);
  54        error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  55        up_write(&current->mm->mmap_sem);
  56
  57        if (file)
  58                fput(file);
  59out:
  60        return error;
  61}
  62
  63asmlinkage long old_mmap(unsigned long addr, unsigned long len,
  64                         unsigned long prot, unsigned long flags,
  65                         unsigned long fd, unsigned long offset)
  66{
  67        if (offset & ~PAGE_MASK)
  68                return -EINVAL;
  69        return sys_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
  70}
  71
  72struct sel_arg_struct {
  73        unsigned long n;
  74        fd_set *inp;
  75        fd_set *outp;
  76        fd_set *exp;
  77        struct timeval *tvp;
  78};
  79
  80asmlinkage int old_select(struct sel_arg_struct __user *arg)
  81{
  82        struct sel_arg_struct a;
  83
  84        if (copy_from_user(&a, arg, sizeof(a)))
  85                return -EFAULT;
  86        /* sys_select() does the appropriate kernel locking */
  87        return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp);
  88}
  89
  90/*
  91 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  92 *
  93 * This is really horribly ugly.
  94 */
  95asmlinkage long sys_ipc(uint call, int first, int second,
  96                        int third, void __user *ptr, long fifth)
  97{
  98        int version, ret;
  99
 100        version = call >> 16; /* hack for backward compatibility */
 101        call &= 0xffff;
 102
 103        switch (call) {
 104        case SEMOP:
 105                return sys_semtimedop(first, (struct sembuf __user *)ptr,
 106                                      second, NULL);
 107        case SEMTIMEDOP:
 108                return sys_semtimedop(first, (struct sembuf __user *)ptr,
 109                                      second,
 110                                      (const struct timespec __user *)fifth);
 111        case SEMGET:
 112                return sys_semget(first, second, third);
 113        case SEMCTL: {
 114                union semun fourth;
 115                if (!ptr)
 116                        return -EINVAL;
 117                if (get_user(fourth.__pad, (void __user * __user *) ptr))
 118                        return -EFAULT;
 119                return sys_semctl(first, second, third, fourth);
 120        }
 121
 122        case MSGSND:
 123                return sys_msgsnd(first, (struct msgbuf __user *) ptr,
 124                                  second, third);
 125        case MSGRCV:
 126                switch (version) {
 127                case 0: {
 128                        struct ipc_kludge tmp;
 129                        if (!ptr)
 130                                return -EINVAL;
 131
 132                        if (copy_from_user(&tmp,
 133                                           (struct ipc_kludge __user *) ptr,
 134                                           sizeof(tmp)))
 135                                return -EFAULT;
 136                        return sys_msgrcv(first, tmp.msgp, second,
 137                                          tmp.msgtyp, third);
 138                }
 139                default:
 140                        return sys_msgrcv(first,
 141                                          (struct msgbuf __user *) ptr,
 142                                           second, fifth, third);
 143                }
 144        case MSGGET:
 145                return sys_msgget((key_t) first, second);
 146        case MSGCTL:
 147                return sys_msgctl(first, second,
 148                                   (struct msqid_ds __user *) ptr);
 149
 150        case SHMAT:
 151                switch (version) {
 152                default: {
 153                        ulong raddr;
 154                        ret = do_shmat(first, (char __user *) ptr, second,
 155                                       &raddr);
 156                        if (ret)
 157                                return ret;
 158                        return put_user(raddr, (ulong *) third);
 159                }
 160                case 1: /* iBCS2 emulator entry point */
 161                        if (!segment_eq(get_fs(), get_ds()))
 162                                return -EINVAL;
 163                        return do_shmat(first, (char __user *) ptr, second,
 164                                        (ulong *) third);
 165                }
 166        case SHMDT:
 167                return sys_shmdt((char __user *)ptr);
 168        case SHMGET:
 169                return sys_shmget(first, second, third);
 170        case SHMCTL:
 171                return sys_shmctl(first, second,
 172                                  (struct shmid_ds __user *) ptr);
 173        default:
 174                return -EINVAL;
 175        }
 176}
 177