• David Hildenbrand's avatar
    mm/gup: sanity-check with CONFIG_DEBUG_VM that anonymous pages are exclusive when (un)pinning · b6a2619c
    David Hildenbrand authored
    Let's verify when (un)pinning anonymous pages that we always deal with
    exclusive anonymous pages, which guarantees that we'll have a reliable
    PIN, meaning that we cannot end up with the GUP pin being inconsistent
    with he pages mapped into the page tables due to a COW triggered by a
    write fault.
    
    When pinning pages, after conditionally triggering GUP unsharing of
    possibly shared anonymous pages, we should always only see exclusive
    anonymous pages.  Note that anonymous pages that are mapped writable must
    be marked exclusive, otherwise we'd have a BUG.
    
    When pinning during ordinary GUP, simply add a check after our conditional
    GUP-triggered unsharing checks.  As we know exactly how the page is
    mapped, we know exactly in which page we have to check for
    PageAnonExclusive().
    
    When pinning via GUP-fast we have to be careful, because we can race with
    fork(): verify only after we made sure via the seqcount that we didn't
    race with concurrent fork() that we didn't end up pinning a possibly
    shared anonymous page.
    
    Similarly, when unpinning, verify that the pages are still marked as
    exclusive: otherwise something turned the pages possibly shared, which can
    result in random memory corruptions, which we really want to catch.
    
    With only the pinned pages at hand and not the actual page table entries
    we have to be a bit careful: hugetlb pages are always mapped via a single
    logical page table entry referencing the head page and PG_anon_exclusive
    of the head page applies.  Anon THP are a bit more complicated, because we
    might have obtained the page reference either via a PMD or a PTE --
    depending on the mapping type we either have to check PageAnonExclusive of
    the head page (PMD-mapped THP) or the tail page (PTE-mapped THP) applies:
    as we don't know and to make our life easier, check that either is set.
    
    Take care to not verify in case we're unpinning during GUP-fast because we
    detected concurrent fork(): we might stumble over an anonymous page that
    is now shared.
    
    Link: https://lkml.kernel.org/r/20220428083441.37290-18-david@redhat.comSigned-off-by: default avatarDavid Hildenbrand <david@redhat.com>
    Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
    Cc: Andrea Arcangeli <aarcange@redhat.com>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: David Rientjes <rientjes@google.com>
    Cc: Don Dutile <ddutile@redhat.com>
    Cc: Hugh Dickins <hughd@google.com>
    Cc: Jan Kara <jack@suse.cz>
    Cc: Jann Horn <jannh@google.com>
    Cc: Jason Gunthorpe <jgg@nvidia.com>
    Cc: John Hubbard <jhubbard@nvidia.com>
    Cc: Khalid Aziz <khalid.aziz@oracle.com>
    Cc: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
    Cc: Liang Zhang <zhangliang5@huawei.com>
    Cc: "Matthew Wilcox (Oracle)" <willy@infradead.org>
    Cc: Michal Hocko <mhocko@kernel.org>
    Cc: Mike Kravetz <mike.kravetz@oracle.com>
    Cc: Mike Rapoport <rppt@linux.ibm.com>
    Cc: Nadav Amit <namit@vmware.com>
    Cc: Oded Gabbay <oded.gabbay@gmail.com>
    Cc: Oleg Nesterov <oleg@redhat.com>
    Cc: Pedro Demarchi Gomes <pedrodemargomes@gmail.com>
    Cc: Peter Xu <peterx@redhat.com>
    Cc: Rik van Riel <riel@surriel.com>
    Cc: Roman Gushchin <guro@fb.com>
    Cc: Shakeel Butt <shakeelb@google.com>
    Cc: Yang Shi <shy828301@gmail.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    b6a2619c
hugetlb.c 195 KB