Skip to contentSkip to conversation

generic sys_ipc wrapper

PATCH In review Christoph Hellwig 6 participants 14 messages Jan 6, 2010 – Jan 14, 2010

Subsystems (11)
Arm (32-bit) x86 PowerPC MIPS +7 more subsystems
lore
Share & tools
lore
#0 lore raw

PATCH 3/3 generic sys_ipc wrapper

Add a generic implementation of the ipc demultiplexer syscall. Except for s390 and sparc64 all implementations of the sys_ipc are nearly identical.

There are slight differences in the types of the parameters, where mips and powerpc as the only 64-bit architectures with sys_ipc use unsigned long for the "third" argument as it gets casted to a pointer later, while it traditionally is an "int" like most other paramters. frv goes even further and uses unsigned long for all parameters execept for "ptr" which is a pointer type everywhere. The change from int to unsigned long for "third" and back to "int" for the others on frv should be fine due to the in-register calling conventions for syscalls (we already had a similar issue with the generic sys_ptrace), but I'd prefer to have the arch maintainers looks over this in details.

Except for that h8300, m68k and m68knommu lack an impplementation of the semtimedop sub call which this patch adds, and various architectures have different strategies for the SHMAT version 1 case which apparently never gets used - at least on i386 it seems superflous as the compat code on x86-64 and ia64 doesn't even bother to implement it.

ipc/syscall.c new file +112 -0
Index: linux-2.6/ipc/syscall.c
===================================================================
@@ -0,0 +1,112 @@
+/*
+ * sys_ipc() is the old de-multiplexer for the SysV IPC calls.
+ *
+ * This is really horribly ugly, and new architectures should just wire up
+ * the individual syscalls instead.
+ */
+#include <linux/unistd.h>
+
+#ifdef __ARCH_WANT_SYS_IPC
+#include <linux/errno.h>
+#include <linux/ipc.h>
+#include <linux/shm.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+
+SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second,
+		unsigned long, third, void __user *, ptr, long, fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		return sys_semtimedop(first, (struct sembuf __user *)ptr,
+				      second, NULL);
+	case SEMTIMEDOP:
+		return sys_semtimedop(first, (struct sembuf __user *)ptr,
+				      second,
+				      (const struct timespec __user *)fifth);
+
+	case SEMGET:
+		return sys_semget(first, 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, second, third, fourth);
+	}
+
+	case MSGSND:
+		return sys_msgsnd(first, (struct msgbuf __user *) ptr,
+				  second, third);
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+			if (!ptr)
+				return -EINVAL;
+
+			if (copy_from_user(&tmp,
+					   (struct ipc_kludge __user *) ptr,
+					   sizeof(tmp)))
+				return -EFAULT;
+			return sys_msgrcv(first, tmp.msgp, second,
+					   tmp.msgtyp, third);
+		}
+		default:
+			return sys_msgrcv(first,
+					   (struct msgbuf __user *) ptr,
+					   second, fifth, third);
+		}
+	case MSGGET:
+		return sys_msgget((key_t) first, second);
+	case MSGCTL:
+		return sys_msgctl(first, second, (struct msqid_ds __user *)ptr);
+
+	case SHMAT:
+		switch (version) {
+		default: {
+			ulong raddr;
+			ret = do_shmat(first, (char __user *)ptr,
+				       second, &raddr);
+			if (ret)
+				return ret;
+			return put_user(raddr, (ulong __user *) third);
+		}
+
+#if defined(__i386__) || defined(__frv__) || defined(__mips__) ||\
+    defined(__mn10300__)
+		case 1:
+			/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				return -EINVAL;
+			/*
+			 * The "(ulong *) third" is valid _only_ because of
+			 * the kernel segment thing.
+			 */
+			return do_shmat(first, (char __user *) ptr, second,
+					(unsigned long *)third);
+#endif
+#if defined(__arm__) || defined(__sparc__)
+		case 1:
+			/* Of course, we don't support iBCS2! */
+			return -EINVAL;
+#endif
+		}
+	case SHMDT:
+		return sys_shmdt((char __user *)ptr);
+	case SHMGET:
+		return sys_shmget(first, second, third);
+	case SHMCTL:
+		return sys_shmctl(first, second,
+				   (struct shmid_ds __user *) ptr);
+	default:
+		return -ENOSYS;
+	}
+}
+#endif
arch/arm/kernel/sys_arm.c +0 -82

88 lines not on this page · raw message

arch/arm/kernel/sys_oabi-compat.c +0 -3
Index: linux-2.6/arch/arm/kernel/sys_oabi-compat.c
===================================================================
@@ -346,9 +346,6 @@ asmlinkage long sys_oabi_semop(int semid
 	return sys_oabi_semtimedop(semid, tsops, nsops, NULL);
 }
 
-extern asmlinkage int sys_ipc(uint call, int first, int second, int third,
-			      void __user *ptr, long fifth);
-
 asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
 			    void __user *ptr, long fifth)
 {
arch/cris/kernel/sys_cris.c +0 -78

81 lines not on this page · raw message

arch/frv/kernel/sys_frv.c +0 -89

92 lines not on this page · raw message

arch/m32r/kernel/sys_m32r.c +0 -81

87 lines not on this page · raw message

arch/m68k/kernel/sys_m68k.c +0 -81

87 lines not on this page · raw message

arch/mips/kernel/syscall.c +0 -88

94 lines not on this page · raw message

arch/mn10300/kernel/sys_mn10300.c +0 -88

91 lines not on this page · raw message

arch/powerpc/include/asm/syscalls.h +0 -2
Index: linux-2.6/arch/powerpc/include/asm/syscalls.h
===================================================================
@@ -35,8 +35,6 @@ asmlinkage long sys_pipe2(int __user *fi
 asmlinkage long sys_rt_sigaction(int sig,
 		const struct sigaction __user *act,
 		struct sigaction __user *oact, size_t sigsetsize);
-asmlinkage int sys_ipc(uint call, int first, unsigned long second,
-		long third, void __user *ptr, long fifth);
 asmlinkage long ppc64_personality(unsigned long personality);
 asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
 asmlinkage time_t sys64_time(time_t __user * tloc);
arch/powerpc/kernel/syscalls.c +0 -94

100 lines not on this page · raw message

arch/s390/kernel/entry.h +1 -1
Index: linux-2.6/arch/s390/kernel/entry.h
===================================================================
@@ -30,7 +30,7 @@ struct fadvise64_64_args;
 struct old_sigaction;
 
 long sys_mmap2(struct s390_mmap_arg_struct __user  *arg);
-long sys_ipc(uint call, int first, unsigned long second,
+long sys_s390_ipc(uint call, int first, unsigned long second,
 	     unsigned long third, void __user *ptr);
 long sys_s390_newuname(struct new_utsname __user *name);
 long sys_s390_personality(unsigned long personality);
arch/s390/kernel/sys_s390.c +1 -1
Index: linux-2.6/arch/s390/kernel/sys_s390.c
===================================================================
@@ -64,7 +64,7 @@ out:
  *
  * This is really horribly ugly.
  */
-SYSCALL_DEFINE5(ipc, uint, call, int, first, unsigned long, second,
+SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
 		unsigned long, third, void __user *, ptr)
 {
         struct ipc_kludge tmp;
arch/s390/kernel/syscalls.S +1 -1
Index: linux-2.6/arch/s390/kernel/syscalls.S
===================================================================
@@ -125,7 +125,7 @@ NI_SYSCALL							/* vm86old for i386 */
 SYSCALL(sys_wait4,sys_wait4,compat_sys_wait4_wrapper)
 SYSCALL(sys_swapoff,sys_swapoff,sys32_swapoff_wrapper)		/* 115 */
 SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper)
-SYSCALL(sys_ipc,sys_ipc,sys32_ipc_wrapper)
+SYSCALL(sys_s390_ipc,sys_s390_ipc,sys32_ipc_wrapper)
 SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper)
 SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn)
 SYSCALL(sys_clone,sys_clone,sys_clone_wrapper)			/* 120 */
arch/sh/include/asm/syscalls.h +0 -2
Index: linux-2.6/arch/sh/include/asm/syscalls.h
===================================================================
@@ -11,8 +11,6 @@ asmlinkage int old_mmap(unsigned long ad
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
 			  unsigned long prot, unsigned long flags,
 			  unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_ipc(uint call, int first, int second,
-		       int third, void __user *ptr, long fifth);
 asmlinkage int sys_uname(struct old_utsname __user *name);
 
 #ifdef CONFIG_SUPERH32
arch/sh/kernel/sys_sh.c +0 -104

110 lines not on this page · raw message

arch/sparc/kernel/sys_sparc_32.c +0 -113

119 lines not on this page · raw message

arch/um/sys-i386/syscalls.c +0 -86

92 lines not on this page · raw message

arch/x86/include/asm/syscalls.h +0 -1
Index: linux-2.6/arch/x86/include/asm/syscalls.h
===================================================================
@@ -54,7 +54,6 @@ unsigned long sys_sigreturn(struct pt_re
 struct oldold_utsname;
 struct old_utsname;
 
-asmlinkage int sys_ipc(uint, int, int, int, void __user *, long);
 asmlinkage int sys_uname(struct old_utsname __user *);
 asmlinkage int sys_olduname(struct oldold_utsname __user *);
 
ipc/Makefile +1 -1
Index: linux-2.6/ipc/Makefile
===================================================================
@@ -3,7 +3,7 @@
 #
 
 obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o
-obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o ipcns_notifier.o
+obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o ipcns_notifier.o syscall.o
 obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
 obj_mq-$(CONFIG_COMPAT) += compat_mq.o
 obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
arch/h8300/kernel/sys_h8300.c +0 -88

94 lines not on this page · raw message

arch/m68knommu/kernel/sys_m68k.c +0 -86

92 lines not on this page · raw message

arch/sparc/kernel/sys_sparc_64.c +1 -1
Index: linux-2.6/arch/sparc/kernel/sys_sparc_64.c
===================================================================
@@ -427,7 +427,7 @@ out:
  * This is really horribly ugly.
  */
 
-SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
+SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second,
 		unsigned long, third, void __user *, ptr, long, fifth)
 {
 	long err;
arch/sparc/kernel/systbls.h +1 -1
Index: linux-2.6/arch/sparc/kernel/systbls.h
===================================================================
@@ -10,7 +10,7 @@ struct new_utsname;
 
 extern asmlinkage unsigned long sys_getpagesize(void);
 extern asmlinkage long sparc_pipe(struct pt_regs *regs);
-extern asmlinkage long sys_ipc(unsigned int call, int first,
+extern asmlinkage long sys_sparc_ipc(unsigned int call, int first,
 			       unsigned long second,
 			       unsigned long third,
 			       void __user *ptr, long fifth);
arch/sparc/kernel/systbls_64.S +1 -1
Index: linux-2.6/arch/sparc/kernel/systbls_64.S
===================================================================
@@ -136,7 +136,7 @@ sys_call_table:
 /*200*/	.word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
 	.word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64
 /*210*/	.word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo
-	.word sys_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex
+	.word sys_sparc_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex
 /*220*/	.word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid
 	.word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid
 /*230*/	.word sys_select, sys_nis_syscall, sys_splice, sys_stime, sys_statfs64
arch/x86/kernel/sys_i386_32.c +0 -85

91 lines not on this page · raw message

arch/arm/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/arm/include/asm/unistd.h
===================================================================
@@ -447,6 +447,7 @@
 
 #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
 #define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_UTIME
arch/cris/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/cris/include/asm/unistd.h
===================================================================
@@ -352,6 +352,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/frv/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/frv/include/asm/unistd.h
===================================================================
@@ -354,6 +354,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 /* #define __ARCH_WANT_SYS_GETHOSTNAME */
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 /* #define __ARCH_WANT_SYS_SGETMASK */
 /* #define __ARCH_WANT_SYS_SIGNAL */
arch/h8300/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/h8300/include/asm/unistd.h
===================================================================
@@ -336,6 +336,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/m32r/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/m32r/include/asm/unistd.h
===================================================================
@@ -339,6 +339,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
arch/m68k/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/m68k/include/asm/unistd.h
===================================================================
@@ -347,6 +347,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/mips/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/mips/include/asm/unistd.h
===================================================================
@@ -1004,6 +1004,7 @@
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_UTIME
arch/mn10300/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/mn10300/include/asm/unistd.h
===================================================================
@@ -362,6 +362,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/powerpc/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/powerpc/include/asm/unistd.h
===================================================================
@@ -364,6 +364,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/s390/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/s390/include/asm/unistd.h
===================================================================
@@ -381,6 +381,7 @@
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SIGNAL
 #define __ARCH_WANT_SYS_UTIME
arch/sh/include/asm/unistd_32.h +1 -0
Index: linux-2.6/arch/sh/include/asm/unistd_32.h
===================================================================
@@ -357,6 +357,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/sh/include/asm/unistd_64.h +1 -0
Index: linux-2.6/arch/sh/include/asm/unistd_64.h
===================================================================
@@ -397,6 +397,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/sparc/include/asm/unistd.h +3 -1
Index: linux-2.6/arch/sparc/include/asm/unistd.h
===================================================================
@@ -432,7 +432,9 @@
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#ifndef __32bit_syscall_numbers__
+#ifdef __32bit_syscall_numbers__
+#define __ARCH_WANT_SYS_IPC
+#else
 #define __ARCH_WANT_COMPAT_SYS_TIME
 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 #endif
arch/x86/include/asm/unistd_32.h +1 -0
Index: linux-2.6/arch/x86/include/asm/unistd_32.h
===================================================================
@@ -354,6 +354,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
#1 lore raw
Quoted 5 lines · Christoph Hellwig

Except for that h8300, m68k and m68knommu lack an impplementation of the semtimedop sub call which this patch adds, and various architectures have different strategies for the SHMAT version 1 case which apparently never gets used - at least on i386 it seems superflous as the compat code on x86-64 and ia64 doesn't even bother to implement it.

Kill the SHMAT crap; it's _not_ a part of user-visible API (note that it checks that we'd come there with KERNEL_DS).

It had been a one-time kludge for ibcs2 module. Blindly copied to architectures than never had that shite at all, not that it had survived even on i386 past 2.2.x (2.4 analog doesn't use that thing).

Just make it fail with -EINVAL in that case.

#2 lore raw
In reply to Christoph Hellwig
Quoted 3 lines · Christoph Hellwig

various architectures have different strategies for the SHMAT version 1 case which apparently never gets used - at least on i386 it seems superflous as the compat code on x86-64 and ia64 doesn't even bother to implement it.

The SHMAT version 1 case can be dropped for FRV and MN10300 - neither of them support iBCS.

Quoted 6 lines

frv goes even further and uses unsigned long for all parameters execept for "ptr" which is a pointer type everywhere. The change from int to unsigned long for "third" and back to "int" for the others on frv should be fine due to the in-register calling conventions for syscalls (we already had a similar issue with the generic sys_ptrace), but I'd prefer to have the arch maintainers looks over this in details.

That should be okay - the registers are all 32-bits, so int, long and pointers are all the same size.

David

maintainer
#3 lore raw
In reply to Christoph Hellwig
Quoted 3 lines · On Wednesday 06 January 2010 18:21:52 Christoph Hellwig wrote:

Add a generic implementation of the ipc demultiplexer syscall. Except for s390 and sparc64 all implementations of the sys_ipc are nearly identical.

Very nice patch, too bad we didn't already do that ages ago ;)

Quoted 19 lines
ipc/syscall.c new file +19 -0
+		switch (version) {
+		default: {
+			ulong raddr;
+			ret = do_shmat(first, (char __user *)ptr,
+				       second, &raddr);
+			if (ret)
+				return ret;
+			return put_user(raddr, (ulong __user *) third);
+		}
+
+#if defined(__i386__) || defined(__frv__) || defined(__mips__) ||\
+    defined(__mn10300__)
+		case 1:
+			/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				return -EINVAL;
+			/*
+			 * The "(ulong *) third" is valid _only_ because of
+			 * the kernel segment thing.

ipc/syscall.c line 100

Quoted 10 lines
ipc/syscall.c new file +10 -0
+			 */
+			return do_shmat(first, (char __user *) ptr, second,
+					(unsigned long *)third);
+#endif
+#if defined(__arm__) || defined(__sparc__)
+		case 1:
+			/* Of course, we don't support iBCS2! */
+			return -EINVAL;
+#endif
+		}

This would not build on any of the architecture mentioned, because of incorrect placement of curly braces, but as Al mentioned it should just go away entirely.

arch/powerpc/include/asm/syscalls.h asmlinkage long sys_pipe2(int __user *fi · line 40

Quoted 13 lines

Index: linux-2.6/arch/powerpc/include/asm/syscalls.h
===================================================================

arch/powerpc/include/asm/syscalls.h +0 -2
@@ -35,8 +35,6 @@ asmlinkage long sys_pipe2(int __user *fi
 asmlinkage long sys_rt_sigaction(int sig,
 		const struct sigaction __user *act,
 		struct sigaction __user *oact, size_t sigsetsize);
-asmlinkage int sys_ipc(uint call, int first, unsigned long second,
-		long third, void __user *ptr, long fifth);
 asmlinkage long ppc64_personality(unsigned long personality);
 asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
 asmlinkage time_t sys64_time(time_t __user * tloc);

I did not see you add the prototype back into include/linux/syscalls.h, which is required for building some architectures, including ppc64 with SPU support.

Arnd

Acked-by Russell King
#4 lore raw
Quoted 1 line · Arnd Bergmann

Review

Quoted 1 line
(quoted diff) +1 -0
+		switch (version) {

Open of first

Quoted 1 line

ipc/syscall.c line 73

Quoted 1 line
ipc/syscall.c new file +1 -0
+		default: {

Open of second

Quoted 7 lines

ipc/syscall.c line 80

Quoted 7 lines
ipc/syscall.c new file +7 -0
+			ulong raddr;
+			ret = do_shmat(first, (char __user *)ptr,
+				       second, &raddr);
+			if (ret)
+				return ret;
+			return put_user(raddr, (ulong __user *) third);
+		}

close of second

Quoted 12 lines
Quoted 12 lines
ipc/syscall.c new file +12 -0
+
+#if defined(__i386__) || defined(__frv__) || defined(__mips__) ||\
+    defined(__mn10300__)
+		case 1:
+			/* iBCS2 emulator entry point */
+			if (!segment_eq(get_fs(), get_ds()))
+				return -EINVAL;
+			/*
+			 * The "(ulong *) third" is valid _only_ because of
+			 * the kernel segment thing.
+			 */
+			return do_shmat(first, (char __user *) ptr, second,
Quoted 8 lines

ipc/syscall.c line 100

Quoted 8 lines
ipc/syscall.c new file +8 -0
+					(unsigned long *)third);
+#endif
+#if defined(__arm__) || defined(__sparc__)
+		case 1:
+			/* Of course, we don't support iBCS2! */
+			return -EINVAL;
+#endif
+		}

close of first.

Quoted 3 lines

This would not build on any of the architecture mentioned, because of incorrect placement of curly braces, but as Al mentioned it should just go away entirely.

They look fine to me.

In any case, all three patches get my ack.

Thanks.

maintainer
#5 lore raw
Quoted 5 lines · On Wednesday 06 January 2010 20:59:05 Russell King - ARM Linux wrote:
Quoted 3 lines

This would not build on any of the architecture mentioned, because of incorrect placement of curly braces, but as Al mentioned it should just go away entirely.

They look fine to me.

Ah, right. I just got confused.

Arnd

#6 lore raw
In reply to Christoph Hellwig
Quoted 10 lines · Christoph Hellwig

Add a generic implementation of the ipc demultiplexer syscall. Except for s390 and sparc64 all implementations of the sys_ipc are nearly identical. [...]

Index: linux-2.6/arch/s390/include/asm/unistd.h
===================================================================

arch/s390/include/asm/unistd.h line 387

Quoted 7 lines
arch/s390/include/asm/unistd.h +1 -0
@@ -381,6 +381,7 @@
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SIGNAL
 #define __ARCH_WANT_SYS_UTIME

This should be dropped then, I would guess?

#7 lore raw

PATCH v2 3/3 generic sys_ipc wrapper

In reply to Christoph Hellwig

Always return -EINVAL for the iBCS2 special case in SHMAT, and add a prototype to linux/syscalls.h

---

From: Christoph Hellwig <[email protected]>
Subject: generic sys_ipc wrapper

Add a generic implementation of the ipc demultiplexer syscall. Except for s390 and sparc64 all implementations of the sys_ipc are nearly identical.

There are slight differences in the types of the parameters, where mips and powerpc as the only 64-bit architectures with sys_ipc use unsigned long for the "third" argument as it gets casted to a pointer later, while it traditionally is an "int" like most other paramters. frv goes even further and uses unsigned long for all parameters execept for "ptr" which is a pointer type everywhere. The change from int to unsigned long for "third" and back to "int" for the others on frv should be fine due to the in-register calling conventions for syscalls (we already had a similar issue with the generic sys_ptrace), but I'd prefer to have the arch maintainers looks over this in details.

Except for that h8300, m68k and m68knommu lack an impplementation of the semtimedop sub call which this patch adds, and various architectures have different strategies for the SHMAT version 1 case which apparently never gets used - at least on i386 it seems superflous as the compat code on x86-64 and ia64 doesn't even bother to implement it.

ipc/syscall.c new file +99 -0
Index: linux-2.6/ipc/syscall.c
===================================================================
@@ -0,0 +1,99 @@
+/*
+ * sys_ipc() is the old de-multiplexer for the SysV IPC calls.
+ *
+ * This is really horribly ugly, and new architectures should just wire up
+ * the individual syscalls instead.
+ */
+#include <linux/unistd.h>
+
+#ifdef __ARCH_WANT_SYS_IPC
+#include <linux/errno.h>
+#include <linux/ipc.h>
+#include <linux/shm.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+
+SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second,
+		unsigned long, third, void __user *, ptr, long, fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		return sys_semtimedop(first, (struct sembuf __user *)ptr,
+				      second, NULL);
+	case SEMTIMEDOP:
+		return sys_semtimedop(first, (struct sembuf __user *)ptr,
+				      second,
+				      (const struct timespec __user *)fifth);
+
+	case SEMGET:
+		return sys_semget(first, 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, second, third, fourth);
+	}
+
+	case MSGSND:
+		return sys_msgsnd(first, (struct msgbuf __user *) ptr,
+				  second, third);
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+			if (!ptr)
+				return -EINVAL;
+
+			if (copy_from_user(&tmp,
+					   (struct ipc_kludge __user *) ptr,
+					   sizeof(tmp)))
+				return -EFAULT;
+			return sys_msgrcv(first, tmp.msgp, second,
+					   tmp.msgtyp, third);
+		}
+		default:
+			return sys_msgrcv(first,
+					   (struct msgbuf __user *) ptr,
+					   second, fifth, third);
+		}
+	case MSGGET:
+		return sys_msgget((key_t) first, second);
+	case MSGCTL:
+		return sys_msgctl(first, second, (struct msqid_ds __user *)ptr);
+
+	case SHMAT:
+		switch (version) {
+		default: {
+			unsigned long raddr;
+			ret = do_shmat(first, (char __user *)ptr,
+				       second, &raddr);
+			if (ret)
+				return ret;
+			return put_user(raddr, (unsigned long __user *) third);
+		}
+		case 1:
+			/*
+			 * This was the entry point for kernel-originating calls
+			 * from iBCS2 in 2.2 days.
+			 */
+			return -EINVAL;
+		}
+	case SHMDT:
+		return sys_shmdt((char __user *)ptr);
+	case SHMGET:
+		return sys_shmget(first, second, third);
+	case SHMCTL:
+		return sys_shmctl(first, second,
+				   (struct shmid_ds __user *) ptr);
+	default:
+		return -ENOSYS;
+	}
+}
+#endif
arch/arm/kernel/sys_arm.c +0 -82

88 lines not on this page · raw message

arch/arm/kernel/sys_oabi-compat.c +0 -3
Index: linux-2.6/arch/arm/kernel/sys_oabi-compat.c
===================================================================
@@ -346,9 +346,6 @@ asmlinkage long sys_oabi_semop(int semid
 	return sys_oabi_semtimedop(semid, tsops, nsops, NULL);
 }
 
-extern asmlinkage int sys_ipc(uint call, int first, int second, int third,
-			      void __user *ptr, long fifth);
-
 asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
 			    void __user *ptr, long fifth)
 {
arch/cris/kernel/sys_cris.c +0 -78

81 lines not on this page · raw message

arch/frv/kernel/sys_frv.c +0 -89

92 lines not on this page · raw message

arch/m32r/kernel/sys_m32r.c +0 -81

87 lines not on this page · raw message

arch/m68k/kernel/sys_m68k.c +0 -81

87 lines not on this page · raw message

arch/mips/kernel/syscall.c +0 -88

94 lines not on this page · raw message

arch/mn10300/kernel/sys_mn10300.c +0 -88

91 lines not on this page · raw message

arch/powerpc/include/asm/syscalls.h +0 -2
Index: linux-2.6/arch/powerpc/include/asm/syscalls.h
===================================================================
@@ -35,8 +35,6 @@ asmlinkage long sys_pipe2(int __user *fi
 asmlinkage long sys_rt_sigaction(int sig,
 		const struct sigaction __user *act,
 		struct sigaction __user *oact, size_t sigsetsize);
-asmlinkage int sys_ipc(uint call, int first, unsigned long second,
-		long third, void __user *ptr, long fifth);
 asmlinkage long ppc64_personality(unsigned long personality);
 asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
 asmlinkage time_t sys64_time(time_t __user * tloc);
arch/powerpc/kernel/syscalls.c +0 -94

100 lines not on this page · raw message

arch/s390/kernel/entry.h +1 -1
Index: linux-2.6/arch/s390/kernel/entry.h
===================================================================
@@ -30,7 +30,7 @@ struct fadvise64_64_args;
 struct old_sigaction;
 
 long sys_mmap2(struct s390_mmap_arg_struct __user  *arg);
-long sys_ipc(uint call, int first, unsigned long second,
+long sys_s390_ipc(uint call, int first, unsigned long second,
 	     unsigned long third, void __user *ptr);
 long sys_s390_newuname(struct new_utsname __user *name);
 long sys_s390_personality(unsigned long personality);
arch/s390/kernel/sys_s390.c +1 -1
Index: linux-2.6/arch/s390/kernel/sys_s390.c
===================================================================
@@ -64,7 +64,7 @@ out:
  *
  * This is really horribly ugly.
  */
-SYSCALL_DEFINE5(ipc, uint, call, int, first, unsigned long, second,
+SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
 		unsigned long, third, void __user *, ptr)
 {
         struct ipc_kludge tmp;
arch/s390/kernel/syscalls.S +1 -1
Index: linux-2.6/arch/s390/kernel/syscalls.S
===================================================================
@@ -125,7 +125,7 @@ NI_SYSCALL							/* vm86old for i386 */
 SYSCALL(sys_wait4,sys_wait4,compat_sys_wait4_wrapper)
 SYSCALL(sys_swapoff,sys_swapoff,sys32_swapoff_wrapper)		/* 115 */
 SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper)
-SYSCALL(sys_ipc,sys_ipc,sys32_ipc_wrapper)
+SYSCALL(sys_s390_ipc,sys_s390_ipc,sys32_ipc_wrapper)
 SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper)
 SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn)
 SYSCALL(sys_clone,sys_clone,sys_clone_wrapper)			/* 120 */
arch/sh/include/asm/syscalls.h +0 -2
Index: linux-2.6/arch/sh/include/asm/syscalls.h
===================================================================
@@ -11,8 +11,6 @@ asmlinkage int old_mmap(unsigned long ad
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
 			  unsigned long prot, unsigned long flags,
 			  unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_ipc(uint call, int first, int second,
-		       int third, void __user *ptr, long fifth);
 asmlinkage int sys_uname(struct old_utsname __user *name);
 
 #ifdef CONFIG_SUPERH32
arch/sh/kernel/sys_sh.c +0 -104

110 lines not on this page · raw message

arch/sparc/kernel/sys_sparc_32.c +0 -113

119 lines not on this page · raw message

arch/um/sys-i386/syscalls.c +0 -86

92 lines not on this page · raw message

arch/x86/include/asm/syscalls.h +0 -1
Index: linux-2.6/arch/x86/include/asm/syscalls.h
===================================================================
@@ -54,7 +54,6 @@ unsigned long sys_sigreturn(struct pt_re
 struct oldold_utsname;
 struct old_utsname;
 
-asmlinkage int sys_ipc(uint, int, int, int, void __user *, long);
 asmlinkage int sys_uname(struct old_utsname __user *);
 asmlinkage int sys_olduname(struct oldold_utsname __user *);
 
ipc/Makefile +1 -1
Index: linux-2.6/ipc/Makefile
===================================================================
@@ -3,7 +3,7 @@
 #
 
 obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o
-obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o ipcns_notifier.o
+obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o ipcns_notifier.o syscall.o
 obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
 obj_mq-$(CONFIG_COMPAT) += compat_mq.o
 obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
arch/h8300/kernel/sys_h8300.c +0 -88

94 lines not on this page · raw message

arch/m68knommu/kernel/sys_m68k.c +0 -86

92 lines not on this page · raw message

arch/sparc/kernel/sys_sparc_64.c +1 -1
Index: linux-2.6/arch/sparc/kernel/sys_sparc_64.c
===================================================================
@@ -427,7 +427,7 @@ out:
  * This is really horribly ugly.
  */
 
-SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
+SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second,
 		unsigned long, third, void __user *, ptr, long, fifth)
 {
 	long err;
arch/sparc/kernel/systbls.h +1 -1
Index: linux-2.6/arch/sparc/kernel/systbls.h
===================================================================
@@ -10,7 +10,7 @@ struct new_utsname;
 
 extern asmlinkage unsigned long sys_getpagesize(void);
 extern asmlinkage long sparc_pipe(struct pt_regs *regs);
-extern asmlinkage long sys_ipc(unsigned int call, int first,
+extern asmlinkage long sys_sparc_ipc(unsigned int call, int first,
 			       unsigned long second,
 			       unsigned long third,
 			       void __user *ptr, long fifth);
arch/sparc/kernel/systbls_64.S +1 -1
Index: linux-2.6/arch/sparc/kernel/systbls_64.S
===================================================================
@@ -136,7 +136,7 @@ sys_call_table:
 /*200*/	.word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
 	.word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64
 /*210*/	.word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo
-	.word sys_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex
+	.word sys_sparc_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex
 /*220*/	.word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid
 	.word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid
 /*230*/	.word sys_select, sys_nis_syscall, sys_splice, sys_stime, sys_statfs64
arch/x86/kernel/sys_i386_32.c +0 -85

91 lines not on this page · raw message

arch/arm/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/arm/include/asm/unistd.h
===================================================================
@@ -447,6 +447,7 @@
 
 #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
 #define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_UTIME
arch/cris/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/cris/include/asm/unistd.h
===================================================================
@@ -352,6 +352,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/frv/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/frv/include/asm/unistd.h
===================================================================
@@ -354,6 +354,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 /* #define __ARCH_WANT_SYS_GETHOSTNAME */
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 /* #define __ARCH_WANT_SYS_SGETMASK */
 /* #define __ARCH_WANT_SYS_SIGNAL */
arch/h8300/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/h8300/include/asm/unistd.h
===================================================================
@@ -336,6 +336,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/m32r/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/m32r/include/asm/unistd.h
===================================================================
@@ -339,6 +339,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
arch/m68k/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/m68k/include/asm/unistd.h
===================================================================
@@ -347,6 +347,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/mips/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/mips/include/asm/unistd.h
===================================================================
@@ -1004,6 +1004,7 @@
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_UTIME
arch/mn10300/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/mn10300/include/asm/unistd.h
===================================================================
@@ -362,6 +362,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/powerpc/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/powerpc/include/asm/unistd.h
===================================================================
@@ -364,6 +364,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/s390/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/s390/include/asm/unistd.h
===================================================================
@@ -381,6 +381,7 @@
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SIGNAL
 #define __ARCH_WANT_SYS_UTIME
arch/sh/include/asm/unistd_32.h +1 -0
Index: linux-2.6/arch/sh/include/asm/unistd_32.h
===================================================================
@@ -357,6 +357,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/sh/include/asm/unistd_64.h +1 -0
Index: linux-2.6/arch/sh/include/asm/unistd_64.h
===================================================================
@@ -397,6 +397,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/sparc/include/asm/unistd.h +3 -1
Index: linux-2.6/arch/sparc/include/asm/unistd.h
===================================================================
@@ -432,7 +432,9 @@
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#ifndef __32bit_syscall_numbers__
+#ifdef __32bit_syscall_numbers__
+#define __ARCH_WANT_SYS_IPC
+#else
 #define __ARCH_WANT_COMPAT_SYS_TIME
 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 #endif
arch/x86/include/asm/unistd_32.h +1 -0
Index: linux-2.6/arch/x86/include/asm/unistd_32.h
===================================================================
@@ -354,6 +354,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
include/linux/syscalls.h +2 -0
Index: linux-2.6/include/linux/syscalls.h
===================================================================
@@ -684,6 +684,8 @@ asmlinkage long sys_shmat(int shmid, cha
 asmlinkage long sys_shmget(key_t key, size_t size, int flag);
 asmlinkage long sys_shmdt(char __user *shmaddr);
 asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
+asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second,
+		long third, void __user *ptr, long fifth);
 
 asmlinkage long sys_mq_open(const char __user *name, int oflag, mode_t mode, struct mq_attr __user *attr);
 asmlinkage long sys_mq_unlink(const char __user *name);
#8 lore raw
Quoted 2 lines · Christoph Hellwig

Always return -EINVAL for the iBCS2 special case in SHMAT, and add a prototype to linux/syscalls.h

and stop compiling the generic sys_ipc on s390:

---
From: Christoph Hellwig <[email protected]>
Subject: generic sys_ipc wrapper

Add a generic implementation of the ipc demultiplexer syscall. Except for s390 and sparc64 all implementations of the sys_ipc are nearly identical.

There are slight differences in the types of the parameters, where mips and powerpc as the only 64-bit architectures with sys_ipc use unsigned long for the "third" argument as it gets casted to a pointer later, while it traditionally is an "int" like most other paramters. frv goes even further and uses unsigned long for all parameters execept for "ptr" which is a pointer type everywhere. The change from int to unsigned long for "third" and back to "int" for the others on frv should be fine due to the in-register calling conventions for syscalls (we already had a similar issue with the generic sys_ptrace), but I'd prefer to have the arch maintainers looks over this in details.

Except for that h8300, m68k and m68knommu lack an impplementation of the semtimedop sub call which this patch adds, and various architectures have different strategies for the SHMAT version 1 case which apparently never gets used - at least on i386 it seems superflous as the compat code on x86-64 and ia64 doesn't even bother to implement it.

ipc/syscall.c new file +99 -0
Index: linux-2.6/ipc/syscall.c
===================================================================
@@ -0,0 +1,99 @@
+/*
+ * sys_ipc() is the old de-multiplexer for the SysV IPC calls.
+ *
+ * This is really horribly ugly, and new architectures should just wire up
+ * the individual syscalls instead.
+ */
+#include <linux/unistd.h>
+
+#ifdef __ARCH_WANT_SYS_IPC
+#include <linux/errno.h>
+#include <linux/ipc.h>
+#include <linux/shm.h>
+#include <linux/syscalls.h>
+#include <linux/uaccess.h>
+
+SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second,
+		unsigned long, third, void __user *, ptr, long, fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		return sys_semtimedop(first, (struct sembuf __user *)ptr,
+				      second, NULL);
+	case SEMTIMEDOP:
+		return sys_semtimedop(first, (struct sembuf __user *)ptr,
+				      second,
+				      (const struct timespec __user *)fifth);
+
+	case SEMGET:
+		return sys_semget(first, 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, second, third, fourth);
+	}
+
+	case MSGSND:
+		return sys_msgsnd(first, (struct msgbuf __user *) ptr,
+				  second, third);
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+			if (!ptr)
+				return -EINVAL;
+
+			if (copy_from_user(&tmp,
+					   (struct ipc_kludge __user *) ptr,
+					   sizeof(tmp)))
+				return -EFAULT;
+			return sys_msgrcv(first, tmp.msgp, second,
+					   tmp.msgtyp, third);
+		}
+		default:
+			return sys_msgrcv(first,
+					   (struct msgbuf __user *) ptr,
+					   second, fifth, third);
+		}
+	case MSGGET:
+		return sys_msgget((key_t) first, second);
+	case MSGCTL:
+		return sys_msgctl(first, second, (struct msqid_ds __user *)ptr);
+
+	case SHMAT:
+		switch (version) {
+		default: {
+			unsigned long raddr;
+			ret = do_shmat(first, (char __user *)ptr,
+				       second, &raddr);
+			if (ret)
+				return ret;
+			return put_user(raddr, (unsigned long __user *) third);
+		}
+		case 1:
+			/*
+			 * This was the entry point for kernel-originating calls
+			 * from iBCS2 in 2.2 days.
+			 */
+			return -EINVAL;
+		}
+	case SHMDT:
+		return sys_shmdt((char __user *)ptr);
+	case SHMGET:
+		return sys_shmget(first, second, third);
+	case SHMCTL:
+		return sys_shmctl(first, second,
+				   (struct shmid_ds __user *) ptr);
+	default:
+		return -ENOSYS;
+	}
+}
+#endif
arch/arm/kernel/sys_arm.c +0 -82

88 lines not on this page · raw message

arch/arm/kernel/sys_oabi-compat.c +0 -3
Index: linux-2.6/arch/arm/kernel/sys_oabi-compat.c
===================================================================
@@ -346,9 +346,6 @@ asmlinkage long sys_oabi_semop(int semid
 	return sys_oabi_semtimedop(semid, tsops, nsops, NULL);
 }
 
-extern asmlinkage int sys_ipc(uint call, int first, int second, int third,
-			      void __user *ptr, long fifth);
-
 asmlinkage int sys_oabi_ipc(uint call, int first, int second, int third,
 			    void __user *ptr, long fifth)
 {
arch/cris/kernel/sys_cris.c +0 -78

81 lines not on this page · raw message

arch/frv/kernel/sys_frv.c +0 -89

92 lines not on this page · raw message

arch/m32r/kernel/sys_m32r.c +0 -81

87 lines not on this page · raw message

arch/m68k/kernel/sys_m68k.c +0 -81

87 lines not on this page · raw message

arch/mips/kernel/syscall.c +0 -88

94 lines not on this page · raw message

arch/mn10300/kernel/sys_mn10300.c +0 -88

91 lines not on this page · raw message

arch/powerpc/include/asm/syscalls.h +0 -2
Index: linux-2.6/arch/powerpc/include/asm/syscalls.h
===================================================================
@@ -35,8 +35,6 @@ asmlinkage long sys_pipe2(int __user *fi
 asmlinkage long sys_rt_sigaction(int sig,
 		const struct sigaction __user *act,
 		struct sigaction __user *oact, size_t sigsetsize);
-asmlinkage int sys_ipc(uint call, int first, unsigned long second,
-		long third, void __user *ptr, long fifth);
 asmlinkage long ppc64_personality(unsigned long personality);
 asmlinkage int ppc_rtas(struct rtas_args __user *uargs);
 asmlinkage time_t sys64_time(time_t __user * tloc);
arch/powerpc/kernel/syscalls.c +0 -94

100 lines not on this page · raw message

arch/s390/kernel/entry.h +1 -1
Index: linux-2.6/arch/s390/kernel/entry.h
===================================================================
@@ -30,7 +30,7 @@ struct fadvise64_64_args;
 struct old_sigaction;
 
 long sys_mmap2(struct s390_mmap_arg_struct __user  *arg);
-long sys_ipc(uint call, int first, unsigned long second,
+long sys_s390_ipc(uint call, int first, unsigned long second,
 	     unsigned long third, void __user *ptr);
 long sys_s390_newuname(struct new_utsname __user *name);
 long sys_s390_personality(unsigned long personality);
arch/s390/kernel/sys_s390.c +1 -1
Index: linux-2.6/arch/s390/kernel/sys_s390.c
===================================================================
@@ -64,7 +64,7 @@ out:
  *
  * This is really horribly ugly.
  */
-SYSCALL_DEFINE5(ipc, uint, call, int, first, unsigned long, second,
+SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
 		unsigned long, third, void __user *, ptr)
 {
         struct ipc_kludge tmp;
arch/s390/kernel/syscalls.S +1 -1
Index: linux-2.6/arch/s390/kernel/syscalls.S
===================================================================
@@ -125,7 +125,7 @@ NI_SYSCALL							/* vm86old for i386 */
 SYSCALL(sys_wait4,sys_wait4,compat_sys_wait4_wrapper)
 SYSCALL(sys_swapoff,sys_swapoff,sys32_swapoff_wrapper)		/* 115 */
 SYSCALL(sys_sysinfo,sys_sysinfo,compat_sys_sysinfo_wrapper)
-SYSCALL(sys_ipc,sys_ipc,sys32_ipc_wrapper)
+SYSCALL(sys_s390_ipc,sys_s390_ipc,sys32_ipc_wrapper)
 SYSCALL(sys_fsync,sys_fsync,sys32_fsync_wrapper)
 SYSCALL(sys_sigreturn,sys_sigreturn,sys32_sigreturn)
 SYSCALL(sys_clone,sys_clone,sys_clone_wrapper)			/* 120 */
arch/sh/include/asm/syscalls.h +0 -2
Index: linux-2.6/arch/sh/include/asm/syscalls.h
===================================================================
@@ -11,8 +11,6 @@ asmlinkage int old_mmap(unsigned long ad
 asmlinkage long sys_mmap2(unsigned long addr, unsigned long len,
 			  unsigned long prot, unsigned long flags,
 			  unsigned long fd, unsigned long pgoff);
-asmlinkage int sys_ipc(uint call, int first, int second,
-		       int third, void __user *ptr, long fifth);
 asmlinkage int sys_uname(struct old_utsname __user *name);
 
 #ifdef CONFIG_SUPERH32
arch/sh/kernel/sys_sh.c +0 -104

110 lines not on this page · raw message

arch/sparc/kernel/sys_sparc_32.c +0 -113

119 lines not on this page · raw message

arch/um/sys-i386/syscalls.c +0 -86

92 lines not on this page · raw message

arch/x86/include/asm/syscalls.h +0 -1
Index: linux-2.6/arch/x86/include/asm/syscalls.h
===================================================================
@@ -54,7 +54,6 @@ unsigned long sys_sigreturn(struct pt_re
 struct oldold_utsname;
 struct old_utsname;
 
-asmlinkage int sys_ipc(uint, int, int, int, void __user *, long);
 asmlinkage int sys_uname(struct old_utsname __user *);
 asmlinkage int sys_olduname(struct oldold_utsname __user *);
 
ipc/Makefile +1 -1
Index: linux-2.6/ipc/Makefile
===================================================================
@@ -3,7 +3,7 @@
 #
 
 obj-$(CONFIG_SYSVIPC_COMPAT) += compat.o
-obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o ipcns_notifier.o
+obj-$(CONFIG_SYSVIPC) += util.o msgutil.o msg.o sem.o shm.o ipcns_notifier.o syscall.o
 obj-$(CONFIG_SYSVIPC_SYSCTL) += ipc_sysctl.o
 obj_mq-$(CONFIG_COMPAT) += compat_mq.o
 obj-$(CONFIG_POSIX_MQUEUE) += mqueue.o msgutil.o $(obj_mq-y)
arch/h8300/kernel/sys_h8300.c +0 -88

94 lines not on this page · raw message

arch/m68knommu/kernel/sys_m68k.c +0 -86

92 lines not on this page · raw message

arch/sparc/kernel/sys_sparc_64.c +1 -1
Index: linux-2.6/arch/sparc/kernel/sys_sparc_64.c
===================================================================
@@ -427,7 +427,7 @@ out:
  * This is really horribly ugly.
  */
 
-SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
+SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second,
 		unsigned long, third, void __user *, ptr, long, fifth)
 {
 	long err;
arch/sparc/kernel/systbls.h +1 -1
Index: linux-2.6/arch/sparc/kernel/systbls.h
===================================================================
@@ -10,7 +10,7 @@ struct new_utsname;
 
 extern asmlinkage unsigned long sys_getpagesize(void);
 extern asmlinkage long sparc_pipe(struct pt_regs *regs);
-extern asmlinkage long sys_ipc(unsigned int call, int first,
+extern asmlinkage long sys_sparc_ipc(unsigned int call, int first,
 			       unsigned long second,
 			       unsigned long third,
 			       void __user *ptr, long fifth);
arch/sparc/kernel/systbls_64.S +1 -1
Index: linux-2.6/arch/sparc/kernel/systbls_64.S
===================================================================
@@ -136,7 +136,7 @@ sys_call_table:
 /*200*/	.word sys_ssetmask, sys_nis_syscall, sys_newlstat, sys_uselib, sys_nis_syscall
 	.word sys_readahead, sys_socketcall, sys_syslog, sys_lookup_dcookie, sys_fadvise64
 /*210*/	.word sys_fadvise64_64, sys_tgkill, sys_waitpid, sys_swapoff, sys_sysinfo
-	.word sys_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex
+	.word sys_sparc_ipc, sys_nis_syscall, sys_clone, sys_ioprio_get, sys_adjtimex
 /*220*/	.word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid
 	.word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid
 /*230*/	.word sys_select, sys_nis_syscall, sys_splice, sys_stime, sys_statfs64
arch/x86/kernel/sys_i386_32.c +0 -85

91 lines not on this page · raw message

arch/arm/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/arm/include/asm/unistd.h
===================================================================
@@ -447,6 +447,7 @@
 
 #if !defined(CONFIG_AEABI) || defined(CONFIG_OABI_COMPAT)
 #define __ARCH_WANT_SYS_TIME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_OLDUMOUNT
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_UTIME
arch/cris/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/cris/include/asm/unistd.h
===================================================================
@@ -352,6 +352,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/frv/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/frv/include/asm/unistd.h
===================================================================
@@ -354,6 +354,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 /* #define __ARCH_WANT_SYS_GETHOSTNAME */
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 /* #define __ARCH_WANT_SYS_SGETMASK */
 /* #define __ARCH_WANT_SYS_SIGNAL */
arch/h8300/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/h8300/include/asm/unistd.h
===================================================================
@@ -336,6 +336,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/m32r/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/m32r/include/asm/unistd.h
===================================================================
@@ -339,6 +339,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_TIME
 #define __ARCH_WANT_SYS_UTIME
arch/m68k/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/m68k/include/asm/unistd.h
===================================================================
@@ -347,6 +347,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/mips/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/mips/include/asm/unistd.h
===================================================================
@@ -1004,6 +1004,7 @@
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_UTIME
arch/mn10300/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/mn10300/include/asm/unistd.h
===================================================================
@@ -362,6 +362,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/powerpc/include/asm/unistd.h +1 -0
Index: linux-2.6/arch/powerpc/include/asm/unistd.h
===================================================================
@@ -364,6 +364,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/sh/include/asm/unistd_32.h +1 -0
Index: linux-2.6/arch/sh/include/asm/unistd_32.h
===================================================================
@@ -357,6 +357,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/sh/include/asm/unistd_64.h +1 -0
Index: linux-2.6/arch/sh/include/asm/unistd_64.h
===================================================================
@@ -397,6 +397,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
arch/sparc/include/asm/unistd.h +3 -1
Index: linux-2.6/arch/sparc/include/asm/unistd.h
===================================================================
@@ -432,7 +432,9 @@
 #define __ARCH_WANT_SYS_SIGPENDING
 #define __ARCH_WANT_SYS_SIGPROCMASK
 #define __ARCH_WANT_SYS_RT_SIGSUSPEND
-#ifndef __32bit_syscall_numbers__
+#ifdef __32bit_syscall_numbers__
+#define __ARCH_WANT_SYS_IPC
+#else
 #define __ARCH_WANT_COMPAT_SYS_TIME
 #define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND
 #endif
arch/x86/include/asm/unistd_32.h +1 -0
Index: linux-2.6/arch/x86/include/asm/unistd_32.h
===================================================================
@@ -354,6 +354,7 @@
 #define __ARCH_WANT_STAT64
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
+#define __ARCH_WANT_SYS_IPC
 #define __ARCH_WANT_SYS_PAUSE
 #define __ARCH_WANT_SYS_SGETMASK
 #define __ARCH_WANT_SYS_SIGNAL
include/linux/syscalls.h +2 -0
Index: linux-2.6/include/linux/syscalls.h
===================================================================
@@ -684,6 +684,8 @@ asmlinkage long sys_shmat(int shmid, cha
 asmlinkage long sys_shmget(key_t key, size_t size, int flag);
 asmlinkage long sys_shmdt(char __user *shmaddr);
 asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf);
+asmlinkage long sys_ipc(unsigned int call, int first, int second,
+		unsigned long third, void __user *ptr, long fifth);
 
 asmlinkage long sys_mq_open(const char __user *name, int oflag, mode_t mode, struct mq_attr __user *attr);
 asmlinkage long sys_mq_unlink(const char __user *name);
maintainer
#9 lore raw
Quoted 3 lines · On Friday 08 January 2010 11:03:47 Christoph Hellwig wrote:
Quoted 2 lines · Christoph Hellwig

Always return -EINVAL for the iBCS2 special case in SHMAT, and add a prototype to linux/syscalls.h

ok, the changes look good.

Quoted 2 lines

Add a generic implementation of the ipc demultiplexer syscall. Except for s390 and sparc64 all implementations of the sys_ipc are nearly identical.

I think the s390 version is trivial to add as well, like

SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
unsigned long, third, void __user *, ptr)

{
	if (call == SEMTIMEDOP)
		return sys_semtimedop(first, (struct sembuf __user *)ptr,
				      (unsigned) second,
				      (const struct timespec __user *)third);

	return sys_ipc(call & 0xffff, first, second, third, ptr, 0);
}

But while going over the code again, I noticed that you broke sign extension at least on powerpc and s390, possibly on all 64 bit machines:

ipc/syscall.c line 27

Quoted 12 lines
ipc/syscall.c new file +12 -0
+SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, int, second,
+		unsigned long, third, void __user *, ptr, long, fifth)
+{
+	int version, ret;
+
+	version = call >> 16; /* hack for backward compatibility */
+	call &= 0xffff;
+
+	switch (call) {
+	case SEMOP:
+		return sys_semtimedop(first, (struct sembuf __user *)ptr,
+				      second, NULL);

(unsigned)second, NULL

ipc/syscall.c line 30

Quoted 3 lines
ipc/syscall.c new file +3 -0
+	case SEMTIMEDOP:
+		return sys_semtimedop(first, (struct sembuf __user *)ptr,
+				      second,

(unsigned)second,

ipc/syscall.c line 34

Quoted 4 lines
ipc/syscall.c new file +4 -0
+				      (const struct timespec __user *)fifth);
+
+	case SEMGET:
+		return sys_semget(first, second, third);

(int)second,

ipc/syscall.c line 41

Quoted 7 lines
ipc/syscall.c new file +7 -0
+	case SEMCTL: {
+		union semun fourth;
+		if (!ptr)
+			return -EINVAL;
+		if (get_user(fourth.__pad, (void __user * __user *) ptr))
+			return -EFAULT;
+		return sys_semctl(first, second, third, fourth);
		return sys_semctl(first, (int)second, third, fourth);

ipc/syscall.c line 46

Quoted 3 lines
ipc/syscall.c new file +3 -0
+	case MSGSND:
+		return sys_msgsnd(first, (struct msgbuf __user *) ptr,
+				  second, third);
				  (size_t)second, third);

ipc/syscall.c line 58

Quoted 12 lines
ipc/syscall.c new file +12 -0
+	case MSGRCV:
+		switch (version) {
+		case 0: {
+			struct ipc_kludge tmp;
+			if (!ptr)
+				return -EINVAL;
+
+			if (copy_from_user(&tmp,
+					   (struct ipc_kludge __user *) ptr,
+					   sizeof(tmp)))
+				return -EFAULT;
+			return sys_msgrcv(first, tmp.msgp, second,

return sys_msgrcv(first, tmp.msgp, (size_t)second,

ipc/syscall.c line 64

Quoted 6 lines
ipc/syscall.c new file +6 -0
+					   tmp.msgtyp, third);
+		}
+		default:
+			return sys_msgrcv(first,
+					   (struct msgbuf __user *) ptr,
+					   second, fifth, third);
					   (size_t)second, fifth, third);

ipc/syscall.c line 67

Quoted 3 lines
ipc/syscall.c new file +3 -0
+		}
+	case MSGGET:
+		return sys_msgget((key_t) first, second);
		return sys_msgget((key_t) first, (int)second);

ipc/syscall.c line 69

Quoted 2 lines
ipc/syscall.c new file +2 -0
+	case MSGCTL:
+		return sys_msgctl(first, second, (struct msqid_ds __user *)ptr);
		return sys_msgctl(first, (int)second, (struct msqid_ds __user *)ptr);

ipc/syscall.c line 76

Quoted 6 lines
ipc/syscall.c new file +6 -0
+	case SHMAT:
+		switch (version) {
+		default: {
+			unsigned long raddr;
+			ret = do_shmat(first, (char __user *)ptr,
+				       second, &raddr);
				       (int)second, &raddr);
Quoted 5 lines
ipc/syscall.c new file +5 -0
+			if (ret)
+				return ret;
+			return put_user(raddr, (unsigned long __user *) third);
+		}
+		case 1:

ipc/syscall.c line 91

Quoted 10 lines
ipc/syscall.c new file +10 -0
+			/*
+			 * This was the entry point for kernel-originating calls
+			 * from iBCS2 in 2.2 days.
+			 */
+			return -EINVAL;
+		}
+	case SHMDT:
+		return sys_shmdt((char __user *)ptr);
+	case SHMGET:
+		return sys_shmget(first, second, third);
				       (size_t)second, &raddr);

ipc/syscall.c line 93

Quoted 2 lines
ipc/syscall.c new file +2 -0
+	case SHMCTL:
+		return sys_shmctl(first, second,

return sys_shmctl(first, (int)second,

ipc/syscall.c line 98

Quoted 5 lines
ipc/syscall.c new file +5 -0
+				   (struct shmid_ds __user *) ptr);
+	default:
+		return -ENOSYS;
+	}
+}

This is needed to make sure the upper half of the register is filled with zero-extended or sign-extended correctly and does not contain random garbage in the native 64 bit case. IIRC, x86_64 does not have this problem and mips64 may have the wrong code already. Alpha, parisc and ia64 don't have a native sys_ipc and the rest are 32 bit, so they don't care.

Arnd

#10 lore raw
Quoted 7 lines · Arnd Bergmann
Quoted 2 lines

Add a generic implementation of the ipc demultiplexer syscall. Except for s390 and sparc64 all implementations of the sys_ipc are nearly identical.

I think the s390 version is trivial to add as well, like

SYSCALL_DEFINE5(s390_ipc, uint, call, int, first, unsigned long, second,
unsigned long, third, void __user *, ptr)

Quoted 8 lines
{
	if (call == SEMTIMEDOP)
		return sys_semtimedop(first, (struct sembuf __user *)ptr,
				      (unsigned) second,
				      (const struct timespec __user *)third);

	return sys_ipc(call & 0xffff, first, second, third, ptr, 0);
}

Possiblly. Not sure if it's worth it, though. If the s390 maintainers want it I'd say do it as a separate patch.

Quoted 9 lines

But while going over the code again, I noticed that you broke sign extension at least on powerpc and s390, possibly on all 64 bit machines:

ipc/syscall.c line 41

Quoted 4 lines
ipc/syscall.c new file +4 -0
+			return -EINVAL;
+		if (get_user(fourth.__pad, (void __user * __user *) ptr))
+			return -EFAULT;
+		return sys_semctl(first, second, third, fourth);
		return sys_semctl(first, (int)second, third, fourth);

What does the explicit case buy us in terms of sign-extension over the implicit one given that the second argument to sys_semctl already is types as int?

Quoted 5 lines

This is needed to make sure the upper half of the register is filled with zero-extended or sign-extended correctly and does not contain random garbage in the native 64 bit case. IIRC, x86_64 does not have this problem and mips64 may have the wrong code already. Alpha, parisc and ia64 don't have a native sys_ipc and the rest are 32 bit, so they don't care.

I can fix it up, but I don't quite understand the need.

maintainer Acked-by
#11 lore raw
Quoted 2 lines · Christoph Hellwig

Possiblly. Not sure if it's worth it, though. If the s390 maintainers want it I'd say do it as a separate patch.

Sounds fair.

Quoted 7 lines

at least on powerpc and s390, possibly on all 64 bit machines:

Quoted 5 lines
Quoted 4 lines
ipc/syscall.c new file +4 -0
+                   return -EINVAL;
+           if (get_user(fourth.__pad, (void __user * __user *) ptr))
+                   return -EFAULT;
+           return sys_semctl(first, second, third, fourth);
Quoted 5 lines
Quoted 1 line
              return sys_semctl(first, (int)second, third, fourth);

What does the explicit case buy us in terms of sign-extension over the implicit one given that the second argument to sys_semctl already is types as int?

You're right, it's not needed any more, in particular since Heiko added the wrappers around each syscall to do yet another sign extension, but this one was probably right in your version already.

You convinced me that the patch is good in its current shape.

Arnd

#12 lore raw
In reply to Christoph Hellwig
Quoted 5 lines · Christoph Hellwig
Quoted 2 lines · Christoph Hellwig

Always return -EINVAL for the iBCS2 special case in SHMAT, and add a prototype to linux/syscalls.h

and stop compiling the generic sys_ipc on s390:

... and maybe update the commit message? Other than that, ACK.

Acked-by
#13 lore raw
In reply to Christoph Hellwig
Quoted 17 lines · Christoph Hellwig

From: Christoph Hellwig <[email protected]>
Subject: generic sys_ipc wrapper

Add a generic implementation of the ipc demultiplexer syscall. Except for s390 and sparc64 all implementations of the sys_ipc are nearly identical.

There are slight differences in the types of the parameters, where mips and powerpc as the only 64-bit architectures with sys_ipc use unsigned long for the "third" argument as it gets casted to a pointer later, while it traditionally is an "int" like most other paramters. frv goes even further and uses unsigned long for all parameters execept for "ptr" which is a pointer type everywhere. The change from int to unsigned long for "third" and back to "int" for the others on frv should be fine due to the in-register calling conventions for syscalls (we already had a similar issue with the generic sys_ptrace), but I'd prefer to have the arch maintainers looks over this in details.

Quoted 8 lines

Except for that h8300, m68k and m68knommu lack an impplementation of the semtimedop sub call which this patch adds, and various architectures have different strategies for the SHMAT version 1 case which apparently never gets used - at least on i386 it seems superflous as the compat code on x86-64 and ia64 doesn't even bother to implement it.