Patch from Anton Blanchard arch/ppc64/kernel/misc.S | 10 ++-- arch/ppc64/kernel/sys_ppc32.c | 93 ++++++++++++++++++++++++++++++++++++++++++ fs/aio.c | 2 3 files changed, 98 insertions(+), 7 deletions(-) diff -puN arch/ppc64/kernel/misc.S~ppc64-aio-32bit-emulation arch/ppc64/kernel/misc.S --- 25/arch/ppc64/kernel/misc.S~ppc64-aio-32bit-emulation 2003-04-20 18:02:45.000000000 -0700 +++ 25-akpm/arch/ppc64/kernel/misc.S 2003-04-20 18:02:45.000000000 -0700 @@ -729,11 +729,11 @@ _GLOBAL(sys_call_table32) .llong .sys_ni_syscall .llong .sys_ni_syscall /* 225 - reserved for tux */ .llong .sys32_sendfile64 - .llong .sys_ni_syscall /* reserved for sys_io_setup */ - .llong .sys_ni_syscall /* reserved for sys_io_destroy */ - .llong .sys_ni_syscall /* reserved for sys_io_getevents */ - .llong .sys_ni_syscall /* 230 - reserved for sys_io_submit */ - .llong .sys_ni_syscall /* reserved for sys_io_cancel */ + .llong .sys32_io_setup + .llong .sys_io_destroy + .llong .sys32_io_getevents + .llong .sys32_io_submit + .llong .sys_io_cancel .llong .sys_set_tid_address .llong .ppc32_fadvise64 .llong .sys_exit_group diff -puN arch/ppc64/kernel/sys_ppc32.c~ppc64-aio-32bit-emulation arch/ppc64/kernel/sys_ppc32.c --- 25/arch/ppc64/kernel/sys_ppc32.c~ppc64-aio-32bit-emulation 2003-04-20 18:02:45.000000000 -0700 +++ 25-akpm/arch/ppc64/kernel/sys_ppc32.c 2003-04-20 18:02:45.000000000 -0700 @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -2643,6 +2644,98 @@ unsigned long sys32_mmap2(unsigned long return sys_mmap(addr, len, prot, flags, fd, pgoff << 12); } +extern long sys_io_setup(unsigned nr_reqs, aio_context_t *ctx); + +long sys32_io_setup(unsigned nr_reqs, u32 *ctx32p) +{ + long ret; + aio_context_t ctx64; + mm_segment_t oldfs = get_fs(); + + if (get_user((u32)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; +} + +long sys_io_getevents(aio_context_t ctx_id, long min_nr, long nr, + struct io_event *events, struct timespec *timeout); + +long sys32_io_getevents(aio_context_t ctx_id, u32 min_nr, u32 nr, + struct io_event *events, struct compat_timespec *t32) +{ + struct timespec t; + long ret; + mm_segment_t oldfs = get_fs(); + + if (t32) { + if (get_user(t.tv_sec, &t32->tv_sec) || + __get_user(t.tv_nsec, &t32->tv_nsec)) + return -EFAULT; + } + + if (verify_area(VERIFY_WRITE, events, nr * sizeof(*events))) + return -EFAULT; + + set_fs(KERNEL_DS); + /* sign extend min_nr and nr */ + ret = sys_io_getevents(ctx_id, (int)min_nr, (int)nr, events, + t32 ? &t : NULL); + set_fs(oldfs); + + return ret; +} + +long sys32_io_submit(aio_context_t ctx_id, u32 number, u32 *iocbpp) +{ + struct kioctx *ctx; + long ret = 0; + int i; + int nr = (int)number; /* sign extend */ + + if (unlikely(nr < 0)) + return -EINVAL; + + if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(u32))))) + return -EFAULT; + + ctx = lookup_ioctx(ctx_id); + if (unlikely(!ctx)) { + pr_debug("EINVAL: io_submit: invalid context id\n"); + return -EINVAL; + } + + for (i=0; i