From 531f65ae673826d3c42e8724f74d3a8de22140fa Mon Sep 17 00:00:00 2001 From: Patrick Daly Date: Fri, 18 Oct 2019 19:55:49 -0700 Subject: [PATCH] ANDROID: mm: Fix sleeping while atomic during speculative page fault A speculative page fault may race with a call to free_pagetables. If free_pagetables is called first, *(vmf->pmd) may be empty. __might_sleep() __alloc_pages_nodemask() pte_alloc_one(inline) __pte_alloc() pte_alloc_one_map(inline) alloc_set_pte() filemap_map_pages() do_fault_around(inline) do_read_fault(inline) do_fault(inline) handle_pte_fault() mem_cgroup_exit_user_fault(inline) __handle_speculative_fault() do_page_fault() As filemap_map_pages() holds an rcu_lock(), this triggers a sleeping-while-atomic BUG(). As free_pagetables has already been called, it is also a memory leak. Fix this by skipping to pte_map_lock() to allow spf to detect that the vma has changed, and a normal page fault should be taken instead. Change-Id: I121ca4be99c908656db3a1dc88cfb3b64f01e2fb Bug: 161210518 Signed-off-by: Patrick Daly Signed-off-by: Vinayak Menon --- mm/memory.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/memory.c b/mm/memory.c index 3c6d065b93fb..94f5be19d31d 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3877,7 +3877,7 @@ static vm_fault_t pte_alloc_one_map(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; - if (!pmd_none(*vmf->pmd)) + if (!pmd_none(*vmf->pmd) || (vmf->flags & FAULT_FLAG_SPECULATIVE)) goto map_pte; if (vmf->prealloc_pte) { vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd);