FAILED: patch "[PATCH] mm: mempolicy: fix potential pte_unmap_unlock pte error" failed to apply to 4.14-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 4.14-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 3f08842098e842c51e3b97d0dcdebf810b32558e Mon Sep 17 00:00:00 2001
From: Shijie Luo <[email protected]>
Date: Sun, 1 Nov 2020 17:07:40 -0800
Subject: [PATCH] mm: mempolicy: fix potential pte_unmap_unlock pte error
When flags in queue_pages_pte_range don't have MPOL_MF_MOVE or MPOL_MF_MOVE_ALL bits, code breaks and passing origin pte - 1 to pte_unmap_unlock seems like not a good idea.
queue_pages_pte_range can run in MPOL_MF_MOVE_ALL mode which doesn't migrate misplaced pages but returns with EIO when encountering such a page. Since commit a7f40cfe3b7a ("mm: mempolicy: make mbind() return -EIO when MPOL_MF_STRICT is specified") and early break on the first pte in the range results in pte_unmap_unlock on an underflow pte. This can lead to lockups later on when somebody tries to lock the pte resp. page_table_lock again..
mm/mempolicy.c +3 -3
@@ -525,7 +525,7 @@ static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr,unsigned long flags = qp->flags;int ret;bool has_unmovable = false; -pte_t *pte; +pte_t *pte, *mapped_pte;spinlock_t *ptl; ptl =pmd_trans_huge_lock (pmd, vma);
@@ -539,7 +539,7 @@ static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr,if (pmd_trans_unstable (pmd))return 0 ; - pte =pte_offset_map_lock (walk->mm, pmd, addr, &ptl); + mapped_pte = pte =pte_offset_map_lock (walk->mm, pmd, addr, &ptl);for (; addr != end; pte++, addr +=PAGE_SIZE ) {if (!pte_present (*pte))continue ;
@@ -571,7 +571,7 @@ static int queue_pages_pte_range(pmd_t *pmd, unsigned long addr, }else break ; } -pte_unmap_unlock (pte -1 , ptl); +pte_unmap_unlock (mapped_pte, ptl);cond_resched ();if (has_unmovable)