@@ -63,19 +63,30 @@ pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
6363}
6464EXPORT_SYMBOL (phys_mem_access_prot );
6565
66- static void __init * early_pgtable_alloc (void )
66+ static phys_addr_t __init early_pgtable_alloc (void )
6767{
6868 phys_addr_t phys ;
6969 void * ptr ;
7070
7171 phys = memblock_alloc (PAGE_SIZE , PAGE_SIZE );
7272 BUG_ON (!phys );
73- ptr = __va (phys );
73+
74+ /*
75+ * The FIX_{PGD,PUD,PMD} slots may be in active use, but the FIX_PTE
76+ * slot will be free, so we can (ab)use the FIX_PTE slot to initialise
77+ * any level of table.
78+ */
79+ ptr = pte_set_fixmap (phys );
80+
7481 memset (ptr , 0 , PAGE_SIZE );
7582
76- /* Ensure the zeroed page is visible to the page table walker */
77- dsb (ishst );
78- return ptr ;
83+ /*
84+ * Implicit barriers also ensure the zeroed page is visible to the page
85+ * table walker
86+ */
87+ pte_clear_fixmap ();
88+
89+ return phys ;
7990}
8091
8192/*
@@ -99,24 +110,28 @@ static void split_pmd(pmd_t *pmd, pte_t *pte)
99110static void alloc_init_pte (pmd_t * pmd , unsigned long addr ,
100111 unsigned long end , unsigned long pfn ,
101112 pgprot_t prot ,
102- void * (* pgtable_alloc )(void ))
113+ phys_addr_t (* pgtable_alloc )(void ))
103114{
104115 pte_t * pte ;
105116
106117 if (pmd_none (* pmd ) || pmd_sect (* pmd )) {
107- pte = pgtable_alloc ();
118+ phys_addr_t pte_phys = pgtable_alloc ();
119+ pte = pte_set_fixmap (pte_phys );
108120 if (pmd_sect (* pmd ))
109121 split_pmd (pmd , pte );
110- __pmd_populate (pmd , __pa ( pte ) , PMD_TYPE_TABLE );
122+ __pmd_populate (pmd , pte_phys , PMD_TYPE_TABLE );
111123 flush_tlb_all ();
124+ pte_clear_fixmap ();
112125 }
113126 BUG_ON (pmd_bad (* pmd ));
114127
115- pte = pte_offset_kernel (pmd , addr );
128+ pte = pte_set_fixmap_offset (pmd , addr );
116129 do {
117130 set_pte (pte , pfn_pte (pfn , prot ));
118131 pfn ++ ;
119132 } while (pte ++ , addr += PAGE_SIZE , addr != end );
133+
134+ pte_clear_fixmap ();
120135}
121136
122137static void split_pud (pud_t * old_pud , pmd_t * pmd )
@@ -134,7 +149,7 @@ static void split_pud(pud_t *old_pud, pmd_t *pmd)
134149static void alloc_init_pmd (struct mm_struct * mm , pud_t * pud ,
135150 unsigned long addr , unsigned long end ,
136151 phys_addr_t phys , pgprot_t prot ,
137- void * (* pgtable_alloc )(void ))
152+ phys_addr_t (* pgtable_alloc )(void ))
138153{
139154 pmd_t * pmd ;
140155 unsigned long next ;
@@ -143,20 +158,22 @@ static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud,
143158 * Check for initial section mappings in the pgd/pud and remove them.
144159 */
145160 if (pud_none (* pud ) || pud_sect (* pud )) {
146- pmd = pgtable_alloc ();
161+ phys_addr_t pmd_phys = pgtable_alloc ();
162+ pmd = pmd_set_fixmap (pmd_phys );
147163 if (pud_sect (* pud )) {
148164 /*
149165 * need to have the 1G of mappings continue to be
150166 * present
151167 */
152168 split_pud (pud , pmd );
153169 }
154- pud_populate ( mm , pud , pmd );
170+ __pud_populate ( pud , pmd_phys , PUD_TYPE_TABLE );
155171 flush_tlb_all ();
172+ pmd_clear_fixmap ();
156173 }
157174 BUG_ON (pud_bad (* pud ));
158175
159- pmd = pmd_offset (pud , addr );
176+ pmd = pmd_set_fixmap_offset (pud , addr );
160177 do {
161178 next = pmd_addr_end (addr , end );
162179 /* try section mapping first */
@@ -182,6 +199,8 @@ static void alloc_init_pmd(struct mm_struct *mm, pud_t *pud,
182199 }
183200 phys += next - addr ;
184201 } while (pmd ++ , addr = next , addr != end );
202+
203+ pmd_clear_fixmap ();
185204}
186205
187206static inline bool use_1G_block (unsigned long addr , unsigned long next ,
@@ -199,18 +218,18 @@ static inline bool use_1G_block(unsigned long addr, unsigned long next,
199218static void alloc_init_pud (struct mm_struct * mm , pgd_t * pgd ,
200219 unsigned long addr , unsigned long end ,
201220 phys_addr_t phys , pgprot_t prot ,
202- void * (* pgtable_alloc )(void ))
221+ phys_addr_t (* pgtable_alloc )(void ))
203222{
204223 pud_t * pud ;
205224 unsigned long next ;
206225
207226 if (pgd_none (* pgd )) {
208- pud = pgtable_alloc ();
209- pgd_populate ( mm , pgd , pud );
227+ phys_addr_t pud_phys = pgtable_alloc ();
228+ __pgd_populate ( pgd , pud_phys , PUD_TYPE_TABLE );
210229 }
211230 BUG_ON (pgd_bad (* pgd ));
212231
213- pud = pud_offset (pgd , addr );
232+ pud = pud_set_fixmap_offset (pgd , addr );
214233 do {
215234 next = pud_addr_end (addr , end );
216235
@@ -243,6 +262,8 @@ static void alloc_init_pud(struct mm_struct *mm, pgd_t *pgd,
243262 }
244263 phys += next - addr ;
245264 } while (pud ++ , addr = next , addr != end );
265+
266+ pud_clear_fixmap ();
246267}
247268
248269/*
@@ -252,7 +273,7 @@ static void alloc_init_pud(struct mm_struct *mm, pgd_t *pgd,
252273static void __create_mapping (struct mm_struct * mm , pgd_t * pgd ,
253274 phys_addr_t phys , unsigned long virt ,
254275 phys_addr_t size , pgprot_t prot ,
255- void * (* pgtable_alloc )(void ))
276+ phys_addr_t (* pgtable_alloc )(void ))
256277{
257278 unsigned long addr , length , end , next ;
258279
@@ -267,14 +288,14 @@ static void __create_mapping(struct mm_struct *mm, pgd_t *pgd,
267288 } while (pgd ++ , addr = next , addr != end );
268289}
269290
270- static void * late_pgtable_alloc (void )
291+ static phys_addr_t late_pgtable_alloc (void )
271292{
272293 void * ptr = (void * )__get_free_page (PGALLOC_GFP );
273294 BUG_ON (!ptr );
274295
275296 /* Ensure the zeroed page is visible to the page table walker */
276297 dsb (ishst );
277- return ptr ;
298+ return __pa ( ptr ) ;
278299}
279300
280301static void __init create_mapping (phys_addr_t phys , unsigned long virt ,
0 commit comments