huge_pte_alloc() for non-HUGEPD targets is reserved for 8xx at the moment. In order to convert other targets for non-HUGEPD, complement huge_pte_alloc() to support any standard cont-PxD setup. Signed-off-by: Christophe Leroy <christophe.leroy@xxxxxxxxxx> --- arch/powerpc/mm/hugetlbpage.c | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 42b12e1ec851..f8aefa1e7363 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -195,11 +195,34 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long sz) { - pmd_t *pmd = pmd_off(mm, addr); + pgd_t *pgd; + p4d_t *p4d; + pud_t *pud; + pmd_t *pmd; + + addr &= ~(sz - 1); + pgd = pgd_offset(mm, addr); + + p4d = p4d_offset(pgd, addr); + if (sz >= PGDIR_SIZE) + return (pte_t *)p4d; + + pud = pud_alloc(mm, p4d, addr); + if (!pud) + return NULL; + if (sz >= PUD_SIZE) + return (pte_t *)pud; + + pmd = pmd_alloc(mm, pud, addr); + if (!pmd) + return NULL; if (sz < PMD_SIZE) return pte_alloc_huge(mm, pmd, addr, sz); + if (!IS_ENABLED(CONFIG_PPC_8xx)) + return (pte_t *)pmd; + if (sz != SZ_8M) return NULL; if (!pte_alloc_huge(mm, pmd, addr, sz)) -- 2.44.0