xref: /linux/arch/powerpc/include/asm/pte-walk.h (revision 7ae9fb1b7ecbb5d85d07857943f677fd1a559b18)
194171b19SAneesh Kumar K.V #ifndef _ASM_POWERPC_PTE_WALK_H
294171b19SAneesh Kumar K.V #define _ASM_POWERPC_PTE_WALK_H
394171b19SAneesh Kumar K.V 
494171b19SAneesh Kumar K.V #include <linux/sched.h>
594171b19SAneesh Kumar K.V 
694171b19SAneesh Kumar K.V /* Don't use this directly */
794171b19SAneesh Kumar K.V extern pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea,
894171b19SAneesh Kumar K.V 			       bool *is_thp, unsigned *hshift);
994171b19SAneesh Kumar K.V 
find_linux_pte(pgd_t * pgdir,unsigned long ea,bool * is_thp,unsigned * hshift)1094171b19SAneesh Kumar K.V static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea,
1194171b19SAneesh Kumar K.V 				    bool *is_thp, unsigned *hshift)
1294171b19SAneesh Kumar K.V {
13d6eaceddSAneesh Kumar K.V 	pte_t *pte;
14d6eaceddSAneesh Kumar K.V 
1594171b19SAneesh Kumar K.V 	VM_WARN(!arch_irqs_disabled(), "%s called with irq enabled\n", __func__);
16d6eaceddSAneesh Kumar K.V 	pte = __find_linux_pte(pgdir, ea, is_thp, hshift);
17d6eaceddSAneesh Kumar K.V 
18d6eaceddSAneesh Kumar K.V #if defined(CONFIG_DEBUG_VM) &&						\
19d6eaceddSAneesh Kumar K.V 	!(defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE))
20d6eaceddSAneesh Kumar K.V 	/*
21d6eaceddSAneesh Kumar K.V 	 * We should not find huge page if these configs are not enabled.
22d6eaceddSAneesh Kumar K.V 	 */
23d6eaceddSAneesh Kumar K.V 	if (hshift)
24d6eaceddSAneesh Kumar K.V 		WARN_ON(*hshift);
25d6eaceddSAneesh Kumar K.V #endif
26d6eaceddSAneesh Kumar K.V 	return pte;
2794171b19SAneesh Kumar K.V }
2894171b19SAneesh Kumar K.V 
find_init_mm_pte(unsigned long ea,unsigned * hshift)2994171b19SAneesh Kumar K.V static inline pte_t *find_init_mm_pte(unsigned long ea, unsigned *hshift)
3094171b19SAneesh Kumar K.V {
3194171b19SAneesh Kumar K.V 	pgd_t *pgdir = init_mm.pgd;
3294171b19SAneesh Kumar K.V 	return __find_linux_pte(pgdir, ea, NULL, hshift);
3394171b19SAneesh Kumar K.V }
34*5362a4b6SNicholas Piggin 
35*5362a4b6SNicholas Piggin /*
36*5362a4b6SNicholas Piggin  * Convert a kernel vmap virtual address (vmalloc or ioremap space) to a
37*5362a4b6SNicholas Piggin  * physical address, without taking locks. This can be used in real-mode.
38*5362a4b6SNicholas Piggin  */
ppc_find_vmap_phys(unsigned long addr)39*5362a4b6SNicholas Piggin static inline phys_addr_t ppc_find_vmap_phys(unsigned long addr)
40*5362a4b6SNicholas Piggin {
41*5362a4b6SNicholas Piggin 	pte_t *ptep;
42*5362a4b6SNicholas Piggin 	phys_addr_t pa;
43*5362a4b6SNicholas Piggin 	int hugepage_shift;
44*5362a4b6SNicholas Piggin 
45*5362a4b6SNicholas Piggin 	/*
46*5362a4b6SNicholas Piggin 	 * init_mm does not free page tables, and does not do THP. It may
47*5362a4b6SNicholas Piggin 	 * have huge pages from huge vmalloc / ioremap etc.
48*5362a4b6SNicholas Piggin 	 */
49*5362a4b6SNicholas Piggin 	ptep = find_init_mm_pte(addr, &hugepage_shift);
50*5362a4b6SNicholas Piggin 	if (WARN_ON(!ptep))
51*5362a4b6SNicholas Piggin 		return 0;
52*5362a4b6SNicholas Piggin 
53*5362a4b6SNicholas Piggin 	pa = PFN_PHYS(pte_pfn(*ptep));
54*5362a4b6SNicholas Piggin 
55*5362a4b6SNicholas Piggin 	if (!hugepage_shift)
56*5362a4b6SNicholas Piggin 		hugepage_shift = PAGE_SHIFT;
57*5362a4b6SNicholas Piggin 
58*5362a4b6SNicholas Piggin 	pa |= addr & ((1ul << hugepage_shift) - 1);
59*5362a4b6SNicholas Piggin 
60*5362a4b6SNicholas Piggin 	return pa;
61*5362a4b6SNicholas Piggin }
62*5362a4b6SNicholas Piggin 
6394171b19SAneesh Kumar K.V #endif /* _ASM_POWERPC_PTE_WALK_H */
64