]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - mm/page_vma_mapped.c
ARM: dts: sun8i: Add basic dtsi file for Allwinner R40
[mirror_ubuntu-bionic-kernel.git] / mm / page_vma_mapped.c
index 8ec6ba230bb9dabba967489f0ba8f15ca61b8806..6a03946469a99eb535851194f519893a5e8a2d11 100644 (file)
@@ -48,6 +48,7 @@ static bool check_pte(struct page_vma_mapped_walk *pvmw)
                if (!is_swap_pte(*pvmw->pte))
                        return false;
                entry = pte_to_swp_entry(*pvmw->pte);
+
                if (!is_migration_entry(entry))
                        return false;
                if (migration_entry_to_page(entry) - pvmw->page >=
@@ -60,6 +61,15 @@ static bool check_pte(struct page_vma_mapped_walk *pvmw)
                WARN_ON_ONCE(1);
 #endif
        } else {
+               if (is_swap_pte(*pvmw->pte)) {
+                       swp_entry_t entry;
+
+                       entry = pte_to_swp_entry(*pvmw->pte);
+                       if (is_device_private_entry(entry) &&
+                           device_private_entry_to_page(entry) == pvmw->page)
+                               return true;
+               }
+
                if (!pte_present(*pvmw->pte))
                        return false;
 
@@ -138,16 +148,28 @@ restart:
        if (!pud_present(*pud))
                return false;
        pvmw->pmd = pmd_offset(pud, pvmw->address);
-       if (pmd_trans_huge(*pvmw->pmd)) {
+       if (pmd_trans_huge(*pvmw->pmd) || is_pmd_migration_entry(*pvmw->pmd)) {
                pvmw->ptl = pmd_lock(mm, pvmw->pmd);
-               if (!pmd_present(*pvmw->pmd))
-                       return not_found(pvmw);
                if (likely(pmd_trans_huge(*pvmw->pmd))) {
                        if (pvmw->flags & PVMW_MIGRATION)
                                return not_found(pvmw);
                        if (pmd_page(*pvmw->pmd) != page)
                                return not_found(pvmw);
                        return true;
+               } else if (!pmd_present(*pvmw->pmd)) {
+                       if (thp_migration_supported()) {
+                               if (!(pvmw->flags & PVMW_MIGRATION))
+                                       return not_found(pvmw);
+                               if (is_migration_entry(pmd_to_swp_entry(*pvmw->pmd))) {
+                                       swp_entry_t entry = pmd_to_swp_entry(*pvmw->pmd);
+
+                                       if (migration_entry_to_page(entry) != page)
+                                               return not_found(pvmw);
+                                       return true;
+                               }
+                       } else
+                               WARN_ONCE(1, "Non present huge pmd without pmd migration enabled!");
+                       return not_found(pvmw);
                } else {
                        /* THP pmd was split under us: handle on pte level */
                        spin_unlock(pvmw->ptl);