@@ -1223,6 +1223,46 @@ static inline void __wrprotect_ptes(struct mm_struct *mm, unsigned long address,
1223
1223
__ptep_set_wrprotect (mm , address , ptep );
1224
1224
}
1225
1225
1226
+ static inline void __clear_young_dirty_pte (struct vm_area_struct * vma ,
1227
+ unsigned long addr , pte_t * ptep ,
1228
+ pte_t pte , cydp_t flags )
1229
+ {
1230
+ pte_t old_pte ;
1231
+
1232
+ do {
1233
+ old_pte = pte ;
1234
+
1235
+ if (flags & CYDP_CLEAR_YOUNG )
1236
+ pte = pte_mkold (pte );
1237
+ if (flags & CYDP_CLEAR_DIRTY )
1238
+ pte = pte_mkclean (pte );
1239
+
1240
+ pte_val (pte ) = cmpxchg_relaxed (& pte_val (* ptep ),
1241
+ pte_val (old_pte ), pte_val (pte ));
1242
+ } while (pte_val (pte ) != pte_val (old_pte ));
1243
+ }
1244
+
1245
+ static inline void __clear_young_dirty_ptes (struct vm_area_struct * vma ,
1246
+ unsigned long addr , pte_t * ptep ,
1247
+ unsigned int nr , cydp_t flags )
1248
+ {
1249
+ pte_t pte ;
1250
+
1251
+ for (;;) {
1252
+ pte = __ptep_get (ptep );
1253
+
1254
+ if (flags == (CYDP_CLEAR_YOUNG | CYDP_CLEAR_DIRTY ))
1255
+ __set_pte (ptep , pte_mkclean (pte_mkold (pte )));
1256
+ else
1257
+ __clear_young_dirty_pte (vma , addr , ptep , pte , flags );
1258
+
1259
+ if (-- nr == 0 )
1260
+ break ;
1261
+ ptep ++ ;
1262
+ addr += PAGE_SIZE ;
1263
+ }
1264
+ }
1265
+
1226
1266
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
1227
1267
#define __HAVE_ARCH_PMDP_SET_WRPROTECT
1228
1268
static inline void pmdp_set_wrprotect (struct mm_struct * mm ,
@@ -1379,6 +1419,9 @@ extern void contpte_wrprotect_ptes(struct mm_struct *mm, unsigned long addr,
1379
1419
extern int contpte_ptep_set_access_flags (struct vm_area_struct * vma ,
1380
1420
unsigned long addr , pte_t * ptep ,
1381
1421
pte_t entry , int dirty );
1422
+ extern void contpte_clear_young_dirty_ptes (struct vm_area_struct * vma ,
1423
+ unsigned long addr , pte_t * ptep ,
1424
+ unsigned int nr , cydp_t flags );
1382
1425
1383
1426
static __always_inline void contpte_try_fold (struct mm_struct * mm ,
1384
1427
unsigned long addr , pte_t * ptep , pte_t pte )
@@ -1603,6 +1646,17 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
1603
1646
return contpte_ptep_set_access_flags (vma , addr , ptep , entry , dirty );
1604
1647
}
1605
1648
1649
+ #define clear_young_dirty_ptes clear_young_dirty_ptes
1650
+ static inline void clear_young_dirty_ptes (struct vm_area_struct * vma ,
1651
+ unsigned long addr , pte_t * ptep ,
1652
+ unsigned int nr , cydp_t flags )
1653
+ {
1654
+ if (likely (nr == 1 && !pte_cont (__ptep_get (ptep ))))
1655
+ __clear_young_dirty_ptes (vma , addr , ptep , nr , flags );
1656
+ else
1657
+ contpte_clear_young_dirty_ptes (vma , addr , ptep , nr , flags );
1658
+ }
1659
+
1606
1660
#else /* CONFIG_ARM64_CONTPTE */
1607
1661
1608
1662
#define ptep_get __ptep_get
@@ -1622,6 +1676,7 @@ static inline int ptep_set_access_flags(struct vm_area_struct *vma,
1622
1676
#define wrprotect_ptes __wrprotect_ptes
1623
1677
#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
1624
1678
#define ptep_set_access_flags __ptep_set_access_flags
1679
+ #define clear_young_dirty_ptes __clear_young_dirty_ptes
1625
1680
1626
1681
#endif /* CONFIG_ARM64_CONTPTE */
1627
1682
0 commit comments