From 1169f70f8f15ea4378ecadb9baba8791824c8b2a Mon Sep 17 00:00:00 2001 From: Suren Baghdasaryan Date: Fri, 18 Nov 2022 15:05:48 -0800 Subject: [PATCH] ANDROID: mm: skip pte_alloc during speculative page fault Speculative page fault checks pmd to be valid before starting to handle the page fault and pte_alloc() should do nothing if pmd stays valid. If pmd gets changed during speculative page fault, we will detect the change later and retry with mmap_lock. Therefore pte_alloc() can be safely skipped and this prevents the racy pmd_lock() call which can access pmd->ptl after pmd was cleared. Bug: 257443051 Change-Id: Iec57df5530dba6e0e0bdf9f7500f910851c3d3fd Signed-off-by: Suren Baghdasaryan --- mm/memory.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mm/memory.c b/mm/memory.c index 1b768d29f9d2..639b9b09e36e 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3858,6 +3858,10 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf) if (vmf->vma_flags & VM_SHARED) return VM_FAULT_SIGBUS; + /* Do not check unstable pmd, if it's changed will retry later */ + if (vmf->flags & FAULT_FLAG_SPECULATIVE) + goto skip_pmd_checks; + /* * Use pte_alloc() instead of pte_alloc_map(). We can't run * pte_offset_map() on pmds where a huge pmd might be created @@ -3875,6 +3879,7 @@ static vm_fault_t do_anonymous_page(struct vm_fault *vmf) if (unlikely(pmd_trans_unstable(vmf->pmd))) return 0; +skip_pmd_checks: /* Use the zero-page for reads */ if (!(vmf->flags & FAULT_FLAG_WRITE) && !mm_forbids_zeropage(vma->vm_mm)) {