Merge tag 'pstore-v4.12-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/kees...
[sfrench/cifs-2.6.git] / arch / arm / kvm / init.S
1 /*
2  * Copyright (C) 2012 - Virtual Open Systems and Columbia University
3  * Author: Christoffer Dall <c.dall@virtualopensystems.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License, version 2, as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17  */
18
19 #include <linux/linkage.h>
20 #include <asm/assembler.h>
21 #include <asm/unified.h>
22 #include <asm/asm-offsets.h>
23 #include <asm/kvm_asm.h>
24 #include <asm/kvm_arm.h>
25 #include <asm/kvm_mmu.h>
26 #include <asm/virt.h>
27
28 /********************************************************************
29  * Hypervisor initialization
30  *   - should be called with:
31  *       r0 = top of Hyp stack (kernel VA)
32  *       r1 = pointer to hyp vectors
33  *       r2,r3 = Hypervisor pgd pointer
34  *
35  * The init scenario is:
36  * - We jump in HYP with 3 parameters: runtime HYP pgd, runtime stack,
37  *   runtime vectors
38  * - Invalidate TLBs
39  * - Set stack and vectors
40  * - Setup the page tables
41  * - Enable the MMU
42  * - Profit! (or eret, if you only care about the code).
43  *
44  * Another possibility is to get a HYP stub hypercall.
45  * We discriminate between the two by checking if r0 contains a value
46  * that is less than HVC_STUB_HCALL_NR.
47  */
48
49         .text
50         .pushsection    .hyp.idmap.text,"ax"
51         .align 5
52 __kvm_hyp_init:
53         .globl __kvm_hyp_init
54
55         @ Hyp-mode exception vector
56         W(b)    .
57         W(b)    .
58         W(b)    .
59         W(b)    .
60         W(b)    .
61         W(b)    __do_hyp_init
62         W(b)    .
63         W(b)    .
64
65 __do_hyp_init:
66         @ Check for a stub hypercall
67         cmp     r0, #HVC_STUB_HCALL_NR
68         blo     __kvm_handle_stub_hvc
69
70         @ Set stack pointer
71         mov     sp, r0
72
73         @ Set HVBAR to point to the HYP vectors
74         mcr     p15, 4, r1, c12, c0, 0  @ HVBAR
75
76         @ Set the HTTBR to point to the hypervisor PGD pointer passed
77         mcrr    p15, 4, rr_lo_hi(r2, r3), c2
78
79         @ Set the HTCR and VTCR to the same shareability and cacheability
80         @ settings as the non-secure TTBCR and with T0SZ == 0.
81         mrc     p15, 4, r0, c2, c0, 2   @ HTCR
82         ldr     r2, =HTCR_MASK
83         bic     r0, r0, r2
84         mrc     p15, 0, r1, c2, c0, 2   @ TTBCR
85         and     r1, r1, #(HTCR_MASK & ~TTBCR_T0SZ)
86         orr     r0, r0, r1
87         mcr     p15, 4, r0, c2, c0, 2   @ HTCR
88
89         @ Use the same memory attributes for hyp. accesses as the kernel
90         @ (copy MAIRx ro HMAIRx).
91         mrc     p15, 0, r0, c10, c2, 0
92         mcr     p15, 4, r0, c10, c2, 0
93         mrc     p15, 0, r0, c10, c2, 1
94         mcr     p15, 4, r0, c10, c2, 1
95
96         @ Invalidate the stale TLBs from Bootloader
97         mcr     p15, 4, r0, c8, c7, 0   @ TLBIALLH
98         dsb     ish
99
100         @ Set the HSCTLR to:
101         @  - ARM/THUMB exceptions: Kernel config (Thumb-2 kernel)
102         @  - Endianness: Kernel config
103         @  - Fast Interrupt Features: Kernel config
104         @  - Write permission implies XN: disabled
105         @  - Instruction cache: enabled
106         @  - Data/Unified cache: enabled
107         @  - Memory alignment checks: enabled
108         @  - MMU: enabled (this code must be run from an identity mapping)
109         mrc     p15, 4, r0, c1, c0, 0   @ HSCR
110         ldr     r2, =HSCTLR_MASK
111         bic     r0, r0, r2
112         mrc     p15, 0, r1, c1, c0, 0   @ SCTLR
113         ldr     r2, =(HSCTLR_EE | HSCTLR_FI | HSCTLR_I | HSCTLR_C)
114         and     r1, r1, r2
115  ARM(   ldr     r2, =(HSCTLR_M | HSCTLR_A)                      )
116  THUMB( ldr     r2, =(HSCTLR_M | HSCTLR_A | HSCTLR_TE)          )
117         orr     r1, r1, r2
118         orr     r0, r0, r1
119         mcr     p15, 4, r0, c1, c0, 0   @ HSCR
120         isb
121
122         eret
123
124 ENTRY(__kvm_handle_stub_hvc)
125         cmp     r0, #HVC_SOFT_RESTART
126         bne     1f
127
128         /* The target is expected in r1 */
129         msr     ELR_hyp, r1
130         mrs     r0, cpsr
131         bic     r0, r0, #MODE_MASK
132         orr     r0, r0, #HYP_MODE
133 THUMB(  orr     r0, r0, #PSR_T_BIT      )
134         msr     spsr_cxsf, r0
135         b       reset
136
137 1:      cmp     r0, #HVC_RESET_VECTORS
138         bne     1f
139
140 reset:
141         /* We're now in idmap, disable MMU */
142         mrc     p15, 4, r1, c1, c0, 0   @ HSCTLR
143         ldr     r0, =(HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I)
144         bic     r1, r1, r0
145         mcr     p15, 4, r1, c1, c0, 0   @ HSCTLR
146
147         /*
148          * Install stub vectors, using ardb's VA->PA trick.
149          */
150 0:      adr     r0, 0b                                  @ PA(0)
151         movw    r1, #:lower16:__hyp_stub_vectors - 0b   @ VA(stub) - VA(0)
152         movt    r1, #:upper16:__hyp_stub_vectors - 0b
153         add     r1, r1, r0                              @ PA(stub)
154         mcr     p15, 4, r1, c12, c0, 0  @ HVBAR
155         b       exit
156
157 1:      ldr     r0, =HVC_STUB_ERR
158         eret
159
160 exit:
161         mov     r0, #0
162         eret
163 ENDPROC(__kvm_handle_stub_hvc)
164
165         .ltorg
166
167         .globl __kvm_hyp_init_end
168 __kvm_hyp_init_end:
169
170         .popsection