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]1583aa278f("mm: mremap: unlink anon_vmas when mremap with MREMAP_DONTUNMAP success") [2]ee8ab1903e("mm: rmap: explicitly reset vma->anon_vma in unlink_anon_vmas()") Bug: 257443051 Change-Id: I4e7611137f4a49c94bfe73532b4b06cbb0d2405b Signed-off-by: Suren Baghdasaryan <surenb@google.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user