xref: /linux/arch/arm64/include/asm/pgtable.h (revision a6fadf7e67d3794aae40244f435d281a62736c93)
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  */
27*a6fadf7eSWill Deacon #define PTE_VALID		(_AT(pteval_t, 1) << 0)
28*a6fadf7eSWill Deacon #define PTE_PROT_NONE		(_AT(pteval_t, 1) << 1)	/* only when !PTE_VALID */
294f04d8f0SCatalin Marinas #define PTE_FILE		(_AT(pteval_t, 1) << 2)	/* only when !pte_present() */
304f04d8f0SCatalin Marinas #define PTE_DIRTY		(_AT(pteval_t, 1) << 55)
314f04d8f0SCatalin Marinas #define PTE_SPECIAL		(_AT(pteval_t, 1) << 56)
324f04d8f0SCatalin Marinas 
334f04d8f0SCatalin Marinas /*
344f04d8f0SCatalin Marinas  * VMALLOC and SPARSEMEM_VMEMMAP ranges.
354f04d8f0SCatalin Marinas  */
364f04d8f0SCatalin Marinas #define VMALLOC_START		UL(0xffffff8000000000)
374f04d8f0SCatalin Marinas #define VMALLOC_END		(PAGE_OFFSET - UL(0x400000000) - SZ_64K)
384f04d8f0SCatalin Marinas 
394f04d8f0SCatalin Marinas #define vmemmap			((struct page *)(VMALLOC_END + SZ_64K))
404f04d8f0SCatalin Marinas 
414f04d8f0SCatalin Marinas #define FIRST_USER_ADDRESS	0
424f04d8f0SCatalin Marinas 
434f04d8f0SCatalin Marinas #ifndef __ASSEMBLY__
444f04d8f0SCatalin Marinas extern void __pte_error(const char *file, int line, unsigned long val);
454f04d8f0SCatalin Marinas extern void __pmd_error(const char *file, int line, unsigned long val);
464f04d8f0SCatalin Marinas extern void __pgd_error(const char *file, int line, unsigned long val);
474f04d8f0SCatalin Marinas 
484f04d8f0SCatalin Marinas #define pte_ERROR(pte)		__pte_error(__FILE__, __LINE__, pte_val(pte))
494f04d8f0SCatalin Marinas #ifndef CONFIG_ARM64_64K_PAGES
504f04d8f0SCatalin Marinas #define pmd_ERROR(pmd)		__pmd_error(__FILE__, __LINE__, pmd_val(pmd))
514f04d8f0SCatalin Marinas #endif
524f04d8f0SCatalin Marinas #define pgd_ERROR(pgd)		__pgd_error(__FILE__, __LINE__, pgd_val(pgd))
534f04d8f0SCatalin Marinas 
544f04d8f0SCatalin Marinas /*
554f04d8f0SCatalin Marinas  * The pgprot_* and protection_map entries will be fixed up at runtime to
564f04d8f0SCatalin Marinas  * include the cachable and bufferable bits based on memory policy, as well as
574f04d8f0SCatalin Marinas  * any architecture dependent bits like global/ASID and SMP shared mapping
584f04d8f0SCatalin Marinas  * bits.
594f04d8f0SCatalin Marinas  */
604f04d8f0SCatalin Marinas #define _PAGE_DEFAULT		PTE_TYPE_PAGE | PTE_AF
614f04d8f0SCatalin Marinas 
624f04d8f0SCatalin Marinas extern pgprot_t pgprot_default;
634f04d8f0SCatalin Marinas 
64*a6fadf7eSWill Deacon #define __pgprot_modify(prot,mask,bits) \
65*a6fadf7eSWill Deacon 	__pgprot((pgprot_val(prot) & ~(mask)) | (bits))
664f04d8f0SCatalin Marinas 
67*a6fadf7eSWill Deacon #define _MOD_PROT(p, b)		__pgprot_modify(p, 0, b)
68*a6fadf7eSWill Deacon 
69*a6fadf7eSWill Deacon #define PAGE_NONE		__pgprot_modify(pgprot_default, PTE_TYPE_MASK, PTE_PROT_NONE)
708e620b04SCatalin Marinas #define PAGE_SHARED		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
718e620b04SCatalin Marinas #define PAGE_SHARED_EXEC	_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN)
728e620b04SCatalin Marinas #define PAGE_COPY		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
738e620b04SCatalin Marinas #define PAGE_COPY_EXEC		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
748e620b04SCatalin Marinas #define PAGE_READONLY		_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
758e620b04SCatalin Marinas #define PAGE_READONLY_EXEC	_MOD_PROT(pgprot_default, PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
768e620b04SCatalin Marinas #define PAGE_KERNEL		_MOD_PROT(pgprot_default, PTE_PXN | PTE_UXN | PTE_DIRTY)
778e620b04SCatalin Marinas #define PAGE_KERNEL_EXEC	_MOD_PROT(pgprot_default, PTE_UXN | PTE_DIRTY)
784f04d8f0SCatalin Marinas 
79*a6fadf7eSWill Deacon #define __PAGE_NONE		__pgprot(((_PAGE_DEFAULT) & ~PTE_TYPE_MASK) | PTE_PROT_NONE)
808e620b04SCatalin Marinas #define __PAGE_SHARED		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
818e620b04SCatalin Marinas #define __PAGE_SHARED_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
828e620b04SCatalin Marinas #define __PAGE_COPY		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
838e620b04SCatalin Marinas #define __PAGE_COPY_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
848e620b04SCatalin Marinas #define __PAGE_READONLY		__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN | PTE_RDONLY)
858e620b04SCatalin Marinas #define __PAGE_READONLY_EXEC	__pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_RDONLY)
864f04d8f0SCatalin Marinas 
874f04d8f0SCatalin Marinas #endif /* __ASSEMBLY__ */
884f04d8f0SCatalin Marinas 
894f04d8f0SCatalin Marinas #define __P000  __PAGE_NONE
904f04d8f0SCatalin Marinas #define __P001  __PAGE_READONLY
914f04d8f0SCatalin Marinas #define __P010  __PAGE_COPY
924f04d8f0SCatalin Marinas #define __P011  __PAGE_COPY
934f04d8f0SCatalin Marinas #define __P100  __PAGE_READONLY_EXEC
944f04d8f0SCatalin Marinas #define __P101  __PAGE_READONLY_EXEC
954f04d8f0SCatalin Marinas #define __P110  __PAGE_COPY_EXEC
964f04d8f0SCatalin Marinas #define __P111  __PAGE_COPY_EXEC
974f04d8f0SCatalin Marinas 
984f04d8f0SCatalin Marinas #define __S000  __PAGE_NONE
994f04d8f0SCatalin Marinas #define __S001  __PAGE_READONLY
1004f04d8f0SCatalin Marinas #define __S010  __PAGE_SHARED
1014f04d8f0SCatalin Marinas #define __S011  __PAGE_SHARED
1024f04d8f0SCatalin Marinas #define __S100  __PAGE_READONLY_EXEC
1034f04d8f0SCatalin Marinas #define __S101  __PAGE_READONLY_EXEC
1044f04d8f0SCatalin Marinas #define __S110  __PAGE_SHARED_EXEC
1054f04d8f0SCatalin Marinas #define __S111  __PAGE_SHARED_EXEC
1064f04d8f0SCatalin Marinas 
1074f04d8f0SCatalin Marinas #ifndef __ASSEMBLY__
1084f04d8f0SCatalin Marinas /*
1094f04d8f0SCatalin Marinas  * ZERO_PAGE is a global shared page that is always zero: used
1104f04d8f0SCatalin Marinas  * for zero-mapped memory areas etc..
1114f04d8f0SCatalin Marinas  */
1124f04d8f0SCatalin Marinas extern struct page *empty_zero_page;
1134f04d8f0SCatalin Marinas #define ZERO_PAGE(vaddr)	(empty_zero_page)
1144f04d8f0SCatalin Marinas 
1154f04d8f0SCatalin Marinas #define pte_pfn(pte)		((pte_val(pte) & PHYS_MASK) >> PAGE_SHIFT)
1164f04d8f0SCatalin Marinas 
1174f04d8f0SCatalin Marinas #define pfn_pte(pfn,prot)	(__pte(((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot)))
1184f04d8f0SCatalin Marinas 
1194f04d8f0SCatalin Marinas #define pte_none(pte)		(!pte_val(pte))
1204f04d8f0SCatalin Marinas #define pte_clear(mm,addr,ptep)	set_pte(ptep, __pte(0))
1214f04d8f0SCatalin Marinas #define pte_page(pte)		(pfn_to_page(pte_pfn(pte)))
1224f04d8f0SCatalin Marinas #define pte_offset_kernel(dir,addr)	(pmd_page_vaddr(*(dir)) + __pte_index(addr))
1234f04d8f0SCatalin Marinas 
1244f04d8f0SCatalin Marinas #define pte_offset_map(dir,addr)	pte_offset_kernel((dir), (addr))
1254f04d8f0SCatalin Marinas #define pte_offset_map_nested(dir,addr)	pte_offset_kernel((dir), (addr))
1264f04d8f0SCatalin Marinas #define pte_unmap(pte)			do { } while (0)
1274f04d8f0SCatalin Marinas #define pte_unmap_nested(pte)		do { } while (0)
1284f04d8f0SCatalin Marinas 
1294f04d8f0SCatalin Marinas /*
1304f04d8f0SCatalin Marinas  * The following only work if pte_present(). Undefined behaviour otherwise.
1314f04d8f0SCatalin Marinas  */
132*a6fadf7eSWill Deacon #define pte_present(pte)	(pte_val(pte) & (PTE_VALID | PTE_PROT_NONE))
1334f04d8f0SCatalin Marinas #define pte_dirty(pte)		(pte_val(pte) & PTE_DIRTY)
1344f04d8f0SCatalin Marinas #define pte_young(pte)		(pte_val(pte) & PTE_AF)
1354f04d8f0SCatalin Marinas #define pte_special(pte)	(pte_val(pte) & PTE_SPECIAL)
1364f04d8f0SCatalin Marinas #define pte_write(pte)		(!(pte_val(pte) & PTE_RDONLY))
1378e620b04SCatalin Marinas #define pte_exec(pte)		(!(pte_val(pte) & PTE_UXN))
1384f04d8f0SCatalin Marinas 
139*a6fadf7eSWill Deacon #define pte_valid_user(pte) \
14002522463SWill Deacon 	((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
1414f04d8f0SCatalin Marinas 
1424f04d8f0SCatalin Marinas #define PTE_BIT_FUNC(fn,op) \
1434f04d8f0SCatalin Marinas static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; }
1444f04d8f0SCatalin Marinas 
1454f04d8f0SCatalin Marinas PTE_BIT_FUNC(wrprotect, |= PTE_RDONLY);
1464f04d8f0SCatalin Marinas PTE_BIT_FUNC(mkwrite,   &= ~PTE_RDONLY);
1474f04d8f0SCatalin Marinas PTE_BIT_FUNC(mkclean,   &= ~PTE_DIRTY);
1484f04d8f0SCatalin Marinas PTE_BIT_FUNC(mkdirty,   |= PTE_DIRTY);
1494f04d8f0SCatalin Marinas PTE_BIT_FUNC(mkold,     &= ~PTE_AF);
1504f04d8f0SCatalin Marinas PTE_BIT_FUNC(mkyoung,   |= PTE_AF);
1514f04d8f0SCatalin Marinas PTE_BIT_FUNC(mkspecial, |= PTE_SPECIAL);
1524f04d8f0SCatalin Marinas 
1534f04d8f0SCatalin Marinas static inline void set_pte(pte_t *ptep, pte_t pte)
1544f04d8f0SCatalin Marinas {
1554f04d8f0SCatalin Marinas 	*ptep = pte;
1564f04d8f0SCatalin Marinas }
1574f04d8f0SCatalin Marinas 
1584f04d8f0SCatalin Marinas extern void __sync_icache_dcache(pte_t pteval, unsigned long addr);
1594f04d8f0SCatalin Marinas 
1604f04d8f0SCatalin Marinas static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
1614f04d8f0SCatalin Marinas 			      pte_t *ptep, pte_t pte)
1624f04d8f0SCatalin Marinas {
163*a6fadf7eSWill Deacon 	if (pte_valid_user(pte)) {
16402522463SWill Deacon 		if (pte_exec(pte))
1654f04d8f0SCatalin Marinas 			__sync_icache_dcache(pte, addr);
16633eaa58fSCatalin Marinas 		if (!pte_dirty(pte))
16733eaa58fSCatalin Marinas 			pte = pte_wrprotect(pte);
16802522463SWill Deacon 	}
16902522463SWill Deacon 
1704f04d8f0SCatalin Marinas 	set_pte(ptep, pte);
1714f04d8f0SCatalin Marinas }
1724f04d8f0SCatalin Marinas 
1734f04d8f0SCatalin Marinas /*
1744f04d8f0SCatalin Marinas  * Huge pte definitions.
1754f04d8f0SCatalin Marinas  */
1764f04d8f0SCatalin Marinas #define pte_huge(pte)		((pte_val(pte) & PTE_TYPE_MASK) == PTE_TYPE_HUGEPAGE)
1774f04d8f0SCatalin Marinas #define pte_mkhuge(pte)		(__pte((pte_val(pte) & ~PTE_TYPE_MASK) | PTE_TYPE_HUGEPAGE))
1784f04d8f0SCatalin Marinas 
1794f04d8f0SCatalin Marinas #define __HAVE_ARCH_PTE_SPECIAL
1804f04d8f0SCatalin Marinas 
1814f04d8f0SCatalin Marinas /*
1824f04d8f0SCatalin Marinas  * Mark the prot value as uncacheable and unbufferable.
1834f04d8f0SCatalin Marinas  */
1844f04d8f0SCatalin Marinas #define pgprot_noncached(prot) \
1854f04d8f0SCatalin Marinas 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_nGnRnE))
1864f04d8f0SCatalin Marinas #define pgprot_writecombine(prot) \
1874f04d8f0SCatalin Marinas 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_DEVICE_GRE))
1884f04d8f0SCatalin Marinas #define pgprot_dmacoherent(prot) \
1894f04d8f0SCatalin Marinas 	__pgprot_modify(prot, PTE_ATTRINDX_MASK, PTE_ATTRINDX(MT_NORMAL_NC))
1904f04d8f0SCatalin Marinas #define __HAVE_PHYS_MEM_ACCESS_PROT
1914f04d8f0SCatalin Marinas struct file;
1924f04d8f0SCatalin Marinas extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
1934f04d8f0SCatalin Marinas 				     unsigned long size, pgprot_t vma_prot);
1944f04d8f0SCatalin Marinas 
1954f04d8f0SCatalin Marinas #define pmd_none(pmd)		(!pmd_val(pmd))
1964f04d8f0SCatalin Marinas #define pmd_present(pmd)	(pmd_val(pmd))
1974f04d8f0SCatalin Marinas 
1984f04d8f0SCatalin Marinas #define pmd_bad(pmd)		(!(pmd_val(pmd) & 2))
1994f04d8f0SCatalin Marinas 
2004f04d8f0SCatalin Marinas static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
2014f04d8f0SCatalin Marinas {
2024f04d8f0SCatalin Marinas 	*pmdp = pmd;
2034f04d8f0SCatalin Marinas 	dsb();
2044f04d8f0SCatalin Marinas }
2054f04d8f0SCatalin Marinas 
2064f04d8f0SCatalin Marinas static inline void pmd_clear(pmd_t *pmdp)
2074f04d8f0SCatalin Marinas {
2084f04d8f0SCatalin Marinas 	set_pmd(pmdp, __pmd(0));
2094f04d8f0SCatalin Marinas }
2104f04d8f0SCatalin Marinas 
2114f04d8f0SCatalin Marinas static inline pte_t *pmd_page_vaddr(pmd_t pmd)
2124f04d8f0SCatalin Marinas {
2134f04d8f0SCatalin Marinas 	return __va(pmd_val(pmd) & PHYS_MASK & (s32)PAGE_MASK);
2144f04d8f0SCatalin Marinas }
2154f04d8f0SCatalin Marinas 
2164f04d8f0SCatalin Marinas #define pmd_page(pmd)		pfn_to_page(__phys_to_pfn(pmd_val(pmd) & PHYS_MASK))
2174f04d8f0SCatalin Marinas 
2184f04d8f0SCatalin Marinas /*
2194f04d8f0SCatalin Marinas  * Conversion functions: convert a page and protection to a page entry,
2204f04d8f0SCatalin Marinas  * and a page entry and page directory to the page they refer to.
2214f04d8f0SCatalin Marinas  */
2224f04d8f0SCatalin Marinas #define mk_pte(page,prot)	pfn_pte(page_to_pfn(page),prot)
2234f04d8f0SCatalin Marinas 
2244f04d8f0SCatalin Marinas #ifndef CONFIG_ARM64_64K_PAGES
2254f04d8f0SCatalin Marinas 
2264f04d8f0SCatalin Marinas #define pud_none(pud)		(!pud_val(pud))
2274f04d8f0SCatalin Marinas #define pud_bad(pud)		(!(pud_val(pud) & 2))
2284f04d8f0SCatalin Marinas #define pud_present(pud)	(pud_val(pud))
2294f04d8f0SCatalin Marinas 
2304f04d8f0SCatalin Marinas static inline void set_pud(pud_t *pudp, pud_t pud)
2314f04d8f0SCatalin Marinas {
2324f04d8f0SCatalin Marinas 	*pudp = pud;
2334f04d8f0SCatalin Marinas 	dsb();
2344f04d8f0SCatalin Marinas }
2354f04d8f0SCatalin Marinas 
2364f04d8f0SCatalin Marinas static inline void pud_clear(pud_t *pudp)
2374f04d8f0SCatalin Marinas {
2384f04d8f0SCatalin Marinas 	set_pud(pudp, __pud(0));
2394f04d8f0SCatalin Marinas }
2404f04d8f0SCatalin Marinas 
2414f04d8f0SCatalin Marinas static inline pmd_t *pud_page_vaddr(pud_t pud)
2424f04d8f0SCatalin Marinas {
2434f04d8f0SCatalin Marinas 	return __va(pud_val(pud) & PHYS_MASK & (s32)PAGE_MASK);
2444f04d8f0SCatalin Marinas }
2454f04d8f0SCatalin Marinas 
2464f04d8f0SCatalin Marinas #endif	/* CONFIG_ARM64_64K_PAGES */
2474f04d8f0SCatalin Marinas 
2484f04d8f0SCatalin Marinas /* to find an entry in a page-table-directory */
2494f04d8f0SCatalin Marinas #define pgd_index(addr)		(((addr) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1))
2504f04d8f0SCatalin Marinas 
2514f04d8f0SCatalin Marinas #define pgd_offset(mm, addr)	((mm)->pgd+pgd_index(addr))
2524f04d8f0SCatalin Marinas 
2534f04d8f0SCatalin Marinas /* to find an entry in a kernel page-table-directory */
2544f04d8f0SCatalin Marinas #define pgd_offset_k(addr)	pgd_offset(&init_mm, addr)
2554f04d8f0SCatalin Marinas 
2564f04d8f0SCatalin Marinas /* Find an entry in the second-level page table.. */
2574f04d8f0SCatalin Marinas #ifndef CONFIG_ARM64_64K_PAGES
2584f04d8f0SCatalin Marinas #define pmd_index(addr)		(((addr) >> PMD_SHIFT) & (PTRS_PER_PMD - 1))
2594f04d8f0SCatalin Marinas static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
2604f04d8f0SCatalin Marinas {
2614f04d8f0SCatalin Marinas 	return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(addr);
2624f04d8f0SCatalin Marinas }
2634f04d8f0SCatalin Marinas #endif
2644f04d8f0SCatalin Marinas 
2654f04d8f0SCatalin Marinas /* Find an entry in the third-level page table.. */
2664f04d8f0SCatalin Marinas #define __pte_index(addr)	(((addr) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
2674f04d8f0SCatalin Marinas 
2684f04d8f0SCatalin Marinas static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
2694f04d8f0SCatalin Marinas {
270*a6fadf7eSWill Deacon 	const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY |
271*a6fadf7eSWill Deacon 			      PTE_PROT_NONE | PTE_VALID;
2724f04d8f0SCatalin Marinas 	pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask);
2734f04d8f0SCatalin Marinas 	return pte;
2744f04d8f0SCatalin Marinas }
2754f04d8f0SCatalin Marinas 
2764f04d8f0SCatalin Marinas extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
2774f04d8f0SCatalin Marinas extern pgd_t idmap_pg_dir[PTRS_PER_PGD];
2784f04d8f0SCatalin Marinas 
2794f04d8f0SCatalin Marinas #define SWAPPER_DIR_SIZE	(3 * PAGE_SIZE)
2804f04d8f0SCatalin Marinas #define IDMAP_DIR_SIZE		(2 * PAGE_SIZE)
2814f04d8f0SCatalin Marinas 
2824f04d8f0SCatalin Marinas /*
2834f04d8f0SCatalin Marinas  * Encode and decode a swap entry:
2844f04d8f0SCatalin Marinas  *	bits 0-1:	present (must be zero)
2854f04d8f0SCatalin Marinas  *	bit  2:		PTE_FILE
2864f04d8f0SCatalin Marinas  *	bits 3-8:	swap type
2874f04d8f0SCatalin Marinas  *	bits 9-63:	swap offset
2884f04d8f0SCatalin Marinas  */
2894f04d8f0SCatalin Marinas #define __SWP_TYPE_SHIFT	3
2904f04d8f0SCatalin Marinas #define __SWP_TYPE_BITS		6
2914f04d8f0SCatalin Marinas #define __SWP_TYPE_MASK		((1 << __SWP_TYPE_BITS) - 1)
2924f04d8f0SCatalin Marinas #define __SWP_OFFSET_SHIFT	(__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
2934f04d8f0SCatalin Marinas 
2944f04d8f0SCatalin Marinas #define __swp_type(x)		(((x).val >> __SWP_TYPE_SHIFT) & __SWP_TYPE_MASK)
2954f04d8f0SCatalin Marinas #define __swp_offset(x)		((x).val >> __SWP_OFFSET_SHIFT)
2964f04d8f0SCatalin Marinas #define __swp_entry(type,offset) ((swp_entry_t) { ((type) << __SWP_TYPE_SHIFT) | ((offset) << __SWP_OFFSET_SHIFT) })
2974f04d8f0SCatalin Marinas 
2984f04d8f0SCatalin Marinas #define __pte_to_swp_entry(pte)	((swp_entry_t) { pte_val(pte) })
2994f04d8f0SCatalin Marinas #define __swp_entry_to_pte(swp)	((pte_t) { (swp).val })
3004f04d8f0SCatalin Marinas 
3014f04d8f0SCatalin Marinas /*
3024f04d8f0SCatalin Marinas  * Ensure that there are not more swap files than can be encoded in the kernel
3034f04d8f0SCatalin Marinas  * the PTEs.
3044f04d8f0SCatalin Marinas  */
3054f04d8f0SCatalin Marinas #define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
3064f04d8f0SCatalin Marinas 
3074f04d8f0SCatalin Marinas /*
3084f04d8f0SCatalin Marinas  * Encode and decode a file entry:
3094f04d8f0SCatalin Marinas  *	bits 0-1:	present (must be zero)
3104f04d8f0SCatalin Marinas  *	bit  2:		PTE_FILE
3114f04d8f0SCatalin Marinas  *	bits 3-63:	file offset / PAGE_SIZE
3124f04d8f0SCatalin Marinas  */
3134f04d8f0SCatalin Marinas #define pte_file(pte)		(pte_val(pte) & PTE_FILE)
3144f04d8f0SCatalin Marinas #define pte_to_pgoff(x)		(pte_val(x) >> 3)
3154f04d8f0SCatalin Marinas #define pgoff_to_pte(x)		__pte(((x) << 3) | PTE_FILE)
3164f04d8f0SCatalin Marinas 
3174f04d8f0SCatalin Marinas #define PTE_FILE_MAX_BITS	61
3184f04d8f0SCatalin Marinas 
3194f04d8f0SCatalin Marinas extern int kern_addr_valid(unsigned long addr);
3204f04d8f0SCatalin Marinas 
3214f04d8f0SCatalin Marinas #include <asm-generic/pgtable.h>
3224f04d8f0SCatalin Marinas 
3234f04d8f0SCatalin Marinas /*
3244f04d8f0SCatalin Marinas  * remap a physical page `pfn' of size `size' with page protection `prot'
3254f04d8f0SCatalin Marinas  * into virtual address `from'
3264f04d8f0SCatalin Marinas  */
3274f04d8f0SCatalin Marinas #define io_remap_pfn_range(vma,from,pfn,size,prot) \
3284f04d8f0SCatalin Marinas 		remap_pfn_range(vma, from, pfn, size, prot)
3294f04d8f0SCatalin Marinas 
3304f04d8f0SCatalin Marinas #define pgtable_cache_init() do { } while (0)
3314f04d8f0SCatalin Marinas 
3324f04d8f0SCatalin Marinas #endif /* !__ASSEMBLY__ */
3334f04d8f0SCatalin Marinas 
3344f04d8f0SCatalin Marinas #endif /* __ASM_PGTABLE_H */
335