Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8c539ce authored by Mark Rutland's avatar Mark Rutland Committed by Mark Salyzyn
Browse files

UPSTREAM: arm64: mm: add __{pud,pgd}_populate



(cherry picked from commit 1e531cce68c92b46c7d29f36a72f9a3e5886678f)

We currently have __pmd_populate for creating a pmd table entry given
the physical address of a pte, but don't have equivalents for the pud or
pgd levels of table.

To enable us to manipulate tables which are mapped outside of the linear
mapping (where we have a PA, but not a linear map VA), it is useful to
have these functions.

This patch adds __{pud,pgd}_populate. As these should not be called when
the kernel uses folded {pmd,pud}s, in these cases they expand to
BUILD_BUG(). So long as the appropriate checks are made on the {pud,pgd}
entry prior to attempting population, these should be optimized out at
compile time.

Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
Reviewed-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Tested-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: default avatarArd Biesheuvel <ard.biesheuvel@linaro.org>
Tested-by: default avatarJeremy Linton <jeremy.linton@arm.com>
Cc: Laura Abbott <labbott@fedoraproject.org>
Cc: Will Deacon <will.deacon@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Bug: 20045882
Bug: 63737556
Change-Id: I014e24adec99f29fa1019e541fce3ac2cf1973b4
parent a2ec34c8
Loading
Loading
Loading
Loading
+22 −4
Original line number Diff line number Diff line
@@ -39,11 +39,20 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
	free_page((unsigned long)pmd);
}

static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot)
{
	set_pud(pud, __pud(__pa(pmd) | PMD_TYPE_TABLE));
	set_pud(pud, __pud(pmd | prot));
}

static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
{
	__pud_populate(pud, __pa(pmd), PMD_TYPE_TABLE);
}
#else
static inline void __pud_populate(pud_t *pud, phys_addr_t pmd, pudval_t prot)
{
	BUILD_BUG();
}
#endif	/* CONFIG_PGTABLE_LEVELS > 2 */

#if CONFIG_PGTABLE_LEVELS > 3
@@ -59,11 +68,20 @@ static inline void pud_free(struct mm_struct *mm, pud_t *pud)
	free_page((unsigned long)pud);
}

static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot)
{
	set_pgd(pgd, __pgd(__pa(pud) | PUD_TYPE_TABLE));
	set_pgd(pgdp, __pgd(pud | prot));
}

static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
{
	__pgd_populate(pgd, __pa(pud), PUD_TYPE_TABLE);
}
#else
static inline void __pgd_populate(pgd_t *pgdp, phys_addr_t pud, pgdval_t prot)
{
	BUILD_BUG();
}
#endif	/* CONFIG_PGTABLE_LEVELS > 3 */

extern pgd_t *pgd_alloc(struct mm_struct *mm);