18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci#ifndef _LINUX_PGALLLC_TRACK_H
38c2ecf20Sopenharmony_ci#define _LINUX_PGALLLC_TRACK_H
48c2ecf20Sopenharmony_ci
58c2ecf20Sopenharmony_ci#if defined(CONFIG_MMU)
68c2ecf20Sopenharmony_cistatic inline p4d_t *p4d_alloc_track(struct mm_struct *mm, pgd_t *pgd,
78c2ecf20Sopenharmony_ci				     unsigned long address,
88c2ecf20Sopenharmony_ci				     pgtbl_mod_mask *mod_mask)
98c2ecf20Sopenharmony_ci{
108c2ecf20Sopenharmony_ci	if (unlikely(pgd_none(*pgd))) {
118c2ecf20Sopenharmony_ci		if (__p4d_alloc(mm, pgd, address))
128c2ecf20Sopenharmony_ci			return NULL;
138c2ecf20Sopenharmony_ci		*mod_mask |= PGTBL_PGD_MODIFIED;
148c2ecf20Sopenharmony_ci	}
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci	return p4d_offset(pgd, address);
178c2ecf20Sopenharmony_ci}
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_cistatic inline pud_t *pud_alloc_track(struct mm_struct *mm, p4d_t *p4d,
208c2ecf20Sopenharmony_ci				     unsigned long address,
218c2ecf20Sopenharmony_ci				     pgtbl_mod_mask *mod_mask)
228c2ecf20Sopenharmony_ci{
238c2ecf20Sopenharmony_ci	if (unlikely(p4d_none(*p4d))) {
248c2ecf20Sopenharmony_ci		if (__pud_alloc(mm, p4d, address))
258c2ecf20Sopenharmony_ci			return NULL;
268c2ecf20Sopenharmony_ci		*mod_mask |= PGTBL_P4D_MODIFIED;
278c2ecf20Sopenharmony_ci	}
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	return pud_offset(p4d, address);
308c2ecf20Sopenharmony_ci}
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_cistatic inline pmd_t *pmd_alloc_track(struct mm_struct *mm, pud_t *pud,
338c2ecf20Sopenharmony_ci				     unsigned long address,
348c2ecf20Sopenharmony_ci				     pgtbl_mod_mask *mod_mask)
358c2ecf20Sopenharmony_ci{
368c2ecf20Sopenharmony_ci	if (unlikely(pud_none(*pud))) {
378c2ecf20Sopenharmony_ci		if (__pmd_alloc(mm, pud, address))
388c2ecf20Sopenharmony_ci			return NULL;
398c2ecf20Sopenharmony_ci		*mod_mask |= PGTBL_PUD_MODIFIED;
408c2ecf20Sopenharmony_ci	}
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	return pmd_offset(pud, address);
438c2ecf20Sopenharmony_ci}
448c2ecf20Sopenharmony_ci#endif /* CONFIG_MMU */
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci#define pte_alloc_kernel_track(pmd, address, mask)			\
478c2ecf20Sopenharmony_ci	((unlikely(pmd_none(*(pmd))) &&					\
488c2ecf20Sopenharmony_ci	  (__pte_alloc_kernel(pmd) || ({*(mask)|=PGTBL_PMD_MODIFIED;0;})))?\
498c2ecf20Sopenharmony_ci		NULL: pte_offset_kernel(pmd, address))
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci#endif /* _LINUX_PGALLLC_TRACK_H */
52