xref: /openbmc/linux/arch/arm/mm/mmu.c (revision f6d73b12ca9fd3b1c29a6a725cd751b972c740cf)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2d111e8f9SRussell King /*
3d111e8f9SRussell King  *  linux/arch/arm/mm/mmu.c
4d111e8f9SRussell King  *
5d111e8f9SRussell King  *  Copyright (C) 1995-2005 Russell King
6d111e8f9SRussell King  */
7ae8f1541SRussell King #include <linux/module.h>
8d111e8f9SRussell King #include <linux/kernel.h>
9d111e8f9SRussell King #include <linux/errno.h>
10d111e8f9SRussell King #include <linux/init.h>
11d111e8f9SRussell King #include <linux/mman.h>
12d111e8f9SRussell King #include <linux/nodemask.h>
132778f620SRussell King #include <linux/memblock.h>
14d907387cSCatalin Marinas #include <linux/fs.h>
150536bdf3SNicolas Pitre #include <linux/vmalloc.h>
16158e8bfeSAlessandro Rubini #include <linux/sizes.h>
17d111e8f9SRussell King 
1815d07dc9SRussell King #include <asm/cp15.h>
190ba8b9b2SRussell King #include <asm/cputype.h>
203f973e22SNicolas Pitre #include <asm/cachetype.h>
21ebd4922eSRussell King #include <asm/sections.h>
22d111e8f9SRussell King #include <asm/setup.h>
23e616c591SRussell King #include <asm/smp_plat.h>
24aecc83e5SArnd Bergmann #include <asm/tcm.h>
25d111e8f9SRussell King #include <asm/tlb.h>
26d73cd428SNicolas Pitre #include <asm/highmem.h>
279f97da78SDavid Howells #include <asm/system_info.h>
28247055aaSCatalin Marinas #include <asm/traps.h>
29a77e0c7bSSantosh Shilimkar #include <asm/procinfo.h>
30a9ff6961SLinus Walleij #include <asm/page.h>
31ca15ca40SMike Rapoport #include <asm/pgalloc.h>
32c12366baSLinus Walleij #include <asm/kasan_def.h>
33d111e8f9SRussell King 
34d111e8f9SRussell King #include <asm/mach/arch.h>
35d111e8f9SRussell King #include <asm/mach/map.h>
36c2794437SRob Herring #include <asm/mach/pci.h>
37a05e54c1SLiu Hua #include <asm/fixmap.h>
38d111e8f9SRussell King 
399254970cSLucas Stach #include "fault.h"
40d111e8f9SRussell King #include "mm.h"
41d111e8f9SRussell King 
427a1be318SArd Biesheuvel extern unsigned long __atags_pointer;
437a1be318SArd Biesheuvel 
44d111e8f9SRussell King /*
45d111e8f9SRussell King  * empty_zero_page is a special page that is used for
46d111e8f9SRussell King  * zero-initialized data and COW.
47d111e8f9SRussell King  */
48d111e8f9SRussell King struct page *empty_zero_page;
493653f3abSAneesh Kumar K.V EXPORT_SYMBOL(empty_zero_page);
50d111e8f9SRussell King 
51d111e8f9SRussell King /*
52d111e8f9SRussell King  * The pmd table for the upper-most set of pages.
53d111e8f9SRussell King  */
54d111e8f9SRussell King pmd_t *top_pmd;
55d111e8f9SRussell King 
561d4d3715SJungseung Lee pmdval_t user_pmd_table = _PAGE_USER_TABLE;
571d4d3715SJungseung Lee 
58ae8f1541SRussell King #define CPOLICY_UNCACHED	0
59ae8f1541SRussell King #define CPOLICY_BUFFERED	1
60ae8f1541SRussell King #define CPOLICY_WRITETHROUGH	2
61ae8f1541SRussell King #define CPOLICY_WRITEBACK	3
62ae8f1541SRussell King #define CPOLICY_WRITEALLOC	4
63ae8f1541SRussell King 
64ae8f1541SRussell King static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK;
65ae8f1541SRussell King static unsigned int ecc_mask __initdata = 0;
6644b18693SImre_Deak pgprot_t pgprot_user;
67ae8f1541SRussell King pgprot_t pgprot_kernel;
68ae8f1541SRussell King 
6944b18693SImre_Deak EXPORT_SYMBOL(pgprot_user);
70ae8f1541SRussell King EXPORT_SYMBOL(pgprot_kernel);
71ae8f1541SRussell King 
72ae8f1541SRussell King struct cachepolicy {
73ae8f1541SRussell King 	const char	policy[16];
74ae8f1541SRussell King 	unsigned int	cr_mask;
75442e70c0SCatalin Marinas 	pmdval_t	pmd;
76f6e3354dSRussell King 	pteval_t	pte;
77ae8f1541SRussell King };
78ae8f1541SRussell King 
79ae8f1541SRussell King static struct cachepolicy cache_policies[] __initdata = {
80ae8f1541SRussell King 	{
81ae8f1541SRussell King 		.policy		= "uncached",
82ae8f1541SRussell King 		.cr_mask	= CR_W|CR_C,
83ae8f1541SRussell King 		.pmd		= PMD_SECT_UNCACHED,
84bb30f36fSRussell King 		.pte		= L_PTE_MT_UNCACHED,
85ae8f1541SRussell King 	}, {
86ae8f1541SRussell King 		.policy		= "buffered",
87ae8f1541SRussell King 		.cr_mask	= CR_C,
88ae8f1541SRussell King 		.pmd		= PMD_SECT_BUFFERED,
89bb30f36fSRussell King 		.pte		= L_PTE_MT_BUFFERABLE,
90ae8f1541SRussell King 	}, {
91ae8f1541SRussell King 		.policy		= "writethrough",
92ae8f1541SRussell King 		.cr_mask	= 0,
93ae8f1541SRussell King 		.pmd		= PMD_SECT_WT,
94bb30f36fSRussell King 		.pte		= L_PTE_MT_WRITETHROUGH,
95ae8f1541SRussell King 	}, {
96ae8f1541SRussell King 		.policy		= "writeback",
97ae8f1541SRussell King 		.cr_mask	= 0,
98ae8f1541SRussell King 		.pmd		= PMD_SECT_WB,
99bb30f36fSRussell King 		.pte		= L_PTE_MT_WRITEBACK,
100ae8f1541SRussell King 	}, {
101ae8f1541SRussell King 		.policy		= "writealloc",
102ae8f1541SRussell King 		.cr_mask	= 0,
103ae8f1541SRussell King 		.pmd		= PMD_SECT_WBWA,
104bb30f36fSRussell King 		.pte		= L_PTE_MT_WRITEALLOC,
105ae8f1541SRussell King 	}
106ae8f1541SRussell King };
107ae8f1541SRussell King 
108b849a60eSUwe Kleine-König #ifdef CONFIG_CPU_CP15
10920e7e364SRussell King static unsigned long initial_pmd_value __initdata = 0;
11020e7e364SRussell King 
111ae8f1541SRussell King /*
112ca8f0b0aSRussell King  * Initialise the cache_policy variable with the initial state specified
113ca8f0b0aSRussell King  * via the "pmd" value.  This is used to ensure that on ARMv6 and later,
114ca8f0b0aSRussell King  * the C code sets the page tables up with the same policy as the head
115ca8f0b0aSRussell King  * assembly code, which avoids an illegal state where the TLBs can get
116ca8f0b0aSRussell King  * confused.  See comments in early_cachepolicy() for more information.
117ca8f0b0aSRussell King  */
init_default_cache_policy(unsigned long pmd)118ca8f0b0aSRussell King void __init init_default_cache_policy(unsigned long pmd)
119ca8f0b0aSRussell King {
120ca8f0b0aSRussell King 	int i;
121ca8f0b0aSRussell King 
12220e7e364SRussell King 	initial_pmd_value = pmd;
12320e7e364SRussell King 
1246b3142b2SStefan Agner 	pmd &= PMD_SECT_CACHE_MASK;
125ca8f0b0aSRussell King 
126ca8f0b0aSRussell King 	for (i = 0; i < ARRAY_SIZE(cache_policies); i++)
127ca8f0b0aSRussell King 		if (cache_policies[i].pmd == pmd) {
128ca8f0b0aSRussell King 			cachepolicy = i;
129ca8f0b0aSRussell King 			break;
130ca8f0b0aSRussell King 		}
131ca8f0b0aSRussell King 
132ca8f0b0aSRussell King 	if (i == ARRAY_SIZE(cache_policies))
133ca8f0b0aSRussell King 		pr_err("ERROR: could not find cache policy\n");
134ca8f0b0aSRussell King }
135ca8f0b0aSRussell King 
136ca8f0b0aSRussell King /*
137ca8f0b0aSRussell King  * These are useful for identifying cache coherency problems by allowing
138ca8f0b0aSRussell King  * the cache or the cache and writebuffer to be turned off.  (Note: the
139ca8f0b0aSRussell King  * write buffer should not be on and the cache off).
140ae8f1541SRussell King  */
early_cachepolicy(char * p)1412b0d8c25SJeremy Kerr static int __init early_cachepolicy(char *p)
142ae8f1541SRussell King {
143ca8f0b0aSRussell King 	int i, selected = -1;
144ae8f1541SRussell King 
145ae8f1541SRussell King 	for (i = 0; i < ARRAY_SIZE(cache_policies); i++) {
146ae8f1541SRussell King 		int len = strlen(cache_policies[i].policy);
147ae8f1541SRussell King 
1482b0d8c25SJeremy Kerr 		if (memcmp(p, cache_policies[i].policy, len) == 0) {
149ca8f0b0aSRussell King 			selected = i;
150ae8f1541SRussell King 			break;
151ae8f1541SRussell King 		}
152ae8f1541SRussell King 	}
153ca8f0b0aSRussell King 
154ca8f0b0aSRussell King 	if (selected == -1)
155ca8f0b0aSRussell King 		pr_err("ERROR: unknown or unsupported cache policy\n");
156ca8f0b0aSRussell King 
1574b46d641SRussell King 	/*
1584b46d641SRussell King 	 * This restriction is partly to do with the way we boot; it is
1594b46d641SRussell King 	 * unpredictable to have memory mapped using two different sets of
1604b46d641SRussell King 	 * memory attributes (shared, type, and cache attribs).  We can not
1614b46d641SRussell King 	 * change these attributes once the initial assembly has setup the
1624b46d641SRussell King 	 * page tables.
1634b46d641SRussell King 	 */
164ca8f0b0aSRussell King 	if (cpu_architecture() >= CPU_ARCH_ARMv6 && selected != cachepolicy) {
165ca8f0b0aSRussell King 		pr_warn("Only cachepolicy=%s supported on ARMv6 and later\n",
166ca8f0b0aSRussell King 			cache_policies[cachepolicy].policy);
167ca8f0b0aSRussell King 		return 0;
16811179d8cSCatalin Marinas 	}
169ca8f0b0aSRussell King 
170ca8f0b0aSRussell King 	if (selected != cachepolicy) {
171ca8f0b0aSRussell King 		unsigned long cr = __clear_cr(cache_policies[selected].cr_mask);
172ca8f0b0aSRussell King 		cachepolicy = selected;
173ae8f1541SRussell King 		flush_cache_all();
174b4b20ad8SRussell King 		set_cr(cr);
175ca8f0b0aSRussell King 	}
1762b0d8c25SJeremy Kerr 	return 0;
177ae8f1541SRussell King }
1782b0d8c25SJeremy Kerr early_param("cachepolicy", early_cachepolicy);
179ae8f1541SRussell King 
early_nocache(char * __unused)1802b0d8c25SJeremy Kerr static int __init early_nocache(char *__unused)
181ae8f1541SRussell King {
182ae8f1541SRussell King 	char *p = "buffered";
1834ed89f22SRussell King 	pr_warn("nocache is deprecated; use cachepolicy=%s\n", p);
1842b0d8c25SJeremy Kerr 	early_cachepolicy(p);
1852b0d8c25SJeremy Kerr 	return 0;
186ae8f1541SRussell King }
1872b0d8c25SJeremy Kerr early_param("nocache", early_nocache);
188ae8f1541SRussell King 
early_nowrite(char * __unused)1892b0d8c25SJeremy Kerr static int __init early_nowrite(char *__unused)
190ae8f1541SRussell King {
191ae8f1541SRussell King 	char *p = "uncached";
1924ed89f22SRussell King 	pr_warn("nowb is deprecated; use cachepolicy=%s\n", p);
1932b0d8c25SJeremy Kerr 	early_cachepolicy(p);
1942b0d8c25SJeremy Kerr 	return 0;
195ae8f1541SRussell King }
1962b0d8c25SJeremy Kerr early_param("nowb", early_nowrite);
197ae8f1541SRussell King 
1981b6ba46bSCatalin Marinas #ifndef CONFIG_ARM_LPAE
early_ecc(char * p)1992b0d8c25SJeremy Kerr static int __init early_ecc(char *p)
200ae8f1541SRussell King {
2012b0d8c25SJeremy Kerr 	if (memcmp(p, "on", 2) == 0)
202ae8f1541SRussell King 		ecc_mask = PMD_PROTECTION;
2032b0d8c25SJeremy Kerr 	else if (memcmp(p, "off", 3) == 0)
204ae8f1541SRussell King 		ecc_mask = 0;
2052b0d8c25SJeremy Kerr 	return 0;
206ae8f1541SRussell King }
2072b0d8c25SJeremy Kerr early_param("ecc", early_ecc);
2081b6ba46bSCatalin Marinas #endif
209ae8f1541SRussell King 
210b849a60eSUwe Kleine-König #else /* ifdef CONFIG_CPU_CP15 */
211b849a60eSUwe Kleine-König 
early_cachepolicy(char * p)212b849a60eSUwe Kleine-König static int __init early_cachepolicy(char *p)
213b849a60eSUwe Kleine-König {
2148b521cb2SJoe Perches 	pr_warn("cachepolicy kernel parameter not supported without cp15\n");
2157b83299eSRandy Dunlap 	return 0;
216b849a60eSUwe Kleine-König }
217b849a60eSUwe Kleine-König early_param("cachepolicy", early_cachepolicy);
218b849a60eSUwe Kleine-König 
noalign_setup(char * __unused)219b849a60eSUwe Kleine-König static int __init noalign_setup(char *__unused)
220b849a60eSUwe Kleine-König {
2218b521cb2SJoe Perches 	pr_warn("noalign kernel parameter not supported without cp15\n");
2227b83299eSRandy Dunlap 	return 1;
223b849a60eSUwe Kleine-König }
224b849a60eSUwe Kleine-König __setup("noalign", noalign_setup);
225b849a60eSUwe Kleine-König 
226b849a60eSUwe Kleine-König #endif /* ifdef CONFIG_CPU_CP15 / else */
227b849a60eSUwe Kleine-König 
22836bb94baSRussell King #define PROT_PTE_DEVICE		L_PTE_PRESENT|L_PTE_YOUNG|L_PTE_DIRTY|L_PTE_XN
2294d9c5b89SChristoffer Dall #define PROT_PTE_S2_DEVICE	PROT_PTE_DEVICE
230b1cce6b1SRussell King #define PROT_SECT_DEVICE	PMD_TYPE_SECT|PMD_SECT_AP_WRITE
2310af92befSRussell King 
2327619751fSKees Cook static struct mem_type mem_types[] __ro_after_init = {
2330af92befSRussell King 	[MT_DEVICE] = {		  /* Strongly ordered / ARMv6 shared device */
234bb30f36fSRussell King 		.prot_pte	= PROT_PTE_DEVICE | L_PTE_MT_DEV_SHARED |
235bb30f36fSRussell King 				  L_PTE_SHARED,
236ae8f1541SRussell King 		.prot_l1	= PMD_TYPE_TABLE,
237b1cce6b1SRussell King 		.prot_sect	= PROT_SECT_DEVICE | PMD_SECT_S,
2380af92befSRussell King 		.domain		= DOMAIN_IO,
2390af92befSRussell King 	},
2400af92befSRussell King 	[MT_DEVICE_NONSHARED] = { /* ARMv6 non-shared device */
241bb30f36fSRussell King 		.prot_pte	= PROT_PTE_DEVICE | L_PTE_MT_DEV_NONSHARED,
2420af92befSRussell King 		.prot_l1	= PMD_TYPE_TABLE,
243b1cce6b1SRussell King 		.prot_sect	= PROT_SECT_DEVICE,
2440af92befSRussell King 		.domain		= DOMAIN_IO,
2450af92befSRussell King 	},
2466a22d824SChristoph Hellwig 	[MT_DEVICE_CACHED] = {	  /* ioremap_cache */
247bb30f36fSRussell King 		.prot_pte	= PROT_PTE_DEVICE | L_PTE_MT_DEV_CACHED,
2480af92befSRussell King 		.prot_l1	= PMD_TYPE_TABLE,
2490af92befSRussell King 		.prot_sect	= PROT_SECT_DEVICE | PMD_SECT_WB,
2500af92befSRussell King 		.domain		= DOMAIN_IO,
2510af92befSRussell King 	},
2521ad77a87SLennert Buytenhek 	[MT_DEVICE_WC] = {	/* ioremap_wc */
253bb30f36fSRussell King 		.prot_pte	= PROT_PTE_DEVICE | L_PTE_MT_DEV_WC,
2540af92befSRussell King 		.prot_l1	= PMD_TYPE_TABLE,
255b1cce6b1SRussell King 		.prot_sect	= PROT_SECT_DEVICE,
256ae8f1541SRussell King 		.domain		= DOMAIN_IO,
257ae8f1541SRussell King 	},
258ebb4c658SRussell King 	[MT_UNCACHED] = {
259ebb4c658SRussell King 		.prot_pte	= PROT_PTE_DEVICE,
260ebb4c658SRussell King 		.prot_l1	= PMD_TYPE_TABLE,
261ebb4c658SRussell King 		.prot_sect	= PMD_TYPE_SECT | PMD_SECT_XN,
262ebb4c658SRussell King 		.domain		= DOMAIN_IO,
263ebb4c658SRussell King 	},
264ae8f1541SRussell King 	[MT_CACHECLEAN] = {
2659ef79635SRussell King 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
266ae8f1541SRussell King 		.domain    = DOMAIN_KERNEL,
267ae8f1541SRussell King 	},
2681b6ba46bSCatalin Marinas #ifndef CONFIG_ARM_LPAE
269ae8f1541SRussell King 	[MT_MINICLEAN] = {
2709ef79635SRussell King 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN | PMD_SECT_MINICACHE,
271ae8f1541SRussell King 		.domain    = DOMAIN_KERNEL,
272ae8f1541SRussell King 	},
2731b6ba46bSCatalin Marinas #endif
274ae8f1541SRussell King 	[MT_LOW_VECTORS] = {
275ae8f1541SRussell King 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
27636bb94baSRussell King 				L_PTE_RDONLY,
277ae8f1541SRussell King 		.prot_l1   = PMD_TYPE_TABLE,
278a02d8dfdSRussell King 		.domain    = DOMAIN_VECTORS,
279ae8f1541SRussell King 	},
280ae8f1541SRussell King 	[MT_HIGH_VECTORS] = {
281ae8f1541SRussell King 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
28236bb94baSRussell King 				L_PTE_USER | L_PTE_RDONLY,
283ae8f1541SRussell King 		.prot_l1   = PMD_TYPE_TABLE,
284a02d8dfdSRussell King 		.domain    = DOMAIN_VECTORS,
285ae8f1541SRussell King 	},
2862e2c9de2SRussell King 	[MT_MEMORY_RWX] = {
28736bb94baSRussell King 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
288f1a2481cSSantosh Shilimkar 		.prot_l1   = PMD_TYPE_TABLE,
2899ef79635SRussell King 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
290ae8f1541SRussell King 		.domain    = DOMAIN_KERNEL,
291ae8f1541SRussell King 	},
292ebd4922eSRussell King 	[MT_MEMORY_RW] = {
293ebd4922eSRussell King 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
294ebd4922eSRussell King 			     L_PTE_XN,
295ebd4922eSRussell King 		.prot_l1   = PMD_TYPE_TABLE,
296ebd4922eSRussell King 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
297ebd4922eSRussell King 		.domain    = DOMAIN_KERNEL,
298ebd4922eSRussell King 	},
299598f0a99SZhen Lei 	[MT_MEMORY_RO] = {
300598f0a99SZhen Lei 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
301598f0a99SZhen Lei 			     L_PTE_XN | L_PTE_RDONLY,
302598f0a99SZhen Lei 		.prot_l1   = PMD_TYPE_TABLE,
30314ca1a46SWang Kefeng #ifdef CONFIG_ARM_LPAE
30414ca1a46SWang Kefeng 		.prot_sect = PMD_TYPE_SECT | L_PMD_SECT_RDONLY | PMD_SECT_AP2,
30514ca1a46SWang Kefeng #else
306598f0a99SZhen Lei 		.prot_sect = PMD_TYPE_SECT,
30714ca1a46SWang Kefeng #endif
308598f0a99SZhen Lei 		.domain    = DOMAIN_KERNEL,
309598f0a99SZhen Lei 	},
310ae8f1541SRussell King 	[MT_ROM] = {
3119ef79635SRussell King 		.prot_sect = PMD_TYPE_SECT,
312ae8f1541SRussell King 		.domain    = DOMAIN_KERNEL,
313ae8f1541SRussell King 	},
3142e2c9de2SRussell King 	[MT_MEMORY_RWX_NONCACHED] = {
315f1a2481cSSantosh Shilimkar 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
31636bb94baSRussell King 				L_PTE_MT_BUFFERABLE,
317f1a2481cSSantosh Shilimkar 		.prot_l1   = PMD_TYPE_TABLE,
318e4707dd3SPaul Walmsley 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE,
319e4707dd3SPaul Walmsley 		.domain    = DOMAIN_KERNEL,
320e4707dd3SPaul Walmsley 	},
3212e2c9de2SRussell King 	[MT_MEMORY_RW_DTCM] = {
322f444fce3SLinus Walleij 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
32336bb94baSRussell King 				L_PTE_XN,
324cb9d7707SLinus Walleij 		.prot_l1   = PMD_TYPE_TABLE,
325cb9d7707SLinus Walleij 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_XN,
326cb9d7707SLinus Walleij 		.domain    = DOMAIN_KERNEL,
327cb9d7707SLinus Walleij 	},
3282e2c9de2SRussell King 	[MT_MEMORY_RWX_ITCM] = {
32936bb94baSRussell King 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY,
330cb9d7707SLinus Walleij 		.prot_l1   = PMD_TYPE_TABLE,
331f444fce3SLinus Walleij 		.domain    = DOMAIN_KERNEL,
332cb9d7707SLinus Walleij 	},
3332e2c9de2SRussell King 	[MT_MEMORY_RW_SO] = {
3348fb54284SSantosh Shilimkar 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
33593d5bf07SSantosh Shilimkar 				L_PTE_MT_UNCACHED | L_PTE_XN,
3368fb54284SSantosh Shilimkar 		.prot_l1   = PMD_TYPE_TABLE,
3378fb54284SSantosh Shilimkar 		.prot_sect = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_S |
3388fb54284SSantosh Shilimkar 				PMD_SECT_UNCACHED | PMD_SECT_XN,
3398fb54284SSantosh Shilimkar 		.domain    = DOMAIN_KERNEL,
3408fb54284SSantosh Shilimkar 	},
341c7909509SMarek Szyprowski 	[MT_MEMORY_DMA_READY] = {
34271b55663SRussell King 		.prot_pte  = L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_DIRTY |
34371b55663SRussell King 				L_PTE_XN,
344c7909509SMarek Szyprowski 		.prot_l1   = PMD_TYPE_TABLE,
345c7909509SMarek Szyprowski 		.domain    = DOMAIN_KERNEL,
346c7909509SMarek Szyprowski 	},
347ae8f1541SRussell King };
348ae8f1541SRussell King 
get_mem_type(unsigned int type)349b29e9f5eSRussell King const struct mem_type *get_mem_type(unsigned int type)
350b29e9f5eSRussell King {
351b29e9f5eSRussell King 	return type < ARRAY_SIZE(mem_types) ? &mem_types[type] : NULL;
352b29e9f5eSRussell King }
35369d3a84aSHiroshi DOYU EXPORT_SYMBOL(get_mem_type);
354b29e9f5eSRussell King 
355a5f4c561SStefan Agner static pte_t *(*pte_offset_fixmap)(pmd_t *dir, unsigned long addr);
356a5f4c561SStefan Agner 
357a5f4c561SStefan Agner static pte_t bm_pte[PTRS_PER_PTE + PTE_HWTABLE_PTRS]
358a5f4c561SStefan Agner 	__aligned(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE) __initdata;
359a5f4c561SStefan Agner 
pte_offset_early_fixmap(pmd_t * dir,unsigned long addr)360a5f4c561SStefan Agner static pte_t * __init pte_offset_early_fixmap(pmd_t *dir, unsigned long addr)
361a5f4c561SStefan Agner {
362a5f4c561SStefan Agner 	return &bm_pte[pte_index(addr)];
363a5f4c561SStefan Agner }
364a5f4c561SStefan Agner 
pte_offset_late_fixmap(pmd_t * dir,unsigned long addr)365a5f4c561SStefan Agner static pte_t *pte_offset_late_fixmap(pmd_t *dir, unsigned long addr)
366a5f4c561SStefan Agner {
367a5f4c561SStefan Agner 	return pte_offset_kernel(dir, addr);
368a5f4c561SStefan Agner }
369a5f4c561SStefan Agner 
fixmap_pmd(unsigned long addr)370a5f4c561SStefan Agner static inline pmd_t * __init fixmap_pmd(unsigned long addr)
371a5f4c561SStefan Agner {
372e05c7b1fSMike Rapoport 	return pmd_off_k(addr);
373a5f4c561SStefan Agner }
374a5f4c561SStefan Agner 
early_fixmap_init(void)375a5f4c561SStefan Agner void __init early_fixmap_init(void)
376a5f4c561SStefan Agner {
377a5f4c561SStefan Agner 	pmd_t *pmd;
378a5f4c561SStefan Agner 
379a5f4c561SStefan Agner 	/*
380a5f4c561SStefan Agner 	 * The early fixmap range spans multiple pmds, for which
381a5f4c561SStefan Agner 	 * we are not prepared:
382a5f4c561SStefan Agner 	 */
3832937367bSArd Biesheuvel 	BUILD_BUG_ON((__fix_to_virt(__end_of_early_ioremap_region) >> PMD_SHIFT)
384a5f4c561SStefan Agner 		     != FIXADDR_TOP >> PMD_SHIFT);
385a5f4c561SStefan Agner 
386a5f4c561SStefan Agner 	pmd = fixmap_pmd(FIXADDR_TOP);
387a5f4c561SStefan Agner 	pmd_populate_kernel(&init_mm, pmd, bm_pte);
388a5f4c561SStefan Agner 
389a5f4c561SStefan Agner 	pte_offset_fixmap = pte_offset_early_fixmap;
390a5f4c561SStefan Agner }
391a5f4c561SStefan Agner 
392ae8f1541SRussell King /*
39399b4ac9aSKees Cook  * To avoid TLB flush broadcasts, this uses local_flush_tlb_kernel_range().
39499b4ac9aSKees Cook  * As a result, this can only be called with preemption disabled, as under
39599b4ac9aSKees Cook  * stop_machine().
39699b4ac9aSKees Cook  */
__set_fixmap(enum fixed_addresses idx,phys_addr_t phys,pgprot_t prot)39799b4ac9aSKees Cook void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
39899b4ac9aSKees Cook {
39999b4ac9aSKees Cook 	unsigned long vaddr = __fix_to_virt(idx);
400a5f4c561SStefan Agner 	pte_t *pte = pte_offset_fixmap(pmd_off_k(vaddr), vaddr);
40199b4ac9aSKees Cook 
40299b4ac9aSKees Cook 	/* Make sure fixmap region does not exceed available allocation. */
403d624833fSArd Biesheuvel 	BUILD_BUG_ON(__fix_to_virt(__end_of_fixed_addresses) < FIXADDR_START);
40499b4ac9aSKees Cook 	BUG_ON(idx >= __end_of_fixed_addresses);
40599b4ac9aSKees Cook 
4060d08e7bfSMichał Mirosław 	/* We support only device mappings before pgprot_kernel is set. */
407b089c31cSJon Medhurst 	if (WARN_ON(pgprot_val(prot) != pgprot_val(FIXMAP_PAGE_IO) &&
4080d08e7bfSMichał Mirosław 		    pgprot_val(prot) && pgprot_val(pgprot_kernel) == 0))
409b089c31cSJon Medhurst 		return;
410b089c31cSJon Medhurst 
41199b4ac9aSKees Cook 	if (pgprot_val(prot))
41299b4ac9aSKees Cook 		set_pte_at(NULL, vaddr, pte,
41399b4ac9aSKees Cook 			pfn_pte(phys >> PAGE_SHIFT, prot));
41499b4ac9aSKees Cook 	else
41599b4ac9aSKees Cook 		pte_clear(NULL, vaddr, pte);
41699b4ac9aSKees Cook 	local_flush_tlb_kernel_range(vaddr, vaddr + PAGE_SIZE);
41799b4ac9aSKees Cook }
41899b4ac9aSKees Cook 
419ca26f936SAnshuman Khandual static pgprot_t protection_map[16] __ro_after_init = {
420ca26f936SAnshuman Khandual 	[VM_NONE]					= __PAGE_NONE,
421ca26f936SAnshuman Khandual 	[VM_READ]					= __PAGE_READONLY,
422ca26f936SAnshuman Khandual 	[VM_WRITE]					= __PAGE_COPY,
423ca26f936SAnshuman Khandual 	[VM_WRITE | VM_READ]				= __PAGE_COPY,
424ca26f936SAnshuman Khandual 	[VM_EXEC]					= __PAGE_READONLY_EXEC,
425ca26f936SAnshuman Khandual 	[VM_EXEC | VM_READ]				= __PAGE_READONLY_EXEC,
426ca26f936SAnshuman Khandual 	[VM_EXEC | VM_WRITE]				= __PAGE_COPY_EXEC,
427ca26f936SAnshuman Khandual 	[VM_EXEC | VM_WRITE | VM_READ]			= __PAGE_COPY_EXEC,
428ca26f936SAnshuman Khandual 	[VM_SHARED]					= __PAGE_NONE,
429ca26f936SAnshuman Khandual 	[VM_SHARED | VM_READ]				= __PAGE_READONLY,
430ca26f936SAnshuman Khandual 	[VM_SHARED | VM_WRITE]				= __PAGE_SHARED,
431ca26f936SAnshuman Khandual 	[VM_SHARED | VM_WRITE | VM_READ]		= __PAGE_SHARED,
432ca26f936SAnshuman Khandual 	[VM_SHARED | VM_EXEC]				= __PAGE_READONLY_EXEC,
433ca26f936SAnshuman Khandual 	[VM_SHARED | VM_EXEC | VM_READ]			= __PAGE_READONLY_EXEC,
434ca26f936SAnshuman Khandual 	[VM_SHARED | VM_EXEC | VM_WRITE]		= __PAGE_SHARED_EXEC,
435ca26f936SAnshuman Khandual 	[VM_SHARED | VM_EXEC | VM_WRITE | VM_READ]	= __PAGE_SHARED_EXEC
436ca26f936SAnshuman Khandual };
437ca26f936SAnshuman Khandual DECLARE_VM_GET_PAGE_PROT
438ca26f936SAnshuman Khandual 
43999b4ac9aSKees Cook /*
440ae8f1541SRussell King  * Adjust the PMD section entries according to the CPU in use.
441ae8f1541SRussell King  */
build_mem_type_table(void)442ae8f1541SRussell King static void __init build_mem_type_table(void)
443ae8f1541SRussell King {
444ae8f1541SRussell King 	struct cachepolicy *cp;
445ae8f1541SRussell King 	unsigned int cr = get_cr();
446442e70c0SCatalin Marinas 	pteval_t user_pgprot, kern_pgprot, vecs_pgprot;
447ae8f1541SRussell King 	int cpu_arch = cpu_architecture();
448ae8f1541SRussell King 	int i;
449ae8f1541SRussell King 
45011179d8cSCatalin Marinas 	if (cpu_arch < CPU_ARCH_ARMv6) {
451ae8f1541SRussell King #if defined(CONFIG_CPU_DCACHE_DISABLE)
452ae8f1541SRussell King 		if (cachepolicy > CPOLICY_BUFFERED)
453ae8f1541SRussell King 			cachepolicy = CPOLICY_BUFFERED;
454ae8f1541SRussell King #elif defined(CONFIG_CPU_DCACHE_WRITETHROUGH)
455ae8f1541SRussell King 		if (cachepolicy > CPOLICY_WRITETHROUGH)
456ae8f1541SRussell King 			cachepolicy = CPOLICY_WRITETHROUGH;
457ae8f1541SRussell King #endif
45811179d8cSCatalin Marinas 	}
459ae8f1541SRussell King 	if (cpu_arch < CPU_ARCH_ARMv5) {
460ae8f1541SRussell King 		if (cachepolicy >= CPOLICY_WRITEALLOC)
461ae8f1541SRussell King 			cachepolicy = CPOLICY_WRITEBACK;
462ae8f1541SRussell King 		ecc_mask = 0;
463ae8f1541SRussell King 	}
464ca8f0b0aSRussell King 
46520e7e364SRussell King 	if (is_smp()) {
46620e7e364SRussell King 		if (cachepolicy != CPOLICY_WRITEALLOC) {
467ca8f0b0aSRussell King 			pr_warn("Forcing write-allocate cache policy for SMP\n");
468bb30f36fSRussell King 			cachepolicy = CPOLICY_WRITEALLOC;
469ca8f0b0aSRussell King 		}
47020e7e364SRussell King 		if (!(initial_pmd_value & PMD_SECT_S)) {
47120e7e364SRussell King 			pr_warn("Forcing shared mappings for SMP\n");
47220e7e364SRussell King 			initial_pmd_value |= PMD_SECT_S;
47320e7e364SRussell King 		}
47420e7e364SRussell King 	}
475ae8f1541SRussell King 
476ae8f1541SRussell King 	/*
477b1cce6b1SRussell King 	 * Strip out features not present on earlier architectures.
478b1cce6b1SRussell King 	 * Pre-ARMv5 CPUs don't have TEX bits.  Pre-ARMv6 CPUs or those
479b1cce6b1SRussell King 	 * without extended page tables don't have the 'Shared' bit.
4801ad77a87SLennert Buytenhek 	 */
481b1cce6b1SRussell King 	if (cpu_arch < CPU_ARCH_ARMv5)
482b1cce6b1SRussell King 		for (i = 0; i < ARRAY_SIZE(mem_types); i++)
483b1cce6b1SRussell King 			mem_types[i].prot_sect &= ~PMD_SECT_TEX(7);
484b1cce6b1SRussell King 	if ((cpu_arch < CPU_ARCH_ARMv6 || !(cr & CR_XP)) && !cpu_is_xsc3())
485b1cce6b1SRussell King 		for (i = 0; i < ARRAY_SIZE(mem_types); i++)
486b1cce6b1SRussell King 			mem_types[i].prot_sect &= ~PMD_SECT_S;
487ae8f1541SRussell King 
488ae8f1541SRussell King 	/*
489b1cce6b1SRussell King 	 * ARMv5 and lower, bit 4 must be set for page tables (was: cache
490b1cce6b1SRussell King 	 * "update-able on write" bit on ARM610).  However, Xscale and
491b1cce6b1SRussell King 	 * Xscale3 require this bit to be cleared.
492ae8f1541SRussell King 	 */
493d33c43acSArnd Bergmann 	if (cpu_is_xscale_family()) {
4949ef79635SRussell King 		for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
495ae8f1541SRussell King 			mem_types[i].prot_sect &= ~PMD_BIT4;
4969ef79635SRussell King 			mem_types[i].prot_l1 &= ~PMD_BIT4;
4979ef79635SRussell King 		}
4989ef79635SRussell King 	} else if (cpu_arch < CPU_ARCH_ARMv6) {
4999ef79635SRussell King 		for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
500ae8f1541SRussell King 			if (mem_types[i].prot_l1)
501ae8f1541SRussell King 				mem_types[i].prot_l1 |= PMD_BIT4;
5029ef79635SRussell King 			if (mem_types[i].prot_sect)
5039ef79635SRussell King 				mem_types[i].prot_sect |= PMD_BIT4;
5049ef79635SRussell King 		}
5059ef79635SRussell King 	}
506ae8f1541SRussell King 
507b1cce6b1SRussell King 	/*
508b1cce6b1SRussell King 	 * Mark the device areas according to the CPU/architecture.
509b1cce6b1SRussell King 	 */
510b1cce6b1SRussell King 	if (cpu_is_xsc3() || (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP))) {
511b1cce6b1SRussell King 		if (!cpu_is_xsc3()) {
512b1cce6b1SRussell King 			/*
513b1cce6b1SRussell King 			 * Mark device regions on ARMv6+ as execute-never
514b1cce6b1SRussell King 			 * to prevent speculative instruction fetches.
515b1cce6b1SRussell King 			 */
516b1cce6b1SRussell King 			mem_types[MT_DEVICE].prot_sect |= PMD_SECT_XN;
517b1cce6b1SRussell King 			mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_XN;
518b1cce6b1SRussell King 			mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_XN;
519b1cce6b1SRussell King 			mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_XN;
520ebd4922eSRussell King 
521ebd4922eSRussell King 			/* Also setup NX memory mapping */
522ebd4922eSRussell King 			mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_XN;
523598f0a99SZhen Lei 			mem_types[MT_MEMORY_RO].prot_sect |= PMD_SECT_XN;
524b1cce6b1SRussell King 		}
525b1cce6b1SRussell King 		if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
526b1cce6b1SRussell King 			/*
527b1cce6b1SRussell King 			 * For ARMv7 with TEX remapping,
528b1cce6b1SRussell King 			 * - shared device is SXCB=1100
529b1cce6b1SRussell King 			 * - nonshared device is SXCB=0100
530b1cce6b1SRussell King 			 * - write combine device mem is SXCB=0001
531b1cce6b1SRussell King 			 * (Uncached Normal memory)
532b1cce6b1SRussell King 			 */
533b1cce6b1SRussell King 			mem_types[MT_DEVICE].prot_sect |= PMD_SECT_TEX(1);
534b1cce6b1SRussell King 			mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_TEX(1);
535b1cce6b1SRussell King 			mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_BUFFERABLE;
536b1cce6b1SRussell King 		} else if (cpu_is_xsc3()) {
537b1cce6b1SRussell King 			/*
538b1cce6b1SRussell King 			 * For Xscale3,
539b1cce6b1SRussell King 			 * - shared device is TEXCB=00101
540b1cce6b1SRussell King 			 * - nonshared device is TEXCB=01000
541b1cce6b1SRussell King 			 * - write combine device mem is TEXCB=00100
542b1cce6b1SRussell King 			 * (Inner/Outer Uncacheable in xsc3 parlance)
543b1cce6b1SRussell King 			 */
544b1cce6b1SRussell King 			mem_types[MT_DEVICE].prot_sect |= PMD_SECT_TEX(1) | PMD_SECT_BUFFERED;
545b1cce6b1SRussell King 			mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_TEX(2);
546b1cce6b1SRussell King 			mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_TEX(1);
547b1cce6b1SRussell King 		} else {
548b1cce6b1SRussell King 			/*
549b1cce6b1SRussell King 			 * For ARMv6 and ARMv7 without TEX remapping,
550b1cce6b1SRussell King 			 * - shared device is TEXCB=00001
551b1cce6b1SRussell King 			 * - nonshared device is TEXCB=01000
552b1cce6b1SRussell King 			 * - write combine device mem is TEXCB=00100
553b1cce6b1SRussell King 			 * (Uncached Normal in ARMv6 parlance).
554b1cce6b1SRussell King 			 */
555b1cce6b1SRussell King 			mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
556b1cce6b1SRussell King 			mem_types[MT_DEVICE_NONSHARED].prot_sect |= PMD_SECT_TEX(2);
557b1cce6b1SRussell King 			mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_TEX(1);
558b1cce6b1SRussell King 		}
559b1cce6b1SRussell King 	} else {
560b1cce6b1SRussell King 		/*
561b1cce6b1SRussell King 		 * On others, write combining is "Uncached/Buffered"
562b1cce6b1SRussell King 		 */
563b1cce6b1SRussell King 		mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_BUFFERABLE;
564b1cce6b1SRussell King 	}
565b1cce6b1SRussell King 
566b1cce6b1SRussell King 	/*
567b1cce6b1SRussell King 	 * Now deal with the memory-type mappings
568b1cce6b1SRussell King 	 */
569ae8f1541SRussell King 	cp = &cache_policies[cachepolicy];
570bb30f36fSRussell King 	vecs_pgprot = kern_pgprot = user_pgprot = cp->pte;
571bb30f36fSRussell King 
5721d4d3715SJungseung Lee #ifndef CONFIG_ARM_LPAE
573bb30f36fSRussell King 	/*
574b6ccb980SWill Deacon 	 * We don't use domains on ARMv6 (since this causes problems with
575b6ccb980SWill Deacon 	 * v6/v7 kernels), so we must use a separate memory type for user
576b6ccb980SWill Deacon 	 * r/o, kernel r/w to map the vectors page.
577b6ccb980SWill Deacon 	 */
578b6ccb980SWill Deacon 	if (cpu_arch == CPU_ARCH_ARMv6)
579b6ccb980SWill Deacon 		vecs_pgprot |= L_PTE_MT_VECTORS;
5801d4d3715SJungseung Lee 
5811d4d3715SJungseung Lee 	/*
5821d4d3715SJungseung Lee 	 * Check is it with support for the PXN bit
5831d4d3715SJungseung Lee 	 * in the Short-descriptor translation table format descriptors.
5841d4d3715SJungseung Lee 	 */
5851d4d3715SJungseung Lee 	if (cpu_arch == CPU_ARCH_ARMv7 &&
586ad84f56bSJungseung Lee 		(read_cpuid_ext(CPUID_EXT_MMFR0) & 0xF) >= 4) {
5871d4d3715SJungseung Lee 		user_pmd_table |= PMD_PXNTABLE;
5881d4d3715SJungseung Lee 	}
589b6ccb980SWill Deacon #endif
590bb30f36fSRussell King 
591bb30f36fSRussell King 	/*
592ae8f1541SRussell King 	 * ARMv6 and above have extended page tables.
593ae8f1541SRussell King 	 */
594ae8f1541SRussell King 	if (cpu_arch >= CPU_ARCH_ARMv6 && (cr & CR_XP)) {
5951b6ba46bSCatalin Marinas #ifndef CONFIG_ARM_LPAE
596ae8f1541SRussell King 		/*
597ae8f1541SRussell King 		 * Mark cache clean areas and XIP ROM read only
598ae8f1541SRussell King 		 * from SVC mode and no access from userspace.
599ae8f1541SRussell King 		 */
600ae8f1541SRussell King 		mem_types[MT_ROM].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
601ae8f1541SRussell King 		mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
602ae8f1541SRussell King 		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
603598f0a99SZhen Lei 		mem_types[MT_MEMORY_RO].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
6041b6ba46bSCatalin Marinas #endif
605ae8f1541SRussell King 
606ae8f1541SRussell King 		/*
60720e7e364SRussell King 		 * If the initial page tables were created with the S bit
60820e7e364SRussell King 		 * set, then we need to do the same here for the same
60920e7e364SRussell King 		 * reasons given in early_cachepolicy().
610ae8f1541SRussell King 		 */
61120e7e364SRussell King 		if (initial_pmd_value & PMD_SECT_S) {
612ae8f1541SRussell King 			user_pgprot |= L_PTE_SHARED;
613ae8f1541SRussell King 			kern_pgprot |= L_PTE_SHARED;
614bb30f36fSRussell King 			vecs_pgprot |= L_PTE_SHARED;
61585b3cce8SRussell King 			mem_types[MT_DEVICE_WC].prot_sect |= PMD_SECT_S;
61685b3cce8SRussell King 			mem_types[MT_DEVICE_WC].prot_pte |= L_PTE_SHARED;
61785b3cce8SRussell King 			mem_types[MT_DEVICE_CACHED].prot_sect |= PMD_SECT_S;
61885b3cce8SRussell King 			mem_types[MT_DEVICE_CACHED].prot_pte |= L_PTE_SHARED;
6192e2c9de2SRussell King 			mem_types[MT_MEMORY_RWX].prot_sect |= PMD_SECT_S;
6202e2c9de2SRussell King 			mem_types[MT_MEMORY_RWX].prot_pte |= L_PTE_SHARED;
621ebd4922eSRussell King 			mem_types[MT_MEMORY_RW].prot_sect |= PMD_SECT_S;
622ebd4922eSRussell King 			mem_types[MT_MEMORY_RW].prot_pte |= L_PTE_SHARED;
623598f0a99SZhen Lei 			mem_types[MT_MEMORY_RO].prot_sect |= PMD_SECT_S;
624598f0a99SZhen Lei 			mem_types[MT_MEMORY_RO].prot_pte |= L_PTE_SHARED;
625c7909509SMarek Szyprowski 			mem_types[MT_MEMORY_DMA_READY].prot_pte |= L_PTE_SHARED;
6262e2c9de2SRussell King 			mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_S;
6272e2c9de2SRussell King 			mem_types[MT_MEMORY_RWX_NONCACHED].prot_pte |= L_PTE_SHARED;
628f00ec48fSRussell King 		}
629ae8f1541SRussell King 	}
630ae8f1541SRussell King 
631e4707dd3SPaul Walmsley 	/*
632e4707dd3SPaul Walmsley 	 * Non-cacheable Normal - intended for memory areas that must
633e4707dd3SPaul Walmsley 	 * not cause dirty cache line writebacks when used
634e4707dd3SPaul Walmsley 	 */
635e4707dd3SPaul Walmsley 	if (cpu_arch >= CPU_ARCH_ARMv6) {
636e4707dd3SPaul Walmsley 		if (cpu_arch >= CPU_ARCH_ARMv7 && (cr & CR_TRE)) {
637e4707dd3SPaul Walmsley 			/* Non-cacheable Normal is XCB = 001 */
6382e2c9de2SRussell King 			mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |=
639e4707dd3SPaul Walmsley 				PMD_SECT_BUFFERED;
640e4707dd3SPaul Walmsley 		} else {
641e4707dd3SPaul Walmsley 			/* For both ARMv6 and non-TEX-remapping ARMv7 */
6422e2c9de2SRussell King 			mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |=
643e4707dd3SPaul Walmsley 				PMD_SECT_TEX(1);
644e4707dd3SPaul Walmsley 		}
645e4707dd3SPaul Walmsley 	} else {
6462e2c9de2SRussell King 		mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= PMD_SECT_BUFFERABLE;
647e4707dd3SPaul Walmsley 	}
648e4707dd3SPaul Walmsley 
6491b6ba46bSCatalin Marinas #ifdef CONFIG_ARM_LPAE
6501b6ba46bSCatalin Marinas 	/*
6511b6ba46bSCatalin Marinas 	 * Do not generate access flag faults for the kernel mappings.
6521b6ba46bSCatalin Marinas 	 */
6531b6ba46bSCatalin Marinas 	for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
6541b6ba46bSCatalin Marinas 		mem_types[i].prot_pte |= PTE_EXT_AF;
6551a3abcf4SVitaly Andrianov 		if (mem_types[i].prot_sect)
6561b6ba46bSCatalin Marinas 			mem_types[i].prot_sect |= PMD_SECT_AF;
6571b6ba46bSCatalin Marinas 	}
6581b6ba46bSCatalin Marinas 	kern_pgprot |= PTE_EXT_AF;
6591b6ba46bSCatalin Marinas 	vecs_pgprot |= PTE_EXT_AF;
6601d4d3715SJungseung Lee 
6611d4d3715SJungseung Lee 	/*
6621d4d3715SJungseung Lee 	 * Set PXN for user mappings
6631d4d3715SJungseung Lee 	 */
6641d4d3715SJungseung Lee 	user_pgprot |= PTE_EXT_PXN;
6651b6ba46bSCatalin Marinas #endif
6661b6ba46bSCatalin Marinas 
667ae8f1541SRussell King 	for (i = 0; i < 16; i++) {
668864aa04cSWill Deacon 		pteval_t v = pgprot_val(protection_map[i]);
669bb30f36fSRussell King 		protection_map[i] = __pgprot(v | user_pgprot);
670ae8f1541SRussell King 	}
671ae8f1541SRussell King 
672bb30f36fSRussell King 	mem_types[MT_LOW_VECTORS].prot_pte |= vecs_pgprot;
673bb30f36fSRussell King 	mem_types[MT_HIGH_VECTORS].prot_pte |= vecs_pgprot;
674ae8f1541SRussell King 
67544b18693SImre_Deak 	pgprot_user   = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot);
676ae8f1541SRussell King 	pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
67736bb94baSRussell King 				 L_PTE_DIRTY | kern_pgprot);
678ae8f1541SRussell King 
679ae8f1541SRussell King 	mem_types[MT_LOW_VECTORS].prot_l1 |= ecc_mask;
680ae8f1541SRussell King 	mem_types[MT_HIGH_VECTORS].prot_l1 |= ecc_mask;
6812e2c9de2SRussell King 	mem_types[MT_MEMORY_RWX].prot_sect |= ecc_mask | cp->pmd;
6822e2c9de2SRussell King 	mem_types[MT_MEMORY_RWX].prot_pte |= kern_pgprot;
683ebd4922eSRussell King 	mem_types[MT_MEMORY_RW].prot_sect |= ecc_mask | cp->pmd;
684ebd4922eSRussell King 	mem_types[MT_MEMORY_RW].prot_pte |= kern_pgprot;
685598f0a99SZhen Lei 	mem_types[MT_MEMORY_RO].prot_sect |= ecc_mask | cp->pmd;
686598f0a99SZhen Lei 	mem_types[MT_MEMORY_RO].prot_pte |= kern_pgprot;
687c7909509SMarek Szyprowski 	mem_types[MT_MEMORY_DMA_READY].prot_pte |= kern_pgprot;
6882e2c9de2SRussell King 	mem_types[MT_MEMORY_RWX_NONCACHED].prot_sect |= ecc_mask;
689ae8f1541SRussell King 	mem_types[MT_ROM].prot_sect |= cp->pmd;
690ae8f1541SRussell King 
691ae8f1541SRussell King 	switch (cp->pmd) {
692ae8f1541SRussell King 	case PMD_SECT_WT:
693ae8f1541SRussell King 		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WT;
694ae8f1541SRussell King 		break;
695ae8f1541SRussell King 	case PMD_SECT_WB:
696ae8f1541SRussell King 	case PMD_SECT_WBWA:
697ae8f1541SRussell King 		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_WB;
698ae8f1541SRussell King 		break;
699ae8f1541SRussell King 	}
700905b5797SMichal Simek 	pr_info("Memory policy: %sData cache %s\n",
701905b5797SMichal Simek 		ecc_mask ? "ECC enabled, " : "", cp->policy);
7022497f0a8SRussell King 
7032497f0a8SRussell King 	for (i = 0; i < ARRAY_SIZE(mem_types); i++) {
7042497f0a8SRussell King 		struct mem_type *t = &mem_types[i];
7052497f0a8SRussell King 		if (t->prot_l1)
7062497f0a8SRussell King 			t->prot_l1 |= PMD_DOMAIN(t->domain);
7072497f0a8SRussell King 		if (t->prot_sect)
7082497f0a8SRussell King 			t->prot_sect |= PMD_DOMAIN(t->domain);
7092497f0a8SRussell King 	}
710ae8f1541SRussell King }
711ae8f1541SRussell King 
712d907387cSCatalin Marinas #ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
phys_mem_access_prot(struct file * file,unsigned long pfn,unsigned long size,pgprot_t vma_prot)713d907387cSCatalin Marinas pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
714d907387cSCatalin Marinas 			      unsigned long size, pgprot_t vma_prot)
715d907387cSCatalin Marinas {
716d907387cSCatalin Marinas 	if (!pfn_valid(pfn))
717d907387cSCatalin Marinas 		return pgprot_noncached(vma_prot);
718d907387cSCatalin Marinas 	else if (file->f_flags & O_SYNC)
719d907387cSCatalin Marinas 		return pgprot_writecombine(vma_prot);
720d907387cSCatalin Marinas 	return vma_prot;
721d907387cSCatalin Marinas }
722d907387cSCatalin Marinas EXPORT_SYMBOL(phys_mem_access_prot);
723d907387cSCatalin Marinas #endif
724d907387cSCatalin Marinas 
725ae8f1541SRussell King #define vectors_base()	(vectors_high() ? 0xffff0000 : 0)
726ae8f1541SRussell King 
early_alloc(unsigned long sz)7270536bdf3SNicolas Pitre static void __init *early_alloc(unsigned long sz)
7280536bdf3SNicolas Pitre {
7298a7f97b9SMike Rapoport 	void *ptr = memblock_alloc(sz, sz);
7308a7f97b9SMike Rapoport 
7318a7f97b9SMike Rapoport 	if (!ptr)
7328a7f97b9SMike Rapoport 		panic("%s: Failed to allocate %lu bytes align=0x%lx\n",
7338a7f97b9SMike Rapoport 		      __func__, sz, sz);
7348a7f97b9SMike Rapoport 
7358a7f97b9SMike Rapoport 	return ptr;
7360536bdf3SNicolas Pitre }
7370536bdf3SNicolas Pitre 
late_alloc(unsigned long sz)738c7936206SArd Biesheuvel static void *__init late_alloc(unsigned long sz)
739c7936206SArd Biesheuvel {
740358d1c39SVishal Moola (Oracle) 	void *ptdesc = pagetable_alloc(GFP_PGTABLE_KERNEL & ~__GFP_HIGHMEM,
741358d1c39SVishal Moola (Oracle) 			get_order(sz));
742c7936206SArd Biesheuvel 
743358d1c39SVishal Moola (Oracle) 	if (!ptdesc || !pagetable_pte_ctor(ptdesc))
74461444cdeSArd Biesheuvel 		BUG();
745358d1c39SVishal Moola (Oracle) 	return ptdesc_to_virt(ptdesc);
746c7936206SArd Biesheuvel }
747c7936206SArd Biesheuvel 
arm_pte_alloc(pmd_t * pmd,unsigned long addr,unsigned long prot,void * (* alloc)(unsigned long sz))7483ed3a4f0SKirill A. Shutemov static pte_t * __init arm_pte_alloc(pmd_t *pmd, unsigned long addr,
749f579b2b1SArd Biesheuvel 				unsigned long prot,
750f579b2b1SArd Biesheuvel 				void *(*alloc)(unsigned long sz))
7514bb2e27dSRussell King {
7524bb2e27dSRussell King 	if (pmd_none(*pmd)) {
753f579b2b1SArd Biesheuvel 		pte_t *pte = alloc(PTE_HWTABLE_OFF + PTE_HWTABLE_SIZE);
75497092e0cSRussell King 		__pmd_populate(pmd, __pa(pte), prot);
7554bb2e27dSRussell King 	}
7564bb2e27dSRussell King 	BUG_ON(pmd_bad(*pmd));
7574bb2e27dSRussell King 	return pte_offset_kernel(pmd, addr);
7584bb2e27dSRussell King }
7594bb2e27dSRussell King 
early_pte_alloc(pmd_t * pmd,unsigned long addr,unsigned long prot)760f579b2b1SArd Biesheuvel static pte_t * __init early_pte_alloc(pmd_t *pmd, unsigned long addr,
761f579b2b1SArd Biesheuvel 				      unsigned long prot)
762f579b2b1SArd Biesheuvel {
7633ed3a4f0SKirill A. Shutemov 	return arm_pte_alloc(pmd, addr, prot, early_alloc);
764f579b2b1SArd Biesheuvel }
765f579b2b1SArd Biesheuvel 
alloc_init_pte(pmd_t * pmd,unsigned long addr,unsigned long end,unsigned long pfn,const struct mem_type * type,void * (* alloc)(unsigned long sz),bool ng)76624e6c699SRussell King static void __init alloc_init_pte(pmd_t *pmd, unsigned long addr,
76724e6c699SRussell King 				  unsigned long end, unsigned long pfn,
768f579b2b1SArd Biesheuvel 				  const struct mem_type *type,
769b430e55bSArd Biesheuvel 				  void *(*alloc)(unsigned long sz),
770b430e55bSArd Biesheuvel 				  bool ng)
771ae8f1541SRussell King {
7723ed3a4f0SKirill A. Shutemov 	pte_t *pte = arm_pte_alloc(pmd, addr, type->prot_l1, alloc);
77324e6c699SRussell King 	do {
774b430e55bSArd Biesheuvel 		set_pte_ext(pte, pfn_pte(pfn, __pgprot(type->prot_pte)),
775b430e55bSArd Biesheuvel 			    ng ? PTE_EXT_NG : 0);
77624e6c699SRussell King 		pfn++;
77724e6c699SRussell King 	} while (pte++, addr += PAGE_SIZE, addr != end);
778ae8f1541SRussell King }
779ae8f1541SRussell King 
__map_init_section(pmd_t * pmd,unsigned long addr,unsigned long end,phys_addr_t phys,const struct mem_type * type,bool ng)78037468b30SPo-Yu Chuang static void __init __map_init_section(pmd_t *pmd, unsigned long addr,
78197092e0cSRussell King 			unsigned long end, phys_addr_t phys,
782b430e55bSArd Biesheuvel 			const struct mem_type *type, bool ng)
78324e6c699SRussell King {
78437468b30SPo-Yu Chuang 	pmd_t *p = pmd;
78537468b30SPo-Yu Chuang 
7861b6ba46bSCatalin Marinas #ifndef CONFIG_ARM_LPAE
787e651eab0SSricharan R 	/*
788e651eab0SSricharan R 	 * In classic MMU format, puds and pmds are folded in to
789e651eab0SSricharan R 	 * the pgds. pmd_offset gives the PGD entry. PGDs refer to a
790e651eab0SSricharan R 	 * group of L1 entries making up one logical pointer to
791e651eab0SSricharan R 	 * an L2 table (2MB), where as PMDs refer to the individual
792e651eab0SSricharan R 	 * L1 entries (1MB). Hence increment to get the correct
793e651eab0SSricharan R 	 * offset for odd 1MB sections.
794e651eab0SSricharan R 	 * (See arch/arm/include/asm/pgtable-2level.h)
795e651eab0SSricharan R 	 */
79624e6c699SRussell King 	if (addr & SECTION_SIZE)
79724e6c699SRussell King 		pmd++;
7981b6ba46bSCatalin Marinas #endif
79924e6c699SRussell King 	do {
800b430e55bSArd Biesheuvel 		*pmd = __pmd(phys | type->prot_sect | (ng ? PMD_SECT_nG : 0));
80124e6c699SRussell King 		phys += SECTION_SIZE;
80224e6c699SRussell King 	} while (pmd++, addr += SECTION_SIZE, addr != end);
80324e6c699SRussell King 
80437468b30SPo-Yu Chuang 	flush_pmd_entry(p);
80524e6c699SRussell King }
806e651eab0SSricharan R 
alloc_init_pmd(pud_t * pud,unsigned long addr,unsigned long end,phys_addr_t phys,const struct mem_type * type,void * (* alloc)(unsigned long sz),bool ng)807e651eab0SSricharan R static void __init alloc_init_pmd(pud_t *pud, unsigned long addr,
808e651eab0SSricharan R 				      unsigned long end, phys_addr_t phys,
809f579b2b1SArd Biesheuvel 				      const struct mem_type *type,
810b430e55bSArd Biesheuvel 				      void *(*alloc)(unsigned long sz), bool ng)
811e651eab0SSricharan R {
812e651eab0SSricharan R 	pmd_t *pmd = pmd_offset(pud, addr);
813e651eab0SSricharan R 	unsigned long next;
814e651eab0SSricharan R 
815e651eab0SSricharan R 	do {
816e651eab0SSricharan R 		/*
817e651eab0SSricharan R 		 * With LPAE, we must loop over to map
818e651eab0SSricharan R 		 * all the pmds for the given range.
819e651eab0SSricharan R 		 */
820e651eab0SSricharan R 		next = pmd_addr_end(addr, end);
821e651eab0SSricharan R 
822e651eab0SSricharan R 		/*
823e651eab0SSricharan R 		 * Try a section mapping - addr, next and phys must all be
824e651eab0SSricharan R 		 * aligned to a section boundary.
825e651eab0SSricharan R 		 */
826e651eab0SSricharan R 		if (type->prot_sect &&
827e651eab0SSricharan R 				((addr | next | phys) & ~SECTION_MASK) == 0) {
828b430e55bSArd Biesheuvel 			__map_init_section(pmd, addr, next, phys, type, ng);
829e651eab0SSricharan R 		} else {
830e651eab0SSricharan R 			alloc_init_pte(pmd, addr, next,
831b430e55bSArd Biesheuvel 				       __phys_to_pfn(phys), type, alloc, ng);
832e651eab0SSricharan R 		}
833e651eab0SSricharan R 
834e651eab0SSricharan R 		phys += next - addr;
835e651eab0SSricharan R 
836e651eab0SSricharan R 	} while (pmd++, addr = next, addr != end);
837ae8f1541SRussell King }
838ae8f1541SRussell King 
alloc_init_pud(p4d_t * p4d,unsigned long addr,unsigned long end,phys_addr_t phys,const struct mem_type * type,void * (* alloc)(unsigned long sz),bool ng)83984e6ffb2SMike Rapoport static void __init alloc_init_pud(p4d_t *p4d, unsigned long addr,
84020d6956dSVitaly Andrianov 				  unsigned long end, phys_addr_t phys,
841f579b2b1SArd Biesheuvel 				  const struct mem_type *type,
842b430e55bSArd Biesheuvel 				  void *(*alloc)(unsigned long sz), bool ng)
843516295e5SRussell King {
84484e6ffb2SMike Rapoport 	pud_t *pud = pud_offset(p4d, addr);
845516295e5SRussell King 	unsigned long next;
846516295e5SRussell King 
847516295e5SRussell King 	do {
848516295e5SRussell King 		next = pud_addr_end(addr, end);
849b430e55bSArd Biesheuvel 		alloc_init_pmd(pud, addr, next, phys, type, alloc, ng);
850516295e5SRussell King 		phys += next - addr;
851516295e5SRussell King 	} while (pud++, addr = next, addr != end);
852516295e5SRussell King }
853516295e5SRussell King 
alloc_init_p4d(pgd_t * pgd,unsigned long addr,unsigned long end,phys_addr_t phys,const struct mem_type * type,void * (* alloc)(unsigned long sz),bool ng)85484e6ffb2SMike Rapoport static void __init alloc_init_p4d(pgd_t *pgd, unsigned long addr,
85584e6ffb2SMike Rapoport 				  unsigned long end, phys_addr_t phys,
85684e6ffb2SMike Rapoport 				  const struct mem_type *type,
85784e6ffb2SMike Rapoport 				  void *(*alloc)(unsigned long sz), bool ng)
85884e6ffb2SMike Rapoport {
85984e6ffb2SMike Rapoport 	p4d_t *p4d = p4d_offset(pgd, addr);
86084e6ffb2SMike Rapoport 	unsigned long next;
86184e6ffb2SMike Rapoport 
86284e6ffb2SMike Rapoport 	do {
86384e6ffb2SMike Rapoport 		next = p4d_addr_end(addr, end);
86484e6ffb2SMike Rapoport 		alloc_init_pud(p4d, addr, next, phys, type, alloc, ng);
86584e6ffb2SMike Rapoport 		phys += next - addr;
86684e6ffb2SMike Rapoport 	} while (p4d++, addr = next, addr != end);
86784e6ffb2SMike Rapoport }
86884e6ffb2SMike Rapoport 
8691b6ba46bSCatalin Marinas #ifndef CONFIG_ARM_LPAE
create_36bit_mapping(struct mm_struct * mm,struct map_desc * md,const struct mem_type * type,bool ng)8701bdb2d4eSArd Biesheuvel static void __init create_36bit_mapping(struct mm_struct *mm,
8711bdb2d4eSArd Biesheuvel 					struct map_desc *md,
872b430e55bSArd Biesheuvel 					const struct mem_type *type,
873b430e55bSArd Biesheuvel 					bool ng)
8744a56c1e4SRussell King {
87597092e0cSRussell King 	unsigned long addr, length, end;
87697092e0cSRussell King 	phys_addr_t phys;
8774a56c1e4SRussell King 	pgd_t *pgd;
8784a56c1e4SRussell King 
8794a56c1e4SRussell King 	addr = md->virtual;
880cae6292bSWill Deacon 	phys = __pfn_to_phys(md->pfn);
8814a56c1e4SRussell King 	length = PAGE_ALIGN(md->length);
8824a56c1e4SRussell King 
8834a56c1e4SRussell King 	if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) {
8844ed89f22SRussell King 		pr_err("MM: CPU does not support supersection mapping for 0x%08llx at 0x%08lx\n",
88529a38193SWill Deacon 		       (long long)__pfn_to_phys((u64)md->pfn), addr);
8864a56c1e4SRussell King 		return;
8874a56c1e4SRussell King 	}
8884a56c1e4SRussell King 
8894a56c1e4SRussell King 	/* N.B.	ARMv6 supersections are only defined to work with domain 0.
8904a56c1e4SRussell King 	 *	Since domain assignments can in fact be arbitrary, the
8914a56c1e4SRussell King 	 *	'domain == 0' check below is required to insure that ARMv6
8924a56c1e4SRussell King 	 *	supersections are only allocated for domain 0 regardless
8934a56c1e4SRussell King 	 *	of the actual domain assignments in use.
8944a56c1e4SRussell King 	 */
8954a56c1e4SRussell King 	if (type->domain) {
8964ed89f22SRussell King 		pr_err("MM: invalid domain in supersection mapping for 0x%08llx at 0x%08lx\n",
89729a38193SWill Deacon 		       (long long)__pfn_to_phys((u64)md->pfn), addr);
8984a56c1e4SRussell King 		return;
8994a56c1e4SRussell King 	}
9004a56c1e4SRussell King 
9014a56c1e4SRussell King 	if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) {
9024ed89f22SRussell King 		pr_err("MM: cannot create mapping for 0x%08llx at 0x%08lx invalid alignment\n",
90329a38193SWill Deacon 		       (long long)__pfn_to_phys((u64)md->pfn), addr);
9044a56c1e4SRussell King 		return;
9054a56c1e4SRussell King 	}
9064a56c1e4SRussell King 
9074a56c1e4SRussell King 	/*
9084a56c1e4SRussell King 	 * Shift bits [35:32] of address into bits [23:20] of PMD
9094a56c1e4SRussell King 	 * (See ARMv6 spec).
9104a56c1e4SRussell King 	 */
9114a56c1e4SRussell King 	phys |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20);
9124a56c1e4SRussell King 
9131bdb2d4eSArd Biesheuvel 	pgd = pgd_offset(mm, addr);
9144a56c1e4SRussell King 	end = addr + length;
9154a56c1e4SRussell King 	do {
91684e6ffb2SMike Rapoport 		p4d_t *p4d = p4d_offset(pgd, addr);
91784e6ffb2SMike Rapoport 		pud_t *pud = pud_offset(p4d, addr);
918516295e5SRussell King 		pmd_t *pmd = pmd_offset(pud, addr);
9194a56c1e4SRussell King 		int i;
9204a56c1e4SRussell King 
9214a56c1e4SRussell King 		for (i = 0; i < 16; i++)
922b430e55bSArd Biesheuvel 			*pmd++ = __pmd(phys | type->prot_sect | PMD_SECT_SUPER |
923b430e55bSArd Biesheuvel 				       (ng ? PMD_SECT_nG : 0));
9244a56c1e4SRussell King 
9254a56c1e4SRussell King 		addr += SUPERSECTION_SIZE;
9264a56c1e4SRussell King 		phys += SUPERSECTION_SIZE;
9274a56c1e4SRussell King 		pgd += SUPERSECTION_SIZE >> PGDIR_SHIFT;
9284a56c1e4SRussell King 	} while (addr != end);
9294a56c1e4SRussell King }
9301b6ba46bSCatalin Marinas #endif	/* !CONFIG_ARM_LPAE */
9314a56c1e4SRussell King 
__create_mapping(struct mm_struct * mm,struct map_desc * md,void * (* alloc)(unsigned long sz),bool ng)932f579b2b1SArd Biesheuvel static void __init __create_mapping(struct mm_struct *mm, struct map_desc *md,
933b430e55bSArd Biesheuvel 				    void *(*alloc)(unsigned long sz),
934b430e55bSArd Biesheuvel 				    bool ng)
935ae8f1541SRussell King {
936cae6292bSWill Deacon 	unsigned long addr, length, end;
937cae6292bSWill Deacon 	phys_addr_t phys;
938d5c98176SRussell King 	const struct mem_type *type;
93924e6c699SRussell King 	pgd_t *pgd;
940ae8f1541SRussell King 
941d5c98176SRussell King 	type = &mem_types[md->type];
942ae8f1541SRussell King 
9431b6ba46bSCatalin Marinas #ifndef CONFIG_ARM_LPAE
944ae8f1541SRussell King 	/*
945ae8f1541SRussell King 	 * Catch 36-bit addresses
946ae8f1541SRussell King 	 */
947ae8f1541SRussell King 	if (md->pfn >= 0x100000) {
948b430e55bSArd Biesheuvel 		create_36bit_mapping(mm, md, type, ng);
949ae8f1541SRussell King 		return;
950ae8f1541SRussell King 	}
9511b6ba46bSCatalin Marinas #endif
952ae8f1541SRussell King 
9537b9c7b4dSRussell King 	addr = md->virtual & PAGE_MASK;
954cae6292bSWill Deacon 	phys = __pfn_to_phys(md->pfn);
9557b9c7b4dSRussell King 	length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
956ae8f1541SRussell King 
95724e6c699SRussell King 	if (type->prot_l1 == 0 && ((addr | phys | length) & ~SECTION_MASK)) {
9584ed89f22SRussell King 		pr_warn("BUG: map for 0x%08llx at 0x%08lx can not be mapped using pages, ignoring.\n",
95929a38193SWill Deacon 			(long long)__pfn_to_phys(md->pfn), addr);
960ae8f1541SRussell King 		return;
961ae8f1541SRussell King 	}
962ae8f1541SRussell King 
9631bdb2d4eSArd Biesheuvel 	pgd = pgd_offset(mm, addr);
96424e6c699SRussell King 	end = addr + length;
96524e6c699SRussell King 	do {
96624e6c699SRussell King 		unsigned long next = pgd_addr_end(addr, end);
967ae8f1541SRussell King 
96884e6ffb2SMike Rapoport 		alloc_init_p4d(pgd, addr, next, phys, type, alloc, ng);
969ae8f1541SRussell King 
97024e6c699SRussell King 		phys += next - addr;
97124e6c699SRussell King 		addr = next;
97224e6c699SRussell King 	} while (pgd++, addr != end);
973ae8f1541SRussell King }
974ae8f1541SRussell King 
975ae8f1541SRussell King /*
9761bdb2d4eSArd Biesheuvel  * Create the page directory entries and any necessary
9771bdb2d4eSArd Biesheuvel  * page tables for the mapping specified by `md'.  We
9781bdb2d4eSArd Biesheuvel  * are able to cope here with varying sizes and address
9791bdb2d4eSArd Biesheuvel  * offsets, and we take full advantage of sections and
9801bdb2d4eSArd Biesheuvel  * supersections.
9811bdb2d4eSArd Biesheuvel  */
create_mapping(struct map_desc * md)9821bdb2d4eSArd Biesheuvel static void __init create_mapping(struct map_desc *md)
9831bdb2d4eSArd Biesheuvel {
9841bdb2d4eSArd Biesheuvel 	if (md->virtual != vectors_base() && md->virtual < TASK_SIZE) {
9851bdb2d4eSArd Biesheuvel 		pr_warn("BUG: not creating mapping for 0x%08llx at 0x%08lx in user region\n",
9861bdb2d4eSArd Biesheuvel 			(long long)__pfn_to_phys((u64)md->pfn), md->virtual);
9871bdb2d4eSArd Biesheuvel 		return;
9881bdb2d4eSArd Biesheuvel 	}
9891bdb2d4eSArd Biesheuvel 
9907a1be318SArd Biesheuvel 	if (md->type == MT_DEVICE &&
9911bdb2d4eSArd Biesheuvel 	    md->virtual >= PAGE_OFFSET && md->virtual < FIXADDR_START &&
9921bdb2d4eSArd Biesheuvel 	    (md->virtual < VMALLOC_START || md->virtual >= VMALLOC_END)) {
9931bdb2d4eSArd Biesheuvel 		pr_warn("BUG: mapping for 0x%08llx at 0x%08lx out of vmalloc space\n",
9941bdb2d4eSArd Biesheuvel 			(long long)__pfn_to_phys((u64)md->pfn), md->virtual);
9951bdb2d4eSArd Biesheuvel 	}
9961bdb2d4eSArd Biesheuvel 
997b430e55bSArd Biesheuvel 	__create_mapping(&init_mm, md, early_alloc, false);
9981bdb2d4eSArd Biesheuvel }
9991bdb2d4eSArd Biesheuvel 
create_mapping_late(struct mm_struct * mm,struct map_desc * md,bool ng)1000c7936206SArd Biesheuvel void __init create_mapping_late(struct mm_struct *mm, struct map_desc *md,
1001c7936206SArd Biesheuvel 				bool ng)
1002c7936206SArd Biesheuvel {
1003c7936206SArd Biesheuvel #ifdef CONFIG_ARM_LPAE
100484e6ffb2SMike Rapoport 	p4d_t *p4d;
100584e6ffb2SMike Rapoport 	pud_t *pud;
100684e6ffb2SMike Rapoport 
100784e6ffb2SMike Rapoport 	p4d = p4d_alloc(mm, pgd_offset(mm, md->virtual), md->virtual);
10085c6360eeSArd Biesheuvel 	if (WARN_ON(!p4d))
100984e6ffb2SMike Rapoport 		return;
101084e6ffb2SMike Rapoport 	pud = pud_alloc(mm, p4d, md->virtual);
1011c7936206SArd Biesheuvel 	if (WARN_ON(!pud))
1012c7936206SArd Biesheuvel 		return;
1013c7936206SArd Biesheuvel 	pmd_alloc(mm, pud, 0);
1014c7936206SArd Biesheuvel #endif
1015c7936206SArd Biesheuvel 	__create_mapping(mm, md, late_alloc, ng);
1016c7936206SArd Biesheuvel }
1017c7936206SArd Biesheuvel 
10181bdb2d4eSArd Biesheuvel /*
1019ae8f1541SRussell King  * Create the architecture specific mappings
1020ae8f1541SRussell King  */
iotable_init(struct map_desc * io_desc,int nr)1021ae8f1541SRussell King void __init iotable_init(struct map_desc *io_desc, int nr)
1022ae8f1541SRussell King {
10230536bdf3SNicolas Pitre 	struct map_desc *md;
10240536bdf3SNicolas Pitre 	struct vm_struct *vm;
1025101eeda3SJoonsoo Kim 	struct static_vm *svm;
1026ae8f1541SRussell King 
10270536bdf3SNicolas Pitre 	if (!nr)
10280536bdf3SNicolas Pitre 		return;
10290536bdf3SNicolas Pitre 
1030c2938eebSMike Rapoport 	svm = memblock_alloc(sizeof(*svm) * nr, __alignof__(*svm));
10318a7f97b9SMike Rapoport 	if (!svm)
10328a7f97b9SMike Rapoport 		panic("%s: Failed to allocate %zu bytes align=0x%zx\n",
10338a7f97b9SMike Rapoport 		      __func__, sizeof(*svm) * nr, __alignof__(*svm));
10340536bdf3SNicolas Pitre 
10350536bdf3SNicolas Pitre 	for (md = io_desc; nr; md++, nr--) {
10360536bdf3SNicolas Pitre 		create_mapping(md);
1037101eeda3SJoonsoo Kim 
1038101eeda3SJoonsoo Kim 		vm = &svm->vm;
10390536bdf3SNicolas Pitre 		vm->addr = (void *)(md->virtual & PAGE_MASK);
10400536bdf3SNicolas Pitre 		vm->size = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK));
10410536bdf3SNicolas Pitre 		vm->phys_addr = __pfn_to_phys(md->pfn);
1042576d2f25SNicolas Pitre 		vm->flags = VM_IOREMAP | VM_ARM_STATIC_MAPPING;
1043576d2f25SNicolas Pitre 		vm->flags |= VM_ARM_MTYPE(md->type);
10440536bdf3SNicolas Pitre 		vm->caller = iotable_init;
1045101eeda3SJoonsoo Kim 		add_static_vm_early(svm++);
10460536bdf3SNicolas Pitre 	}
1047ae8f1541SRussell King }
1048ae8f1541SRussell King 
vm_reserve_area_early(unsigned long addr,unsigned long size,void * caller)1049c2794437SRob Herring void __init vm_reserve_area_early(unsigned long addr, unsigned long size,
1050c2794437SRob Herring 				  void *caller)
1051c2794437SRob Herring {
1052c2794437SRob Herring 	struct vm_struct *vm;
1053101eeda3SJoonsoo Kim 	struct static_vm *svm;
1054c2794437SRob Herring 
1055c2938eebSMike Rapoport 	svm = memblock_alloc(sizeof(*svm), __alignof__(*svm));
10568a7f97b9SMike Rapoport 	if (!svm)
10578a7f97b9SMike Rapoport 		panic("%s: Failed to allocate %zu bytes align=0x%zx\n",
10588a7f97b9SMike Rapoport 		      __func__, sizeof(*svm), __alignof__(*svm));
1059101eeda3SJoonsoo Kim 
1060101eeda3SJoonsoo Kim 	vm = &svm->vm;
1061c2794437SRob Herring 	vm->addr = (void *)addr;
1062c2794437SRob Herring 	vm->size = size;
1063863e99a8SArnd Bergmann 	vm->flags = VM_IOREMAP | VM_ARM_EMPTY_MAPPING;
1064c2794437SRob Herring 	vm->caller = caller;
1065101eeda3SJoonsoo Kim 	add_static_vm_early(svm);
1066c2794437SRob Herring }
1067c2794437SRob Herring 
106819b52abeSNicolas Pitre #ifndef CONFIG_ARM_LPAE
106919b52abeSNicolas Pitre 
107019b52abeSNicolas Pitre /*
107119b52abeSNicolas Pitre  * The Linux PMD is made of two consecutive section entries covering 2MB
107219b52abeSNicolas Pitre  * (see definition in include/asm/pgtable-2level.h).  However a call to
107319b52abeSNicolas Pitre  * create_mapping() may optimize static mappings by using individual
107419b52abeSNicolas Pitre  * 1MB section mappings.  This leaves the actual PMD potentially half
107519b52abeSNicolas Pitre  * initialized if the top or bottom section entry isn't used, leaving it
107619b52abeSNicolas Pitre  * open to problems if a subsequent ioremap() or vmalloc() tries to use
107719b52abeSNicolas Pitre  * the virtual space left free by that unused section entry.
107819b52abeSNicolas Pitre  *
107919b52abeSNicolas Pitre  * Let's avoid the issue by inserting dummy vm entries covering the unused
108019b52abeSNicolas Pitre  * PMD halves once the static mappings are in place.
108119b52abeSNicolas Pitre  */
108219b52abeSNicolas Pitre 
pmd_empty_section_gap(unsigned long addr)108319b52abeSNicolas Pitre static void __init pmd_empty_section_gap(unsigned long addr)
108419b52abeSNicolas Pitre {
1085c2794437SRob Herring 	vm_reserve_area_early(addr, SECTION_SIZE, pmd_empty_section_gap);
108619b52abeSNicolas Pitre }
108719b52abeSNicolas Pitre 
fill_pmd_gaps(void)108819b52abeSNicolas Pitre static void __init fill_pmd_gaps(void)
108919b52abeSNicolas Pitre {
1090101eeda3SJoonsoo Kim 	struct static_vm *svm;
109119b52abeSNicolas Pitre 	struct vm_struct *vm;
109219b52abeSNicolas Pitre 	unsigned long addr, next = 0;
109319b52abeSNicolas Pitre 	pmd_t *pmd;
109419b52abeSNicolas Pitre 
1095101eeda3SJoonsoo Kim 	list_for_each_entry(svm, &static_vmlist, list) {
1096101eeda3SJoonsoo Kim 		vm = &svm->vm;
109719b52abeSNicolas Pitre 		addr = (unsigned long)vm->addr;
109819b52abeSNicolas Pitre 		if (addr < next)
109919b52abeSNicolas Pitre 			continue;
110019b52abeSNicolas Pitre 
110119b52abeSNicolas Pitre 		/*
110219b52abeSNicolas Pitre 		 * Check if this vm starts on an odd section boundary.
110319b52abeSNicolas Pitre 		 * If so and the first section entry for this PMD is free
110419b52abeSNicolas Pitre 		 * then we block the corresponding virtual address.
110519b52abeSNicolas Pitre 		 */
110619b52abeSNicolas Pitre 		if ((addr & ~PMD_MASK) == SECTION_SIZE) {
110719b52abeSNicolas Pitre 			pmd = pmd_off_k(addr);
110819b52abeSNicolas Pitre 			if (pmd_none(*pmd))
110919b52abeSNicolas Pitre 				pmd_empty_section_gap(addr & PMD_MASK);
111019b52abeSNicolas Pitre 		}
111119b52abeSNicolas Pitre 
111219b52abeSNicolas Pitre 		/*
111319b52abeSNicolas Pitre 		 * Then check if this vm ends on an odd section boundary.
111419b52abeSNicolas Pitre 		 * If so and the second section entry for this PMD is empty
111519b52abeSNicolas Pitre 		 * then we block the corresponding virtual address.
111619b52abeSNicolas Pitre 		 */
111719b52abeSNicolas Pitre 		addr += vm->size;
111819b52abeSNicolas Pitre 		if ((addr & ~PMD_MASK) == SECTION_SIZE) {
111919b52abeSNicolas Pitre 			pmd = pmd_off_k(addr) + 1;
112019b52abeSNicolas Pitre 			if (pmd_none(*pmd))
112119b52abeSNicolas Pitre 				pmd_empty_section_gap(addr);
112219b52abeSNicolas Pitre 		}
112319b52abeSNicolas Pitre 
112419b52abeSNicolas Pitre 		/* no need to look at any vm entry until we hit the next PMD */
112519b52abeSNicolas Pitre 		next = (addr + PMD_SIZE - 1) & PMD_MASK;
112619b52abeSNicolas Pitre 	}
112719b52abeSNicolas Pitre }
112819b52abeSNicolas Pitre 
112919b52abeSNicolas Pitre #else
113019b52abeSNicolas Pitre #define fill_pmd_gaps() do { } while (0)
113119b52abeSNicolas Pitre #endif
113219b52abeSNicolas Pitre 
1133c2794437SRob Herring #if defined(CONFIG_PCI) && !defined(CONFIG_NEED_MACH_IO_H)
pci_reserve_io(void)1134c2794437SRob Herring static void __init pci_reserve_io(void)
1135c2794437SRob Herring {
1136101eeda3SJoonsoo Kim 	struct static_vm *svm;
1137c2794437SRob Herring 
1138101eeda3SJoonsoo Kim 	svm = find_static_vm_vaddr((void *)PCI_IO_VIRT_BASE);
1139101eeda3SJoonsoo Kim 	if (svm)
1140c2794437SRob Herring 		return;
1141c2794437SRob Herring 
1142c2794437SRob Herring 	vm_reserve_area_early(PCI_IO_VIRT_BASE, SZ_2M, pci_reserve_io);
1143c2794437SRob Herring }
1144c2794437SRob Herring #else
1145c2794437SRob Herring #define pci_reserve_io() do { } while (0)
1146c2794437SRob Herring #endif
1147c2794437SRob Herring 
1148e5c5f2adSRob Herring #ifdef CONFIG_DEBUG_LL
debug_ll_io_init(void)1149e5c5f2adSRob Herring void __init debug_ll_io_init(void)
1150e5c5f2adSRob Herring {
1151e5c5f2adSRob Herring 	struct map_desc map;
1152e5c5f2adSRob Herring 
1153e5c5f2adSRob Herring 	debug_ll_addr(&map.pfn, &map.virtual);
1154e5c5f2adSRob Herring 	if (!map.pfn || !map.virtual)
1155e5c5f2adSRob Herring 		return;
1156e5c5f2adSRob Herring 	map.pfn = __phys_to_pfn(map.pfn);
1157e5c5f2adSRob Herring 	map.virtual &= PAGE_MASK;
1158e5c5f2adSRob Herring 	map.length = PAGE_SIZE;
1159e5c5f2adSRob Herring 	map.type = MT_DEVICE;
1160ee4de5d9SStephen Boyd 	iotable_init(&map, 1);
1161e5c5f2adSRob Herring }
1162e5c5f2adSRob Herring #endif
1163e5c5f2adSRob Herring 
116408b84240SRussell King (Oracle) static unsigned long __initdata vmalloc_size = 240 * SZ_1M;
11656c5da7acSRussell King 
11666c5da7acSRussell King /*
11676c5da7acSRussell King  * vmalloc=size forces the vmalloc area to be exactly 'size'
11686c5da7acSRussell King  * bytes. This can be used to increase (or decrease) the vmalloc
1169c01914efSRussell King (Oracle)  * area - the default is 240MiB.
11706c5da7acSRussell King  */
early_vmalloc(char * arg)11712b0d8c25SJeremy Kerr static int __init early_vmalloc(char *arg)
11726c5da7acSRussell King {
117379612395SRussell King 	unsigned long vmalloc_reserve = memparse(arg, NULL);
11744f706b07SRussell King (Oracle) 	unsigned long vmalloc_max;
11756c5da7acSRussell King 
11766c5da7acSRussell King 	if (vmalloc_reserve < SZ_16M) {
11776c5da7acSRussell King 		vmalloc_reserve = SZ_16M;
1178c01914efSRussell King (Oracle) 		pr_warn("vmalloc area is too small, limiting to %luMiB\n",
11796c5da7acSRussell King 			vmalloc_reserve >> 20);
11806c5da7acSRussell King 	}
11819210807cSNicolas Pitre 
1182f572f5cbSRussell King (Oracle) 	vmalloc_max = VMALLOC_END - (PAGE_OFFSET + SZ_32M + VMALLOC_OFFSET);
11834f706b07SRussell King (Oracle) 	if (vmalloc_reserve > vmalloc_max) {
11844f706b07SRussell King (Oracle) 		vmalloc_reserve = vmalloc_max;
1185c01914efSRussell King (Oracle) 		pr_warn("vmalloc area is too big, limiting to %luMiB\n",
11869210807cSNicolas Pitre 			vmalloc_reserve >> 20);
11879210807cSNicolas Pitre 	}
118879612395SRussell King 
11894c1b7a76SRussell King (Oracle) 	vmalloc_size = vmalloc_reserve;
11902b0d8c25SJeremy Kerr 	return 0;
11916c5da7acSRussell King }
11922b0d8c25SJeremy Kerr early_param("vmalloc", early_vmalloc);
11936c5da7acSRussell King 
1194c7909509SMarek Szyprowski phys_addr_t arm_lowmem_limit __initdata = 0;
11958df65168SRussell King 
adjust_lowmem_bounds(void)1196374d446dSLaura Abbott void __init adjust_lowmem_bounds(void)
119760296c71SLennert Buytenhek {
1198b10d6bcaSMike Rapoport 	phys_addr_t block_start, block_end, memblock_limit = 0;
1199b10d6bcaSMike Rapoport 	u64 vmalloc_limit, i;
120098562656SLaura Abbott 	phys_addr_t lowmem_limit = 0;
120160296c71SLennert Buytenhek 
1202b9a01989SNicolas Pitre 	/*
1203b9a01989SNicolas Pitre 	 * Let's use our own (unoptimized) equivalent of __pa() that is
1204b9a01989SNicolas Pitre 	 * not affected by wrap-arounds when sizeof(phys_addr_t) == 4.
1205b9a01989SNicolas Pitre 	 * The result is used as the upper bound on physical memory address
1206b9a01989SNicolas Pitre 	 * and may itself be outside the valid range for which phys_addr_t
1207b9a01989SNicolas Pitre 	 * and therefore __pa() is defined.
1208b9a01989SNicolas Pitre 	 */
12094c1b7a76SRussell King (Oracle) 	vmalloc_limit = (u64)VMALLOC_END - vmalloc_size - VMALLOC_OFFSET -
1210f572f5cbSRussell King (Oracle) 			PAGE_OFFSET + PHYS_OFFSET;
1211b9a01989SNicolas Pitre 
121200d2ec1eSMike Rapoport 	/*
121300d2ec1eSMike Rapoport 	 * The first usable region must be PMD aligned. Mark its start
121400d2ec1eSMike Rapoport 	 * as MEMBLOCK_NOMAP if it isn't
121500d2ec1eSMike Rapoport 	 */
1216b10d6bcaSMike Rapoport 	for_each_mem_range(i, &block_start, &block_end) {
1217b10d6bcaSMike Rapoport 		if (!IS_ALIGNED(block_start, PMD_SIZE)) {
121800d2ec1eSMike Rapoport 			phys_addr_t len;
121900d2ec1eSMike Rapoport 
1220b10d6bcaSMike Rapoport 			len = round_up(block_start, PMD_SIZE) - block_start;
1221b10d6bcaSMike Rapoport 			memblock_mark_nomap(block_start, len);
122200d2ec1eSMike Rapoport 		}
122300d2ec1eSMike Rapoport 		break;
122400d2ec1eSMike Rapoport 	}
122500d2ec1eSMike Rapoport 
1226b10d6bcaSMike Rapoport 	for_each_mem_range(i, &block_start, &block_end) {
1227b10d6bcaSMike Rapoport 		if (block_start < vmalloc_limit) {
122898562656SLaura Abbott 			if (block_end > lowmem_limit)
1229374d446dSLaura Abbott 				/*
1230374d446dSLaura Abbott 				 * Compare as u64 to ensure vmalloc_limit does
1231374d446dSLaura Abbott 				 * not get truncated. block_end should always
1232374d446dSLaura Abbott 				 * fit in phys_addr_t so there should be no
1233374d446dSLaura Abbott 				 * issue with assignment.
1234374d446dSLaura Abbott 				 */
123598562656SLaura Abbott 				lowmem_limit = min_t(u64,
1236374d446dSLaura Abbott 							 vmalloc_limit,
1237374d446dSLaura Abbott 							 block_end);
1238c65b7e98SRussell King 
1239c65b7e98SRussell King 			/*
1240965278dcSMark Rutland 			 * Find the first non-pmd-aligned page, and point
1241c65b7e98SRussell King 			 * memblock_limit at it. This relies on rounding the
1242965278dcSMark Rutland 			 * limit down to be pmd-aligned, which happens at the
1243965278dcSMark Rutland 			 * end of this function.
1244c65b7e98SRussell King 			 *
1245c65b7e98SRussell King 			 * With this algorithm, the start or end of almost any
1246965278dcSMark Rutland 			 * bank can be non-pmd-aligned. The only exception is
1247965278dcSMark Rutland 			 * that the start of the bank 0 must be section-
1248c65b7e98SRussell King 			 * aligned, since otherwise memory would need to be
1249c65b7e98SRussell King 			 * allocated when mapping the start of bank 0, which
1250c65b7e98SRussell King 			 * occurs before any free memory is mapped.
1251c65b7e98SRussell King 			 */
1252c65b7e98SRussell King 			if (!memblock_limit) {
1253965278dcSMark Rutland 				if (!IS_ALIGNED(block_start, PMD_SIZE))
12541c2f87c2SLaura Abbott 					memblock_limit = block_start;
1255965278dcSMark Rutland 				else if (!IS_ALIGNED(block_end, PMD_SIZE))
125698562656SLaura Abbott 					memblock_limit = lowmem_limit;
1257c65b7e98SRussell King 			}
1258e616c591SRussell King 
1259e616c591SRussell King 		}
1260e616c591SRussell King 	}
12611c2f87c2SLaura Abbott 
126298562656SLaura Abbott 	arm_lowmem_limit = lowmem_limit;
126398562656SLaura Abbott 
1264c7909509SMarek Szyprowski 	high_memory = __va(arm_lowmem_limit - 1) + 1;
1265c65b7e98SRussell King 
12669e25ebfeSDoug Berger 	if (!memblock_limit)
12679e25ebfeSDoug Berger 		memblock_limit = arm_lowmem_limit;
12689e25ebfeSDoug Berger 
1269c65b7e98SRussell King 	/*
1270965278dcSMark Rutland 	 * Round the memblock limit down to a pmd size.  This
1271c65b7e98SRussell King 	 * helps to ensure that we will allocate memory from the
1272965278dcSMark Rutland 	 * last full pmd, which should be mapped.
1273c65b7e98SRussell King 	 */
1274965278dcSMark Rutland 	memblock_limit = round_down(memblock_limit, PMD_SIZE);
1275c65b7e98SRussell King 
1276374d446dSLaura Abbott 	if (!IS_ENABLED(CONFIG_HIGHMEM) || cache_is_vipt_aliasing()) {
1277374d446dSLaura Abbott 		if (memblock_end_of_DRAM() > arm_lowmem_limit) {
1278374d446dSLaura Abbott 			phys_addr_t end = memblock_end_of_DRAM();
1279374d446dSLaura Abbott 
1280374d446dSLaura Abbott 			pr_notice("Ignoring RAM at %pa-%pa\n",
1281374d446dSLaura Abbott 				  &memblock_limit, &end);
1282374d446dSLaura Abbott 			pr_notice("Consider using a HIGHMEM enabled kernel.\n");
1283374d446dSLaura Abbott 
1284374d446dSLaura Abbott 			memblock_remove(memblock_limit, end - memblock_limit);
1285374d446dSLaura Abbott 		}
1286374d446dSLaura Abbott 	}
1287374d446dSLaura Abbott 
1288c65b7e98SRussell King 	memblock_set_current_limit(memblock_limit);
128960296c71SLennert Buytenhek }
129060296c71SLennert Buytenhek 
prepare_page_table(void)1291ae7ba761SArnd Bergmann static __init void prepare_page_table(void)
1292d111e8f9SRussell King {
1293d111e8f9SRussell King 	unsigned long addr;
12948df65168SRussell King 	phys_addr_t end;
1295d111e8f9SRussell King 
1296d111e8f9SRussell King 	/*
1297d111e8f9SRussell King 	 * Clear out all the mappings below the kernel image.
1298d111e8f9SRussell King 	 */
1299c12366baSLinus Walleij #ifdef CONFIG_KASAN
1300c12366baSLinus Walleij 	/*
1301c12366baSLinus Walleij 	 * KASan's shadow memory inserts itself between the TASK_SIZE
1302c12366baSLinus Walleij 	 * and MODULES_VADDR. Do not clear the KASan shadow memory mappings.
1303c12366baSLinus Walleij 	 */
1304c12366baSLinus Walleij 	for (addr = 0; addr < KASAN_SHADOW_START; addr += PMD_SIZE)
1305c12366baSLinus Walleij 		pmd_clear(pmd_off_k(addr));
1306c12366baSLinus Walleij 	/*
1307c12366baSLinus Walleij 	 * Skip over the KASan shadow area. KASAN_SHADOW_END is sometimes
1308c12366baSLinus Walleij 	 * equal to MODULES_VADDR and then we exit the pmd clearing. If we
1309c12366baSLinus Walleij 	 * are using a thumb-compiled kernel, there there will be 8MB more
1310c12366baSLinus Walleij 	 * to clear as KASan always offset to 16 MB below MODULES_VADDR.
1311c12366baSLinus Walleij 	 */
1312c12366baSLinus Walleij 	for (addr = KASAN_SHADOW_END; addr < MODULES_VADDR; addr += PMD_SIZE)
1313c12366baSLinus Walleij 		pmd_clear(pmd_off_k(addr));
1314c12366baSLinus Walleij #else
1315e73fc88eSCatalin Marinas 	for (addr = 0; addr < MODULES_VADDR; addr += PMD_SIZE)
1316d111e8f9SRussell King 		pmd_clear(pmd_off_k(addr));
1317c12366baSLinus Walleij #endif
1318d111e8f9SRussell King 
1319d111e8f9SRussell King #ifdef CONFIG_XIP_KERNEL
1320d111e8f9SRussell King 	/* The XIP kernel is mapped in the module area -- skip over it */
132102afa9a8SChris Brandt 	addr = ((unsigned long)_exiprom + PMD_SIZE - 1) & PMD_MASK;
1322d111e8f9SRussell King #endif
1323e73fc88eSCatalin Marinas 	for ( ; addr < PAGE_OFFSET; addr += PMD_SIZE)
1324d111e8f9SRussell King 		pmd_clear(pmd_off_k(addr));
1325d111e8f9SRussell King 
1326d111e8f9SRussell King 	/*
13278df65168SRussell King 	 * Find the end of the first block of lowmem.
13288df65168SRussell King 	 */
13298df65168SRussell King 	end = memblock.memory.regions[0].base + memblock.memory.regions[0].size;
1330c7909509SMarek Szyprowski 	if (end >= arm_lowmem_limit)
1331c7909509SMarek Szyprowski 		end = arm_lowmem_limit;
13328df65168SRussell King 
13338df65168SRussell King 	/*
1334d111e8f9SRussell King 	 * Clear out all the kernel space mappings, except for the first
13350536bdf3SNicolas Pitre 	 * memory bank, up to the vmalloc region.
1336d111e8f9SRussell King 	 */
13378df65168SRussell King 	for (addr = __phys_to_virt(end);
13380536bdf3SNicolas Pitre 	     addr < VMALLOC_START; addr += PMD_SIZE)
1339d111e8f9SRussell King 		pmd_clear(pmd_off_k(addr));
1340d111e8f9SRussell King }
1341d111e8f9SRussell King 
13421b6ba46bSCatalin Marinas #ifdef CONFIG_ARM_LPAE
13431b6ba46bSCatalin Marinas /* the first page is reserved for pgd */
13441b6ba46bSCatalin Marinas #define SWAPPER_PG_DIR_SIZE	(PAGE_SIZE + \
13451b6ba46bSCatalin Marinas 				 PTRS_PER_PGD * PTRS_PER_PMD * sizeof(pmd_t))
13461b6ba46bSCatalin Marinas #else
1347e73fc88eSCatalin Marinas #define SWAPPER_PG_DIR_SIZE	(PTRS_PER_PGD * sizeof(pgd_t))
13481b6ba46bSCatalin Marinas #endif
1349e73fc88eSCatalin Marinas 
1350d111e8f9SRussell King /*
13512778f620SRussell King  * Reserve the special regions of memory
1352d111e8f9SRussell King  */
arm_mm_memblock_reserve(void)13532778f620SRussell King void __init arm_mm_memblock_reserve(void)
1354d111e8f9SRussell King {
1355d111e8f9SRussell King 	/*
1356d111e8f9SRussell King 	 * Reserve the page tables.  These are already in use,
1357d111e8f9SRussell King 	 * and can only be in node 0.
1358d111e8f9SRussell King 	 */
1359e73fc88eSCatalin Marinas 	memblock_reserve(__pa(swapper_pg_dir), SWAPPER_PG_DIR_SIZE);
1360d111e8f9SRussell King 
1361d111e8f9SRussell King #ifdef CONFIG_SA1111
1362d111e8f9SRussell King 	/*
1363d111e8f9SRussell King 	 * Because of the SA1111 DMA bug, we want to preserve our
1364d111e8f9SRussell King 	 * precious DMA-able memory...
1365d111e8f9SRussell King 	 */
13662778f620SRussell King 	memblock_reserve(PHYS_OFFSET, __pa(swapper_pg_dir) - PHYS_OFFSET);
1367d111e8f9SRussell King #endif
1368d111e8f9SRussell King }
1369d111e8f9SRussell King 
1370d111e8f9SRussell King /*
13710536bdf3SNicolas Pitre  * Set up the device mappings.  Since we clear out the page tables for all
1372a5f4c561SStefan Agner  * mappings above VMALLOC_START, except early fixmap, we might remove debug
1373a5f4c561SStefan Agner  * device mappings.  This means earlycon can be used to debug this function
1374a5f4c561SStefan Agner  * Any other function or debugging method which may touch any device _will_
1375a5f4c561SStefan Agner  * crash the kernel.
1376d111e8f9SRussell King  */
devicemaps_init(const struct machine_desc * mdesc)1377ff69a4c8SRussell King static void __init devicemaps_init(const struct machine_desc *mdesc)
1378d111e8f9SRussell King {
1379d111e8f9SRussell King 	struct map_desc map;
1380d111e8f9SRussell King 	unsigned long addr;
138194e5a85bSRussell King 	void *vectors;
1382d111e8f9SRussell King 
1383d111e8f9SRussell King 	/*
1384d111e8f9SRussell King 	 * Allocate the vector page early.
1385d111e8f9SRussell King 	 */
138619accfd3SRussell King 	vectors = early_alloc(PAGE_SIZE * 2);
138794e5a85bSRussell King 
138894e5a85bSRussell King 	early_trap_init(vectors);
1389d111e8f9SRussell King 
1390a5f4c561SStefan Agner 	/*
1391a5f4c561SStefan Agner 	 * Clear page table except top pmd used by early fixmaps
1392a5f4c561SStefan Agner 	 */
1393a5f4c561SStefan Agner 	for (addr = VMALLOC_START; addr < (FIXADDR_TOP & PMD_MASK); addr += PMD_SIZE)
1394d111e8f9SRussell King 		pmd_clear(pmd_off_k(addr));
1395d111e8f9SRussell King 
13967a1be318SArd Biesheuvel 	if (__atags_pointer) {
13977a1be318SArd Biesheuvel 		/* create a read-only mapping of the device tree */
13987a1be318SArd Biesheuvel 		map.pfn = __phys_to_pfn(__atags_pointer & SECTION_MASK);
13997a1be318SArd Biesheuvel 		map.virtual = FDT_FIXED_BASE;
14007a1be318SArd Biesheuvel 		map.length = FDT_FIXED_SIZE;
1401598f0a99SZhen Lei 		map.type = MT_MEMORY_RO;
14027a1be318SArd Biesheuvel 		create_mapping(&map);
14037a1be318SArd Biesheuvel 	}
14047a1be318SArd Biesheuvel 
1405d111e8f9SRussell King 	/*
1406d111e8f9SRussell King 	 * Map the cache flushing regions.
1407d111e8f9SRussell King 	 */
1408d111e8f9SRussell King #ifdef FLUSH_BASE
1409d111e8f9SRussell King 	map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS);
1410d111e8f9SRussell King 	map.virtual = FLUSH_BASE;
1411d111e8f9SRussell King 	map.length = SZ_1M;
1412d111e8f9SRussell King 	map.type = MT_CACHECLEAN;
1413d111e8f9SRussell King 	create_mapping(&map);
1414d111e8f9SRussell King #endif
1415d111e8f9SRussell King #ifdef FLUSH_BASE_MINICACHE
1416d111e8f9SRussell King 	map.pfn = __phys_to_pfn(FLUSH_BASE_PHYS + SZ_1M);
1417d111e8f9SRussell King 	map.virtual = FLUSH_BASE_MINICACHE;
1418d111e8f9SRussell King 	map.length = SZ_1M;
1419d111e8f9SRussell King 	map.type = MT_MINICLEAN;
1420d111e8f9SRussell King 	create_mapping(&map);
1421d111e8f9SRussell King #endif
1422d111e8f9SRussell King 
1423d111e8f9SRussell King 	/*
1424d111e8f9SRussell King 	 * Create a mapping for the machine vectors at the high-vectors
1425d111e8f9SRussell King 	 * location (0xffff0000).  If we aren't using high-vectors, also
1426d111e8f9SRussell King 	 * create a mapping at the low-vectors virtual address.
1427d111e8f9SRussell King 	 */
142894e5a85bSRussell King 	map.pfn = __phys_to_pfn(virt_to_phys(vectors));
1429d111e8f9SRussell King 	map.virtual = 0xffff0000;
1430d111e8f9SRussell King 	map.length = PAGE_SIZE;
1431a5463cd3SRussell King #ifdef CONFIG_KUSER_HELPERS
1432d111e8f9SRussell King 	map.type = MT_HIGH_VECTORS;
1433a5463cd3SRussell King #else
1434a5463cd3SRussell King 	map.type = MT_LOW_VECTORS;
1435a5463cd3SRussell King #endif
1436d111e8f9SRussell King 	create_mapping(&map);
1437d111e8f9SRussell King 
1438d111e8f9SRussell King 	if (!vectors_high()) {
1439d111e8f9SRussell King 		map.virtual = 0;
144019accfd3SRussell King 		map.length = PAGE_SIZE * 2;
1441d111e8f9SRussell King 		map.type = MT_LOW_VECTORS;
1442d111e8f9SRussell King 		create_mapping(&map);
1443d111e8f9SRussell King 	}
1444d111e8f9SRussell King 
144519accfd3SRussell King 	/* Now create a kernel read-only mapping */
144619accfd3SRussell King 	map.pfn += 1;
144719accfd3SRussell King 	map.virtual = 0xffff0000 + PAGE_SIZE;
144819accfd3SRussell King 	map.length = PAGE_SIZE;
144919accfd3SRussell King 	map.type = MT_LOW_VECTORS;
145019accfd3SRussell King 	create_mapping(&map);
145119accfd3SRussell King 
1452d111e8f9SRussell King 	/*
1453d111e8f9SRussell King 	 * Ask the machine support to map in the statically mapped devices.
1454d111e8f9SRussell King 	 */
1455d111e8f9SRussell King 	if (mdesc->map_io)
1456d111e8f9SRussell King 		mdesc->map_io();
1457bc37324eSMaxime Ripard 	else
1458bc37324eSMaxime Ripard 		debug_ll_io_init();
145919b52abeSNicolas Pitre 	fill_pmd_gaps();
1460d111e8f9SRussell King 
1461c2794437SRob Herring 	/* Reserve fixed i/o space in VMALLOC region */
1462c2794437SRob Herring 	pci_reserve_io();
1463c2794437SRob Herring 
1464d111e8f9SRussell King 	/*
1465d111e8f9SRussell King 	 * Finally flush the caches and tlb to ensure that we're in a
1466d111e8f9SRussell King 	 * consistent state wrt the writebuffer.  This also ensures that
1467d111e8f9SRussell King 	 * any write-allocated cache lines in the vector page are written
1468d111e8f9SRussell King 	 * back.  After this point, we can start to touch devices again.
1469d111e8f9SRussell King 	 */
1470d111e8f9SRussell King 	local_flush_tlb_all();
1471d111e8f9SRussell King 	flush_cache_all();
1472bbeb9209SLucas Stach 
1473bbeb9209SLucas Stach 	/* Enable asynchronous aborts */
14749254970cSLucas Stach 	early_abt_enable();
1475d111e8f9SRussell King }
1476d111e8f9SRussell King 
kmap_init(void)1477d73cd428SNicolas Pitre static void __init kmap_init(void)
1478d73cd428SNicolas Pitre {
1479d73cd428SNicolas Pitre #ifdef CONFIG_HIGHMEM
14804bb2e27dSRussell King 	pkmap_page_table = early_pte_alloc(pmd_off_k(PKMAP_BASE),
14814bb2e27dSRussell King 		PKMAP_BASE, _PAGE_KERNEL_TABLE);
1482d73cd428SNicolas Pitre #endif
1483836a2418SRob Herring 
1484836a2418SRob Herring 	early_pte_alloc(pmd_off_k(FIXADDR_START), FIXADDR_START,
1485836a2418SRob Herring 			_PAGE_KERNEL_TABLE);
1486d73cd428SNicolas Pitre }
1487d73cd428SNicolas Pitre 
map_lowmem(void)14888df65168SRussell King static void __init map_lowmem(void)
1489a2227120SRussell King {
1490b10d6bcaSMike Rapoport 	phys_addr_t start, end;
1491b10d6bcaSMike Rapoport 	u64 i;
14928df65168SRussell King 
14938df65168SRussell King 	/* Map all the lowmem memory banks. */
1494b10d6bcaSMike Rapoport 	for_each_mem_range(i, &start, &end) {
1495a2227120SRussell King 		struct map_desc map;
1496a2227120SRussell King 
14976e121df1SLinus Walleij 		pr_debug("map lowmem start: 0x%08llx, end: 0x%08llx\n",
14986e121df1SLinus Walleij 			 (long long)start, (long long)end);
1499c7909509SMarek Szyprowski 		if (end > arm_lowmem_limit)
1500c7909509SMarek Szyprowski 			end = arm_lowmem_limit;
15018df65168SRussell King 		if (start >= end)
15028df65168SRussell King 			break;
15038df65168SRussell King 
15046e121df1SLinus Walleij 		/*
15056e121df1SLinus Walleij 		 * If our kernel image is in the VMALLOC area we need to remove
15066e121df1SLinus Walleij 		 * the kernel physical memory from lowmem since the kernel will
15076e121df1SLinus Walleij 		 * be mapped separately.
15086e121df1SLinus Walleij 		 *
15096e121df1SLinus Walleij 		 * The kernel will typically be at the very start of lowmem,
15106e121df1SLinus Walleij 		 * but any placement relative to memory ranges is possible.
15116e121df1SLinus Walleij 		 *
15126e121df1SLinus Walleij 		 * If the memblock contains the kernel, we have to chisel out
15136e121df1SLinus Walleij 		 * the kernel memory from it and map each part separately. We
15146e121df1SLinus Walleij 		 * get 6 different theoretical cases:
15156e121df1SLinus Walleij 		 *
15166e121df1SLinus Walleij 		 *                            +--------+ +--------+
15176e121df1SLinus Walleij 		 *  +-- start --+  +--------+ | Kernel | | Kernel |
15186e121df1SLinus Walleij 		 *  |           |  | Kernel | | case 2 | | case 5 |
15196e121df1SLinus Walleij 		 *  |           |  | case 1 | +--------+ |        | +--------+
15206e121df1SLinus Walleij 		 *  |  Memory   |  +--------+            |        | | Kernel |
15216e121df1SLinus Walleij 		 *  |  range    |  +--------+            |        | | case 6 |
15226e121df1SLinus Walleij 		 *  |           |  | Kernel | +--------+ |        | +--------+
15236e121df1SLinus Walleij 		 *  |           |  | case 3 | | Kernel | |        |
15246e121df1SLinus Walleij 		 *  +-- end ----+  +--------+ | case 4 | |        |
15256e121df1SLinus Walleij 		 *                            +--------+ +--------+
15266e121df1SLinus Walleij 		 */
15276e121df1SLinus Walleij 
15286e121df1SLinus Walleij 		/* Case 5: kernel covers range, don't map anything, should be rare */
15296e121df1SLinus Walleij 		if ((start > kernel_sec_start) && (end < kernel_sec_end))
15306e121df1SLinus Walleij 			break;
15316e121df1SLinus Walleij 
15326e121df1SLinus Walleij 		/* Cases where the kernel is starting inside the range */
15336e121df1SLinus Walleij 		if ((kernel_sec_start >= start) && (kernel_sec_start <= end)) {
15346e121df1SLinus Walleij 			/* Case 6: kernel is embedded in the range, we need two mappings */
15356e121df1SLinus Walleij 			if ((start < kernel_sec_start) && (end > kernel_sec_end)) {
15366e121df1SLinus Walleij 				/* Map memory below the kernel */
15378df65168SRussell King 				map.pfn = __phys_to_pfn(start);
15388df65168SRussell King 				map.virtual = __phys_to_virt(start);
15396e121df1SLinus Walleij 				map.length = kernel_sec_start - start;
15406e121df1SLinus Walleij 				map.type = MT_MEMORY_RW;
1541a2227120SRussell King 				create_mapping(&map);
15426e121df1SLinus Walleij 				/* Map memory above the kernel */
15436e121df1SLinus Walleij 				map.pfn = __phys_to_pfn(kernel_sec_end);
15446e121df1SLinus Walleij 				map.virtual = __phys_to_virt(kernel_sec_end);
15456e121df1SLinus Walleij 				map.length = end - kernel_sec_end;
15466e121df1SLinus Walleij 				map.type = MT_MEMORY_RW;
15476e121df1SLinus Walleij 				create_mapping(&map);
15486e121df1SLinus Walleij 				break;
15496e121df1SLinus Walleij 			}
15506e121df1SLinus Walleij 			/* Case 1: kernel and range start at the same address, should be common */
15516e121df1SLinus Walleij 			if (kernel_sec_start == start)
15526e121df1SLinus Walleij 				start = kernel_sec_end;
15536e121df1SLinus Walleij 			/* Case 3: kernel and range end at the same address, should be rare */
15546e121df1SLinus Walleij 			if (kernel_sec_end == end)
15556e121df1SLinus Walleij 				end = kernel_sec_start;
15566e121df1SLinus Walleij 		} else if ((kernel_sec_start < start) && (kernel_sec_end > start) && (kernel_sec_end < end)) {
15576e121df1SLinus Walleij 			/* Case 2: kernel ends inside range, starts below it */
15586e121df1SLinus Walleij 			start = kernel_sec_end;
15596e121df1SLinus Walleij 		} else if ((kernel_sec_start > start) && (kernel_sec_start < end) && (kernel_sec_end > end)) {
15606e121df1SLinus Walleij 			/* Case 4: kernel starts inside range, ends above it */
15616e121df1SLinus Walleij 			end = kernel_sec_start;
15626e121df1SLinus Walleij 		}
15631e6b4811SKees Cook 		map.pfn = __phys_to_pfn(start);
15641e6b4811SKees Cook 		map.virtual = __phys_to_virt(start);
15651e6b4811SKees Cook 		map.length = end - start;
15661e6b4811SKees Cook 		map.type = MT_MEMORY_RW;
1567ebd4922eSRussell King 		create_mapping(&map);
1568ebd4922eSRussell King 	}
15696e121df1SLinus Walleij }
15706e121df1SLinus Walleij 
map_kernel(void)15716e121df1SLinus Walleij static void __init map_kernel(void)
15726e121df1SLinus Walleij {
15736e121df1SLinus Walleij 	/*
15746e121df1SLinus Walleij 	 * We use the well known kernel section start and end and split the area in the
15756e121df1SLinus Walleij 	 * middle like this:
15766e121df1SLinus Walleij 	 *  .                .
15776e121df1SLinus Walleij 	 *  | RW memory      |
15786e121df1SLinus Walleij 	 *  +----------------+ kernel_x_start
15796e121df1SLinus Walleij 	 *  | Executable     |
15806e121df1SLinus Walleij 	 *  | kernel memory  |
15816e121df1SLinus Walleij 	 *  +----------------+ kernel_x_end / kernel_nx_start
15826e121df1SLinus Walleij 	 *  | Non-executable |
15836e121df1SLinus Walleij 	 *  | kernel memory  |
15846e121df1SLinus Walleij 	 *  +----------------+ kernel_nx_end
15856e121df1SLinus Walleij 	 *  | RW memory      |
15866e121df1SLinus Walleij 	 *  .                .
15876e121df1SLinus Walleij 	 *
15886e121df1SLinus Walleij 	 * Notice that we are dealing with section sized mappings here so all of this
15896e121df1SLinus Walleij 	 * will be bumped to the closest section boundary. This means that some of the
15906e121df1SLinus Walleij 	 * non-executable part of the kernel memory is actually mapped as executable.
15916e121df1SLinus Walleij 	 * This will only persist until we turn on proper memory management later on
15926e121df1SLinus Walleij 	 * and we remap the whole kernel with page granularity.
15936e121df1SLinus Walleij 	 */
1594*4b9fb3aeSHarith G #ifdef CONFIG_XIP_KERNEL
1595*4b9fb3aeSHarith G 	phys_addr_t kernel_nx_start = kernel_sec_start;
1596*4b9fb3aeSHarith G #else
15976e121df1SLinus Walleij 	phys_addr_t kernel_x_start = kernel_sec_start;
15986e121df1SLinus Walleij 	phys_addr_t kernel_x_end = round_up(__pa(__init_end), SECTION_SIZE);
15996e121df1SLinus Walleij 	phys_addr_t kernel_nx_start = kernel_x_end;
1600*4b9fb3aeSHarith G #endif
16016e121df1SLinus Walleij 	phys_addr_t kernel_nx_end = kernel_sec_end;
16026e121df1SLinus Walleij 	struct map_desc map;
1603ebd4922eSRussell King 
1604*4b9fb3aeSHarith G 	/*
1605*4b9fb3aeSHarith G 	 * Map the kernel if it is XIP.
1606*4b9fb3aeSHarith G 	 * It is always first in the modulearea.
1607*4b9fb3aeSHarith G 	 */
1608*4b9fb3aeSHarith G #ifdef CONFIG_XIP_KERNEL
1609*4b9fb3aeSHarith G 	map.pfn = __phys_to_pfn(CONFIG_XIP_PHYS_ADDR & SECTION_MASK);
1610*4b9fb3aeSHarith G 	map.virtual = MODULES_VADDR;
1611*4b9fb3aeSHarith G 	map.length = ((unsigned long)_exiprom - map.virtual + ~SECTION_MASK) & SECTION_MASK;
1612*4b9fb3aeSHarith G 	map.type = MT_ROM;
1613*4b9fb3aeSHarith G 	create_mapping(&map);
1614*4b9fb3aeSHarith G #else
1615ebd4922eSRussell King 	map.pfn = __phys_to_pfn(kernel_x_start);
1616ebd4922eSRussell King 	map.virtual = __phys_to_virt(kernel_x_start);
1617ebd4922eSRussell King 	map.length = kernel_x_end - kernel_x_start;
1618ebd4922eSRussell King 	map.type = MT_MEMORY_RWX;
1619ebd4922eSRussell King 	create_mapping(&map);
1620ebd4922eSRussell King 
16216e121df1SLinus Walleij 	/* If the nx part is small it may end up covered by the tail of the RWX section */
16226e121df1SLinus Walleij 	if (kernel_x_end == kernel_nx_end)
16236e121df1SLinus Walleij 		return;
1624*4b9fb3aeSHarith G #endif
16256e121df1SLinus Walleij 	map.pfn = __phys_to_pfn(kernel_nx_start);
16266e121df1SLinus Walleij 	map.virtual = __phys_to_virt(kernel_nx_start);
16276e121df1SLinus Walleij 	map.length = kernel_nx_end - kernel_nx_start;
1628ebd4922eSRussell King 	map.type = MT_MEMORY_RW;
1629ebd4922eSRussell King 	create_mapping(&map);
1630ebd4922eSRussell King }
1631a2227120SRussell King 
1632d8dc7fbdSRussell King #ifdef CONFIG_ARM_PV_FIXUP
16337a1be318SArd Biesheuvel typedef void pgtables_remap(long long offset, unsigned long pgd);
1634d8dc7fbdSRussell King pgtables_remap lpae_pgtables_remap_asm;
1635d8dc7fbdSRussell King 
1636a77e0c7bSSantosh Shilimkar /*
1637a77e0c7bSSantosh Shilimkar  * early_paging_init() recreates boot time page table setup, allowing machines
1638a77e0c7bSSantosh Shilimkar  * to switch over to a high (>4G) address space on LPAE systems
1639a77e0c7bSSantosh Shilimkar  */
early_paging_init(const struct machine_desc * mdesc)1640b089c31cSJon Medhurst static void __init early_paging_init(const struct machine_desc *mdesc)
1641a77e0c7bSSantosh Shilimkar {
1642d8dc7fbdSRussell King 	pgtables_remap *lpae_pgtables_remap;
1643d8dc7fbdSRussell King 	unsigned long pa_pgd;
1644d8dc7fbdSRussell King 	unsigned int cr, ttbcr;
1645c8ca2b4bSRussell King 	long long offset;
1646a77e0c7bSSantosh Shilimkar 
1647c0b759d8SRussell King 	if (!mdesc->pv_fixup)
1648a77e0c7bSSantosh Shilimkar 		return;
1649a77e0c7bSSantosh Shilimkar 
1650c0b759d8SRussell King 	offset = mdesc->pv_fixup();
1651c8ca2b4bSRussell King 	if (offset == 0)
1652c8ca2b4bSRussell King 		return;
1653a77e0c7bSSantosh Shilimkar 
1654d8dc7fbdSRussell King 	/*
1655463dbba4SLinus Walleij 	 * Offset the kernel section physical offsets so that the kernel
1656463dbba4SLinus Walleij 	 * mapping will work out later on.
1657463dbba4SLinus Walleij 	 */
1658463dbba4SLinus Walleij 	kernel_sec_start += offset;
1659463dbba4SLinus Walleij 	kernel_sec_end += offset;
1660463dbba4SLinus Walleij 
1661463dbba4SLinus Walleij 	/*
1662d8dc7fbdSRussell King 	 * Get the address of the remap function in the 1:1 identity
1663d8dc7fbdSRussell King 	 * mapping setup by the early page table assembly code.  We
1664d8dc7fbdSRussell King 	 * must get this prior to the pv update.  The following barrier
1665d8dc7fbdSRussell King 	 * ensures that this is complete before we fixup any P:V offsets.
1666d8dc7fbdSRussell King 	 */
1667d8dc7fbdSRussell King 	lpae_pgtables_remap = (pgtables_remap *)(unsigned long)__pa(lpae_pgtables_remap_asm);
1668d8dc7fbdSRussell King 	pa_pgd = __pa(swapper_pg_dir);
1669d8dc7fbdSRussell King 	barrier();
1670a77e0c7bSSantosh Shilimkar 
167139b74fe8SRussell King 	pr_info("Switching physical address space to 0x%08llx\n",
167239b74fe8SRussell King 		(u64)PHYS_OFFSET + offset);
1673a77e0c7bSSantosh Shilimkar 
1674c8ca2b4bSRussell King 	/* Re-set the phys pfn offset, and the pv offset */
1675c8ca2b4bSRussell King 	__pv_offset += offset;
1676c8ca2b4bSRussell King 	__pv_phys_pfn_offset += PFN_DOWN(offset);
1677a77e0c7bSSantosh Shilimkar 
1678a77e0c7bSSantosh Shilimkar 	/* Run the patch stub to update the constants */
1679a77e0c7bSSantosh Shilimkar 	fixup_pv_table(&__pv_table_begin,
1680a77e0c7bSSantosh Shilimkar 		(&__pv_table_end - &__pv_table_begin) << 2);
1681a77e0c7bSSantosh Shilimkar 
1682a77e0c7bSSantosh Shilimkar 	/*
1683d8dc7fbdSRussell King 	 * We changing not only the virtual to physical mapping, but also
1684d8dc7fbdSRussell King 	 * the physical addresses used to access memory.  We need to flush
1685d8dc7fbdSRussell King 	 * all levels of cache in the system with caching disabled to
1686d8dc7fbdSRussell King 	 * ensure that all data is written back, and nothing is prefetched
1687d8dc7fbdSRussell King 	 * into the caches.  We also need to prevent the TLB walkers
1688d8dc7fbdSRussell King 	 * allocating into the caches too.  Note that this is ARMv7 LPAE
1689d8dc7fbdSRussell King 	 * specific.
1690a77e0c7bSSantosh Shilimkar 	 */
1691d8dc7fbdSRussell King 	cr = get_cr();
1692d8dc7fbdSRussell King 	set_cr(cr & ~(CR_I | CR_C));
1693d8dc7fbdSRussell King 	asm("mrc p15, 0, %0, c2, c0, 2" : "=r" (ttbcr));
1694d8dc7fbdSRussell King 	asm volatile("mcr p15, 0, %0, c2, c0, 2"
1695d8dc7fbdSRussell King 		: : "r" (ttbcr & ~(3 << 8 | 3 << 10)));
1696a77e0c7bSSantosh Shilimkar 	flush_cache_all();
16973bb70de6SRussell King 
16983bb70de6SRussell King 	/*
1699d8dc7fbdSRussell King 	 * Fixup the page tables - this must be in the idmap region as
1700d8dc7fbdSRussell King 	 * we need to disable the MMU to do this safely, and hence it
1701d8dc7fbdSRussell King 	 * needs to be assembly.  It's fairly simple, as we're using the
1702d8dc7fbdSRussell King 	 * temporary tables setup by the initial assembly code.
17033bb70de6SRussell King 	 */
17047a1be318SArd Biesheuvel 	lpae_pgtables_remap(offset, pa_pgd);
17053bb70de6SRussell King 
1706d8dc7fbdSRussell King 	/* Re-enable the caches and cacheable TLB walks */
1707d8dc7fbdSRussell King 	asm volatile("mcr p15, 0, %0, c2, c0, 2" : : "r" (ttbcr));
1708d8dc7fbdSRussell King 	set_cr(cr);
1709a77e0c7bSSantosh Shilimkar }
1710a77e0c7bSSantosh Shilimkar 
1711a77e0c7bSSantosh Shilimkar #else
1712a77e0c7bSSantosh Shilimkar 
early_paging_init(const struct machine_desc * mdesc)1713b089c31cSJon Medhurst static void __init early_paging_init(const struct machine_desc *mdesc)
1714a77e0c7bSSantosh Shilimkar {
1715c8ca2b4bSRussell King 	long long offset;
1716c8ca2b4bSRussell King 
1717c0b759d8SRussell King 	if (!mdesc->pv_fixup)
1718c8ca2b4bSRussell King 		return;
1719c8ca2b4bSRussell King 
1720c0b759d8SRussell King 	offset = mdesc->pv_fixup();
1721c8ca2b4bSRussell King 	if (offset == 0)
1722c8ca2b4bSRussell King 		return;
1723c8ca2b4bSRussell King 
1724c8ca2b4bSRussell King 	pr_crit("Physical address space modification is only to support Keystone2.\n");
1725c8ca2b4bSRussell King 	pr_crit("Please enable ARM_LPAE and ARM_PATCH_PHYS_VIRT support to use this\n");
1726c8ca2b4bSRussell King 	pr_crit("feature. Your kernel may crash now, have a good day.\n");
1727c8ca2b4bSRussell King 	add_taint(TAINT_CPU_OUT_OF_SPEC, LOCKDEP_STILL_OK);
1728a77e0c7bSSantosh Shilimkar }
1729a77e0c7bSSantosh Shilimkar 
1730a77e0c7bSSantosh Shilimkar #endif
1731a77e0c7bSSantosh Shilimkar 
early_fixmap_shutdown(void)1732a5f4c561SStefan Agner static void __init early_fixmap_shutdown(void)
1733a5f4c561SStefan Agner {
1734a5f4c561SStefan Agner 	int i;
1735a5f4c561SStefan Agner 	unsigned long va = fix_to_virt(__end_of_permanent_fixed_addresses - 1);
1736a5f4c561SStefan Agner 
1737a5f4c561SStefan Agner 	pte_offset_fixmap = pte_offset_late_fixmap;
1738a5f4c561SStefan Agner 	pmd_clear(fixmap_pmd(va));
1739a5f4c561SStefan Agner 	local_flush_tlb_kernel_page(va);
1740a5f4c561SStefan Agner 
1741a5f4c561SStefan Agner 	for (i = 0; i < __end_of_permanent_fixed_addresses; i++) {
1742a5f4c561SStefan Agner 		pte_t *pte;
1743a5f4c561SStefan Agner 		struct map_desc map;
1744a5f4c561SStefan Agner 
1745a5f4c561SStefan Agner 		map.virtual = fix_to_virt(i);
1746a5f4c561SStefan Agner 		pte = pte_offset_early_fixmap(pmd_off_k(map.virtual), map.virtual);
1747a5f4c561SStefan Agner 
1748a5f4c561SStefan Agner 		/* Only i/o device mappings are supported ATM */
1749a5f4c561SStefan Agner 		if (pte_none(*pte) ||
1750a5f4c561SStefan Agner 		    (pte_val(*pte) & L_PTE_MT_MASK) != L_PTE_MT_DEV_SHARED)
1751a5f4c561SStefan Agner 			continue;
1752a5f4c561SStefan Agner 
1753a5f4c561SStefan Agner 		map.pfn = pte_pfn(*pte);
1754a5f4c561SStefan Agner 		map.type = MT_DEVICE;
1755a5f4c561SStefan Agner 		map.length = PAGE_SIZE;
1756a5f4c561SStefan Agner 
1757a5f4c561SStefan Agner 		create_mapping(&map);
1758a5f4c561SStefan Agner 	}
1759a5f4c561SStefan Agner }
1760a5f4c561SStefan Agner 
1761d111e8f9SRussell King /*
1762d111e8f9SRussell King  * paging_init() sets up the page tables, initialises the zone memory
1763d111e8f9SRussell King  * maps, and sets up the zero page, bad page and bad page tables.
1764d111e8f9SRussell King  */
paging_init(const struct machine_desc * mdesc)1765ff69a4c8SRussell King void __init paging_init(const struct machine_desc *mdesc)
1766d111e8f9SRussell King {
1767d111e8f9SRussell King 	void *zero_page;
1768d111e8f9SRussell King 
1769*4b9fb3aeSHarith G #ifdef CONFIG_XIP_KERNEL
1770*4b9fb3aeSHarith G 	/* Store the kernel RW RAM region start/end in these variables */
1771*4b9fb3aeSHarith G 	kernel_sec_start = CONFIG_PHYS_OFFSET & SECTION_MASK;
1772*4b9fb3aeSHarith G 	kernel_sec_end = round_up(__pa(_end), SECTION_SIZE);
1773*4b9fb3aeSHarith G #endif
1774463dbba4SLinus Walleij 	pr_debug("physical kernel sections: 0x%08llx-0x%08llx\n",
17756e121df1SLinus Walleij 		 kernel_sec_start, kernel_sec_end);
17766e121df1SLinus Walleij 
17774b5f32ceSNicolas Pitre 	prepare_page_table();
1778a2227120SRussell King 	map_lowmem();
17793de1f52aSLaura Abbott 	memblock_set_current_limit(arm_lowmem_limit);
17806e121df1SLinus Walleij 	pr_debug("lowmem limit is %08llx\n", (long long)arm_lowmem_limit);
17816e121df1SLinus Walleij 	/*
17826e121df1SLinus Walleij 	 * After this point early_alloc(), i.e. the memblock allocator, can
17836e121df1SLinus Walleij 	 * be used
17846e121df1SLinus Walleij 	 */
17856e121df1SLinus Walleij 	map_kernel();
1786c7909509SMarek Szyprowski 	dma_contiguous_remap();
1787a5f4c561SStefan Agner 	early_fixmap_shutdown();
1788d111e8f9SRussell King 	devicemaps_init(mdesc);
1789d73cd428SNicolas Pitre 	kmap_init();
1790de40614eSJoonsoo Kim 	tcm_init();
1791d111e8f9SRussell King 
1792d111e8f9SRussell King 	top_pmd = pmd_off_k(0xffff0000);
1793d111e8f9SRussell King 
17943abe9d33SRussell King 	/* allocate the zero page. */
17953abe9d33SRussell King 	zero_page = early_alloc(PAGE_SIZE);
17962778f620SRussell King 
17978d717a52SRussell King 	bootmem_init();
17982778f620SRussell King 
1799d111e8f9SRussell King 	empty_zero_page = virt_to_page(zero_page);
18008b5989f3SMatthew Wilcox (Oracle) 	__flush_dcache_folio(NULL, page_folio(empty_zero_page));
1801d111e8f9SRussell King }
1802b089c31cSJon Medhurst 
early_mm_init(const struct machine_desc * mdesc)1803b089c31cSJon Medhurst void __init early_mm_init(const struct machine_desc *mdesc)
1804b089c31cSJon Medhurst {
1805b089c31cSJon Medhurst 	build_mem_type_table();
1806b089c31cSJon Medhurst 	early_paging_init(mdesc);
1807b089c31cSJon Medhurst }
180878e7c5afSAnshuman Khandual 
set_ptes(struct mm_struct * mm,unsigned long addr,pte_t * ptep,pte_t pteval,unsigned int nr)18098b5989f3SMatthew Wilcox (Oracle) void set_ptes(struct mm_struct *mm, unsigned long addr,
18108b5989f3SMatthew Wilcox (Oracle) 			      pte_t *ptep, pte_t pteval, unsigned int nr)
181178e7c5afSAnshuman Khandual {
181278e7c5afSAnshuman Khandual 	unsigned long ext = 0;
181378e7c5afSAnshuman Khandual 
181478e7c5afSAnshuman Khandual 	if (addr < TASK_SIZE && pte_valid_user(pteval)) {
181578e7c5afSAnshuman Khandual 		if (!pte_special(pteval))
181678e7c5afSAnshuman Khandual 			__sync_icache_dcache(pteval);
181778e7c5afSAnshuman Khandual 		ext |= PTE_EXT_NG;
181878e7c5afSAnshuman Khandual 	}
181978e7c5afSAnshuman Khandual 
18208b5989f3SMatthew Wilcox (Oracle) 	for (;;) {
182178e7c5afSAnshuman Khandual 		set_pte_ext(ptep, pteval, ext);
18228b5989f3SMatthew Wilcox (Oracle) 		if (--nr == 0)
18238b5989f3SMatthew Wilcox (Oracle) 			break;
18248b5989f3SMatthew Wilcox (Oracle) 		ptep++;
18258b5989f3SMatthew Wilcox (Oracle) 		pte_val(pteval) += PAGE_SIZE;
18268b5989f3SMatthew Wilcox (Oracle) 	}
182778e7c5afSAnshuman Khandual }
1828