mm: fix NULL pointer dereference in wp_page_reuse()
[linux-2.6-microblaze.git] / mm / rmap.c
index 5bcb334..746c05a 100644 (file)
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -1899,8 +1899,23 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
                /* Unexpected PMD-mapped THP? */
                VM_BUG_ON_FOLIO(!pvmw.pte, folio);
 
-               subpage = folio_page(folio,
-                               pte_pfn(*pvmw.pte) - folio_pfn(folio));
+               if (folio_is_zone_device(folio)) {
+                       /*
+                        * Our PTE is a non-present device exclusive entry and
+                        * calculating the subpage as for the common case would
+                        * result in an invalid pointer.
+                        *
+                        * Since only PAGE_SIZE pages can currently be
+                        * migrated, just set it to page. This will need to be
+                        * changed when hugepage migrations to device private
+                        * memory are supported.
+                        */
+                       VM_BUG_ON_FOLIO(folio_nr_pages(folio) > 1, folio);
+                       subpage = &folio->page;
+               } else {
+                       subpage = folio_page(folio,
+                                       pte_pfn(*pvmw.pte) - folio_pfn(folio));
+               }
                address = pvmw.address;
                anon_exclusive = folio_test_anon(folio) &&
                                 PageAnonExclusive(subpage);
@@ -1993,15 +2008,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
                        /*
                         * No need to invalidate here it will synchronize on
                         * against the special swap migration pte.
-                        *
-                        * The assignment to subpage above was computed from a
-                        * swap PTE which results in an invalid pointer.
-                        * Since only PAGE_SIZE pages can currently be
-                        * migrated, just set it to page. This will need to be
-                        * changed when hugepage migrations to device private
-                        * memory are supported.
                         */
-                       subpage = &folio->page;
                } else if (PageHWPoison(subpage)) {
                        pteval = swp_entry_to_pte(make_hwpoison_entry(subpage));
                        if (folio_test_hugetlb(folio)) {