Jens Axboe <axboe@xxxxxxxxx> writes: > On 10/21/21 12:05 PM, Jeff Moyer wrote: >> >>>> I'll follow up if there are issues. >> >> s390 (big endian, 64 bit) is failing libaio test 21: >> >> # harness/cases/21.p >> Expected -EAGAIN, got 4294967285 >> >> If I print out both res and res2 using %lx, you'll see what happened: >> >> Expected -EAGAIN, got fffffff5,ffffffff >> >> The sign extension is being split up. > > Funky, does it work if you apply this on top? > > diff --git a/fs/aio.c b/fs/aio.c > index 3674abc43788..c56437908339 100644 > --- a/fs/aio.c > +++ b/fs/aio.c > @@ -1442,8 +1442,8 @@ static void aio_complete_rw(struct kiocb *kiocb, u64 res) > * 32-bits of value at most for either value, bundle these up and > * pass them in one u64 value. > */ > - iocb->ki_res.res = lower_32_bits(res); > - iocb->ki_res.res2 = upper_32_bits(res); > + iocb->ki_res.res = (long) (res & 0xffffffff); > + iocb->ki_res.res2 = (long) (res >> 32); > iocb_put(iocb); > } I think you'll also need to clamp any ki_complete() call sites to 32 bits (cast to int, or what have you). Otherwise that sign extension will spill over into res2. fwiw, I tested with this: iocb->ki_res.res = (long)(int)lower_32_bits(res); iocb->ki_res.res2 = (long)(int)upper_32_bits(res); Coupled with the call site changes, that made things work for me. -Jeff