1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * xen/arch/arm/mmu/setup.c
4  *
5  * MMU system boot CPU MM bringup code.
6  */
7 
8 #include <xen/init.h>
9 #include <xen/libfdt/libfdt.h>
10 #include <xen/llc-coloring.h>
11 #include <xen/sections.h>
12 #include <xen/sizes.h>
13 #include <xen/vmap.h>
14 
15 #include <asm/setup.h>
16 #include <asm/fixmap.h>
17 
18 /* Override macros from asm/page.h to make them work with mfn_t */
19 #undef mfn_to_virt
20 #define mfn_to_virt(mfn) __mfn_to_virt(mfn_x(mfn))
21 #undef virt_to_mfn
22 #define virt_to_mfn(va) _mfn(__virt_to_mfn(va))
23 
24 #define virt_to_reloc_virt(virt) \
25     (((vaddr_t)(virt)) - XEN_VIRT_START + BOOT_RELOC_VIRT_START)
26 
27 /* Main runtime page tables */
28 
29 /*
30  * For arm32 xen_pgtable are per-PCPU and are allocated before
31  * bringing up each CPU. For arm64 xen_pgtable is common to all PCPUs.
32  *
33  * xen_second, xen_fixmap and xen_xenmap are always shared between all
34  * PCPUs.
35  */
36 
37 #ifdef CONFIG_ARM_64
38 DEFINE_PAGE_TABLE(xen_pgtable);
39 static DEFINE_PAGE_TABLE(xen_first);
40 #define THIS_CPU_PGTABLE xen_pgtable
41 #else
42 /* Per-CPU pagetable pages */
43 /* xen_pgtable == root of the trie (zeroeth level on 64-bit, first on 32-bit) */
44 DEFINE_PER_CPU(lpae_t *, xen_pgtable);
45 #define THIS_CPU_PGTABLE this_cpu(xen_pgtable)
46 /* Root of the trie for cpu0, other CPU's PTs are dynamically allocated */
47 static DEFINE_PAGE_TABLE(cpu0_pgtable);
48 #endif
49 
50 /* Common pagetable leaves */
51 /* Second level page table used to cover Xen virtual address space */
52 static DEFINE_PAGE_TABLE(xen_second);
53 /* Third level page table used for fixmap */
54 DEFINE_BOOT_PAGE_TABLE(xen_fixmap);
55 /*
56  * Third level page table used to map Xen itself with the XN bit set
57  * as appropriate.
58  */
59 static DEFINE_PAGE_TABLES(xen_xenmap, XEN_NR_ENTRIES(2));
60 
61 /* Limits of the Xen heap */
62 mfn_t directmap_mfn_start __read_mostly = INVALID_MFN_INITIALIZER;
63 mfn_t directmap_mfn_end __read_mostly;
64 vaddr_t directmap_virt_end __read_mostly;
65 #ifdef CONFIG_ARM_64
66 vaddr_t directmap_virt_start __read_mostly;
67 unsigned long directmap_base_pdx __read_mostly;
68 #endif
69 
70 /* Checking VA memory layout alignment. */
build_assertions(void)71 static void __init __maybe_unused build_assertions(void)
72 {
73     /* 2MB aligned regions */
74     BUILD_BUG_ON(XEN_VIRT_START & ~SECOND_MASK);
75     BUILD_BUG_ON(FIXMAP_ADDR(0) & ~SECOND_MASK);
76     BUILD_BUG_ON(BOOT_RELOC_VIRT_START & ~SECOND_MASK);
77     /* 1GB aligned regions */
78 #ifdef CONFIG_ARM_32
79     BUILD_BUG_ON(XENHEAP_VIRT_START & ~FIRST_MASK);
80 #else
81     BUILD_BUG_ON(DIRECTMAP_VIRT_START & ~FIRST_MASK);
82 #endif
83     /* Page table structure constraints */
84 #ifdef CONFIG_ARM_64
85     /*
86      * The first few slots of the L0 table is reserved for the identity
87      * mapping. Check that none of the other regions are overlapping
88      * with it.
89      */
90 #define CHECK_OVERLAP_WITH_IDMAP(virt) \
91     BUILD_BUG_ON(zeroeth_table_offset(virt) < IDENTITY_MAPPING_AREA_NR_L0)
92 
93     CHECK_OVERLAP_WITH_IDMAP(XEN_VIRT_START);
94     CHECK_OVERLAP_WITH_IDMAP(VMAP_VIRT_START);
95     CHECK_OVERLAP_WITH_IDMAP(FRAMETABLE_VIRT_START);
96     CHECK_OVERLAP_WITH_IDMAP(DIRECTMAP_VIRT_START);
97 #undef CHECK_OVERLAP_WITH_IDMAP
98 #endif
99     BUILD_BUG_ON(first_table_offset(XEN_VIRT_START));
100 #ifdef CONFIG_ARCH_MAP_DOMAIN_PAGE
101     BUILD_BUG_ON(DOMHEAP_VIRT_START & ~FIRST_MASK);
102 #endif
103     /*
104      * The boot code expects the regions XEN_VIRT_START, FIXMAP_ADDR(0),
105      * BOOT_FDT_VIRT_START to use the same 0th (arm64 only) and 1st
106      * slot in the page tables.
107      */
108 #define CHECK_SAME_SLOT(level, virt1, virt2) \
109     BUILD_BUG_ON(level##_table_offset(virt1) != level##_table_offset(virt2))
110 
111 #define CHECK_DIFFERENT_SLOT(level, virt1, virt2) \
112     BUILD_BUG_ON(level##_table_offset(virt1) == level##_table_offset(virt2))
113 
114 #ifdef CONFIG_ARM_64
115     CHECK_SAME_SLOT(zeroeth, XEN_VIRT_START, FIXMAP_ADDR(0));
116     CHECK_SAME_SLOT(zeroeth, XEN_VIRT_START, BOOT_FDT_VIRT_START);
117 #endif
118     CHECK_SAME_SLOT(first, XEN_VIRT_START, FIXMAP_ADDR(0));
119     CHECK_SAME_SLOT(first, XEN_VIRT_START, BOOT_FDT_VIRT_START);
120 
121     /*
122      * For arm32, the temporary mapping will re-use the domheap
123      * first slot and the second slots will match.
124      */
125 #ifdef CONFIG_ARM_32
126     CHECK_SAME_SLOT(first, TEMPORARY_XEN_VIRT_START, DOMHEAP_VIRT_START);
127     CHECK_DIFFERENT_SLOT(first, XEN_VIRT_START, TEMPORARY_XEN_VIRT_START);
128     CHECK_SAME_SLOT(first, TEMPORARY_XEN_VIRT_START,
129                     TEMPORARY_FIXMAP_VIRT_START);
130     CHECK_SAME_SLOT(second, XEN_VIRT_START, TEMPORARY_XEN_VIRT_START);
131     CHECK_SAME_SLOT(second, FIXMAP_VIRT_START, TEMPORARY_FIXMAP_VIRT_START);
132 #endif
133 
134 #undef CHECK_SAME_SLOT
135 #undef CHECK_DIFFERENT_SLOT
136 
137     /*
138      * Fixmaps must not overlap with boot FDT mapping area. Make sure there's
139      * at least one guard page in between.
140      */
141     BUILD_BUG_ON(FIXADDR_TOP >= BOOT_FDT_VIRT_START);
142 }
143 
pte_of_xenaddr(vaddr_t va)144 lpae_t __init pte_of_xenaddr(vaddr_t va)
145 {
146     if ( llc_coloring_enabled )
147         va = virt_to_reloc_virt(va);
148 
149     return mfn_to_xen_entry(virt_to_mfn(va), MT_NORMAL);
150 }
151 
early_fdt_map(paddr_t fdt_paddr)152 void * __init early_fdt_map(paddr_t fdt_paddr)
153 {
154     /* We are using 2MB superpage for mapping the FDT */
155     paddr_t base_paddr = fdt_paddr & SECOND_MASK;
156     paddr_t offset;
157     void *fdt_virt;
158     uint32_t size;
159     int rc;
160 
161     /*
162      * Check whether the physical FDT address is set and meets the minimum
163      * alignment requirement. Since we are relying on MIN_FDT_ALIGN to be at
164      * least 8 bytes so that we always access the magic and size fields
165      * of the FDT header after mapping the first chunk, double check if
166      * that is indeed the case.
167      */
168     BUILD_BUG_ON(MIN_FDT_ALIGN < 8);
169     if ( !fdt_paddr || fdt_paddr % MIN_FDT_ALIGN )
170         return NULL;
171 
172     /* The FDT is mapped using 2MB superpage */
173     BUILD_BUG_ON(BOOT_FDT_VIRT_START % SZ_2M);
174 
175     rc = map_pages_to_xen(BOOT_FDT_VIRT_START, maddr_to_mfn(base_paddr),
176                           SZ_2M >> PAGE_SHIFT,
177                           PAGE_HYPERVISOR_RO | _PAGE_BLOCK);
178     if ( rc )
179         panic("Unable to map the device-tree.\n");
180 
181 
182     offset = fdt_paddr % SECOND_SIZE;
183     fdt_virt = (void *)BOOT_FDT_VIRT_START + offset;
184 
185     if ( fdt_magic(fdt_virt) != FDT_MAGIC )
186         return NULL;
187 
188     size = fdt_totalsize(fdt_virt);
189     if ( size > MAX_FDT_SIZE )
190         return NULL;
191 
192     if ( (offset + size) > SZ_2M )
193     {
194         rc = map_pages_to_xen(BOOT_FDT_VIRT_START + SZ_2M,
195                               maddr_to_mfn(base_paddr + SZ_2M),
196                               SZ_2M >> PAGE_SHIFT,
197                               PAGE_HYPERVISOR_RO | _PAGE_BLOCK);
198         if ( rc )
199             panic("Unable to map the device-tree\n");
200     }
201 
202     return fdt_virt;
203 }
204 
remove_early_mappings(void)205 void __init remove_early_mappings(void)
206 {
207     int rc;
208 
209     /* destroy the _PAGE_BLOCK mapping */
210     rc = modify_xen_mappings(BOOT_FDT_VIRT_START,
211                              BOOT_FDT_VIRT_START + BOOT_FDT_VIRT_SIZE,
212                              _PAGE_BLOCK);
213     BUG_ON(rc);
214 }
215 
216 /*
217  * After boot, Xen page-tables should not contain mapping that are both
218  * Writable and eXecutables.
219  *
220  * This should be called on each CPU to enforce the policy.
221  */
xen_pt_enforce_wnx(void)222 static void xen_pt_enforce_wnx(void)
223 {
224     WRITE_SYSREG(READ_SYSREG(SCTLR_EL2) | SCTLR_Axx_ELx_WXN, SCTLR_EL2);
225     /*
226      * The TLBs may cache SCTLR_EL2.WXN. So ensure it is synchronized
227      * before flushing the TLBs.
228      */
229     isb();
230     flush_xen_tlb_local();
231 }
232 
233 /*
234  * Returns the end address of the highest region in the range s..e
235  * with required size and alignment that does not conflict with the
236  * modules from first_mod to nr_modules.
237  *
238  * For non-recursive callers first_mod should normally be 0 (all
239  * modules and Xen itself) or 1 (all modules but not Xen).
240  */
consider_modules(paddr_t s,paddr_t e,uint32_t size,paddr_t align,int first_mod)241 paddr_t __init consider_modules(paddr_t s, paddr_t e,
242                                 uint32_t size, paddr_t align,
243                                 int first_mod)
244 {
245     const struct membanks *reserved_mem = bootinfo_get_reserved_mem();
246 #ifdef CONFIG_STATIC_SHM
247     const struct membanks *shmem = bootinfo_get_shmem();
248 #endif
249     const struct boot_modules *mi = &bootinfo.modules;
250     int i;
251     int nr;
252 
253     s = (s+align-1) & ~(align-1);
254     e = e & ~(align-1);
255 
256     if ( s > e ||  e - s < size )
257         return 0;
258 
259     /* First check the boot modules */
260     for ( i = first_mod; i < mi->nr_mods; i++ )
261     {
262         paddr_t mod_s = mi->module[i].start;
263         paddr_t mod_e = mod_s + mi->module[i].size;
264 
265         if ( s < mod_e && mod_s < e )
266         {
267             mod_e = consider_modules(mod_e, e, size, align, i+1);
268             if ( mod_e )
269                 return mod_e;
270 
271             return consider_modules(s, mod_s, size, align, i+1);
272         }
273     }
274 
275     /*
276      * i is the current boot_module we are evaluating, across all
277      * possible kinds of boot_modules.
278      *
279      * When retrieving the corresponding reserved-memory addresses, we
280      * need to index the reserved_mem bank starting from 0, and only counting
281      * the reserved-memory modules. Hence, we need to use i - nr.
282      */
283     nr = mi->nr_mods;
284     for ( ; i - nr < reserved_mem->nr_banks; i++ )
285     {
286         paddr_t r_s = reserved_mem->bank[i - nr].start;
287         paddr_t r_e = r_s + reserved_mem->bank[i - nr].size;
288 
289         if ( s < r_e && r_s < e )
290         {
291             r_e = consider_modules(r_e, e, size, align, i + 1);
292             if ( r_e )
293                 return r_e;
294 
295             return consider_modules(s, r_s, size, align, i + 1);
296         }
297     }
298 
299 #ifdef CONFIG_STATIC_SHM
300     nr += reserved_mem->nr_banks;
301     for ( ; i - nr < shmem->nr_banks; i++ )
302     {
303         paddr_t r_s, r_e;
304 
305         r_s = shmem->bank[i - nr].start;
306 
307         /* Shared memory banks can contain INVALID_PADDR as start */
308         if ( INVALID_PADDR == r_s )
309             continue;
310 
311         r_e = r_s + shmem->bank[i - nr].size;
312 
313         if ( s < r_e && r_s < e )
314         {
315             r_e = consider_modules(r_e, e, size, align, i + 1);
316             if ( r_e )
317                 return r_e;
318 
319             return consider_modules(s, r_s, size, align, i + 1);
320         }
321     }
322 #endif
323 
324     return e;
325 }
326 
create_llc_coloring_mappings(void)327 static void __init create_llc_coloring_mappings(void)
328 {
329     lpae_t pte;
330     unsigned int i;
331     struct boot_module *xen_boot_module = boot_module_find_by_kind(BOOTMOD_XEN);
332     mfn_t start_mfn = maddr_to_mfn(xen_boot_module->start), mfn;
333 
334     for_each_xen_colored_mfn ( start_mfn, mfn, i )
335     {
336         pte = mfn_to_xen_entry(mfn, MT_NORMAL);
337         pte.pt.table = 1; /* level 3 mappings always have this bit set */
338         xen_xenmap[i] = pte;
339     }
340 
341     for ( i = 0; i < XEN_NR_ENTRIES(2); i++ )
342     {
343         vaddr_t va = BOOT_RELOC_VIRT_START + (i << XEN_PT_LEVEL_SHIFT(2));
344 
345         pte = mfn_to_xen_entry(virt_to_mfn(xen_xenmap +
346                                            i * XEN_PT_LPAE_ENTRIES),
347                                MT_NORMAL);
348         pte.pt.table = 1;
349         write_pte(&boot_second[second_table_offset(va)], pte);
350     }
351 }
352 
353 /*
354  * Boot-time pagetable setup.
355  * Changes here may need matching changes in head.S
356  */
setup_pagetables(void)357 void __init setup_pagetables(void)
358 {
359     uint64_t ttbr;
360     lpae_t pte, *p;
361     int i;
362 
363     /*
364      * In case of cache coloring, map the new physical space in the boot page
365      * tables. From now on, pte_of_xenaddr() will translate addresses to this
366      * new space.
367      */
368     if ( llc_coloring_enabled )
369         create_llc_coloring_mappings();
370 
371     arch_setup_page_tables();
372 
373 #ifdef CONFIG_ARM_64
374     pte = pte_of_xenaddr((uintptr_t)xen_first);
375     pte.pt.table = 1;
376     pte.pt.xn = 0;
377     xen_pgtable[zeroeth_table_offset(XEN_VIRT_START)] = pte;
378 
379     p = (void *) xen_first;
380 #else
381     p = (void *) cpu0_pgtable;
382 #endif
383 
384     /* Map xen second level page-table */
385     p[0] = pte_of_xenaddr((uintptr_t)(xen_second));
386     p[0].pt.table = 1;
387     p[0].pt.xn = 0;
388 
389     /* Break up the Xen mapping into pages and protect them separately. */
390     for ( i = 0; i < XEN_NR_ENTRIES(3); i++ )
391     {
392         vaddr_t va = XEN_VIRT_START + (i << PAGE_SHIFT);
393 
394         if ( !is_kernel(va) )
395             break;
396         pte = pte_of_xenaddr(va);
397         pte.pt.table = 1; /* third level mappings always have this bit set */
398         pte.pt.xn = 0; /* Permissions will be enforced later. Allow execution */
399         xen_xenmap[i] = pte;
400     }
401 
402     /* Initialise xen second level entries ... */
403     /* ... Xen's text etc */
404     for ( i = 0; i < XEN_NR_ENTRIES(2); i++ )
405     {
406         vaddr_t va = XEN_VIRT_START + (i << XEN_PT_LEVEL_SHIFT(2));
407 
408         pte = pte_of_xenaddr((vaddr_t)(xen_xenmap + i * XEN_PT_LPAE_ENTRIES));
409         pte.pt.table = 1;
410         xen_second[second_table_offset(va)] = pte;
411     }
412 
413     /* ... Fixmap */
414     pte = pte_of_xenaddr((vaddr_t)xen_fixmap);
415     pte.pt.table = 1;
416     xen_second[second_table_offset(FIXMAP_ADDR(0))] = pte;
417 
418 #ifdef CONFIG_ARM_32
419     per_cpu(xen_pgtable, 0) = cpu0_pgtable;
420 #endif
421 
422     if ( llc_coloring_enabled )
423     {
424         ttbr = virt_to_maddr(virt_to_reloc_virt(THIS_CPU_PGTABLE));
425         relocate_and_switch_ttbr(ttbr);
426     }
427     else
428     {
429         ttbr = virt_to_maddr(THIS_CPU_PGTABLE);
430         switch_ttbr(ttbr);
431     }
432 
433     /* Protect Xen */
434     for ( i = 0; i < XEN_NR_ENTRIES(3); i++ )
435     {
436         vaddr_t va = XEN_VIRT_START + (i << PAGE_SHIFT);
437         lpae_t *entry = xen_xenmap + i;
438 
439         if ( !is_kernel(va) )
440             break;
441 
442         pte = read_atomic(entry);
443 
444         if ( is_kernel_text(va) || is_kernel_inittext(va) )
445         {
446             pte.pt.xn = 0;
447             pte.pt.ro = 1;
448         }
449         else if ( is_kernel_rodata(va) )
450         {
451             pte.pt.ro = 1;
452             pte.pt.xn = 1;
453         }
454         else
455         {
456             pte.pt.xn = 1;
457             pte.pt.ro = 0;
458         }
459 
460         write_pte(entry, pte);
461     }
462 
463     /*
464      * We modified live page-tables. Ensure the TLBs are invalidated
465      * before setting enforcing the WnX permissions.
466      */
467     flush_xen_tlb_local();
468 
469     xen_pt_enforce_wnx();
470 }
471 
arch_vmap_virt_end(void)472 void *__init arch_vmap_virt_end(void)
473 {
474     return (void *)(VMAP_VIRT_START + VMAP_VIRT_SIZE);
475 }
476 
477 /* Release all __init and __initdata ranges to be reused */
free_init_memory(void)478 void free_init_memory(void)
479 {
480     paddr_t pa = virt_to_maddr(__init_begin);
481     unsigned long len = __init_end - __init_begin;
482     uint32_t insn;
483     unsigned int i, nr = len / sizeof(insn);
484     uint32_t *p;
485     int rc;
486 
487     rc = modify_xen_mappings((unsigned long)__init_begin,
488                              (unsigned long)__init_end, PAGE_HYPERVISOR_RW);
489     if ( rc )
490         panic("Unable to map RW the init section (rc = %d)\n", rc);
491 
492     /*
493      * From now on, init will not be used for execution anymore,
494      * so nuke the instruction cache to remove entries related to init.
495      */
496     invalidate_icache_local();
497 
498 #ifdef CONFIG_ARM_32
499     /* udf instruction i.e (see A8.8.247 in ARM DDI 0406C.c) */
500     insn = 0xe7f000f0;
501 #else
502     insn = AARCH64_BREAK_FAULT;
503 #endif
504     p = (uint32_t *)__init_begin;
505     for ( i = 0; i < nr; i++ )
506         *(p + i) = insn;
507 
508     rc = destroy_xen_mappings((unsigned long)__init_begin,
509                               (unsigned long)__init_end);
510     if ( rc )
511         panic("Unable to remove the init section (rc = %d)\n", rc);
512 
513     if ( !using_static_heap )
514     {
515         init_domheap_pages(pa, pa + len);
516         printk("Freed %ldkB init memory.\n",
517                (long)(__init_end-__init_begin) >> 10);
518     }
519 }
520 
521 /**
522  * copy_from_paddr - copy data from a physical address
523  * @dst: destination virtual address
524  * @paddr: source physical address
525  * @len: length to copy
526  */
copy_from_paddr(void * dst,paddr_t paddr,unsigned long len)527 void __init copy_from_paddr(void *dst, paddr_t paddr, unsigned long len)
528 {
529     void *src = (void *)FIXMAP_ADDR(FIX_MISC);
530 
531     while (len) {
532         unsigned long l, s;
533 
534         s = paddr & (PAGE_SIZE - 1);
535         l = min(PAGE_SIZE - s, len);
536 
537         set_fixmap(FIX_MISC, maddr_to_mfn(paddr), PAGE_HYPERVISOR_WC);
538         memcpy(dst, src + s, l);
539         clean_dcache_va_range(dst, l);
540         clear_fixmap(FIX_MISC);
541 
542         paddr += l;
543         dst += l;
544         len -= l;
545     }
546 }
547 
548 /*
549  * Local variables:
550  * mode: C
551  * c-file-style: "BSD"
552  * c-basic-offset: 4
553  * indent-tabs-mode: nil
554  * End:
555  */
556