__ptep_set_wrprotect(mm, address, ptep);
}
-static inline void __clear_young_dirty_pte(struct vm_area_struct *vma,
- unsigned long addr, pte_t *ptep,
- pte_t pte, cydp_t flags)
-{
- pte_t old_pte;
-
- do {
- old_pte = pte;
-
- if (flags & CYDP_CLEAR_YOUNG)
- pte = pte_mkold(pte);
- if (flags & CYDP_CLEAR_DIRTY)
- pte = pte_mkclean(pte);
-
- pte_val(pte) = cmpxchg_relaxed(&pte_val(*ptep),
- pte_val(old_pte), pte_val(pte));
- } while (pte_val(pte) != pte_val(old_pte));
-}
-
-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 (;;) {
- pte = __ptep_get(ptep);
-
- if (flags == (CYDP_CLEAR_YOUNG | CYDP_CLEAR_DIRTY))
- __set_pte(ptep, pte_mkclean(pte_mkold(pte)));
- else
- __clear_young_dirty_pte(vma, addr, ptep, pte, flags);
-
- if (--nr == 0)
- break;
- ptep++;
- addr += PAGE_SIZE;
- }
-}
-
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
#define __HAVE_ARCH_PMDP_SET_WRPROTECT
static inline void pmdp_set_wrprotect(struct mm_struct *mm,
extern int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t entry, int dirty);
-extern void contpte_clear_young_dirty_ptes(struct vm_area_struct *vma,
- unsigned long addr, pte_t *ptep,
- unsigned int nr, cydp_t flags);
static __always_inline void contpte_try_fold(struct mm_struct *mm,
unsigned long addr, pte_t *ptep, pte_t pte)
return contpte_ptep_set_access_flags(vma, addr, ptep, entry, dirty);
}
-#define clear_young_dirty_ptes clear_young_dirty_ptes
-static inline void clear_young_dirty_ptes(struct vm_area_struct *vma,
- unsigned long addr, pte_t *ptep,
- unsigned int nr, cydp_t flags)
-{
- if (likely(nr == 1 && !pte_cont(__ptep_get(ptep))))
- __clear_young_dirty_ptes(vma, addr, ptep, nr, flags);
- else
- contpte_clear_young_dirty_ptes(vma, addr, ptep, nr, flags);
-}
-
#else /* CONFIG_ARM64_CONTPTE */
#define ptep_get __ptep_get
#define wrprotect_ptes __wrprotect_ptes
#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
#define ptep_set_access_flags __ptep_set_access_flags
-#define clear_young_dirty_ptes __clear_young_dirty_ptes
#endif /* CONFIG_ARM64_CONTPTE */
}
EXPORT_SYMBOL_GPL(contpte_wrprotect_ptes);
-void contpte_clear_young_dirty_ptes(struct vm_area_struct *vma,
- unsigned long addr, pte_t *ptep,
- unsigned int nr, cydp_t flags)
-{
- /*
- * We can safely clear access/dirty without needing to unfold from
- * the architectures perspective, even when contpte is set. If the
- * range starts or ends midway through a contpte block, we can just
- * expand to include the full contpte block. While this is not
- * exactly what the core-mm asked for, it tracks access/dirty per
- * folio, not per page. And since we only create a contpte block
- * when it is covered by a single folio, we can get away with
- * clearing access/dirty for the whole block.
- */
- unsigned long start = addr;
- unsigned long end = start + nr;
-
- if (pte_cont(__ptep_get(ptep + nr - 1)))
- end = ALIGN(end, CONT_PTE_SIZE);
-
- if (pte_cont(__ptep_get(ptep))) {
- start = ALIGN_DOWN(start, CONT_PTE_SIZE);
- ptep = contpte_align_down(ptep);
- }
-
- __clear_young_dirty_ptes(vma, start, ptep, end - start, flags);
-}
-EXPORT_SYMBOL_GPL(contpte_clear_young_dirty_ptes);
-
int contpte_ptep_set_access_flags(struct vm_area_struct *vma,
unsigned long addr, pte_t *ptep,
pte_t entry, int dirty)