The attached patch adds the missing compat syscalls to the ia32 syscall table
on ia64.  We copied a few AIO related syscalls into fs/compat.c.  Other
compat archs may want to use them and get rid of private implementations.



 arch/s390/kernel/compat_wrapper.S |   35 ++++++++++++++
 arch/s390/kernel/syscalls.S       |   10 ++--
 arch/sparc64/kernel/systbls.S     |    4 -
 fs/compat.c                       |   93 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 135 insertions(+), 7 deletions(-)

diff -puN arch/s390/kernel/compat_wrapper.S~ia64-ia32-missing-compat-syscalls arch/s390/kernel/compat_wrapper.S
--- 25/arch/s390/kernel/compat_wrapper.S~ia64-ia32-missing-compat-syscalls	2003-11-19 01:28:45.000000000 -0800
+++ 25-akpm/arch/s390/kernel/compat_wrapper.S	2003-11-19 01:28:45.000000000 -0800
@@ -5,6 +5,7 @@
 *  S390 version
 *    Copyright (C) 2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *    Author(s): Gerhard Tonn (ton@de.ibm.com),
+*               Thomas Spatzier (tspat@de.ibm.com)
 */ 
 
 	.globl  sys32_exit_wrapper 
@@ -1230,3 +1231,37 @@ sys_epoll_wait_wrapper:
 	lgfr	%r4,%r4			# int
 	lgfr	%r5,%r5			# int
 	jg	sys_epoll_wait		# branch to system call
+
+	.globl	sys32_io_setup_wrapper
+sys32_io_setup_wrapper:
+	llgfr	%r2,%r2			# unsigned int
+	llgtr	%r3,%r3			# u32 *
+	jg	compat_sys_io_setup
+
+	.globl	sys32_io_destroy_wrapper
+sys32_io_destroy_wrapper:
+	llgfr	%r2,%r2			# (aio_context_t) u32
+	jg	sys_io_destroy
+
+	.globl	sys32_io_getevents_wrapper
+sys32_io_getevents_wrapper:
+	llgfr	%r2,%r2			# (aio_context_t) u32
+	lgfr	%r3,%r3			# long
+	lgfr	%r4,%r4			# long
+	llgtr	%r5,%r5			# struct io_event *
+	llgtr	%r6,%r6			# struct compat_timespec *
+	jg	compat_sys_io_getevents
+
+	.globl	sys32_io_submit_wrapper
+sys32_io_submit_wrapper:
+	llgfr	%r2,%r2			# (aio_context_t) u32
+	lgfr	%r3,%r3			# long
+	llgtr	%r4,%r4			# struct iocb **
+	jg	compat_sys_io_submit
+
+	.globl	sys32_io_cancel_wrapper
+sys32_io_cancel_wrapper:
+	llgfr	%r2,%r2			# (aio_context_t) u32
+	llgtr	%r3,%r3			# struct iocb *
+	llgtr	%r4,%r4			# struct io_event *
+	jg	sys_io_cancel
diff -puN arch/s390/kernel/syscalls.S~ia64-ia32-missing-compat-syscalls arch/s390/kernel/syscalls.S
--- 25/arch/s390/kernel/syscalls.S~ia64-ia32-missing-compat-syscalls	2003-11-19 01:28:45.000000000 -0800
+++ 25-akpm/arch/s390/kernel/syscalls.S	2003-11-19 01:28:45.000000000 -0800
@@ -251,11 +251,11 @@ SYSCALL(sys_sched_setaffinity,sys_sched_
 SYSCALL(sys_sched_getaffinity,sys_sched_getaffinity,sys32_sched_getaffinity_wrapper)	/* 240 */
 SYSCALL(sys_tgkill,sys_tgkill,sys_tgkill)
 NI_SYSCALL							/* reserved for TUX */
-SYSCALL(sys_io_setup,sys_io_setup,sys_ni_syscall)
-SYSCALL(sys_io_destroy,sys_io_destroy,sys_ni_syscall)
-SYSCALL(sys_io_getevents,sys_io_getevents,sys_ni_syscall)	/* 245 */
-SYSCALL(sys_io_submit,sys_io_submit,sys_ni_syscall)
-SYSCALL(sys_io_cancel,sys_io_cancel,sys_ni_syscall)
+SYSCALL(sys_io_setup,sys_io_setup,sys32_io_setup_wrapper)
+SYSCALL(sys_io_destroy,sys_io_destroy,sys32_io_destroy_wrapper)
+SYSCALL(sys_io_getevents,sys_io_getevents,sys32_io_getevents_wrapper)	/* 245 */
+SYSCALL(sys_io_submit,sys_io_submit,sys32_io_submit_wrapper)
+SYSCALL(sys_io_cancel,sys_io_cancel,sys32_io_cancel_wrapper)
 SYSCALL(sys_exit_group,sys_exit_group,sys32_exit_group_wrapper)
 SYSCALL(sys_epoll_create,sys_epoll_create,sys_epoll_create_wrapper)
 SYSCALL(sys_epoll_ctl,sys_epoll_ctl,sys_epoll_ctl_wrapper)	/* 250 */
diff -puN arch/sparc64/kernel/systbls.S~ia64-ia32-missing-compat-syscalls arch/sparc64/kernel/systbls.S
--- 25/arch/sparc64/kernel/systbls.S~ia64-ia32-missing-compat-syscalls	2003-11-19 01:28:45.000000000 -0800
+++ 25-akpm/arch/sparc64/kernel/systbls.S	2003-11-19 01:28:45.000000000 -0800
@@ -72,8 +72,8 @@ sys_call_table32:
 /*250*/	.word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
 	.word sys_ni_syscall, compat_clock_settime, compat_clock_gettime, compat_clock_getres, compat_clock_nanosleep
 /*260*/	.word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, compat_timer_settime, compat_timer_gettime, sys_timer_getoverrun
-	.word sys_timer_delete, sys32_timer_create, sys_ni_syscall, sys_ni_syscall, sys_ni_syscall
-/*270*/	.word sys_ni_syscall, sys_ni_syscall, sys_ni_syscall, sys_ni_syscall
+	.word sys_timer_delete, sys32_timer_create, sys_ni_syscall, compat_sys_io_setup, sys_io_destroy
+/*270*/	.word compat_sys_io_submit, sys_io_cancel, compat_sys_io_getevents, sys_ni_syscall
 
 	/* Now the 64-bit native Linux syscall table. */
 
diff -puN fs/compat.c~ia64-ia32-missing-compat-syscalls fs/compat.c
--- 25/fs/compat.c~ia64-ia32-missing-compat-syscalls	2003-11-19 01:28:45.000000000 -0800
+++ 25-akpm/fs/compat.c	2003-11-19 01:28:45.000000000 -0800
@@ -559,3 +559,96 @@ asmlinkage long compat_sys_fcntl(unsigne
 	return compat_sys_fcntl64(fd, cmd, arg);
 }
 
+extern asmlinkage long sys_io_setup(unsigned nr_reqs, aio_context_t *ctx);
+
+asmlinkage long
+compat_sys_io_setup(unsigned nr_reqs, u32 *ctx32p)
+{
+	long ret;
+	aio_context_t ctx64;
+
+	mm_segment_t oldfs = get_fs();
+	if (unlikely(get_user(ctx64, ctx32p)))
+		return -EFAULT;
+
+	set_fs(KERNEL_DS);
+	ret = sys_io_setup(nr_reqs, &ctx64);
+	set_fs(oldfs);
+	/* truncating is ok because it's a user address */
+	if (!ret)
+		ret = put_user((u32) ctx64, ctx32p);
+	return ret;
+}
+
+extern asmlinkage long sys_io_getevents(aio_context_t ctx_id,
+					  long min_nr,
+					  long nr,
+					  struct io_event *events,
+					  struct timespec *timeout);
+
+asmlinkage long
+compat_sys_io_getevents(aio_context_t ctx_id,
+				 unsigned long min_nr,
+				 unsigned long nr,
+				 struct io_event *events,
+				 struct compat_timespec *timeout)
+{
+	long ret;
+	struct timespec t;
+	struct timespec *ut = NULL;
+
+	ret = -EFAULT;
+	if (unlikely(!access_ok(VERIFY_WRITE, events,
+				nr * sizeof(struct io_event))))
+		goto out;
+	if (timeout) {
+		if (get_compat_timespec(&t, timeout))
+			goto out;
+
+		ut = compat_alloc_user_space(sizeof(*ut));
+		if (copy_to_user(ut, &t, sizeof(t)) )
+			goto out;
+	}
+	ret = sys_io_getevents(ctx_id, min_nr, nr, events, ut);
+out:
+	return ret;
+}
+
+extern asmlinkage long sys_io_submit(aio_context_t, long,
+				struct iocb __user **);
+
+static inline long
+copy_iocb(long nr, u32 *ptr32, u64 *ptr64)
+{
+	compat_uptr_t uptr;
+	int i;
+
+	for (i = 0; i < nr; ++i) {
+		if (get_user(uptr, ptr32 + i))
+			return -EFAULT;
+		if (put_user((u64)compat_ptr(uptr), ptr64 + i))
+			return -EFAULT;
+	}
+	return 0;
+}
+
+#define MAX_AIO_SUBMITS 	(PAGE_SIZE/sizeof(struct iocb *))
+
+asmlinkage long
+compat_sys_io_submit(aio_context_t ctx_id, int nr, u32 *iocb)
+{
+	struct iocb **iocb64;
+	long ret;
+
+	if (unlikely(nr < 0))
+		return -EINVAL;
+
+	if (nr > MAX_AIO_SUBMITS)
+		nr = MAX_AIO_SUBMITS;
+
+	iocb64 = compat_alloc_user_space(nr * sizeof(*iocb64));
+	ret = copy_iocb(nr, iocb, (u64 *) iocb64);
+	if (!ret)
+		ret = sys_io_submit(ctx_id, nr, iocb64);
+	return ret;
+}

_