162306a36Sopenharmony_ci#ifndef _ASM_POWERPC_PTE_WALK_H
262306a36Sopenharmony_ci#define _ASM_POWERPC_PTE_WALK_H
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#include <linux/sched.h>
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci/* Don't use this directly */
762306a36Sopenharmony_ciextern pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
862306a36Sopenharmony_ci			       bool *is_thp, unsigned *hshift);
962306a36Sopenharmony_ci
1062306a36Sopenharmony_cistatic inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea,
1162306a36Sopenharmony_ci				    bool *is_thp, unsigned *hshift)
1262306a36Sopenharmony_ci{
1362306a36Sopenharmony_ci	pte_t *pte;
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci	VM_WARN(!arch_irqs_disabled(), "%s called with irq enabled\n", __func__);
1662306a36Sopenharmony_ci	pte = __find_linux_pte(pgdir, ea, is_thp, hshift);
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#if defined(CONFIG_DEBUG_VM) &&						\
1962306a36Sopenharmony_ci	!(defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE))
2062306a36Sopenharmony_ci	/*
2162306a36Sopenharmony_ci	 * We should not find huge page if these configs are not enabled.
2262306a36Sopenharmony_ci	 */
2362306a36Sopenharmony_ci	if (hshift)
2462306a36Sopenharmony_ci		WARN_ON(*hshift);
2562306a36Sopenharmony_ci#endif
2662306a36Sopenharmony_ci	return pte;
2762306a36Sopenharmony_ci}
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cistatic inline pte_t *find_init_mm_pte(unsigned long ea, unsigned *hshift)
3062306a36Sopenharmony_ci{
3162306a36Sopenharmony_ci	pgd_t *pgdir = init_mm.pgd;
3262306a36Sopenharmony_ci	return __find_linux_pte(pgdir, ea, NULL, hshift);
3362306a36Sopenharmony_ci}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci/*
3662306a36Sopenharmony_ci * Convert a kernel vmap virtual address (vmalloc or ioremap space) to a
3762306a36Sopenharmony_ci * physical address, without taking locks. This can be used in real-mode.
3862306a36Sopenharmony_ci */
3962306a36Sopenharmony_cistatic inline phys_addr_t ppc_find_vmap_phys(unsigned long addr)
4062306a36Sopenharmony_ci{
4162306a36Sopenharmony_ci	pte_t *ptep;
4262306a36Sopenharmony_ci	phys_addr_t pa;
4362306a36Sopenharmony_ci	int hugepage_shift;
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	/*
4662306a36Sopenharmony_ci	 * init_mm does not free page tables, and does not do THP. It may
4762306a36Sopenharmony_ci	 * have huge pages from huge vmalloc / ioremap etc.
4862306a36Sopenharmony_ci	 */
4962306a36Sopenharmony_ci	ptep = find_init_mm_pte(addr, &hugepage_shift);
5062306a36Sopenharmony_ci	if (WARN_ON(!ptep))
5162306a36Sopenharmony_ci		return 0;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	pa = PFN_PHYS(pte_pfn(*ptep));
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	if (!hugepage_shift)
5662306a36Sopenharmony_ci		hugepage_shift = PAGE_SHIFT;
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	pa |= addr & ((1ul << hugepage_shift) - 1);
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	return pa;
6162306a36Sopenharmony_ci}
6262306a36Sopenharmony_ci
6362306a36Sopenharmony_ci#endif /* _ASM_POWERPC_PTE_WALK_H */
64