btrfs: send: avoid unaligned encoded writes when attempting to clone range
[platform/kernel/linux-rpi.git] / mm / mprotect.c
index e7a4431..ed18dc4 100644 (file)
@@ -94,7 +94,7 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
 
                                /* Also skip shared copy-on-write pages */
                                if (is_cow_mapping(vma->vm_flags) &&
-                                   page_mapcount(page) != 1)
+                                   page_count(page) != 1)
                                        continue;
 
                                /*
@@ -143,26 +143,36 @@ static unsigned long change_pte_range(struct vm_area_struct *vma, pmd_t *pmd,
                        swp_entry_t entry = pte_to_swp_entry(oldpte);
                        pte_t newpte;
 
-                       if (is_write_migration_entry(entry)) {
+                       if (is_writable_migration_entry(entry)) {
                                /*
                                 * A protection check is difficult so
                                 * just be safe and disable write
                                 */
-                               make_migration_entry_read(&entry);
+                               entry = make_readable_migration_entry(
+                                                       swp_offset(entry));
                                newpte = swp_entry_to_pte(entry);
                                if (pte_swp_soft_dirty(oldpte))
                                        newpte = pte_swp_mksoft_dirty(newpte);
                                if (pte_swp_uffd_wp(oldpte))
                                        newpte = pte_swp_mkuffd_wp(newpte);
-                       } else if (is_write_device_private_entry(entry)) {
+                       } else if (is_writable_device_private_entry(entry)) {
                                /*
                                 * We do not preserve soft-dirtiness. See
                                 * copy_one_pte() for explanation.
                                 */
-                               make_device_private_entry_read(&entry);
+                               entry = make_readable_device_private_entry(
+                                                       swp_offset(entry));
                                newpte = swp_entry_to_pte(entry);
                                if (pte_swp_uffd_wp(oldpte))
                                        newpte = pte_swp_mkuffd_wp(newpte);
+                       } else if (is_writable_device_exclusive_entry(entry)) {
+                               entry = make_readable_device_exclusive_entry(
+                                                       swp_offset(entry));
+                               newpte = swp_entry_to_pte(entry);
+                               if (pte_swp_soft_dirty(oldpte))
+                                       newpte = pte_swp_mksoft_dirty(newpte);
+                               if (pte_swp_uffd_wp(oldpte))
+                                       newpte = pte_swp_mkuffd_wp(newpte);
                        } else {
                                newpte = oldpte;
                        }