Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8b8dd3be authored by Patrick Daly's avatar Patrick Daly
Browse files

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
Signed-off-by: default avatarPatrick Daly <pdaly@codeaurora.org>
parent 30d171ac
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -3524,7 +3524,7 @@ static vm_fault_t pte_alloc_one_map(struct vm_fault *vmf)
{
{
	struct vm_area_struct *vma = vmf->vma;
	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;
		goto map_pte;
	if (vmf->prealloc_pte) {
	if (vmf->prealloc_pte) {
		vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd);
		vmf->ptl = pmd_lock(vma->vm_mm, vmf->pmd);