lkml.org 
[lkml]   [2023]   [Mar]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v3 21/55] crypto: af_alg: Pin pages rather than ref'ing if appropriate
    Date
    Convert AF_ALG to use iov_iter_extract_pages() instead of
    iov_iter_get_pages(). This will pin pages or leave them unaltered rather
    than getting a ref on them as appropriate to the iterator.

    The pages need to be pinned for DIO-read rather than having refs taken on
    them to prevent VM copy-on-write from malfunctioning during a concurrent
    fork() (the result of the I/O would otherwise end up only visible to the
    child process and not the parent).

    Signed-off-by: David Howells <dhowells@redhat.com>
    cc: Herbert Xu <herbert@gondor.apana.org.au>
    cc: "David S. Miller" <davem@davemloft.net>
    cc: Eric Dumazet <edumazet@google.com>
    cc: Jakub Kicinski <kuba@kernel.org>
    cc: Paolo Abeni <pabeni@redhat.com>
    cc: Jens Axboe <axboe@kernel.dk>
    cc: Matthew Wilcox <willy@infradead.org>
    cc: linux-crypto@vger.kernel.org
    cc: netdev@vger.kernel.org
    ---
    crypto/af_alg.c | 10 +++++++---
    include/crypto/if_alg.h | 1 +
    2 files changed, 8 insertions(+), 3 deletions(-)

    diff --git a/crypto/af_alg.c b/crypto/af_alg.c
    index 5f7252a5b7b4..7caff10df643 100644
    --- a/crypto/af_alg.c
    +++ b/crypto/af_alg.c
    @@ -533,14 +533,17 @@ static const struct net_proto_family alg_family = {

    int af_alg_make_sg(struct af_alg_sgl *sgl, struct iov_iter *iter, int len)
    {
    + struct page **pages = sgl->pages;
    size_t off;
    ssize_t n;
    int npages, i;

    - n = iov_iter_get_pages2(iter, sgl->pages, len, ALG_MAX_PAGES, &off);
    + n = iov_iter_extract_pages(iter, &pages, len, ALG_MAX_PAGES, 0, &off);
    if (n < 0)
    return n;

    + sgl->need_unpin = iov_iter_extract_will_pin(iter);
    +
    npages = DIV_ROUND_UP(off + n, PAGE_SIZE);
    if (WARN_ON(npages == 0))
    return -EINVAL;
    @@ -573,8 +576,9 @@ void af_alg_free_sg(struct af_alg_sgl *sgl)
    {
    int i;

    - for (i = 0; i < sgl->npages; i++)
    - put_page(sgl->pages[i]);
    + if (sgl->need_unpin)
    + for (i = 0; i < sgl->npages; i++)
    + unpin_user_page(sgl->pages[i]);
    }
    EXPORT_SYMBOL_GPL(af_alg_free_sg);

    diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h
    index 7e76623f9ec3..46494b33f5bc 100644
    --- a/include/crypto/if_alg.h
    +++ b/include/crypto/if_alg.h
    @@ -59,6 +59,7 @@ struct af_alg_sgl {
    struct scatterlist sg[ALG_MAX_PAGES + 1];
    struct page *pages[ALG_MAX_PAGES];
    unsigned int npages;
    + bool need_unpin;
    };

    /* TX SGL entry */
    \
     
     \ /
      Last update: 2023-03-31 18:14    [W:8.710 / U:0.092 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site