162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Based on arch/arm/include/asm/pgalloc.h
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2000-2001 Russell King
662306a36Sopenharmony_ci * Copyright (C) 2012 ARM Ltd.
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci#ifndef __ASM_PGALLOC_H
962306a36Sopenharmony_ci#define __ASM_PGALLOC_H
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <asm/pgtable-hwdef.h>
1262306a36Sopenharmony_ci#include <asm/processor.h>
1362306a36Sopenharmony_ci#include <asm/cacheflush.h>
1462306a36Sopenharmony_ci#include <asm/tlbflush.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define __HAVE_ARCH_PGD_FREE
1762306a36Sopenharmony_ci#include <asm-generic/pgalloc.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#define PGD_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#if CONFIG_PGTABLE_LEVELS > 2
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistatic inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot)
2462306a36Sopenharmony_ci{
2562306a36Sopenharmony_ci	set_pud(pudp, __pud(__phys_to_pud_val(pmdp) | prot));
2662306a36Sopenharmony_ci}
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_cistatic inline void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmdp)
2962306a36Sopenharmony_ci{
3062306a36Sopenharmony_ci	pudval_t pudval = PUD_TYPE_TABLE;
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	pudval |= (mm == &init_mm) ? PUD_TABLE_UXN : PUD_TABLE_PXN;
3362306a36Sopenharmony_ci	__pud_populate(pudp, __pa(pmdp), pudval);
3462306a36Sopenharmony_ci}
3562306a36Sopenharmony_ci#else
3662306a36Sopenharmony_cistatic inline void __pud_populate(pud_t *pudp, phys_addr_t pmdp, pudval_t prot)
3762306a36Sopenharmony_ci{
3862306a36Sopenharmony_ci	BUILD_BUG();
3962306a36Sopenharmony_ci}
4062306a36Sopenharmony_ci#endif	/* CONFIG_PGTABLE_LEVELS > 2 */
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci#if CONFIG_PGTABLE_LEVELS > 3
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistatic inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot)
4562306a36Sopenharmony_ci{
4662306a36Sopenharmony_ci	set_p4d(p4dp, __p4d(__phys_to_p4d_val(pudp) | prot));
4762306a36Sopenharmony_ci}
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_cistatic inline void p4d_populate(struct mm_struct *mm, p4d_t *p4dp, pud_t *pudp)
5062306a36Sopenharmony_ci{
5162306a36Sopenharmony_ci	p4dval_t p4dval = P4D_TYPE_TABLE;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	p4dval |= (mm == &init_mm) ? P4D_TABLE_UXN : P4D_TABLE_PXN;
5462306a36Sopenharmony_ci	__p4d_populate(p4dp, __pa(pudp), p4dval);
5562306a36Sopenharmony_ci}
5662306a36Sopenharmony_ci#else
5762306a36Sopenharmony_cistatic inline void __p4d_populate(p4d_t *p4dp, phys_addr_t pudp, p4dval_t prot)
5862306a36Sopenharmony_ci{
5962306a36Sopenharmony_ci	BUILD_BUG();
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ci#endif	/* CONFIG_PGTABLE_LEVELS > 3 */
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ciextern pgd_t *pgd_alloc(struct mm_struct *mm);
6462306a36Sopenharmony_ciextern void pgd_free(struct mm_struct *mm, pgd_t *pgdp);
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistatic inline void __pmd_populate(pmd_t *pmdp, phys_addr_t ptep,
6762306a36Sopenharmony_ci				  pmdval_t prot)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	set_pmd(pmdp, __pmd(__phys_to_pmd_val(ptep) | prot));
7062306a36Sopenharmony_ci}
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/*
7362306a36Sopenharmony_ci * Populate the pmdp entry with a pointer to the pte.  This pmd is part
7462306a36Sopenharmony_ci * of the mm address space.
7562306a36Sopenharmony_ci */
7662306a36Sopenharmony_cistatic inline void
7762306a36Sopenharmony_cipmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
7862306a36Sopenharmony_ci{
7962306a36Sopenharmony_ci	VM_BUG_ON(mm && mm != &init_mm);
8062306a36Sopenharmony_ci	__pmd_populate(pmdp, __pa(ptep), PMD_TYPE_TABLE | PMD_TABLE_UXN);
8162306a36Sopenharmony_ci}
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_cistatic inline void
8462306a36Sopenharmony_cipmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	VM_BUG_ON(mm == &init_mm);
8762306a36Sopenharmony_ci	__pmd_populate(pmdp, page_to_phys(ptep), PMD_TYPE_TABLE | PMD_TABLE_PXN);
8862306a36Sopenharmony_ci}
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci#endif
91