aboutsummaryrefslogtreecommitdiffstats
path: root/queue-6.8/userfaultfd-change-src_folio-after-ensuring-it-s-unpinned-in-uffdio_move.patch
diff options
context:
space:
mode:
Diffstat (limited to 'queue-6.8/userfaultfd-change-src_folio-after-ensuring-it-s-unpinned-in-uffdio_move.patch')
-rw-r--r--queue-6.8/userfaultfd-change-src_folio-after-ensuring-it-s-unpinned-in-uffdio_move.patch57
1 files changed, 57 insertions, 0 deletions
diff --git a/queue-6.8/userfaultfd-change-src_folio-after-ensuring-it-s-unpinned-in-uffdio_move.patch b/queue-6.8/userfaultfd-change-src_folio-after-ensuring-it-s-unpinned-in-uffdio_move.patch
new file mode 100644
index 0000000000..846ae47680
--- /dev/null
+++ b/queue-6.8/userfaultfd-change-src_folio-after-ensuring-it-s-unpinned-in-uffdio_move.patch
@@ -0,0 +1,57 @@
+From c0205eaf3af9f5db14d4b5ee4abacf4a583c3c50 Mon Sep 17 00:00:00 2001
+From: Lokesh Gidra <lokeshgidra@google.com>
+Date: Thu, 4 Apr 2024 10:17:26 -0700
+Subject: userfaultfd: change src_folio after ensuring it's unpinned in UFFDIO_MOVE
+
+From: Lokesh Gidra <lokeshgidra@google.com>
+
+commit c0205eaf3af9f5db14d4b5ee4abacf4a583c3c50 upstream.
+
+Commit d7a08838ab74 ("mm: userfaultfd: fix unexpected change to src_folio
+when UFFDIO_MOVE fails") moved the src_folio->{mapping, index} changing to
+after clearing the page-table and ensuring that it's not pinned. This
+avoids failure of swapout+migration and possibly memory corruption.
+
+However, the commit missed fixing it in the huge-page case.
+
+Link: https://lkml.kernel.org/r/20240404171726.2302435-1-lokeshgidra@google.com
+Fixes: adef440691ba ("userfaultfd: UFFDIO_MOVE uABI")
+Signed-off-by: Lokesh Gidra <lokeshgidra@google.com>
+Acked-by: David Hildenbrand <david@redhat.com>
+Cc: Andrea Arcangeli <aarcange@redhat.com>
+Cc: Kalesh Singh <kaleshsingh@google.com>
+Cc: Lokesh Gidra <lokeshgidra@google.com>
+Cc: Nicolas Geoffray <ngeoffray@google.com>
+Cc: Peter Xu <peterx@redhat.com>
+Cc: Qi Zheng <zhengqi.arch@bytedance.com>
+Cc: Matthew Wilcox <willy@infradead.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Lokesh Gidra <lokeshgidra@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/huge_memory.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/mm/huge_memory.c
++++ b/mm/huge_memory.c
+@@ -2244,9 +2244,6 @@ int move_pages_huge_pmd(struct mm_struct
+ goto unlock_ptls;
+ }
+
+- folio_move_anon_rmap(src_folio, dst_vma);
+- WRITE_ONCE(src_folio->index, linear_page_index(dst_vma, dst_addr));
+-
+ src_pmdval = pmdp_huge_clear_flush(src_vma, src_addr, src_pmd);
+ /* Folio got pinned from under us. Put it back and fail the move. */
+ if (folio_maybe_dma_pinned(src_folio)) {
+@@ -2255,6 +2252,9 @@ int move_pages_huge_pmd(struct mm_struct
+ goto unlock_ptls;
+ }
+
++ folio_move_anon_rmap(src_folio, dst_vma);
++ WRITE_ONCE(src_folio->index, linear_page_index(dst_vma, dst_addr));
++
+ _dst_pmd = mk_huge_pmd(&src_folio->page, dst_vma->vm_page_prot);
+ /* Follow mremap() behavior and treat the entry dirty after the move */
+ _dst_pmd = pmd_mkwrite(pmd_mkdirty(_dst_pmd), dst_vma);