lkml.org 
[lkml]   [2020]   [Oct]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.9 307/757] misc: mic: scif: Fix error handling path
    Date
    From: Souptick Joarder <jrdr.linux@gmail.com>

    [ Upstream commit a81072a9c0ae734b7889929b0bc070fe3f353f0e ]

    Inside __scif_pin_pages(), when map_flags != SCIF_MAP_KERNEL it
    will call pin_user_pages_fast() to map nr_pages. However,
    pin_user_pages_fast() might fail with a return value -ERRNO.

    The return value is stored in pinned_pages->nr_pages. which in
    turn is passed to unpin_user_pages(), which expects
    pinned_pages->nr_pages >=0, else disaster.

    Fix this by assigning pinned_pages->nr_pages to 0 if
    pin_user_pages_fast() returns -ERRNO.

    Fixes: ba612aa8b487 ("misc: mic: SCIF memory registration and unregistration")
    Cc: John Hubbard <jhubbard@nvidia.com>
    Cc: Ira Weiny <ira.weiny@intel.com>
    Cc: Dan Carpenter <dan.carpenter@oracle.com>
    Reviewed-by: John Hubbard <jhubbard@nvidia.com>
    Signed-off-by: Souptick Joarder <jrdr.linux@gmail.com>
    Link: https://lore.kernel.org/r/1600570295-29546-1-git-send-email-jrdr.linux@gmail.com
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/misc/mic/scif/scif_rma.c | 4 ++--
    1 file changed, 2 insertions(+), 2 deletions(-)

    diff --git a/drivers/misc/mic/scif/scif_rma.c b/drivers/misc/mic/scif/scif_rma.c
    index 2da3b474f4863..18fb9d8b8a4b5 100644
    --- a/drivers/misc/mic/scif/scif_rma.c
    +++ b/drivers/misc/mic/scif/scif_rma.c
    @@ -1392,6 +1392,8 @@ int __scif_pin_pages(void *addr, size_t len, int *out_prot,
    (prot & SCIF_PROT_WRITE) ? FOLL_WRITE : 0,
    pinned_pages->pages);
    if (nr_pages != pinned_pages->nr_pages) {
    + if (pinned_pages->nr_pages < 0)
    + pinned_pages->nr_pages = 0;
    if (try_upgrade) {
    if (ulimit)
    __scif_dec_pinned_vm_lock(mm, nr_pages);
    @@ -1408,7 +1410,6 @@ int __scif_pin_pages(void *addr, size_t len, int *out_prot,

    if (pinned_pages->nr_pages < nr_pages) {
    err = -EFAULT;
    - pinned_pages->nr_pages = nr_pages;
    goto dec_pinned;
    }

    @@ -1421,7 +1422,6 @@ int __scif_pin_pages(void *addr, size_t len, int *out_prot,
    __scif_dec_pinned_vm_lock(mm, nr_pages);
    /* Something went wrong! Rollback */
    error_unmap:
    - pinned_pages->nr_pages = nr_pages;
    scif_destroy_pinned_pages(pinned_pages);
    *pages = NULL;
    dev_dbg(scif_info.mdev.this_device,
    --
    2.25.1


    \
     
     \ /
      Last update: 2020-10-27 17:40    [W:3.095 / U:0.128 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site