From: Zack Rusin <zackr@xxxxxxxxxx> Write page faults on last references might not have a valid page anymore. wp_page_reuse has always dealt with that scenario by making sure the page isn't null (or the reference was shared) before doing anything with it. Recently added checks in VM_BUG_ON (enabled by the CONFIG_DEBUG_VM option) use PageAnon helpers which assume the passed page is never null, before making sure there is a valid page to work with. Move the VM_BUG_ON, which unconditionally uses the page, after the code that checks that we have a valid one. Fixes a kernel oops, which is easy to reproduce with 3D apps on arm64 and x86 on kernels with CONFIG_DEBUG_VM set: Unable to handle kernel paging request at virtual address dfff800000000001 KASAN: null-ptr-deref in range [0x0000000000000008-0x000000000000000f] Mem abort info: ESR = 0x0000000096000004 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x04: level 0 translation fault Data abort info: ISV = 0, ISS = 0x00000004 CM = 0, WnR = 0 [dfff800000000001] address between user and kernel address ranges Internal error: Oops: 96000004 [#1] SMP CPU: 0 PID: 2396 Comm: Xwayland Tainted: G U 5.19.0-rc2-vmwgfx #28 Hardware name: VMware, Inc. VMware20,1/VBSA, BIOS VMW201.00V.20138482.BA64.2207201941 07/20/2022 pstate: 10400005 (nzcV daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : _compound_head+0x24/0xd0 lr : wp_page_reuse+0x8c/0x544 sp : ffff800013637aa0 x29: ffff800013637aa0 x28: ffff00002a28b730 x27: ffff800013637cc8 x26: 0000000000000000 x25: ffff800013637d00 x24: ffff00000c742168 x23: 1ffff000026c6fa0 x22: ffff000013ce59a0 x21: ffff00002a28b730 x20: 0000000000000000 x19: 0000000000000000 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000 x14: 1ffff000026c6f22 x13: 65676170206c6c75 x12: ffff600019dc772f x11: 1fffe00019dc772e x10: ffff600019dc772e x9 : ffff8000085b1a78 x8 : ffff0000cee3b977 x7 : 0000000000000001 x6 : ffff600019dc772e x5 : ffff0000cee3b970 x4 : ffff600019dc772f x3 : 1ffff000026c6f99 x2 : 0000000000000001 x1 : dfff800000000000 x0 : 0000000000000008 Call trace: _compound_head+0x24/0xd0 wp_page_reuse+0x8c/0x544 finish_mkwrite_fault+0x1a0/0x274 do_wp_page+0x6cc/0x1000 __handle_mm_fault+0xdc8/0x2620 handle_mm_fault+0x21c/0x530 do_page_fault+0x250/0xa40 do_mem_abort+0x78/0x1b4 el0_da+0x80/0x1c0 el0t_64_sync_handler+0xf8/0x140 el0t_64_sync+0x1a0/0x1a4 Code: aa0003f3 91002000 f2fbffe1 d343fc02 (38e16841) ---[ end trace 0000000000000000 ]--- Fixes: 6c287605fd56 ("mm: remember exclusively mapped anonymous pages with PG_anon_exclusive") Signed-off-by: Zack Rusin <zackr@xxxxxxxxxx> Cc: David Hildenbrand <david@xxxxxxxxxx> Cc: Vlastimil Babka <vbabka@xxxxxxx> Cc: Andrea Arcangeli <aarcange@xxxxxxxxxx> Cc: Christoph Hellwig <hch@xxxxxx> Cc: David Rientjes <rientjes@xxxxxxxxxx> Cc: Don Dutile <ddutile@xxxxxxxxxx> Cc: Hugh Dickins <hughd@xxxxxxxxxx> Cc: Jan Kara <jack@xxxxxxx> Cc: Jann Horn <jannh@xxxxxxxxxx> Cc: Jason Gunthorpe <jgg@xxxxxxxxxx> Cc: John Hubbard <jhubbard@xxxxxxxxxx> Cc: Khalid Aziz <khalid.aziz@xxxxxxxxxx> Cc: "Kirill A. Shutemov" <kirill.shutemov@xxxxxxxxxxxxxxx> Cc: Liang Zhang <zhangliang5@xxxxxxxxxx> Cc: "Matthew Wilcox (Oracle)" <willy@xxxxxxxxxxxxx> Cc: Michal Hocko <mhocko@xxxxxxxxxx> Cc: Mike Kravetz <mike.kravetz@xxxxxxxxxx> Cc: Mike Rapoport <rppt@xxxxxxxxxxxxx> Cc: Nadav Amit <namit@xxxxxxxxxx> Cc: Oded Gabbay <oded.gabbay@xxxxxxxxx> Cc: Oleg Nesterov <oleg@xxxxxxxxxx> Cc: Pedro Demarchi Gomes <pedrodemargomes@xxxxxxxxx> Cc: Peter Xu <peterx@xxxxxxxxxx> Cc: Rik van Riel <riel@xxxxxxxxxxx> Cc: Roman Gushchin <guro@xxxxxx> Cc: Shakeel Butt <shakeelb@xxxxxxxxxx> Cc: Yang Shi <shy828301@xxxxxxxxx> Cc: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Cc: Muchun Song <songmuchun@xxxxxxxxxxxxx> Cc: Minchan Kim <minchan@xxxxxxxxxx> Cc: David Howells <dhowells@xxxxxxxxxx> Cc: Miaohe Lin <linmiaohe@xxxxxxxxxx> Cc: NeilBrown <neilb@xxxxxxx> Cc: Suren Baghdasaryan <surenb@xxxxxxxxxx> Cc: Hongchen Zhang <zhanghongchen@xxxxxxxxxxx> Cc: linux-mm@xxxxxxxxx --- mm/memory.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mm/memory.c b/mm/memory.c index 7a089145cad4..3e28c652cf60 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3043,15 +3043,16 @@ static inline void wp_page_reuse(struct vm_fault *vmf) pte_t entry; VM_BUG_ON(!(vmf->flags & FAULT_FLAG_WRITE)); - VM_BUG_ON(PageAnon(page) && !PageAnonExclusive(page)); /* * Clear the pages cpupid information as the existing * information potentially belongs to a now completely * unrelated process. */ - if (page) + if (page) { + VM_BUG_ON(PageAnon(page) && !PageAnonExclusive(page)); page_cpupid_xchg_last(page, (1 << LAST_CPUPID_SHIFT) - 1); + } flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte)); entry = pte_mkyoung(vmf->orig_pte); -- 2.34.1