The softleaf changes exposed a BUG in remove_rmap_pmd() where the
migration entry was being overridden when the folio is device private.

Use scope local entry for creating the device private pmde. Make the
pmde writable if the migration entry is writable by moving the check
softleaf_is_migration_write() prior to creating the device private entry.

Cc: Andrew Morton <[email protected]>
Cc: David Hildenbrand <[email protected]>
Cc: Zi Yan <[email protected]>
Cc: Joshua Hahn <[email protected]>
Cc: Rakie Kim <[email protected]>
Cc: Byungchul Park <[email protected]>
Cc: Gregory Price <[email protected]>
Cc: Ying Huang <[email protected]>
Cc: Alistair Popple <[email protected]>
Cc: Oscar Salvador <[email protected]>
Cc: Lorenzo Stoakes <[email protected]>
Cc: Baolin Wang <[email protected]>
Cc: "Liam R. Howlett" <[email protected]>
Cc: Nico Pache <[email protected]>
Cc: Ryan Roberts <[email protected]>
Cc: Dev Jain <[email protected]>
Cc: Barry Song <[email protected]>
Cc: Lyude Paul <[email protected]>
Cc: Danilo Krummrich <[email protected]>
Cc: David Airlie <[email protected]>
Cc: Simona Vetter <[email protected]>
Cc: Ralph Campbell <[email protected]>
Cc: Mika Penttilä <[email protected]>
Cc: Matthew Brost <[email protected]>
Cc: Francois Dugast <[email protected]>

Signed-off-by: Balbir Singh <[email protected]>
---
 mm/huge_memory.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 0184cd915f44..e4dadcb9e90b 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -4850,7 +4850,12 @@ void remove_migration_pmd(struct page_vma_mapped_walk 
*pvmw, struct page *new)
        folio_get(folio);
        pmde = folio_mk_pmd(folio, READ_ONCE(vma->vm_page_prot));
 
+       if (softleaf_is_migration_write(entry))
+               pmde = pmd_mkwrite(pmde, vma);
+
        if (folio_is_device_private(folio)) {
+               swp_entry_t entry;
+
                if (pmd_write(pmde))
                        entry = make_writable_device_private_entry(
                                                        page_to_pfn(new));
@@ -4862,8 +4867,6 @@ void remove_migration_pmd(struct page_vma_mapped_walk 
*pvmw, struct page *new)
 
        if (pmd_swp_soft_dirty(*pvmw->pmd))
                pmde = pmd_mksoft_dirty(pmde);
-       if (softleaf_is_migration_write(entry))
-               pmde = pmd_mkwrite(pmde, vma);
        if (pmd_swp_uffd_wp(*pvmw->pmd))
                pmde = pmd_mkuffd_wp(pmde);
        if (!softleaf_is_migration_young(entry))
-- 
2.51.1

Reply via email to