Commit Graph

190 Commits

Author SHA1 Message Date
Ming Lei 1354d7a2bb lib/iov_iter: fix import_iovec_ubuf iovec management
JIRA: https://issues.redhat.com/browse/RHEL-87739

commit f4b78260fc678ccd7169f32dc9f3bfa3b93931c7
Author: Pavel Begunkov <asml.silence@gmail.com>
Date:   Fri Jan 31 14:13:15 2025 +0000

    lib/iov_iter: fix import_iovec_ubuf iovec management

    import_iovec() says that it should always be fine to kfree the iovec
    returned in @iovp regardless of the error code.  __import_iovec_ubuf()
    never reallocates it and thus should clear the pointer even in cases when
    copy_iovec_*() fail.

    Link: https://lkml.kernel.org/r/378ae26923ffc20fd5e41b4360d673bf47b1775b.1738332461.git.asml.silence@gmail.com
    Fixes: 3b2deb0e46da ("iov_iter: import single vector iovecs as ITER_UBUF")
    Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
    Reviewed-by: Jens Axboe <axboe@kernel.dk>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Cc: Christian Brauner <brauner@kernel.org>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2025-04-21 18:31:29 +08:00
Ming Lei f77b2361bf iov_iter: Mark copy_iovec_from_user() noclone
JIRA: https://issues.redhat.com/browse/RHEL-87739

commit 719a937b7003933de1298ffa4b881dd6a234e244
Author: Peter Zijlstra <peterz@infradead.org>
Date:   Fri Jun 16 14:43:55 2023 +0200

    iov_iter: Mark copy_iovec_from_user() noclone

    Extend commit 50f9a76ef127 ("iov_iter: Mark
    copy_compat_iovec_from_user() noinline") to also cover
    copy_iovec_from_user(). Different compiler versions cause the same
    problem on different functions.

    lib/iov_iter.o: warning: objtool: .altinstr_replacement+0x1f: redundant UACCESS disable
    lib/iov_iter.o: warning: objtool: iovec_from_user+0x84: call to copy_iovec_from_user.part.0() with UACCESS enabled
    lib/iov_iter.o: warning: objtool: __import_iovec+0x143: call to copy_iovec_from_user.part.0() with UACCESS enabled

    Fixes: 50f9a76ef127 ("iov_iter: Mark copy_compat_iovec_from_user() noinline")
    Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
    Tested-by: Borislav Petkov (AMD) <bp@alien8.de>
    Link: https://lkml.kernel.org/r/20230616124354.GD4253@hirez.programming.kicks-ass.net

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2025-04-21 18:31:18 +08:00
Ming Lei 2801478cfa iov_iter: Mark copy_compat_iovec_from_user() noinline
JIRA: https://issues.redhat.com/browse/RHEL-87739

commit 50f9a76ef127367847cf62999c79304e48018cfa
Author: Josh Poimboeuf <jpoimboe@kernel.org>
Date:   Wed Apr 12 10:46:48 2023 -0600

    iov_iter: Mark copy_compat_iovec_from_user() noinline

    After commit 6376ce56feb6 ("iov_iter: import single vector iovecs as
    ITER_UBUF"), GCC does an inter-procedural compiler optimization which
    moves the user_access_begin() out of copy_compat_iovec_from_user() and
    into its callers:

      lib/iov_iter.o: warning: objtool: .altinstr_replacement+0x0: redundant UACCESS disable
      lib/iov_iter.o: warning: objtool: iovec_from_user.part.0+0xc7: call to copy_compat_iovec_from_user.part.0() with UACCESS enabled
      lib/iov_iter.o: warning: objtool: __import_iovec+0x21d: call to copy_compat_iovec_from_user.part.0() with UACCESS enabled

    Enforce the "no UACCESS enable across function boundaries" rule by
    disabling cloning for copy_compat_iovec_from_user().

    Fixes: 6376ce56feb6 ("iov_iter: import single vector iovecs as ITER_UBUF")
    Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
    https://lkml.kernel.org/lkml/20230327120017.6bb826d7@canb.auug.org.au
    Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
    Tested-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2025-04-21 18:21:01 +08:00
Ming Lei a34605b761 iov_iter: import single vector iovecs as ITER_UBUF
JIRA: https://issues.redhat.com/browse/RHEL-87739

commit 3b2deb0e46da9798b694cf50bd8bea1b26dcc789
Author: Jens Axboe <axboe@kernel.dk>
Date:   Fri Mar 24 14:37:19 2023 -0600

    iov_iter: import single vector iovecs as ITER_UBUF

    Add a special case to __import_iovec(), which imports a single segment
    iovec as an ITER_UBUF rather than an ITER_IOVEC. ITER_UBUF is cheaper
    to iterate than ITER_IOVEC, and for a single segment iovec, there's no
    point in using a segmented iterator.

    Signed-off-by: Jens Axboe <axboe@kernel.dk>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2025-04-21 18:20:29 +08:00
Ming Lei 75f107f981 iov_iter: convert import_single_range() to ITER_UBUF
JIRA: https://issues.redhat.com/browse/RHEL-87739

commit e03ad4ee2783e41afc90cc7848468aef10741c0e
Author: Jens Axboe <axboe@kernel.dk>
Date:   Fri Mar 24 14:35:49 2023 -0600

    iov_iter: convert import_single_range() to ITER_UBUF

    Since we're just importing a single vector, we don't have to turn it
    into an ITER_IOVEC. Instead turn it into an ITER_UBUF, which is cheaper
    to iterate.

    Signed-off-by: Jens Axboe <axboe@kernel.dk>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2025-04-21 18:20:05 +08:00
Ming Lei fbef04547e lib/iov_iter: fix bvec iterator setup
JIRA: https://issues.redhat.com/browse/RHEL-79409

commit 341468e0ab4bb1b26ad0b0cee7c6db4bf283043a
Author: Ming Lei <ming.lei@redhat.com>
Date:   Sat Nov 2 09:42:11 2024 +0800

    lib/iov_iter: fix bvec iterator setup

    .bi_size of bvec iterator should be initialized as real max size for
    walking, and .bi_bvec_done just counts how many bytes need to be
    skipped in the 1st bvec, so .bi_size isn't related with .bi_bvec_done.

    This patch fixes bvec iterator initialization, and the inner `size`
    check isn't needed any more, so revert Eric Dumazet's commit
    7bc802acf193 ("iov-iter: do not return more bytes than requested in
    iov_iter_extract_bvec_pages()").

    Cc: Eric Dumazet <edumazet@google.com>
    Fixes: e4e535bff2bc ("iov_iter: don't require contiguous pages in iov_iter_extract_bvec_pages")
    Reported-by: syzbot+71abe7ab2b70bca770fd@syzkaller.appspotmail.com
    Tested-by: syzbot+71abe7ab2b70bca770fd@syzkaller.appspotmail.com
    Signed-off-by: Ming Lei <ming.lei@redhat.com>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2025-03-14 16:48:15 +08:00
Ming Lei 8daf888d83 lib/iov_iter.c: initialize bi.bi_idx before iterating over bvec
JIRA: https://issues.redhat.com/browse/RHEL-79409

commit 496a51b37143c690a06612a6bd58827ef2341761
Author: Ming Lei <ming.lei@redhat.com>
Date:   Thu Oct 31 19:02:24 2024 +0800

    lib/iov_iter.c: initialize bi.bi_idx before iterating over bvec

    Initialize bi.bi_idx as 0 before iterating over bvec, otherwise
    garbage data can be used as ->bi_idx.

    Cc: Christoph Hellwig <hch@lst.de>
    Reported-and-tested-by: Klara Modin <klarasmodin@gmail.com>
    Fixes: e4e535bff2bc ("iov_iter: don't require contiguous pages in iov_iter_extract_bvec_pages")
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Signed-off-by: Ming Lei <ming.lei@redhat.com>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2025-03-14 16:48:15 +08:00
Ming Lei c2f55b2bad iov_iter: don't require contiguous pages in iov_iter_extract_bvec_pages
JIRA: https://issues.redhat.com/browse/RHEL-79409

commit e4e535bff2bc82bb49a633775f9834beeaa527db
Author: Ming Lei <ming.lei@redhat.com>
Date:   Thu Oct 24 07:00:15 2024 +0200

    iov_iter: don't require contiguous pages in iov_iter_extract_bvec_pages

    The iov_iter_extract_pages interface allows to return physically
    discontiguous pages, as long as all but the first and last page
    in the array are page aligned and page size.  Rewrite
    iov_iter_extract_bvec_pages to take advantage of that instead of only
    returning ranges of physically contiguous pages.

    Signed-off-by: Ming Lei <ming.lei@redhat.com>
    [hch: minor cleanups, new commit log]
    Signed-off-by: Christoph Hellwig <hch@lst.de>
    Link: https://lore.kernel.org/r/20241024050021.627350-1-hch@lst.de
    Signed-off-by: Jens Axboe <axboe@kernel.dk>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2025-03-14 16:48:14 +08:00
Ming Lei 8273474e67 iov_iter: Fix iov_iter_extract_pages() with zero-sized entries
JIRA: https://issues.redhat.com/browse/RHEL-56837

commit f741bd7178c95abd7aeac5a9d933ee542f9a5509
Author: David Howells <dhowells@redhat.com>
Date:   Fri Sep 8 17:03:20 2023 +0100

    iov_iter: Fix iov_iter_extract_pages() with zero-sized entries

    iov_iter_extract_pages() doesn't correctly handle skipping over initial
    zero-length entries in ITER_KVEC and ITER_BVEC-type iterators.

    The problem is that it accidentally reduces maxsize to 0 when it
    skipping and thus runs to the end of the array and returns 0.

    Fix this by sticking the calculated size-to-copy in a new variable
    rather than back in maxsize.

    Fixes: 7d58fe731028 ("iov_iter: Add a function to extract a page list from an iterator")
    Signed-off-by: David Howells <dhowells@redhat.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Cc: Christian Brauner <brauner@kernel.org>
    Cc: Jens Axboe <axboe@kernel.dk>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Cc: David Hildenbrand <david@redhat.com>
    Cc: John Hubbard <jhubbard@nvidia.com>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2024-09-27 08:38:52 +08:00
Ming Lei 350d9b43bc iov_iter: Add a function to extract a page list from an iterator
JIRA: https://issues.redhat.com/browse/RHEL-56837

commit 7d58fe731028128f3a7e20b9c492be48aae133ee
Author: David Howells <dhowells@redhat.com>
Date:   Fri Oct 28 21:50:30 2022 +0100

    iov_iter: Add a function to extract a page list from an iterator

    Add a function, iov_iter_extract_pages(), to extract a list of pages from
    an iterator.  The pages may be returned with a pin added or nothing,
    depending on the type of iterator.

    Add a second function, iov_iter_extract_will_pin(), to determine how the
    cleanup should be done.

    There are two cases:

     (1) ITER_IOVEC or ITER_UBUF iterator.

         Extracted pages will have pins (FOLL_PIN) obtained on them so that a
         concurrent fork() will forcibly copy the page so that DMA is done
         to/from the parent's buffer and is unavailable to/unaffected by the
         child process.

         iov_iter_extract_will_pin() will return true for this case.  The
         caller should use something like unpin_user_page() to dispose of the
         page.

     (2) Any other sort of iterator.

         No refs or pins are obtained on the page, the assumption is made that
         the caller will manage page retention.

         iov_iter_extract_will_pin() will return false.  The pages don't need
         additional disposal.

    Signed-off-by: David Howells <dhowells@redhat.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: Jens Axboe <axboe@kernel.dk>
    cc: Al Viro <viro@zeniv.linux.org.uk>
    cc: John Hubbard <jhubbard@nvidia.com>
    cc: David Hildenbrand <david@redhat.com>
    cc: Matthew Wilcox <willy@infradead.org>
    cc: linux-fsdevel@vger.kernel.org
    cc: linux-mm@kvack.org
    Signed-off-by: Steve French <stfrench@microsoft.com>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2024-09-27 08:38:51 +08:00
Ming Lei 4bb40e15ca iov_iter: Define flags to qualify page extraction.
JIRA: https://issues.redhat.com/browse/RHEL-56837

commit f62e52d1276b6cd329fe72d36bdf912b2ce4caaf
Author: David Howells <dhowells@redhat.com>
Date:   Thu Jan 19 12:47:23 2023 +0000

    iov_iter: Define flags to qualify page extraction.

    Define flags to qualify page extraction to pass into iov_iter_*_pages*()
    rather than passing in FOLL_* flags.

    For now only a flag to allow peer-to-peer DMA is supported.

    Signed-off-by: David Howells <dhowells@redhat.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: John Hubbard <jhubbard@nvidia.com>
    Reviewed-by: Jens Axboe <axboe@kernel.dk>
    cc: Al Viro <viro@zeniv.linux.org.uk>
    cc: Logan Gunthorpe <logang@deltatee.com>
    cc: linux-fsdevel@vger.kernel.org
    cc: linux-block@vger.kernel.org
    Signed-off-by: Steve French <stfrench@microsoft.com>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2024-09-27 08:38:51 +08:00
Ming Lei fc2a795442 iov_iter: introduce iov_iter_get_pages_[alloc_]flags()
JIRA: https://issues.redhat.com/browse/RHEL-56837

commit d82076403cef7fcd1e7617c9db48bf21ebdc1f9c
Author: Logan Gunthorpe <logang@deltatee.com>
Date:   Fri Oct 21 11:41:10 2022 -0600

    iov_iter: introduce iov_iter_get_pages_[alloc_]flags()

    Add iov_iter_get_pages_flags() and iov_iter_get_pages_alloc_flags()
    which take a flags argument that is passed to get_user_pages_fast().

    This is so that FOLL_PCI_P2PDMA can be passed when appropriate.

    Signed-off-by: Logan Gunthorpe <logang@deltatee.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Link: https://lore.kernel.org/r/20221021174116.7200-4-logang@deltatee.com
    Signed-off-by: Jens Axboe <axboe@kernel.dk>

Signed-off-by: Ming Lei <ming.lei@redhat.com>
2024-09-27 08:38:50 +08:00
Jaroslav Kysela 230c3241c5 iov_iter: Export import_ubuf()
JIRA: https://issues.redhat.com/browse/RHEL-27515

Omitted-fix: e2964cd7ef58bd97f7acd5340e71d6b7e260fb2d
             ALSA: gus: Convert to generic PCM copy ops
Omitted-fix: 9d0fdc602de9d4368ce58da158725d2c43765fd1
             ALSA: emu8000: Convert to generic PCM copy ops
Omitted-fix: 2f432f4702134fac27677f13aba69ed830984f75
             ALSA: sh: Convert to generic PCM copy ops
Omitted-fix: 44f08b67f2d2c699f2b1784d2aacdf3760a09cc5
             media: solo6x10: Convert to generic PCM copy ops
Omitted-fix: 95396d83e96cc1b7887562d07ff0324c11e744db
             ASoC: mediatek: Convert to generic PCM copy ops

commit 70e969eb235ee6a030ff140b1852b598bf66f9c8
Author: Takashi Iwai <tiwai@suse.de>
Date: Tue Aug 15 21:01:12 2023 +0200

    iov_iter: Export import_ubuf()

    Export import_ubuf() to be used in sound subsystem for generic memory
    handling as Linus suggested.  It's used for constructing an iov_iter
    of a single segment user-space copy for PCM data.

    Cc: Alexander Viro <viro@zeniv.linux.org.uk>
    Link: https://lore.kernel.org/r/CAHk-=wh-mUL6mp4chAc6E_UjwpPLyCPRCJK+iB4ZMD2BqjwGHA@mail.gmail.com
    Link: https://lore.kernel.org/r/20230815190136.8987-2-tiwai@suse.de
    Signed-off-by: Takashi Iwai <tiwai@suse.de>

Signed-off-by: Jaroslav Kysela <jkysela@redhat.com>
2024-07-08 20:53:45 +02:00
Chris von Recklinghausen 82a61332ba iov_iter: add copy_page_to_iter_nofault()
JIRA: https://issues.redhat.com/browse/RHEL-27741

commit 4f80818b4a58c9458dce0df7cce9abe107da445e
Author: Lorenzo Stoakes <lstoakes@gmail.com>
Date:   Wed Mar 22 18:57:03 2023 +0000

    iov_iter: add copy_page_to_iter_nofault()

    Provide a means to copy a page to user space from an iterator, aborting if
    a page fault would occur.  This supports compound pages, but may be passed
    a tail page with an offset extending further into the compound page, so we
    cannot pass a folio.

    This allows for this function to be called from atomic context and _try_
    to user pages if they are faulted in, aborting if not.

    The function does not use _copy_to_iter() in order to not specify
    might_fault(), this is similar to copy_page_from_iter_atomic().

    This is being added in order that an iteratable form of vread() can be
    implemented while holding spinlocks.

    Link: https://lkml.kernel.org/r/19734729defb0f498a76bdec1bef3ac48a3af3e8.1679511146.git.lstoakes@gmail.com
    Signed-off-by: Lorenzo Stoakes <lstoakes@gmail.com>
    Reviewed-by: Baoquan He <bhe@redhat.com>
    Cc: Alexander Viro <viro@zeniv.linux.org.uk>
    Cc: David Hildenbrand <david@redhat.com>
    Cc: Jens Axboe <axboe@kernel.dk>
    Cc: Jiri Olsa <jolsa@kernel.org>
    Cc: Liu Shixin <liushixin2@huawei.com>
    Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
    Cc: Uladzislau Rezki (Sony) <urezki@gmail.com>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2024-04-30 07:00:35 -04:00
Chris von Recklinghausen 70535767f8 iov_iter: saner checks for attempt to copy to/from iterator
Conflicts: lib/iov_iter.c - fuzz

JIRA: https://issues.redhat.com/browse/RHEL-27741

commit a41dad905e5a388f88435a517de102e9b2c8e43d
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Thu Sep 15 20:11:15 2022 -0400

    iov_iter: saner checks for attempt to copy to/from iterator

    instead of "don't do it to ITER_PIPE" check for ->data_source being
    false on copying from iterator.  Check for !->data_source for
    copying to iterator, while we are at it.

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2024-04-30 07:00:02 -04:00
Aristeu Rozanski 9819f337e2 splice: Add a func to do a splice from a buffered file without ITER_PIPE
JIRA: https://issues.redhat.com/browse/RHEL-27740
Tested: by me

commit 07073eb01c5f630344bc1c3e56b0e0d94aedf919
Author: David Howells <dhowells@redhat.com>
Date:   Tue Feb 14 15:01:42 2023 +0000

    splice: Add a func to do a splice from a buffered file without ITER_PIPE

    Provide a function to do splice read from a buffered file, pulling the
    folios out of the pagecache directly by calling filemap_get_pages() to do
    any required reading and then pasting the returned folios into the pipe.

    A helper function is provided to do the actual folio pasting and will
    handle multipage folios by splicing as many of the relevant subpages as
    will fit into the pipe.

    The code is loosely based on filemap_read() and might belong in
    mm/filemap.c with that as it needs to use filemap_get_pages().

    Signed-off-by: David Howells <dhowells@redhat.com>
    Reviewed-by: Jens Axboe <axboe@kernel.dk>
    cc: Christoph Hellwig <hch@lst.de>
    cc: Al Viro <viro@zeniv.linux.org.uk>
    cc: David Hildenbrand <david@redhat.com>
    cc: John Hubbard <jhubbard@nvidia.com>
    cc: linux-mm@kvack.org
    cc: linux-block@vger.kernel.org
    cc: linux-fsdevel@vger.kernel.org
    Signed-off-by: Steve French <stfrench@microsoft.com>

Signed-off-by: Aristeu Rozanski <arozansk@redhat.com>
2024-04-29 14:33:24 -04:00
Jeff Moyer cc3954e1d4 iov_iter: add iter_iovec() helper
JIRA: https://issues.redhat.com/browse/RHEL-12076

commit de4f5fed3f231a8ff4790bf52975f847b95b85ea
Author: Jens Axboe <axboe@kernel.dk>
Date:   Wed Mar 29 08:52:15 2023 -0600

    iov_iter: add iter_iovec() helper
    
    This returns a pointer to the current iovec entry in the iterator. Only
    useful with ITER_IOVEC right now, but it prepares us to treat ITER_UBUF
    and ITER_IOVEC identically for the first segment.
    
    Rename struct iov_iter->iov to iov_iter->__iov to find any potentially
    troublesome spots, and also to prevent anyone from adding new code that
    accesses iter->iov directly.
    
    Signed-off-by: Jens Axboe <axboe@kernel.dk>

Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
2023-11-02 15:31:27 -04:00
Jeff Moyer 0f52408485 iov_iter: move iter_ubuf check inside restore WARN
JIRA: https://issues.redhat.com/browse/RHEL-12076

commit 4397a17c1dc53f436285f372432dd1aea44e7953
Author: Keith Busch <kbusch@kernel.org>
Date:   Thu Jan 5 11:07:33 2023 -0800

    iov_iter: move iter_ubuf check inside restore WARN
    
    io_uring is using iter_ubuf types for single vector requests. We expect
    state restore may happen for this type now, and it is already handled
    correctly, so suppress the warning.
    
    Signed-off-by: Keith Busch <kbusch@kernel.org>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Reviewed-by: Christoph Hellwig <hch@lst.de>

Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
2023-11-02 15:31:06 -04:00
Jeff Moyer d610184bbb iov: add import_ubuf()
JIRA: https://issues.redhat.com/browse/RHEL-12076

commit 2ad9bd8332ac1bc072cc7d785e7cb09d6ad36f4c
Author: Jens Axboe <axboe@kernel.dk>
Date:   Thu Jan 5 11:07:30 2023 -0800

    iov: add import_ubuf()
    
    Like import_single_range(), but for ITER_UBUF.
    
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Signed-off-by: Keith Busch <kbusch@kernel.org>
    Reviewed-by: Christoph Hellwig <hch@lst.de>

Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
2023-11-02 15:29:57 -04:00
Chris von Recklinghausen 546d9d4c70 instrumented.h: allow instrumenting both sides of copy_from_user()
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 33b75c1d884e81ec97525e0a6fdcb187adf273f4
Author: Alexander Potapenko <glider@google.com>
Date:   Thu Sep 15 17:03:37 2022 +0200

    instrumented.h: allow instrumenting both sides of copy_from_user()

    Introduce instrument_copy_from_user_before() and
    instrument_copy_from_user_after() hooks to be invoked before and after the
    call to copy_from_user().

    KASAN and KCSAN will be only using instrument_copy_from_user_before(), but
    for KMSAN we'll need to insert code after copy_from_user().

    Link: https://lkml.kernel.org/r/20220915150417.722975-4-glider@google.com
    Signed-off-by: Alexander Potapenko <glider@google.com>
    Reviewed-by: Marco Elver <elver@google.com>
    Cc: Alexander Viro <viro@zeniv.linux.org.uk>
    Cc: Alexei Starovoitov <ast@kernel.org>
    Cc: Andrey Konovalov <andreyknvl@gmail.com>
    Cc: Andrey Konovalov <andreyknvl@google.com>
    Cc: Andy Lutomirski <luto@kernel.org>
    Cc: Arnd Bergmann <arnd@arndb.de>
    Cc: Borislav Petkov <bp@alien8.de>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: Christoph Lameter <cl@linux.com>
    Cc: David Rientjes <rientjes@google.com>
    Cc: Dmitry Vyukov <dvyukov@google.com>
    Cc: Eric Biggers <ebiggers@google.com>
    Cc: Eric Biggers <ebiggers@kernel.org>
    Cc: Eric Dumazet <edumazet@google.com>
    Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Cc: Herbert Xu <herbert@gondor.apana.org.au>
    Cc: Ilya Leoshkevich <iii@linux.ibm.com>
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Jens Axboe <axboe@kernel.dk>
    Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
    Cc: Kees Cook <keescook@chromium.org>
    Cc: Mark Rutland <mark.rutland@arm.com>
    Cc: Matthew Wilcox <willy@infradead.org>
    Cc: Michael S. Tsirkin <mst@redhat.com>
    Cc: Pekka Enberg <penberg@kernel.org>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Petr Mladek <pmladek@suse.com>
    Cc: Stephen Rothwell <sfr@canb.auug.org.au>
    Cc: Steven Rostedt <rostedt@goodmis.org>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: Vasily Gorbik <gor@linux.ibm.com>
    Cc: Vegard Nossum <vegard.nossum@oracle.com>
    Cc: Vlastimil Babka <vbabka@suse.cz>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:14:32 -04:00
Chris von Recklinghausen aec1e7c1ba fix copy_page_from_iter() for compound destinations
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit c03f05f183cd15f4259684ab658fbc3d23797d99
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Fri Jul 29 12:54:53 2022 -0400

    fix copy_page_from_iter() for compound destinations

    had been broken for ITER_BVEC et.al. since ever (OK, v3.17 when
    ITER_BVEC had first appeared)...

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:07 -04:00
Chris von Recklinghausen 5bf506463c copy_page_to_iter(): don't split high-order page in case of ITER_PIPE
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit f0f6b614f83dbae99d283b7b12ab5dd2e04df979
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Thu Jun 23 17:21:37 2022 -0400

    copy_page_to_iter(): don't split high-order page in case of ITER_PIPE

    ... just shove it into one pipe_buffer.

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:06 -04:00
Chris von Recklinghausen e697b2aacf expand those iov_iter_advance()...
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 310d9d5a5009a93377200b98daa2d84aa2bd8160
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Sat Jun 11 04:04:33 2022 -0400

    expand those iov_iter_advance()...

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:06 -04:00
Chris von Recklinghausen da6c3e73ba pipe_get_pages(): switch to append_pipe()
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 746de1f86fcd33464acac047f111eea877f2f7a0
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Tue Jun 14 16:38:53 2022 -0400

    pipe_get_pages(): switch to append_pipe()

    now that we are advancing the iterator, there's no need to
    treat the first page separately - just call append_pipe()
    in a loop.

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:06 -04:00
Chris von Recklinghausen 627de62239 get rid of non-advancing variants
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit eba2d3d798295dc43cae8fade102f9d083a2a741
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Fri Jun 10 13:05:12 2022 -0400

    get rid of non-advancing variants

    mechanical change; will be further massaged in subsequent commits

    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:05 -04:00
Chris von Recklinghausen 07b20cc7d8 iov_iter: saner helper for page array allocation
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 3cf42da327f26eb4461864dd64812345b37f4fd9
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Fri Jun 17 14:45:41 2022 -0400

    iov_iter: saner helper for page array allocation

    All call sites of get_pages_array() are essenitally identical now.
    Replace with common helper...

    Returns number of slots available in resulting array or 0 on OOM;
    it's up to the caller to make sure it doesn't ask to zero-entry
    array (i.e. neither maxpages nor size are allowed to be zero).

    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:04 -04:00
Chris von Recklinghausen 370a010e2a fold __pipe_get_pages() into pipe_get_pages()
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 8520008417c581c4c22e39597f92b9814ae34c31
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Fri Jun 17 14:30:39 2022 -0400

    fold __pipe_get_pages() into pipe_get_pages()

    ... and don't mangle maxsize there - turn the loop into counting
    one instead.  Easier to see that we won't run out of array that
    way.  Note that special treatment of the partial buffer in that
    thing is an artifact of the non-advancing semantics of
    iov_iter_get_pages() - if not for that, it would be append_pipe(),
    same as the body of the loop that follows it.  IOW, once we make
    iov_iter_get_pages() advancing, the whole thing will turn into
            calculate how many pages do we want
            allocate an array (if needed)
            call append_pipe() that many times.

    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:03 -04:00
Chris von Recklinghausen 073a599c3a ITER_XARRAY: don't open-code DIV_ROUND_UP()
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 0aa4fc32f54028f6fbb35bf71df4b0d86ff1662b
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Fri Jun 10 20:30:35 2022 -0400

    ITER_XARRAY: don't open-code DIV_ROUND_UP()

    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:03 -04:00
Chris von Recklinghausen f4e7e14cf2 unify the rest of iov_iter_get_pages()/iov_iter_get_pages_alloc() guts
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 451c0ba9475ebdce36249c5c769efa5d580d1d83
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Fri Jun 17 13:54:15 2022 -0400

    unify the rest of iov_iter_get_pages()/iov_iter_get_pages_alloc() guts

    same as for pipes and xarrays; after that iov_iter_get_pages() becomes
    a wrapper for __iov_iter_get_pages_alloc().

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:03 -04:00
Chris von Recklinghausen d8bb7d6241 unify xarray_get_pages() and xarray_get_pages_alloc()
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 68fe506f3731ecf7881de9512cc5f4c14fd13f3a
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Fri Jun 17 13:48:03 2022 -0400

    unify xarray_get_pages() and xarray_get_pages_alloc()

    same as for pipes

    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:02 -04:00
Chris von Recklinghausen 575e9988a3 unify pipe_get_pages() and pipe_get_pages_alloc()
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit acbdeb8320b0a470bef1b6c0105d8c2bbc4c4ba0
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Fri Jun 17 13:35:35 2022 -0400

    unify pipe_get_pages() and pipe_get_pages_alloc()

            The differences between those two are
    * pipe_get_pages() gets a non-NULL struct page ** value pointing to
    preallocated array + array size.
    * pipe_get_pages_alloc() gets an address of struct page ** variable that
    contains NULL, allocates the array and (on success) stores its address in
    that variable.

            Not hard to combine - always pass struct page ***, have
    the previous pipe_get_pages_alloc() caller pass ~0U as cap for
    array size.

    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:02 -04:00
Chris von Recklinghausen 81160005f8 iov_iter_get_pages(): sanity-check arguments
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit c81ce28df500b04444ef97dc82a7b0299ce717e8
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Fri Jun 17 15:15:14 2022 -0400

    iov_iter_get_pages(): sanity-check arguments

    zero maxpages is bogus, but best treated as "just return 0";
    NULL pages, OTOH, should be treated as a hard bug.

    get rid of now completely useless checks in xarray_get_pages{,_alloc}().

    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:02 -04:00
Chris von Recklinghausen a1f37635dc iov_iter_get_pages_alloc(): lift freeing pages array on failure exits into wrapper
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 91329559eb07c9b12c7ce80e893ad39579c40aa2
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Fri Jun 10 20:38:20 2022 -0400

    iov_iter_get_pages_alloc(): lift freeing pages array on failure exits into wrapper

    Incidentally, ITER_XARRAY did *not* free the sucker in case when
    iter_xarray_populate_pages() returned 0...

    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:01 -04:00
Chris von Recklinghausen cbf1e7fb09 ITER_PIPE: fold data_start() and pipe_space_for_user() together
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 12d426ab64a1c75f1b2ee5c33e933a4c16004049
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Wed Jun 15 09:44:38 2022 -0400

    ITER_PIPE: fold data_start() and pipe_space_for_user() together

    All their callers are next to each other; all of them
    want the total amount of pages and, possibly, the
    offset in the partial final buffer.

    Combine into a new helper (pipe_npages()), fix the
    bogosity in pipe_space_for_user(), while we are at it.

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:01 -04:00
Chris von Recklinghausen 8cd6c70c0b ITER_PIPE: cache the type of last buffer
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 10f525a8cd7a525e9fc73288bb35428c9cad5e63
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Wed Jun 15 02:02:51 2022 -0400

    ITER_PIPE: cache the type of last buffer

    We often need to find whether the last buffer is anon or not, and
    currently it's rather clumsy:
            check if ->iov_offset is non-zero (i.e. that pipe is not empty)
            if so, get the corresponding pipe_buffer and check its ->ops
            if it's &default_pipe_buf_ops, we have an anon buffer.

    Let's replace the use of ->iov_offset (which is nowhere near similar to
    its role for other flavours) with signed field (->last_offset), with
    the following rules:
            empty, no buffers occupied:             0
            anon, with bytes up to N-1 filled:      N
            zero-copy, with bytes up to N-1 filled: -N

    That way abs(i->last_offset) is equal to what used to be in i->iov_offset
    and empty vs. anon vs. zero-copy can be distinguished by the sign of
    i->last_offset.

            Checks for "should we extend the last buffer or should we start
    a new one?" become easier to follow that way.

            Note that most of the operations can only be done in a sane
    state - i.e. when the pipe has nothing past the current position of
    iterator.  About the only thing that could be done outside of that
    state is iov_iter_advance(), which transitions to the sane state by
    truncating the pipe.  There are only two cases where we leave the
    sane state:
            1) iov_iter_get_pages()/iov_iter_get_pages_alloc().  Will be
    dealt with later, when we make get_pages advancing - the callers are
    actually happier that way.
            2) iov_iter copied, then something is put into the copy.  Since
    they share the underlying pipe, the original gets behind.  When we
    decide that we are done with the copy (original is not usable until then)
    we advance the original.  direct_io used to be done that way; nowadays
    it operates on the original and we do iov_iter_revert() to discard
    the excessive data.  At the moment there's nothing in the kernel that
    could do that to ITER_PIPE iterators, so this reason for insane state
    is theoretical right now.

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:01 -04:00
Chris von Recklinghausen b5f6afed40 ITER_PIPE: clean iov_iter_revert()
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 92acdc4f37207c556baee0ea28ce0823d22b9812
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Sun Jun 12 17:54:35 2022 -0400

    ITER_PIPE: clean iov_iter_revert()

    Fold pipe_truncate() into it, clean up.  We can release buffers
    in the same loop where we walk backwards to the iterator beginning
    looking for the place where the new position will be.

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:00 -04:00
Chris von Recklinghausen 12693626d4 ITER_PIPE: clean pipe_advance() up
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 2c855de93314e9573f31044976ffd89cb70a2dbd
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Wed Jun 15 16:03:25 2022 -0400

    ITER_PIPE: clean pipe_advance() up

    instead of setting ->iov_offset for new position and calling
    pipe_truncate() to adjust ->len of the last buffer and discard
    everything after it, adjust ->len at the same time we set ->iov_offset
    and use pipe_discard_from() to deal with buffers past that.

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:00 -04:00
Chris von Recklinghausen 9cccbd72a7 ITER_PIPE: lose iter_head argument of __pipe_get_pages()
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit ca591967543ab1af7e6e68bd505ef7869d3f2175
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Thu Jun 16 14:26:23 2022 -0400

    ITER_PIPE: lose iter_head argument of __pipe_get_pages()

    it's only used to get to the partial buffer we can add to,
    and that's always the last one, i.e. pipe->head - 1.

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:00 -04:00
Chris von Recklinghausen 5fd20f9adf ITER_PIPE: fold push_pipe() into __pipe_get_pages()
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit e3b42964f84c028f352c11269661d47f6ca4ab2e
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Sat Jun 11 02:52:03 2022 -0400

    ITER_PIPE: fold push_pipe() into __pipe_get_pages()

            Expand the only remaining call of push_pipe() (in
    __pipe_get_pages()), combine it with the page-collecting loop there.

    Note that the only reason it's not a loop doing append_pipe() is
    that append_pipe() is advancing, while iov_iter_get_pages() is not.
    As soon as it switches to saner semantics, this thing will switch
    to using append_pipe().

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:13:00 -04:00
Chris von Recklinghausen 24f15dbb02 ITER_PIPE: allocate buffers as we go in copy-to-pipe primitives
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 8fad7767edcfd3f93e0d9985cb2dc1db270b8719
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Tue Jun 14 13:53:53 2022 -0400

    ITER_PIPE: allocate buffers as we go in copy-to-pipe primitives

    New helper: append_pipe().  Extends the last buffer if possible,
    allocates a new one otherwise.  Returns page and offset in it
    on success, NULL on failure.  iov_iter is advanced past the
    data we've got.

    Use that instead of push_pipe() in copy-to-pipe primitives;
    they get simpler that way.  Handling of short copy (in "mc" one)
    is done simply by iov_iter_revert() - iov_iter is in consistent
    state after that one, so we can use that.

    [Fix for braino caught by Liu Xinpeng <liuxp11@chinatelecom.cn> folded in]
    [another braino fix, this time in copy_pipe_to_iter() and pipe_zero();
    caught by testcase from Hugh Dickins]

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:12:59 -04:00
Chris von Recklinghausen f792a4d6cc ITER_PIPE: helpers for adding pipe buffers
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 47b7fcae419dc940e3fb8e58088a5b80ad813bbf
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Mon Jun 13 14:30:15 2022 -0400

    ITER_PIPE: helpers for adding pipe buffers

    There are only two kinds of pipe_buffer in the area used by ITER_PIPE.

    1) anonymous - copy_to_iter() et.al. end up creating those and copying
    data there.  They have zero ->offset, and their ->ops points to
    default_pipe_page_ops.

    2) zero-copy ones - those come from copy_page_to_iter(), and page
    comes from caller.  ->offset is also caller-supplied - it might be
    non-zero.  ->ops points to page_cache_pipe_buf_ops.

    Move creation and insertion of those into helpers - push_anon(pipe, size)
    and push_page(pipe, page, offset, size) resp., separating them from
    the "could we avoid creating a new buffer by merging with the current
    head?" logics.

    Acked-by: Jeff Layton <jlayton@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:12:59 -04:00
Chris von Recklinghausen c5a5e11878 ITER_PIPE: helper for getting pipe buffer by index
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 2dcedb2a549a4d7430538213b1b28ef7271bc0aa
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Tue Jun 14 10:24:37 2022 -0400

    ITER_PIPE: helper for getting pipe buffer by index

    pipe_buffer instances of a pipe are organized as a ring buffer,
    with power-of-2 size.  Indices are kept *not* reduced modulo ring
    size, so the buffer refered to by index N is
            pipe->bufs[N & (pipe->ring_size - 1)].

    Ring size can change over the lifetime of a pipe, but not while
    the pipe is locked.  So for any iov_iter primitives it's a constant.
    Original conversion of pipes to this layout went overboard trying
    to microoptimize that - calculating pipe->ring_size - 1, storing
    it in a local variable and using through the function.  In some
    cases it might be warranted, but most of the times it only
    obfuscates what's going on in there.

    Introduce a helper (pipe_buf(pipe, N)) that would encapsulate
    that and use it in the obvious cases.  More will follow...

    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:12:59 -04:00
Chris von Recklinghausen bac38e7d31 new iov_iter flavour - ITER_UBUF
Conflicts: include/linux/uio.h - We already have
	de4eda9de2d9 ("use less confusing names for iov_iter direction initializers")
	so we have a preexisting definition of ITER_SOURCE (context)

JIRA: https://issues.redhat.com/browse/RHEL-1848

commit fcb14cb1bdacec5b4374fe161e83fb8208164a85
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Sun May 22 14:59:25 2022 -0400

    new iov_iter flavour - ITER_UBUF

    Equivalent of single-segment iovec.  Initialized by iov_iter_ubuf(),
    checked for by iter_is_ubuf(), otherwise behaves like ITER_IOVEC
    ones.

    We are going to expose the things like ->write_iter() et.al. to those
    in subsequent commits.

    New predicate (user_backed_iter()) that is true for ITER_IOVEC and
    ITER_UBUF; places like direct-IO handling should use that for
    checking that pages we modify after getting them from iov_iter_get_pages()
    would need to be dirtied.

    DO NOT assume that replacing iter_is_iovec() with user_backed_iter()
    will solve all problems - there's code that uses iter_is_iovec() to
    decide how to poke around in iov_iter guts and for that the predicate
    replacement obviously won't suffice.

    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:12:58 -04:00
Chris von Recklinghausen 26ee65b2b1 fix short copy handling in copy_mc_pipe_to_iter()
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit c3497fd009ef2c59eea60d21c3ac22de3585ed7d
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Sun Jun 12 19:50:29 2022 -0400

    fix short copy handling in copy_mc_pipe_to_iter()

    Unlike other copying operations on ITER_PIPE, copy_mc_to_iter() can
    result in a short copy.  In that case we need to trim the unused
    buffers, as well as the length of partially filled one - it's not
    enough to set ->head, ->iov_offset and ->count to reflect how
    much had we copied.  Not hard to fix, fortunately...

    I'd put a helper (pipe_discard_from(pipe, head)) into pipe_fs_i.h,
    rather than iov_iter.c - it has nothing to do with iov_iter and
    having it will allow us to avoid an ugly kludge in fs/splice.c.
    We could put it into lib/iov_iter.c for now and move it later,
    but I don't see the point going that way...

    Cc: stable@kernel.org # 4.19+
    Fixes: ca146f6f09 "lib/iov_iter: Fix pipe handling in _copy_to_iter_mcsafe()"
    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:12:53 -04:00
Chris von Recklinghausen ffa1dcf9f9 iov_iter_get_pages{,_alloc}(): cap the maxsize with MAX_RW_COUNT
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 7392ed1734c319150b5ddec3f192a6405728e8d0
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Sat Jun 11 16:44:21 2022 -0400

    iov_iter_get_pages{,_alloc}(): cap the maxsize with MAX_RW_COUNT

    All callers can and should handle iov_iter_get_pages() returning
    fewer pages than requested.  All in-kernel ones do.  And it makes
    the arithmetical overflow analysis much simpler...

    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:12:53 -04:00
Chris von Recklinghausen d720a3fee3 iov_iter_bvec_advance(): don't bother with bvec_iter
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 18fa9af7263164ec9a8d7b28a848324825f14672
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Mon Jun 6 23:44:33 2022 -0400

    iov_iter_bvec_advance(): don't bother with bvec_iter

    do what we do for iovec/kvec; that ends up generating better code,
    AFAICS.

    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:12:52 -04:00
Chris von Recklinghausen f3f020114c copy_page_{to,from}_iter(): switch iovec variants to generic
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 59bb69c67cf1475a04cd5629d9c4f6dbbcba5e4a
Author: Al Viro <viro@zeniv.linux.org.uk>
Date:   Thu May 26 19:07:11 2022 -0400

    copy_page_{to,from}_iter(): switch iovec variants to generic

    we can do copyin/copyout under kmap_local_page(); it shouldn't overflow
    the kmap stack - the maximal footprint increase only by one here.

    Reviewed-by: Jeff Layton <jlayton@kernel.org>
    Reviewed-by: Christian Brauner (Microsoft) <brauner@kernel.org>
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:12:52 -04:00
Chris von Recklinghausen 7b4bfc5657 iov_iter: fix build issue due to possible type mis-match
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 1c27f1fc1549f0e470429f5497a76ad28a37f21a
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Sat Jun 11 10:30:20 2022 -0700

    iov_iter: fix build issue due to possible type mis-match

    Commit 6c77676645ad ("iov_iter: Fix iter_xarray_get_pages{,_alloc}()")
    introduced a problem on some 32-bit architectures (at least arm, xtensa,
    csky,sparc and mips), that have a 'size_t' that is 'unsigned int'.

    The reason is that we now do

        min(nr * PAGE_SIZE - offset, maxsize);

    where 'nr' and 'offset' and both 'unsigned int', and PAGE_SIZE is
    'unsigned long'.  As a result, the normal C type rules means that the
    first argument to 'min()' ends up being 'unsigned long'.

    In contrast, 'maxsize' is of type 'size_t'.

    Now, 'size_t' and 'unsigned long' are always the same physical type in
    the kernel, so you'd think this doesn't matter, and from an actual
    arithmetic standpoint it doesn't.

    But on 32-bit architectures 'size_t' is commonly 'unsigned int', even if
    it could also be 'unsigned long'.  In that situation, both are unsigned
    32-bit types, but they are not the *same* type.

    And as a result 'min()' will complain about the distinct types (ignore
    the "pointer types" part of the error message: that's an artifact of the
    way we have made 'min()' check types for being the same):

      lib/iov_iter.c: In function 'iter_xarray_get_pages':
      include/linux/minmax.h:20:35: error: comparison of distinct pointer types lacks a cast [-Werror]
         20 |         (!!(sizeof((typeof(x) *)1 == (typeof(y) *)1)))
            |                                   ^~
      lib/iov_iter.c:1464:16: note: in expansion of macro 'min'
       1464 |         return min(nr * PAGE_SIZE - offset, maxsize);
            |                ^~~

    This was not visible on 64-bit architectures (where we always define
    'size_t' to be 'unsigned long').

    Force these cases to use 'min_t(size_t, x, y)' to make the type explicit
    and avoid the issue.

    [ Nit-picky note: technically 'size_t' doesn't have to match 'unsigned
      long' arithmetically. We've certainly historically seen environments
      with 16-bit address spaces and 32-bit 'unsigned long'.

      Similarly, even in 64-bit modern environments, 'size_t' could be its
      own type distinct from 'unsigned long', even if it were arithmetically
      identical.

      So the above type commentary is only really descriptive of the kernel
      environment, not some kind of universal truth for the kinds of wild
      and crazy situations that are allowed by the C standard ]

    Reported-by: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
    Link: https://lore.kernel.org/all/YqRyL2sIqQNDfky2@debian/
    Cc: Jeff Layton <jlayton@kernel.org>
    Cc: David Howells <dhowells@redhat.com>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:12:47 -04:00
Chris von Recklinghausen c2f034f943 iov_iter: Fix iter_xarray_get_pages{,_alloc}()
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 6c77676645ad42993e0a8bdb8dafa517851a352a
Author: David Howells <dhowells@redhat.com>
Date:   Thu Jun 9 09:07:01 2022 +0100

    iov_iter: Fix iter_xarray_get_pages{,_alloc}()

    The maths at the end of iter_xarray_get_pages() to calculate the actual
    size doesn't work under some circumstances, such as when it's been asked to
    extract a partial single page.  Various terms of the equation cancel out
    and you end up with actual == offset.  The same issue exists in
    iter_xarray_get_pages_alloc().

    Fix these to just use min() to select the lesser amount from between the
    amount of page content transcribed into the buffer, minus the offset, and
    the size limit specified.

    This doesn't appear to have caused a problem yet upstream because network
    filesystems aren't getting the pages from an xarray iterator, but rather
    passing it directly to the socket, which just iterates over it.  Cachefiles
    *does* do DIO from one to/from ext4/xfs/btrfs/etc. but it always asks for
    whole pages to be written or read.

    Fixes: 7ff5062079 ("iov_iter: Add ITER_XARRAY")
    Reported-by: Jeff Layton <jlayton@kernel.org>
    Signed-off-by: David Howells <dhowells@redhat.com>
    cc: Alexander Viro <viro@zeniv.linux.org.uk>
    cc: Dominique Martinet <asmadeus@codewreck.org>
    cc: Mike Marshall <hubcap@omnibond.com>
    cc: Gao Xiang <xiang@kernel.org>
    cc: linux-afs@lists.infradead.org
    cc: v9fs-developer@lists.sourceforge.net
    cc: devel@lists.orangefs.org
    cc: linux-erofs@lists.ozlabs.org
    cc: linux-cachefs@redhat.com
    cc: linux-fsdevel@vger.kernel.org
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:12:47 -04:00
Chris von Recklinghausen e9595d1dcf lib/iov_iter.c: fix kernel-doc warnings
JIRA: https://issues.redhat.com/browse/RHEL-1848

commit 44e5599775541eb5e25d6dfb01d9abbd5ad79823
Author: Randy Dunlap <rdunlap@infradead.org>
Date:   Tue Sep 7 19:58:54 2021 -0700

    lib/iov_iter.c: fix kernel-doc warnings

    Fix all kernel-doc warnings in lib/iov_iter.c:

    lib/iov_iter.c:695: warning: Function parameter or member 'i' not described in '_copy_mc_to_iter'
    lib/iov_iter.c:695: warning: Excess function parameter 'iter' description in '_copy_mc_to_iter'
    lib/iov_iter.c:695: warning: No description found for return value of '_copy_mc_to_iter'
    lib/iov_iter.c:758: warning: Function parameter or member 'i' not described in '_copy_from_iter_flushcache'
    lib/iov_iter.c:758: warning: Excess function parameter 'iter' description in '_copy_from_iter_flushcache'
    lib/iov_iter.c:758: warning: No description found for return value of '_copy_from_iter_flushcache'

    Link: https://lkml.kernel.org/r/20210809051053.6531-1-rdunlap@infradead.org
    Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
    Cc: Al Viro <viro@zeniv.linux.org.uk>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Signed-off-by: Chris von Recklinghausen <crecklin@redhat.com>
2023-10-20 06:12:25 -04:00