]> rtime.felk.cvut.cz Git - jailhouse.git/blob - hypervisor/arch/arm/mmu_hyp.c
arm: Fix comment of switch_exception_level
[jailhouse.git] / hypervisor / arch / arm / mmu_hyp.c
1 /*
2  * Jailhouse, a Linux-based partitioning hypervisor
3  *
4  * Copyright (c) ARM Limited, 2014
5  *
6  * Authors:
7  *  Jean-Philippe Brucker <jean-philippe.brucker@arm.com>
8  *
9  * This work is licensed under the terms of the GNU GPL, version 2.  See
10  * the COPYING file in the top-level directory.
11  */
12
13 #include <asm/control.h>
14 #include <asm/setup.h>
15 #include <asm/setup_mmu.h>
16 #include <asm/sysregs.h>
17 #include <jailhouse/paging.h>
18 #include <jailhouse/printk.h>
19
20 /*
21  * Two identity mappings need to be created for enabling the MMU: one for the
22  * code and one for the stack.
23  * There should not currently be any conflict with the existing mappings, but we
24  * still make sure not to override anything by using the 'conflict' flag.
25  */
26 static struct {
27         unsigned long addr;
28         unsigned long flags;
29         bool conflict;
30 } id_maps[2];
31
32 extern unsigned long trampoline_start, trampoline_end;
33
34 /* When disabling Jailhouse, we will need to restore the Linux stub */
35 static unsigned long saved_vectors = 0;
36
37 static int set_id_map(int i, unsigned long address, unsigned long size)
38 {
39         if (i >= ARRAY_SIZE(id_maps))
40                 return -ENOMEM;
41
42         /* The trampoline code should be contained in one page. */
43         if ((address & PAGE_MASK) != ((address + size - 1) & PAGE_MASK)) {
44                 printk("FATAL: Unable to IDmap more than one page at at time.\n");
45                 return -E2BIG;
46         }
47
48         id_maps[i].addr = address;
49         id_maps[i].conflict = false;
50         id_maps[i].flags = PAGE_DEFAULT_FLAGS;
51
52         return 0;
53 }
54
55 static void create_id_maps(void)
56 {
57         unsigned long i;
58         bool conflict;
59
60         for (i = 0; i < ARRAY_SIZE(id_maps); i++) {
61                 conflict = (paging_virt2phys(&hv_paging_structs,
62                                 id_maps[i].addr, PAGE_PRESENT_FLAGS) !=
63                                 INVALID_PHYS_ADDR);
64                 if (conflict) {
65                         /*
66                          * TODO: Get the flags, and update them if they are
67                          * insufficient. Save the current flags in id_maps.
68                          * This extraction should be implemented in the core.
69                          */
70                 } else {
71                         paging_create(&hv_paging_structs, id_maps[i].addr,
72                                 PAGE_SIZE, id_maps[i].addr, id_maps[i].flags,
73                                 PAGING_NON_COHERENT);
74                 }
75                 id_maps[i].conflict = conflict;
76         }
77 }
78
79 static void destroy_id_maps(void)
80 {
81         unsigned long i;
82
83         for (i = 0; i < ARRAY_SIZE(id_maps); i++) {
84                 if (id_maps[i].conflict) {
85                         /* TODO: Switch back to the original flags */
86                 } else {
87                         paging_destroy(&hv_paging_structs, id_maps[i].addr,
88                                        PAGE_SIZE, PAGING_NON_COHERENT);
89                 }
90         }
91 }
92
93 static void __attribute__((naked)) __attribute__((noinline))
94 cpu_switch_el2(unsigned long phys_bootstrap, virt2phys_t virt2phys)
95 {
96         asm volatile(
97                 /*
98                  * The linux hyp stub allows to install the vectors with a
99                  * single hvc. The vector base address is in r0
100                  * (phys_bootstrap).
101                  */
102                 "hvc    #0\n\t"
103
104                 /*
105                  * Now that the bootstrap vectors are installed, call setup_el2
106                  * with the translated physical values of lr and sp as
107                  * arguments.
108                  */
109                 "mov    r0, sp\n\t"
110                 "push   {lr}\n\t"
111                 "blx    %0\n\t"
112                 "pop    {lr}\n\t"
113                 "push   {r0}\n\t"
114                 "mov    r0, lr\n\t"
115                 "blx    %0\n\t"
116                 "pop    {r1}\n\t"
117                 "hvc    #0\n\t"
118                 :
119                 : "r" (virt2phys)
120                 /*
121                  * The call to virt2phys may clobber all temp registers. This
122                  * list ensures that the compiler uses a decent register for
123                  * hvirt2phys.
124                  */
125                 : "cc", "memory", "r0", "r1", "r2", "r3");
126 }
127
128 /*
129  * This code is put in the id-mapped `.trampoline' section, allowing to enable
130  * and disable the MMU in a readable and portable fashion.
131  * This process makes the following function quite fragile: cpu_switch_phys2virt
132  * attempts to translate LR and SP using a call to the virtual address of
133  * phys2virt.
134  * Those two registers are thus supposed to be left intact by the whole MMU
135  * setup. The stack is all the same usable, since it is id-mapped as well.
136  */
137 static void __attribute__((naked)) __attribute__((section(".trampoline")))
138 setup_mmu_el2(struct per_cpu *cpu_data, phys2virt_t phys2virt, u64 ttbr)
139 {
140         u32 tcr = T0SZ
141                 | (TCR_RGN_WB_WA << TCR_IRGN0_SHIFT)
142                 | (TCR_RGN_WB_WA << TCR_ORGN0_SHIFT)
143                 | (TCR_INNER_SHAREABLE << TCR_SH0_SHIFT)
144                 | HTCR_RES1;
145         u32 sctlr_el1, sctlr_el2;
146
147         /* Ensure that MMU is disabled. */
148         arm_read_sysreg(SCTLR_EL2, sctlr_el2);
149         if (sctlr_el2 & SCTLR_M_BIT)
150                 return;
151
152         /*
153          * This setup code is always preceded by a complete cache flush, so
154          * there is already a few memory barriers between the page table writes
155          * and here.
156          */
157         isb();
158         arm_write_sysreg(HMAIR0, DEFAULT_HMAIR0);
159         arm_write_sysreg(HMAIR1, DEFAULT_HMAIR1);
160         arm_write_sysreg(TTBR0_EL2, ttbr);
161         arm_write_sysreg(TCR_EL2, tcr);
162
163         /*
164          * Flush HYP TLB. It should only be necessary if a previous hypervisor
165          * was running.
166          */
167         arm_write_sysreg(TLBIALLH, 1);
168         dsb(nsh);
169
170         /*
171          * We need coherency with the kernel in order to use the setup
172          * spinlocks: only enable the caches if they are enabled at EL1.
173          */
174         arm_read_sysreg(SCTLR_EL1, sctlr_el1);
175         sctlr_el1 &= (SCTLR_I_BIT | SCTLR_C_BIT);
176
177         /* Enable stage-1 translation */
178         arm_read_sysreg(SCTLR_EL2, sctlr_el2);
179         sctlr_el2 |= SCTLR_M_BIT | sctlr_el1;
180         arm_write_sysreg(SCTLR_EL2, sctlr_el2);
181         isb();
182
183         /*
184          * Inlined epilogue that returns to switch_exception_level.
185          * Must not touch anything else than the stack
186          */
187         cpu_switch_phys2virt(phys2virt);
188
189         /* Not reached (cannot be a while(1), it confuses the compiler) */
190         asm volatile("b .");
191 }
192
193 /*
194  * Shutdown the MMU and returns to EL1 with the kernel context stored in `regs'
195  */
196 static void __attribute__((naked)) __attribute__((section(".trampoline")))
197 shutdown_el2(struct registers *regs, unsigned long vectors)
198 {
199         u32 sctlr_el2;
200
201         /* Disable stage-1 translation, caches must be cleaned. */
202         arm_read_sysreg(SCTLR_EL2, sctlr_el2);
203         sctlr_el2 &= ~(SCTLR_M_BIT | SCTLR_C_BIT | SCTLR_I_BIT);
204         arm_write_sysreg(SCTLR_EL2, sctlr_el2);
205         isb();
206
207         /* Clean the MMU registers */
208         arm_write_sysreg(HMAIR0, 0);
209         arm_write_sysreg(HMAIR1, 0);
210         arm_write_sysreg(TTBR0_EL2, 0);
211         arm_write_sysreg(TCR_EL2, 0);
212         isb();
213
214         /* Reset the vectors as late as possible */
215         arm_write_sysreg(HVBAR, vectors);
216
217         vmreturn(regs);
218 }
219
220 static void check_mmu_map(unsigned long virt_addr, unsigned long phys_addr)
221 {
222         unsigned long phys_base;
223         u64 par;
224
225         arm_write_sysreg(ATS1HR, virt_addr);
226         isb();
227         arm_read_sysreg(PAR_EL1, par);
228         phys_base = (unsigned long)(par & PAR_PA_MASK);
229         if ((par & PAR_F_BIT) || (phys_base != phys_addr)) {
230                 printk("VA->PA check failed, expected %x, got %x\n",
231                                 phys_addr, phys_base);
232                 while (1);
233         }
234 }
235
236 /*
237  * Jumping to EL2 in the same C code represents an interesting challenge, since
238  * it will switch from virtual addresses to physical ones, and then back to
239  * virtual after setting up the EL2 MMU.
240  * To this end, the setup_mmu_el2 and cpu_switch_el2 functions are naked and
241  * must handle the stack themselves.
242  */
243 int switch_exception_level(struct per_cpu *cpu_data)
244 {
245         extern unsigned long bootstrap_vectors;
246         extern unsigned long hyp_vectors;
247
248         /* Save the virtual address of the phys2virt function for later */
249         phys2virt_t phys2virt = paging_phys2hvirt;
250         virt2phys_t virt2phys = paging_hvirt2phys;
251         unsigned long phys_bootstrap = virt2phys(&bootstrap_vectors);
252         struct per_cpu *phys_cpu_data = (struct per_cpu *)virt2phys(cpu_data);
253         unsigned long trampoline_phys = virt2phys((void *)&trampoline_start);
254         unsigned long trampoline_size = &trampoline_end - &trampoline_start;
255         unsigned long stack_virt = (unsigned long)cpu_data->stack;
256         unsigned long stack_phys = virt2phys((void *)stack_virt);
257         u64 ttbr_el2;
258
259         /* Check the paging structures as well as the MMU initialisation */
260         unsigned long jailhouse_base_phys =
261                 paging_virt2phys(&hv_paging_structs, JAILHOUSE_BASE,
262                                  PAGE_DEFAULT_FLAGS);
263
264         /*
265          * The hypervisor stub allows to fetch its current vector base by doing
266          * an HVC with r0 = -1. They will need to be restored when disabling
267          * jailhouse.
268          */
269         if (saved_vectors == 0)
270                 saved_vectors = hvc(-1);
271
272         /*
273          * paging struct won't be easily accessible when initializing el2, only
274          * the CPU datas will be readable at their physical address
275          */
276         ttbr_el2 = (u64)virt2phys(hv_paging_structs.root_table) & TTBR_MASK;
277
278         /*
279          * Mirror the mmu setup code, so that we are able to jump to the virtual
280          * address after enabling it.
281          * Those regions must fit on one page.
282          */
283
284         if (set_id_map(0, trampoline_phys, trampoline_size) != 0)
285                 return -E2BIG;
286         if (set_id_map(1, stack_phys, PAGE_SIZE) != 0)
287                 return -E2BIG;
288         create_id_maps();
289
290         /*
291          * Before doing anything hairy, we need to sync the caches with memory:
292          * they will be off at EL2. From this point forward and until the caches
293          * are re-enabled, we cannot write anything critical to memory.
294          */
295         arch_cpu_dcaches_flush(CACHES_CLEAN);
296
297         cpu_switch_el2(phys_bootstrap, virt2phys);
298         /*
299          * At this point, we are at EL2, and we work with physical addresses.
300          * The MMU needs to be initialised and execution must go back to virtual
301          * addresses before returning, or else we are pretty much doomed.
302          */
303
304         setup_mmu_el2(phys_cpu_data, phys2virt, ttbr_el2);
305
306         /* Sanity check */
307         check_mmu_map(JAILHOUSE_BASE, jailhouse_base_phys);
308
309         /* Set the new vectors once we're back to a sane, virtual state */
310         arm_write_sysreg(HVBAR, &hyp_vectors);
311
312         /* Remove the identity mapping */
313         destroy_id_maps();
314
315         return 0;
316 }
317
318 void __attribute__((noreturn)) arch_shutdown_mmu(struct per_cpu *cpu_data)
319 {
320         static DEFINE_SPINLOCK(map_lock);
321
322         virt2phys_t virt2phys = paging_hvirt2phys;
323         void *stack_virt = cpu_data->stack;
324         unsigned long stack_phys = virt2phys((void *)stack_virt);
325         unsigned long trampoline_phys = virt2phys((void *)&trampoline_start);
326         struct registers *regs_phys =
327                         (struct registers *)virt2phys(guest_regs(cpu_data));
328
329         /* Jump to the identity-mapped trampoline page before shutting down */
330         void (*shutdown_fun_phys)(struct registers*, unsigned long);
331         shutdown_fun_phys = (void*)virt2phys(shutdown_el2);
332
333         /*
334          * No need to check for size or overlapping here, it has already be
335          * done, and the paging structures will soon be deleted. However, the
336          * cells' CPUs may execute this concurrently.
337          */
338         spin_lock(&map_lock);
339         paging_create(&hv_paging_structs, stack_phys, PAGE_SIZE, stack_phys,
340                       PAGE_DEFAULT_FLAGS, PAGING_NON_COHERENT);
341         paging_create(&hv_paging_structs, trampoline_phys, PAGE_SIZE,
342                       trampoline_phys, PAGE_DEFAULT_FLAGS,
343                       PAGING_NON_COHERENT);
344         spin_unlock(&map_lock);
345
346         arch_cpu_dcaches_flush(CACHES_CLEAN);
347
348         /*
349          * Final shutdown:
350          * - disable the MMU whilst inside the trampoline page
351          * - reset the vectors
352          * - return to EL1
353          */
354         shutdown_fun_phys(regs_phys, saved_vectors);
355
356         __builtin_unreachable();
357 }
358
359 int arch_map_device(void *paddr, void *vaddr, unsigned long size)
360 {
361         return paging_create(&hv_paging_structs, (unsigned long)paddr, size,
362                         (unsigned long)vaddr,
363                         PAGE_DEFAULT_FLAGS | S1_PTE_FLAG_DEVICE,
364                         PAGING_NON_COHERENT);
365 }
366
367 int arch_unmap_device(void *vaddr, unsigned long size)
368 {
369         return paging_destroy(&hv_paging_structs, (unsigned long)vaddr, size,
370                         PAGING_NON_COHERENT);
371 }