diff mbox series

mm/madvise: fix potential pte_unmap_unlock pte error

Message ID 20220416081416.23304-1-linmiaohe@huawei.com (mailing list archive)
State New
Headers show
Series mm/madvise: fix potential pte_unmap_unlock pte error | expand

Commit Message

Miaohe Lin April 16, 2022, 8:14 a.m. UTC
We can't assume pte_offset_map_lock will return same orig_pte value. So
it's necessary to reacquire the orig_pte or pte_unmap_unlock will unmap
the stale pte.

Fixes: 9c276cc65a58 ("mm: introduce MADV_COLD")
Fixes: 854e9ed09ded ("mm: support madvise(MADV_FREE)")
Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
---
 mm/madvise.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

Comments

Andrew Morton April 19, 2022, 4:09 a.m. UTC | #1
On Sat, 16 Apr 2022 16:14:16 +0800 Miaohe Lin <linmiaohe@huawei.com> wrote:

> We can't assume pte_offset_map_lock will return same orig_pte value. So
> it's necessary to reacquire the orig_pte or pte_unmap_unlock will unmap
> the stale pte.

hm, where did you learn this info about pte_offset_map_lock()?

I assume this is from code inspection only?  No observed runtime failures?
Miaohe Lin April 19, 2022, 6:35 a.m. UTC | #2
On 2022/4/19 12:09, Andrew Morton wrote:
> On Sat, 16 Apr 2022 16:14:16 +0800 Miaohe Lin <linmiaohe@huawei.com> wrote:
> 
>> We can't assume pte_offset_map_lock will return same orig_pte value. So
>> it's necessary to reacquire the orig_pte or pte_unmap_unlock will unmap
>> the stale pte.
> 
> hm, where did you learn this info about pte_offset_map_lock()?
> 
> I assume this is from code inspection only?  No observed runtime failures?

Yes, this is from code inspection. There is no observed runtime failures now due
to the race window being really small. And this becomes noop in !CONFIG_HIGHMEM
system (CONFIG_HIGHMEM system should be rare now). But this could be triggered theoretically.

Thanks!

> .
>
diff mbox series

Patch

diff --git a/mm/madvise.c b/mm/madvise.c
index ec03a76244b7..4d6592488b51 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -437,12 +437,12 @@  static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
 			if (split_huge_page(page)) {
 				unlock_page(page);
 				put_page(page);
-				pte_offset_map_lock(mm, pmd, addr, &ptl);
+				orig_pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
 				break;
 			}
 			unlock_page(page);
 			put_page(page);
-			pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+			orig_pte = pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
 			pte--;
 			addr -= PAGE_SIZE;
 			continue;
@@ -653,12 +653,12 @@  static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
 			if (split_huge_page(page)) {
 				unlock_page(page);
 				put_page(page);
-				pte_offset_map_lock(mm, pmd, addr, &ptl);
+				orig_pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
 				goto out;
 			}
 			unlock_page(page);
 			put_page(page);
-			pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
+			orig_pte = pte = pte_offset_map_lock(mm, pmd, addr, &ptl);
 			pte--;
 			addr -= PAGE_SIZE;
 			continue;