On Fri, Aug 28, 2020 at 9:27 PM Jens Axboe <axboe@xxxxxxxxx> wrote: > On 8/28/20 12:24 PM, Jens Axboe wrote: > >> @@ -1683,8 +1683,13 @@ ssize_t import_iovec(int type, const struct > >> iovec __user * uvector, > >> { > >> ssize_t n; > >> struct iovec *p; > >> - n = rw_copy_check_uvector(type, uvector, nr_segs, fast_segs, > >> - *iov, &p); > >> + > >> + if (in_compat_syscall()) > >> + n = compat_rw_copy_check_uvector(type, uvector, nr_segs, > >> + fast_segs, *iov, &p); > >> + else > >> + n = rw_copy_check_uvector(type, uvector, nr_segs, > >> + fast_segs, *iov, &p); > >> if (n < 0) { > >> if (p != *iov) > >> kfree(p); > > > > Doesn't work for the async case, where you want to be holding on to the > > allocated iovec. But in general I think it's a good helper for the sync > > case, which is by far the majority. > > Nevermind, I'm an idiot for reading this totally wrong. > I think you are right about the need to pick the compat vs native behavior based on req->ctx->compat instead of in_compat_syscall() inside of io_import_iovec(). That one can probably call a lower-level version and when all other callers get changed to calling ssize_t import_iovec(int type, const struct iovec __user * uvector, unsigned nr_segs, unsigned fast_segs, struct iovec **iov, struct iov_iter *i) { return __import_iovec(type, uvector, nr_segs, fast_segs, iov, i, in_compat_syscall()); } Arnd