[S390] ipc: call generic sys_ipc demultiplexer
[firefly-linux-kernel-4.4.55.git] / arch / s390 / kernel / sys_s390.c
index 476081440df9f4ec7674a0aed3f8dbbadcfd6fe5..78ea1948ff514f4e20df0686f38308427644fe21 100644 (file)
@@ -60,74 +60,22 @@ out:
 }
 
 /*
- * sys_ipc() is the de-multiplexer for the SysV IPC calls..
- *
- * This is really horribly ugly.
+ * sys_ipc() is the de-multiplexer for the SysV IPC calls.
  */
 SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
                unsigned long, third, void __user *, ptr)
 {
-        struct ipc_kludge tmp;
-       int ret;
-
-        switch (call) {
-        case SEMOP:
-               return sys_semtimedop(first, (struct sembuf __user *)ptr,
-                                      (unsigned)second, NULL);
-       case SEMTIMEDOP:
-               return sys_semtimedop(first, (struct sembuf __user *)ptr,
-                                      (unsigned)second,
-                                      (const struct timespec __user *) third);
-        case SEMGET:
-                return sys_semget(first, (int)second, third);
-        case SEMCTL: {
-                union semun fourth;
-                if (!ptr)
-                        return -EINVAL;
-                if (get_user(fourth.__pad, (void __user * __user *) ptr))
-                        return -EFAULT;
-                return sys_semctl(first, (int)second, third, fourth);
-        }
-        case MSGSND:
-               return sys_msgsnd (first, (struct msgbuf __user *) ptr,
-                                   (size_t)second, third);
-               break;
-        case MSGRCV:
-                if (!ptr)
-                        return -EINVAL;
-                if (copy_from_user (&tmp, (struct ipc_kludge __user *) ptr,
-                                    sizeof (struct ipc_kludge)))
-                        return -EFAULT;
-                return sys_msgrcv (first, tmp.msgp,
-                                   (size_t)second, tmp.msgtyp, third);
-        case MSGGET:
-                return sys_msgget((key_t)first, (int)second);
-        case MSGCTL:
-                return sys_msgctl(first, (int)second,
-                                  (struct msqid_ds __user *)ptr);
-
-       case SHMAT: {
-               ulong raddr;
-               ret = do_shmat(first, (char __user *)ptr,
-                               (int)second, &raddr);
-               if (ret)
-                       return ret;
-               return put_user (raddr, (ulong __user *) third);
-               break;
-        }
-       case SHMDT:
-               return sys_shmdt ((char __user *)ptr);
-       case SHMGET:
-               return sys_shmget(first, (size_t)second, third);
-       case SHMCTL:
-               return sys_shmctl(first, (int)second,
-                                   (struct shmid_ds __user *) ptr);
-       default:
-               return -ENOSYS;
-
-       }
-
-       return -EINVAL;
+       if (call >> 16)
+               return -EINVAL;
+       /* The s390 sys_ipc variant has only five parameters instead of six
+        * like the generic variant. The only difference is the handling of
+        * the SEMTIMEDOP subcall where on s390 the third parameter is used
+        * as a pointer to a struct timespec where the generic variant uses
+        * the fifth parameter.
+        * Therefore we can call the generic variant by simply passing the
+        * third parameter also as fifth parameter.
+        */
+       return sys_ipc(call, first, second, third, ptr, third);
 }
 
 #ifdef CONFIG_64BIT