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; +} _