• Axel Rasmussen's avatar
    mm: userfaultfd: fix UFFDIO_CONTINUE on fallocated shmem pages · 73f37dbc
    Axel Rasmussen authored
    When fallocate() is used on a shmem file, the pages we allocate can end up
    with !PageUptodate.
    
    Since UFFDIO_CONTINUE tries to find the existing page the user wants to
    map with SGP_READ, we would fail to find such a page, since
    shmem_getpage_gfp returns with a "NULL" pagep for SGP_READ if it discovers
    !PageUptodate.  As a result, UFFDIO_CONTINUE returns -EFAULT, as it would
    do if the page wasn't found in the page cache at all.
    
    This isn't the intended behavior.  UFFDIO_CONTINUE is just trying to find
    if a page exists, and doesn't care whether it still needs to be cleared or
    not.  So, instead of SGP_READ, pass in SGP_NOALLOC.  This is the same,
    except for one critical difference: in the !PageUptodate case, SGP_NOALLOC
    will clear the page and then return it.  With this change, UFFDIO_CONTINUE
    works properly (succeeds) on a shmem file which has been fallocated, but
    otherwise not modified.
    
    Link: https://lkml.kernel.org/r/20220610173812.1768919-1-axelrasmussen@google.com
    Fixes: 15313257 ("userfaultfd/shmem: support UFFDIO_CONTINUE for shmem")
    Signed-off-by: default avatarAxel Rasmussen <axelrasmussen@google.com>
    Acked-by: default avatarPeter Xu <peterx@redhat.com>
    Cc: Hugh Dickins <hughd@google.com>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    73f37dbc
userfaultfd.c 18.6 KB