From 50d2b75b860a6495aac6127a27f75b309e91b689 Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Mon, 21 Nov 2022 17:53:27 -0800 Subject: [PATCH] ANDROID: mm: preserve vma->anon_vma after MREMAP_DONTUNMAP for SPF The optimizations [1] and [2] to reset vma->anon_vma during MREMAP_DONTUNMAP can affect speculative page fault handler. If vma->anon_vma reset happens after do_anonymous_page verified no changes to the vma and obtained the ptl lock but before it calls page_add_new_anon_rmap() then __page_set_anon_rmap() will stumble on BUG_ON(!anon_vma). Disable these optimizations if SPF is enabled to avoid such situations. As a result the reverse map walk will consider the old VMA as it did before these optimizations were introduced. [1] 1583aa278f5f ("mm: mremap: unlink anon_vmas when mremap with MREMAP_DONTUNMAP success") [2] ee8ab1903e3d ("mm: rmap: explicitly reset vma->anon_vma in unlink_anon_vmas()") Bug: 257443051 Change-Id: I4e7611137f4a49c94bfe73532b4b06cbb0d2405b Signed-off-by: Suren Baghdasaryan --- mm/mremap.c | 2 ++ mm/rmap.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/mm/mremap.c b/mm/mremap.c index a46c810407a8..6c87fc859cdc 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -683,6 +683,7 @@ static unsigned long move_vma(struct vm_area_struct *vma, /* We always clear VM_LOCKED[ONFAULT] on the old vma */ vma->vm_flags &= VM_LOCKED_CLEAR_MASK; +#ifndef CONFIG_SPECULATIVE_PAGE_FAULT /* * anon_vma links of the old vma is no longer needed after its page * table has been moved. @@ -690,6 +691,7 @@ static unsigned long move_vma(struct vm_area_struct *vma, if (new_vma != vma && vma->vm_start == old_addr && vma->vm_end == (old_addr + old_len)) unlink_anon_vmas(vma); +#endif /* Because we won't unmap we don't need to touch locked_vm */ return new_addr; diff --git a/mm/rmap.c b/mm/rmap.c index 440085afac6e..df89881c7100 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -422,11 +422,13 @@ void unlink_anon_vmas(struct vm_area_struct *vma) if (vma->anon_vma) { vma->anon_vma->num_active_vmas--; +#ifndef CONFIG_SPECULATIVE_PAGE_FAULT /* * vma would still be needed after unlink, and anon_vma will be prepared * when handle fault. */ vma->anon_vma = NULL; +#endif } unlock_anon_vma_root(root);