xref: /linux/arch/arm64/include/asm/pgtable.h (revision 44b6dfc556811c0e6981329e29e1865fc7a8847d)
14f04d8f0SCatalin Marinas /*
24f04d8f0SCatalin Marinas  * Copyright (C) 2012 ARM Ltd.
34f04d8f0SCatalin Marinas  *
44f04d8f0SCatalin Marinas  * This program is free software; you can redistribute it and/or modify
54f04d8f0SCatalin Marinas  * it under the terms of the GNU General Public License version 2 as
64f04d8f0SCatalin Marinas  * published by the Free Software Foundation.
74f04d8f0SCatalin Marinas  *
84f04d8f0SCatalin Marinas  * This program is distributed in the hope that it will be useful,
94f04d8f0SCatalin Marinas  * but WITHOUT ANY WARRANTY; without even the implied warranty of
104f04d8f0SCatalin Marinas  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
114f04d8f0SCatalin Marinas  * GNU General Public License for more details.
124f04d8f0SCatalin Marinas  *
134f04d8f0SCatalin Marinas  * You should have received a copy of the GNU General Public License
144f04d8f0SCatalin Marinas  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
154f04d8f0SCatalin Marinas  */
164f04d8f0SCatalin Marinas #ifndef __ASM_PGTABLE_H
174f04d8f0SCatalin Marinas #define __ASM_PGTABLE_H
184f04d8f0SCatalin Marinas 
194f04d8f0SCatalin Marinas #include <asm/proc-fns.h>
204f04d8f0SCatalin Marinas 
214f04d8f0SCatalin Marinas #include <asm/memory.h>
224f04d8f0SCatalin Marinas #include <asm/pgtable-hwdef.h>
234f04d8f0SCatalin Marinas 
244f04d8f0SCatalin Marinas /*
254f04d8f0SCatalin Marinas  * Software defined PTE bits definition.
264f04d8f0SCatalin Marinas  */
27a6fadf7eSWill Deacon #define PTE_VALID		(_AT(pteval_t, 1) << 0)
283676f9efSCatalin Marinas #define PTE_FILE		(_AT(pteval_t, 1) << 2)	/* only when !pte_present() */
294f04d8f0SCatalin Marinas #define PTE_DIRTY		(_AT(pteval_t, 1) << 55)
304f04d8f0SCatalin Marinas #define PTE_SPECIAL		(_AT(pteval_t, 1) << 56)
313676f9efSCatalin Marinas 				/* bit 57 for PMD_SECT_SPLITTING */
323676f9efSCatalin Marinas #define PTE_PROT_NONE		(_AT(pteval_t, 1) << 58) /* only when !PTE_VALID */
334f04d8f0SCatalin Marinas 
344f04d8f0SCatalin Marinas /*
354f04d8f0SCatalin Marinas  * VMALLOC and SPARSEMEM_VMEMMAP ranges.
364f04d8f0SCatalin Marinas  */
37847264fbSCatalin Marinas #define VMALLOC_START		(UL(0xffffffffffffffff) << VA_BITS)
384f04d8f0SCatalin Marinas #define VMALLOC_END		(PAGE_OFFSET - UL(0x400000000) - SZ_64K)
394f04d8f0SCatalin Marinas 
404f04d8f0SCatalin Marinas #define vmemmap			((struct page *)(VMALLOC_END + SZ_64K))
414f04d8f0SCatalin Marinas 
424f04d8f0SCatalin Marinas #define FIRST_USER_ADDRESS	0
434f04d8f0SCatalin Marinas 
444f04d8f0SCatalin Marinas #ifndef __ASSEMBLY__
454f04d8f0SCatalin Marinas extern void __pte_error(const char *file, int line, unsigned long val);
464f04d8f0SCatalin Marinas extern void __pmd_error(const char *file, int line, unsigned long val);
474f04d8f0SCatalin Marinas extern void __pgd_error(const char *file, int line, unsigned long val);
484f04d8f0SCatalin Marinas 
494f04d8f0SCatalin Marinas #define pte_ERROR(pte)		__pte_error(__FILE__, __LINE__, pte_val(pte))
504f04d8f0SCatalin Marinas #ifndef CONFIG_ARM64_64K_PAGES
514f04d8f0SCatalin Marinas #define pmd_ERROR(pmd)		__pmd_error(__FILE__, __LINE__, pmd_val(pmd))
524f04d8f0SCatalin Marinas #endif
534f04d8f0SCatalin Marinas #define pgd_ERROR(pgd)		__pgd_error(__FILE__, __LINE__, pgd_val(pgd))
544f04d8f0SCatalin Marinas 
554f04d8f0SCatalin Marinas /*
564f04d8f0SCatalin Marinas  * The pgprot_* and protection_map entries will be fixed up at runtime to
574f04d8f0SCatalin Marinas  * include the cachable and bufferable bits based on memory policy, as well as
584f04d8f0SCatalin Marinas  * any architecture dependent bits like global/ASID and SMP shared mapping
594f04d8f0SCatalin Marinas  * bits.
604f04d8f0SCatalin Marinas  */
614f04d8f0SCatalin Marinas #define _PAGE_DEFAULT		PTE_TYPE_PAGE | PTE_AF
624f04d8f0SCatalin Marinas 
634f04d8f0SCatalin Marinas extern pgprot_t pgprot_default;
644f04d8f0SCatalin Marinas 
65a6fadf7eSWill Deacon #define __pgprot_modify(prot,mask,bits) \
66a6fadf7eSWill Deacon 	__pgprot((pgprot_val(prot) & ~(mask)) | (bits))
674f04d8f0SCatalin Marinas 
68a6fadf7eSWill Deacon #define _MOD_PROT(p, b)		__pgprot_modify(p, 0, b)
69a6fadf7eSWill Deacon 
70072b1b62SSteve Capper #define PAGE_NONE		__pgprot_modify(pgprot_default, PTE_TYPE_MASK, PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN)
718e620b04SCatalin Marinas #define PAGE_SHARED		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
728e620b04SCatalin Marinas #define PAGE_SHARED_EXEC	_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
738e620b04SCatalin Marinas #define PAGE_COPY		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
748e620b04SCatalin Marinas #define PAGE_COPY_EXEC		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
758e620b04SCatalin Marinas #define PAGE_READONLY		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
768e620b04SCatalin Marinas #define PAGE_READONLY_EXEC	_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
778e620b04SCatalin Marinas #define PAGE_KERNEL		_MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY)
788e620b04SCatalin Marinas #define PAGE_KERNEL_EXEC	_MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY)
794f04d8f0SCatalin Marinas 
8036311607SMarc Zyngier #define PAGE_HYP		_MOD_PROT(pgprot_default, PTE_HYP)
8136311607SMarc Zyngier #define PAGE_HYP_DEVICE		__pgprot(PROT_DEVICE_nGnRE | PTE_HYP)
8236311607SMarc Zyngier 
8336311607SMarc Zyngier #define PAGE_S2			__pgprot_modify(pgprot_default, PTE_S2_MEMATTR_MASK, PTE_S2_MEMATTR(MT_S2_NORMAL) | PTE_S2_RDONLY)
8436311607SMarc Zyngier #define PAGE_S2_DEVICE		__pgprot(PROT_DEFAULT | PTE_S2_MEMATTR(MT_S2_DEVICE_nGnRE) | PTE_S2_RDWR | PTE_UXN)
8536311607SMarc Zyngier 
86072b1b62SSteve Capper #define __PAGE_NONE		__pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE | PTE_RDONLY | PTE_PXN | PTE_UXN)
878e620b04SCatalin Marinas #define __PAGE_SHARED		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
888e620b04SCatalin Marinas #define __PAGE_SHARED_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
898e620b04SCatalin Marinas #define __PAGE_COPY		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
908e620b04SCatalin Marinas #define __PAGE_COPY_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
918e620b04SCatalin Marinas #define __PAGE_READONLY		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
928e620b04SCatalin Marinas #define __PAGE_READONLY_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
934f04d8f0SCatalin Marinas 
944f04d8f0SCatalin Marinas #endif /* __ASSEMBLY__ */
954f04d8f0SCatalin Marinas 
964f04d8f0SCatalin Marinas #define __P000  __PAGE_NONE
974f04d8f0SCatalin Marinas #define __P001  __PAGE_READONLY
984f04d8f0SCatalin Marinas #define __P010  __PAGE_COPY
994f04d8f0SCatalin Marinas #define __P011  __PAGE_COPY
1004f04d8f0SCatalin Marinas #define __P100  __PAGE_READONLY_EXEC
1014f04d8f0SCatalin Marinas #define __P101  __PAGE_READONLY_EXEC
1024f04d8f0SCatalin Marinas #define __P110  __PAGE_COPY_EXEC
1034f04d8f0SCatalin Marinas #define __P111  __PAGE_COPY_EXEC
1044f04d8f0SCatalin Marinas 
1054f04d8f0SCatalin Marinas #define __S000  __PAGE_NONE
1064f04d8f0SCatalin Marinas #define __S001  __PAGE_READONLY
1074f04d8f0SCatalin Marinas #define __S010  __PAGE_SHARED
1084f04d8f0SCatalin Marinas #define __S011  __PAGE_SHARED
1094f04d8f0SCatalin Marinas #define __S100  __PAGE_READONLY_EXEC
1104f04d8f0SCatalin Marinas #define __S101  __PAGE_READONLY_EXEC
1114f04d8f0SCatalin Marinas #define __S110  __PAGE_SHARED_EXEC
1124f04d8f0SCatalin Marinas #define __S111  __PAGE_SHARED_EXEC
1134f04d8f0SCatalin Marinas 
1144f04d8f0SCatalin Marinas #ifndef __ASSEMBLY__
1154f04d8f0SCatalin Marinas /*
1164f04d8f0SCatalin Marinas  * ZERO_PAGE is a global shared page that is always zero: used
1174f04d8f0SCatalin Marinas  * for zero-mapped memory areas etc..
1184f04d8f0SCatalin Marinas  */
1194f04d8f0SCatalin Marinas extern struct page *empty_zero_page;
1204f04d8f0SCatalin Marinas #define ZERO_PAGE(vaddr)	(empty_zero_page)
1214f04d8f0SCatalin Marinas 
1224f04d8f0SCatalin Marinas #define pte_pfn(pte)		((pte_val(pte) & PHYS_MASK) >> PAGE_SHIFT)
1234f04d8f0SCatalin Marinas 
1244f04d8f0SCatalin Marinas #define pfn_pte(pfn,prot)	(__pte(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
1254f04d8f0SCatalin Marinas 
1264f04d8f0SCatalin Marinas #define pte_none(pte)		(!pte_val(pte))
1274f04d8f0SCatalin Marinas #define pte_clear(mm,addr,ptep)	set_pte(ptep, __pte(0))
1284f04d8f0SCatalin Marinas #define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
1299ab6d02fSWill Deacon #define pte_offset_kernel(dir,addr)	(pmd_page_vaddr(*(dir)) + pte_index(addr))
1304f04d8f0SCatalin Marinas 
1314f04d8f0SCatalin Marinas #define pte_offset_map(dir,addr)	pte_offset_kernel((dir), (addr))
1324f04d8f0SCatalin Marinas #define pte_offset_map_nested(dir,addr)	pte_offset_kernel((dir), (addr))
1334f04d8f0SCatalin Marinas #define pte_unmap(pte)			do { } while (0)
1344f04d8f0SCatalin Marinas #define pte_unmap_nested(pte)		do { } while (0)
1354f04d8f0SCatalin Marinas 
1364f04d8f0SCatalin Marinas /*
1374f04d8f0SCatalin Marinas  * The following only work if pte_present(). Undefined behaviour otherwise.
1384f04d8f0SCatalin Marinas  */
139a6fadf7eSWill Deacon #define pte_present(pte)	(pte_val(pte) & (PTE_VALID | PTE_PROT_NONE))
1404f04d8f0SCatalin Marinas #define pte_dirty(pte)		(pte_val(pte) & PTE_DIRTY)
1414f04d8f0SCatalin Marinas #define pte_young(pte)		(pte_val(pte) & PTE_AF)
1424f04d8f0SCatalin Marinas #define pte_special(pte)	(pte_val(pte) & PTE_SPECIAL)
1434f04d8f0SCatalin Marinas #define pte_write(pte)		(!(pte_val(pte) & PTE_RDONLY))
1448e620b04SCatalin Marinas #define pte_exec(pte)		(!(pte_val(pte) & PTE_UXN))
1454f04d8f0SCatalin Marinas 
146a6fadf7eSWill Deacon #define pte_valid_user(pte) \
14702522463SWill Deacon 	((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
1484f04d8f0SCatalin Marinas 
149*44b6dfc5SSteve Capper static inline pte_t pte_wrprotect(pte_t pte)
150*44b6dfc5SSteve Capper {
151*44b6dfc5SSteve Capper 	pte_val(pte) |= PTE_RDONLY;
152*44b6dfc5SSteve Capper 	return pte;
153*44b6dfc5SSteve Capper }
1544f04d8f0SCatalin Marinas 
155*44b6dfc5SSteve Capper static inline pte_t pte_mkwrite(pte_t pte)
156*44b6dfc5SSteve Capper {
157*44b6dfc5SSteve Capper 	pte_val(pte) &= ~PTE_RDONLY;
158*44b6dfc5SSteve Capper 	return pte;
159*44b6dfc5SSteve Capper }
160*44b6dfc5SSteve Capper 
161*44b6dfc5SSteve Capper static inline pte_t pte_mkclean(pte_t pte)
162*44b6dfc5SSteve Capper {
163*44b6dfc5SSteve Capper 	pte_val(pte) &= ~PTE_DIRTY;
164*44b6dfc5SSteve Capper 	return pte;
165*44b6dfc5SSteve Capper }
166*44b6dfc5SSteve Capper 
167*44b6dfc5SSteve Capper static inline pte_t pte_mkdirty(pte_t pte)
168*44b6dfc5SSteve Capper {
169*44b6dfc5SSteve Capper 	pte_val(pte) |= PTE_DIRTY;
170*44b6dfc5SSteve Capper 	return pte;
171*44b6dfc5SSteve Capper }
172*44b6dfc5SSteve Capper 
173*44b6dfc5SSteve Capper static inline pte_t pte_mkold(pte_t pte)
174*44b6dfc5SSteve Capper {
175*44b6dfc5SSteve Capper 	pte_val(pte) &= ~PTE_AF;
176*44b6dfc5SSteve Capper 	return pte;
177*44b6dfc5SSteve Capper }
178*44b6dfc5SSteve Capper 
179*44b6dfc5SSteve Capper static inline pte_t pte_mkyoung(pte_t pte)
180*44b6dfc5SSteve Capper {
181*44b6dfc5SSteve Capper 	pte_val(pte) |= PTE_AF;
182*44b6dfc5SSteve Capper 	return pte;
183*44b6dfc5SSteve Capper }
184*44b6dfc5SSteve Capper 
185*44b6dfc5SSteve Capper static inline pte_t pte_mkspecial(pte_t pte)
186*44b6dfc5SSteve Capper {
187*44b6dfc5SSteve Capper 	pte_val(pte) |= PTE_SPECIAL;
188*44b6dfc5SSteve Capper 	return pte;
189*44b6dfc5SSteve Capper }
1904f04d8f0SCatalin Marinas 
1914f04d8f0SCatalin Marinas static inline void set_pte(pte_t *ptep, pte_t pte)
1924f04d8f0SCatalin Marinas {
1934f04d8f0SCatalin Marinas 	*ptep = pte;
1944f04d8f0SCatalin Marinas }
1954f04d8f0SCatalin Marinas 
1964f04d8f0SCatalin Marinas extern void __sync_icache_dcache(pte_t pteval, unsigned long addr);
1974f04d8f0SCatalin Marinas 
1984f04d8f0SCatalin Marinas static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
1994f04d8f0SCatalin Marinas 			      pte_t *ptep, pte_t pte)
2004f04d8f0SCatalin Marinas {
201a6fadf7eSWill Deacon 	if (pte_valid_user(pte)) {
20202522463SWill Deacon 		if (pte_exec(pte))
2034f04d8f0SCatalin Marinas 			__sync_icache_dcache(pte, addr);
20433eaa58fSCatalin Marinas 		if (!pte_dirty(pte))
20533eaa58fSCatalin Marinas 			pte = pte_wrprotect(pte);
20602522463SWill Deacon 	}
20702522463SWill Deacon 
2084f04d8f0SCatalin Marinas 	set_pte(ptep, pte);
2094f04d8f0SCatalin Marinas }
2104f04d8f0SCatalin Marinas 
2114f04d8f0SCatalin Marinas /*
2124f04d8f0SCatalin Marinas  * Huge pte definitions.
2134f04d8f0SCatalin Marinas  */
214084bd298SSteve Capper #define pte_huge(pte)		(!(pte_val(pte) & PTE_TABLE_BIT))
215084bd298SSteve Capper #define pte_mkhuge(pte)		(__pte(pte_val(pte) & ~PTE_TABLE_BIT))
216084bd298SSteve Capper 
217084bd298SSteve Capper /*
218084bd298SSteve Capper  * Hugetlb definitions.
219084bd298SSteve Capper  */
220084bd298SSteve Capper #define HUGE_MAX_HSTATE		2
221084bd298SSteve Capper #define HPAGE_SHIFT		PMD_SHIFT
222084bd298SSteve Capper #define HPAGE_SIZE		(_AC(1, UL) << HPAGE_SHIFT)
223084bd298SSteve Capper #define HPAGE_MASK		(~(HPAGE_SIZE - 1))
224084bd298SSteve Capper #define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
2254f04d8f0SCatalin Marinas 
2264f04d8f0SCatalin Marinas #define __HAVE_ARCH_PTE_SPECIAL
2274f04d8f0SCatalin Marinas 
2284f04d8f0SCatalin Marinas /*
229af074848SSteve Capper  * Software PMD bits for THP
230af074848SSteve Capper  */
231af074848SSteve Capper 
232af074848SSteve Capper #define PMD_SECT_DIRTY		(_AT(pmdval_t, 1) << 55)
233af074848SSteve Capper #define PMD_SECT_SPLITTING	(_AT(pmdval_t, 1) << 57)
234af074848SSteve Capper 
235af074848SSteve Capper /*
236af074848SSteve Capper  * THP definitions.
237af074848SSteve Capper  */
238af074848SSteve Capper #define pmd_young(pmd)		(pmd_val(pmd) & PMD_SECT_AF)
239af074848SSteve Capper 
240af074848SSteve Capper #define __HAVE_ARCH_PMD_WRITE
241af074848SSteve Capper #define pmd_write(pmd)		(!(pmd_val(pmd) & PMD_SECT_RDONLY))
242af074848SSteve Capper 
243af074848SSteve Capper #ifdef CONFIG_TRANSPARENT_HUGEPAGE
244af074848SSteve Capper #define pmd_trans_huge(pmd)	(pmd_val(pmd) && !(pmd_val(pmd) & PMD_TABLE_BIT))
245af074848SSteve Capper #define pmd_trans_splitting(pmd) (pmd_val(pmd) & PMD_SECT_SPLITTING)
246af074848SSteve Capper #endif
247af074848SSteve Capper 
248af074848SSteve Capper #define PMD_BIT_FUNC(fn,op) \
249af074848SSteve Capper static inline pmd_t pmd_##fn(pmd_t pmd) { pmd_val(pmd) op; return pmd; }
250af074848SSteve Capper 
251af074848SSteve Capper PMD_BIT_FUNC(wrprotect,	|= PMD_SECT_RDONLY);
252af074848SSteve Capper PMD_BIT_FUNC(mkold,	&= ~PMD_SECT_AF);
253af074848SSteve Capper PMD_BIT_FUNC(mksplitting, |= PMD_SECT_SPLITTING);
254af074848SSteve Capper PMD_BIT_FUNC(mkwrite,   &= ~PMD_SECT_RDONLY);
255af074848SSteve Capper PMD_BIT_FUNC(mkdirty,   |= PMD_SECT_DIRTY);
256af074848SSteve Capper PMD_BIT_FUNC(mkyoung,   |= PMD_SECT_AF);
257af074848SSteve Capper PMD_BIT_FUNC(mknotpresent, &= ~PMD_TYPE_MASK);
258af074848SSteve Capper 
259af074848SSteve Capper #define pmd_mkhuge(pmd)		(__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
260af074848SSteve Capper 
261af074848SSteve Capper #define pmd_pfn(pmd)		(((pmd_val(pmd) & PMD_MASK) & PHYS_MASK) >> PAGE_SHIFT)
262af074848SSteve Capper #define pfn_pmd(pfn,prot)	(__pmd(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
263af074848SSteve Capper #define mk_pmd(page,prot)	pfn_pmd(page_to_pfn(page),prot)
264af074848SSteve Capper 
265af074848SSteve Capper #define pmd_page(pmd)           pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
266af074848SSteve Capper 
267af074848SSteve Capper static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
268af074848SSteve Capper {
269af074848SSteve Capper 	const pmdval_t mask = PMD_SECT_USER | PMD_SECT_PXN | PMD_SECT_UXN |
270af074848SSteve Capper 			      PMD_SECT_RDONLY | PMD_SECT_PROT_NONE |
271af074848SSteve Capper 			      PMD_SECT_VALID;
272af074848SSteve Capper 	pmd_val(pmd) = (pmd_val(pmd) & ~mask) | (pgprot_val(newprot) & mask);
273af074848SSteve Capper 	return pmd;
274af074848SSteve Capper }
275af074848SSteve Capper 
276af074848SSteve Capper #define set_pmd_at(mm, addr, pmdp, pmd)	set_pmd(pmdp, pmd)
277af074848SSteve Capper 
278af074848SSteve Capper static inline int has_transparent_hugepage(void)
279af074848SSteve Capper {
280af074848SSteve Capper 	return 1;
281af074848SSteve Capper }
282af074848SSteve Capper 
283af074848SSteve Capper /*
2844f04d8f0SCatalin Marinas  * Mark the prot value as uncacheable and unbufferable.
2854f04d8f0SCatalin Marinas  */
2864f04d8f0SCatalin Marinas #define pgprot_noncached(prot) \
2874f04d8f0SCatalin Marinas 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))
2884f04d8f0SCatalin Marinas #define pgprot_writecombine(prot) \
2894f00130bSCatalin Marinas 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
2904f04d8f0SCatalin Marinas #define pgprot_dmacoherent(prot) \
2914f04d8f0SCatalin Marinas 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
2924f04d8f0SCatalin Marinas #define __HAVE_PHYS_MEM_ACCESS_PROT
2934f04d8f0SCatalin Marinas struct file;
2944f04d8f0SCatalin Marinas extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
2954f04d8f0SCatalin Marinas 				     unsigned long size, pgprot_t vma_prot);
2964f04d8f0SCatalin Marinas 
2974f04d8f0SCatalin Marinas #define pmd_none(pmd)		(!pmd_val(pmd))
2984f04d8f0SCatalin Marinas #define pmd_present(pmd)	(pmd_val(pmd))
2994f04d8f0SCatalin Marinas 
3004f04d8f0SCatalin Marinas #define pmd_bad(pmd)		(!(pmd_val(pmd) & 2))
3014f04d8f0SCatalin Marinas 
30236311607SMarc Zyngier #define pmd_table(pmd)		((pmd_val(pmd) & PMD_TYPE_MASK) == \
30336311607SMarc Zyngier 				 PMD_TYPE_TABLE)
30436311607SMarc Zyngier #define pmd_sect(pmd)		((pmd_val(pmd) & PMD_TYPE_MASK) == \
30536311607SMarc Zyngier 				 PMD_TYPE_SECT)
30636311607SMarc Zyngier 
30736311607SMarc Zyngier 
3084f04d8f0SCatalin Marinas static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
3094f04d8f0SCatalin Marinas {
3104f04d8f0SCatalin Marinas 	*pmdp = pmd;
3114f04d8f0SCatalin Marinas 	dsb();
3124f04d8f0SCatalin Marinas }
3134f04d8f0SCatalin Marinas 
3144f04d8f0SCatalin Marinas static inline void pmd_clear(pmd_t *pmdp)
3154f04d8f0SCatalin Marinas {
3164f04d8f0SCatalin Marinas 	set_pmd(pmdp, __pmd(0));
3174f04d8f0SCatalin Marinas }
3184f04d8f0SCatalin Marinas 
3194f04d8f0SCatalin Marinas static inline pte_t *pmd_page_vaddr(pmd_t pmd)
3204f04d8f0SCatalin Marinas {
3214f04d8f0SCatalin Marinas 	return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK);
3224f04d8f0SCatalin Marinas }
3234f04d8f0SCatalin Marinas 
3244f04d8f0SCatalin Marinas #define pmd_page(pmd)		pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
3254f04d8f0SCatalin Marinas 
3264f04d8f0SCatalin Marinas /*
3274f04d8f0SCatalin Marinas  * Conversion functions: convert a page and protection to a page entry,
3284f04d8f0SCatalin Marinas  * and a page entry and page directory to the page they refer to.
3294f04d8f0SCatalin Marinas  */
3304f04d8f0SCatalin Marinas #define mk_pte(page,prot)	pfn_pte(page_to_pfn(page),prot)
3314f04d8f0SCatalin Marinas 
3324f04d8f0SCatalin Marinas #ifndef CONFIG_ARM64_64K_PAGES
3334f04d8f0SCatalin Marinas 
3344f04d8f0SCatalin Marinas #define pud_none(pud)		(!pud_val(pud))
3354f04d8f0SCatalin Marinas #define pud_bad(pud)		(!(pud_val(pud) & 2))
3364f04d8f0SCatalin Marinas #define pud_present(pud)	(pud_val(pud))
3374f04d8f0SCatalin Marinas 
3384f04d8f0SCatalin Marinas static inline void set_pud(pud_t *pudp, pud_t pud)
3394f04d8f0SCatalin Marinas {
3404f04d8f0SCatalin Marinas 	*pudp = pud;
3414f04d8f0SCatalin Marinas 	dsb();
3424f04d8f0SCatalin Marinas }
3434f04d8f0SCatalin Marinas 
3444f04d8f0SCatalin Marinas static inline void pud_clear(pud_t *pudp)
3454f04d8f0SCatalin Marinas {
3464f04d8f0SCatalin Marinas 	set_pud(pudp, __pud(0));
3474f04d8f0SCatalin Marinas }
3484f04d8f0SCatalin Marinas 
3494f04d8f0SCatalin Marinas static inline pmd_t *pud_page_vaddr(pud_t pud)
3504f04d8f0SCatalin Marinas {
3514f04d8f0SCatalin Marinas 	return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK);
3524f04d8f0SCatalin Marinas }
3534f04d8f0SCatalin Marinas 
3544f04d8f0SCatalin Marinas #endif	/* CONFIG_ARM64_64K_PAGES */
3554f04d8f0SCatalin Marinas 
3564f04d8f0SCatalin Marinas /* to find an entry in a page-table-directory */
3574f04d8f0SCatalin Marinas #define pgd_index(addr)		(((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
3584f04d8f0SCatalin Marinas 
3594f04d8f0SCatalin Marinas #define pgd_offset(mm, addr)	((mm)->pgd+pgd_index(addr))
3604f04d8f0SCatalin Marinas 
3614f04d8f0SCatalin Marinas /* to find an entry in a kernel page-table-directory */
3624f04d8f0SCatalin Marinas #define pgd_offset_k(addr)	pgd_offset(&init_mm, addr)
3634f04d8f0SCatalin Marinas 
3644f04d8f0SCatalin Marinas /* Find an entry in the second-level page table.. */
3654f04d8f0SCatalin Marinas #ifndef CONFIG_ARM64_64K_PAGES
3664f04d8f0SCatalin Marinas #define pmd_index(addr)		(((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
3674f04d8f0SCatalin Marinas static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
3684f04d8f0SCatalin Marinas {
3694f04d8f0SCatalin Marinas 	return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
3704f04d8f0SCatalin Marinas }
3714f04d8f0SCatalin Marinas #endif
3724f04d8f0SCatalin Marinas 
3734f04d8f0SCatalin Marinas /* Find an entry in the third-level page table.. */
3749ab6d02fSWill Deacon #define pte_index(addr)		(((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
3754f04d8f0SCatalin Marinas 
3764f04d8f0SCatalin Marinas static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
3774f04d8f0SCatalin Marinas {
378a6fadf7eSWill Deacon 	const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY |
379a6fadf7eSWill Deacon 			      PTE_PROT_NONE | PTE_VALID;
3804f04d8f0SCatalin Marinas 	pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
3814f04d8f0SCatalin Marinas 	return pte;
3824f04d8f0SCatalin Marinas }
3834f04d8f0SCatalin Marinas 
3844f04d8f0SCatalin Marinas extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
3854f04d8f0SCatalin Marinas extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
3864f04d8f0SCatalin Marinas 
3874f04d8f0SCatalin Marinas #define SWAPPER_DIR_SIZE	(3 * PAGE_SIZE)
3884f04d8f0SCatalin Marinas #define IDMAP_DIR_SIZE		(2 * PAGE_SIZE)
3894f04d8f0SCatalin Marinas 
3904f04d8f0SCatalin Marinas /*
3914f04d8f0SCatalin Marinas  * Encode and decode a swap entry:
3923676f9efSCatalin Marinas  *	bits 0-1:	present (must be zero)
3933676f9efSCatalin Marinas  *	bit  2:		PTE_FILE
3943676f9efSCatalin Marinas  *	bits 3-8:	swap type
3953676f9efSCatalin Marinas  *	bits 9-57:	swap offset
3964f04d8f0SCatalin Marinas  */
3973676f9efSCatalin Marinas #define __SWP_TYPE_SHIFT	3
3984f04d8f0SCatalin Marinas #define __SWP_TYPE_BITS		6
3993676f9efSCatalin Marinas #define __SWP_OFFSET_BITS	49
4004f04d8f0SCatalin Marinas #define __SWP_TYPE_MASK		((1 << __SWP_TYPE_BITS) - 1)
4014f04d8f0SCatalin Marinas #define __SWP_OFFSET_SHIFT	(__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
4023676f9efSCatalin Marinas #define __SWP_OFFSET_MASK	((1UL << __SWP_OFFSET_BITS) - 1)
4034f04d8f0SCatalin Marinas 
4044f04d8f0SCatalin Marinas #define __swp_type(x)		(((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
4053676f9efSCatalin Marinas #define __swp_offset(x)		(((x).val >> __SWP_OFFSET_SHIFT) & __SWP_OFFSET_MASK)
4064f04d8f0SCatalin Marinas #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) })
4074f04d8f0SCatalin Marinas 
4084f04d8f0SCatalin Marinas #define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
4094f04d8f0SCatalin Marinas #define __swp_entry_to_pte(swp)	((pte_t) { (swp).val })
4104f04d8f0SCatalin Marinas 
4114f04d8f0SCatalin Marinas /*
4124f04d8f0SCatalin Marinas  * Ensure that there are not more swap files than can be encoded in the kernel
4134f04d8f0SCatalin Marinas  * the PTEs.
4144f04d8f0SCatalin Marinas  */
4154f04d8f0SCatalin Marinas #define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
4164f04d8f0SCatalin Marinas 
4174f04d8f0SCatalin Marinas /*
4184f04d8f0SCatalin Marinas  * Encode and decode a file entry:
4193676f9efSCatalin Marinas  *	bits 0-1:	present (must be zero)
4203676f9efSCatalin Marinas  *	bit  2:		PTE_FILE
4213676f9efSCatalin Marinas  *	bits 3-57:	file offset / PAGE_SIZE
4224f04d8f0SCatalin Marinas  */
4234f04d8f0SCatalin Marinas #define pte_file(pte)		(pte_val(pte) & PTE_FILE)
4243676f9efSCatalin Marinas #define pte_to_pgoff(x)		(pte_val(x) >> 3)
4253676f9efSCatalin Marinas #define pgoff_to_pte(x)		__pte(((x) << 3) | PTE_FILE)
4264f04d8f0SCatalin Marinas 
4273676f9efSCatalin Marinas #define PTE_FILE_MAX_BITS	55
4284f04d8f0SCatalin Marinas 
4294f04d8f0SCatalin Marinas extern int kern_addr_valid(unsigned long addr);
4304f04d8f0SCatalin Marinas 
4314f04d8f0SCatalin Marinas #include <asm-generic/pgtable.h>
4324f04d8f0SCatalin Marinas 
4334f04d8f0SCatalin Marinas #define pgtable_cache_init() do { } while (0)
4344f04d8f0SCatalin Marinas 
4354f04d8f0SCatalin Marinas #endif /* !__ASSEMBLY__ */
4364f04d8f0SCatalin Marinas 
4374f04d8f0SCatalin Marinas #endif /* __ASM_PGTABLE_H */
438