sys_s390.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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. #include <linux/errno.h>
  15. #include <linux/sched.h>
  16. #include <linux/mm.h>
  17. #include <linux/smp.h>
  18. #include <linux/smp_lock.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/file.h>
  25. #include <linux/utsname.h>
  26. #include <linux/personality.h>
  27. #include <asm/uaccess.h>
  28. #include <asm/ipc.h>
  29. /*
  30.  * sys_pipe() is the normal C calling standard for creating
  31.  * a pipe. It's not the way Unix traditionally does this, though.
  32.  */
  33. asmlinkage long sys_pipe(unsigned long * fildes)
  34. {
  35. int fd[2];
  36. int error;
  37. error = do_pipe(fd);
  38. if (!error) {
  39. if (copy_to_user(fildes, fd, 2*sizeof(int)))
  40. error = -EFAULT;
  41. }
  42. return error;
  43. }
  44. /* common code for old and new mmaps */
  45. static inline long do_mmap2(
  46. unsigned long addr, unsigned long len,
  47. unsigned long prot, unsigned long flags,
  48. unsigned long fd, unsigned long pgoff)
  49. {
  50. long error = -EBADF;
  51. struct file * file = NULL;
  52. flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
  53. if (!(flags & MAP_ANONYMOUS)) {
  54. file = fget(fd);
  55. if (!file)
  56. goto out;
  57. }
  58. down_write(&current->mm->mmap_sem);
  59. error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
  60. up_write(&current->mm->mmap_sem);
  61. if (file)
  62. fput(file);
  63. out:
  64. return error;
  65. }
  66. /*
  67.  * Perform the select(nd, in, out, ex, tv) and mmap() system
  68.  * calls. Linux/i386 didn't use to be able to handle more than
  69.  * 4 system call parameters, so these system calls used a memory
  70.  * block for parameter passing..
  71.  */
  72. struct mmap_arg_struct {
  73. unsigned long addr;
  74. unsigned long len;
  75. unsigned long prot;
  76. unsigned long flags;
  77. unsigned long fd;
  78. unsigned long offset;
  79. };
  80. asmlinkage long sys_mmap2(struct mmap_arg_struct *arg)
  81. {
  82. struct mmap_arg_struct a;
  83. int error = -EFAULT;
  84. if (copy_from_user(&a, arg, sizeof(a)))
  85. goto out;
  86. error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset);
  87. out:
  88. return error;
  89. }
  90. asmlinkage long old_mmap(struct mmap_arg_struct *arg)
  91. {
  92. struct mmap_arg_struct a;
  93. long error = -EFAULT;
  94. if (copy_from_user(&a, arg, sizeof(a)))
  95. goto out;
  96. error = -EINVAL;
  97. if (a.offset & ~PAGE_MASK)
  98. goto out;
  99. error = do_mmap2(a.addr, a.len, a.prot, a.flags, a.fd, a.offset >> PAGE_SHIFT);
  100. out:
  101. return error;
  102. }
  103. extern asmlinkage int sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
  104. /*
  105.  * sys_ipc() is the de-multiplexer for the SysV IPC calls..
  106.  *
  107.  * This is really horribly ugly.
  108.  */
  109. asmlinkage int sys_ipc (uint call, int first, long second, 
  110.                         unsigned long third, void *ptr)
  111. {
  112.         struct ipc_kludge tmp;
  113. int ret;
  114.         switch (call) {
  115.         case SEMOP:
  116.                 return sys_semop (first, (struct sembuf *)ptr, second);
  117.         case SEMGET:
  118.                 return sys_semget (first, second, third);
  119.         case SEMCTL: {
  120.                 union semun fourth;
  121.                 if (!ptr)
  122.                         return -EINVAL;
  123.                 if (get_user(fourth.__pad, (void **) ptr))
  124.                         return -EFAULT;
  125.                 return sys_semctl (first, second, third, fourth);
  126.         } 
  127.         case MSGSND:
  128. return sys_msgsnd (first, (struct msgbuf *) ptr, 
  129.                                    second, third);
  130. break;
  131.         case MSGRCV:
  132.                 if (!ptr)
  133.                         return -EINVAL;
  134.                 if (copy_from_user (&tmp, (struct ipc_kludge *) ptr,
  135.                                     sizeof (struct ipc_kludge)))
  136.                         return -EFAULT;
  137.                 return sys_msgrcv (first, tmp.msgp,
  138.                                    second, tmp.msgtyp, third);
  139.         case MSGGET:
  140.                 return sys_msgget ((key_t) first, second);
  141.         case MSGCTL:
  142.                 return sys_msgctl (first, second, (struct msqid_ds *) ptr);
  143.                 
  144. case SHMAT: {
  145. ulong raddr;
  146. ret = sys_shmat (first, (char *) ptr, second, &raddr);
  147. if (ret)
  148. return ret;
  149. return put_user (raddr, (ulong *) third);
  150. break;
  151.         }
  152. case SHMDT: 
  153. return sys_shmdt ((char *)ptr);
  154. case SHMGET:
  155. return sys_shmget (first, second, third);
  156. case SHMCTL:
  157. return sys_shmctl (first, second,
  158.                                    (struct shmid_ds *) ptr);
  159. default:
  160. return -EINVAL;
  161. }
  162.         
  163. return -EINVAL;
  164. }
  165. /*
  166.  * Old cruft
  167.  */
  168. asmlinkage int sys_uname(struct old_utsname * name)
  169. {
  170. int err;
  171. if (!name)
  172. return -EFAULT;
  173. down_read(&uts_sem);
  174. err=copy_to_user(name, &system_utsname, sizeof (*name));
  175. up_read(&uts_sem);
  176. return err?-EFAULT:0;
  177. }
  178. asmlinkage int sys_pause(void)
  179. {
  180. set_current_state(TASK_INTERRUPTIBLE);
  181. schedule();
  182. return -ERESTARTNOHAND;
  183. }
  184. extern asmlinkage int sys_newuname(struct new_utsname * name);
  185. asmlinkage int s390x_newuname(struct new_utsname * name)
  186. {
  187. int ret = sys_newuname(name);
  188. if (current->personality == PER_LINUX32 && !ret) {
  189. ret = copy_to_user(name->machine, "s390", 8);
  190. if (ret) ret = -EFAULT;
  191. }
  192. return ret;
  193. }
  194. extern asmlinkage long sys_personality(unsigned long);
  195. asmlinkage int s390x_personality(unsigned long personality)
  196. {
  197. int ret;
  198. if (current->personality == PER_LINUX32 && personality == PER_LINUX)
  199. personality = PER_LINUX32;
  200. ret = sys_personality(personality);
  201. if (ret == PER_LINUX32)
  202. ret = PER_LINUX;
  203. return ret;
  204. }