}
 #endif
 
-#ifndef mkold_ptes
-/**
- * mkold_ptes - Mark PTEs that map consecutive pages of the same folio as old.
- * @vma: VMA the pages are mapped into.
- * @addr: Address the first page is mapped at.
- * @ptep: Page table pointer for the first entry.
- * @nr: Number of entries to mark old.
- *
- * May be overridden by the architecture; otherwise, implemented as a simple
- * loop over ptep_test_and_clear_young().
- *
- * Note that PTE bits in the PTE range besides the PFN can differ. For example,
- * some PTEs might be write-protected.
- *
- * Context: The caller holds the page table lock.  The PTEs map consecutive
- * pages that belong to the same folio.  The PTEs are all in the same PMD.
- */
-static inline void mkold_ptes(struct vm_area_struct *vma, unsigned long addr,
-               pte_t *ptep, unsigned int nr)
-{
-       for (;;) {
-               ptep_test_and_clear_young(vma, addr, ptep);
-               if (--nr == 0)
-                       break;
-               ptep++;
-               addr += PAGE_SIZE;
-       }
-}
-#endif
-
 #ifndef __HAVE_ARCH_PMDP_TEST_AND_CLEAR_YOUNG
 #if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_ARCH_HAS_NONLEAF_PMD_YOUNG)
 static inline int pmdp_test_and_clear_young(struct vm_area_struct *vma,
 }
 #endif
 
+#ifndef clear_young_dirty_ptes
+/**
+ * clear_young_dirty_ptes - Mark PTEs that map consecutive pages of the
+ *             same folio as old/clean.
+ * @mm: Address space the pages are mapped into.
+ * @addr: Address the first page is mapped at.
+ * @ptep: Page table pointer for the first entry.
+ * @nr: Number of entries to mark old/clean.
+ * @flags: Flags to modify the PTE batch semantics.
+ *
+ * May be overridden by the architecture; otherwise, implemented by
+ * get_and_clear/modify/set for each pte in the range.
+ *
+ * Note that PTE bits in the PTE range besides the PFN can differ. For example,
+ * some PTEs might be write-protected.
+ *
+ * Context: The caller holds the page table lock.  The PTEs map consecutive
+ * pages that belong to the same folio.  The PTEs are all in the same PMD.
+ */
+static inline void clear_young_dirty_ptes(struct vm_area_struct *vma,
+                                         unsigned long addr, pte_t *ptep,
+                                         unsigned int nr, cydp_t flags)
+{
+       pte_t pte;
+
+       for (;;) {
+               if (flags == CYDP_CLEAR_YOUNG)
+                       ptep_test_and_clear_young(vma, addr, ptep);
+               else {
+                       pte = ptep_get_and_clear(vma->vm_mm, addr, ptep);
+                       if (flags & CYDP_CLEAR_YOUNG)
+                               pte = pte_mkold(pte);
+                       if (flags & CYDP_CLEAR_DIRTY)
+                               pte = pte_mkclean(pte);
+                       set_pte_at(vma->vm_mm, addr, ptep, pte);
+               }
+               if (--nr == 0)
+                       break;
+               ptep++;
+               addr += PAGE_SIZE;
+       }
+}
+#endif
+
 static inline void ptep_clear(struct mm_struct *mm, unsigned long addr,
                              pte_t *ptep)
 {