1
2
3
4
5
6
7 #include <linux/arm-smccc.h>
8 #include <linux/linkage.h>
9 #include <asm/kvm_arm.h>
10 #include <asm/kvm_asm.h>
11
12 .arch_extension virt
13
14 .text
15 .pushsection .hyp.text, "ax"
16
17 .macro load_vcpu reg
18 mrc p15, 4, \reg, c13, c0, 2 @ HTPIDR
19 .endm
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 .align 5
50 __kvm_hyp_vector:
51 .global __kvm_hyp_vector
52
53 @ Hyp-mode exception vector
54 W(b) hyp_reset
55 W(b) hyp_undef
56 W(b) hyp_svc
57 W(b) hyp_pabt
58 W(b) hyp_dabt
59 W(b) hyp_hvc
60 W(b) hyp_irq
61 W(b) hyp_fiq
62
63 #ifdef CONFIG_HARDEN_BRANCH_PREDICTOR
64 .align 5
65 __kvm_hyp_vector_ic_inv:
66 .global __kvm_hyp_vector_ic_inv
67
68
69
70
71
72 W(add) sp, sp, #1
73 W(add) sp, sp, #1
74 W(add) sp, sp, #1
75 W(add) sp, sp, #1
76 W(add) sp, sp, #1
77 W(add) sp, sp, #1
78 W(add) sp, sp, #1
79 W(nop)
80
81 mcr p15, 0, r0, c7, c5, 0
82 isb
83
84 b decode_vectors
85
86 .align 5
87 __kvm_hyp_vector_bp_inv:
88 .global __kvm_hyp_vector_bp_inv
89
90
91
92
93
94 W(add) sp, sp, #1
95 W(add) sp, sp, #1
96 W(add) sp, sp, #1
97 W(add) sp, sp, #1
98 W(add) sp, sp, #1
99 W(add) sp, sp, #1
100 W(add) sp, sp, #1
101 W(nop)
102
103 mcr p15, 0, r0, c7, c5, 6
104 isb
105
106 decode_vectors:
107
108 #ifdef CONFIG_THUMB2_KERNEL
109
110
111
112
113
114
115 mcr p15, 4, r0, c0, c0, 0
116 mov r0, sp
117 and r0, r0, #7
118 sub sp, sp, r0
119 push {r1, r2}
120 mov r1, r0
121 mrc p15, 4, r0, c0, c0, 0
122 mrc p15, 0, r2, c0, c0, 0
123 mcr p15, 4, r2, c0, c0, 0
124 #endif
125
126 .macro vect_br val, targ
127 ARM( eor sp, sp, #\val )
128 ARM( tst sp, #7 )
129 ARM( eorne sp, sp, #\val )
130
131 THUMB( cmp r1, #\val )
132 THUMB( popeq {r1, r2} )
133
134 beq \targ
135 .endm
136
137 vect_br 0, hyp_fiq
138 vect_br 1, hyp_irq
139 vect_br 2, hyp_hvc
140 vect_br 3, hyp_dabt
141 vect_br 4, hyp_pabt
142 vect_br 5, hyp_svc
143 vect_br 6, hyp_undef
144 vect_br 7, hyp_reset
145 #endif
146
147 .macro invalid_vector label, cause
148 .align
149 \label: mov r0, #\cause
150 b __hyp_panic
151 .endm
152
153 invalid_vector hyp_reset ARM_EXCEPTION_RESET
154 invalid_vector hyp_undef ARM_EXCEPTION_UNDEFINED
155 invalid_vector hyp_svc ARM_EXCEPTION_SOFTWARE
156 invalid_vector hyp_pabt ARM_EXCEPTION_PREF_ABORT
157 invalid_vector hyp_fiq ARM_EXCEPTION_FIQ
158
159 ENTRY(__hyp_do_panic)
160 mrs lr, cpsr
161 bic lr, lr, #MODE_MASK
162 orr lr, lr, #SVC_MODE
163 THUMB( orr lr, lr, #PSR_T_BIT )
164 msr spsr_cxsf, lr
165 ldr lr, =panic
166 msr ELR_hyp, lr
167 ldr lr, =__kvm_call_hyp
168 clrex
169 eret
170 ENDPROC(__hyp_do_panic)
171
172 hyp_hvc:
173
174
175
176
177
178 push {r0, r1, r2}
179
180 @ Check syndrome register
181 mrc p15, 4, r1, c5, c2, 0 @ HSR
182 lsr r0, r1, #HSR_EC_SHIFT
183 cmp r0, #HSR_EC_HVC
184 bne guest_trap @ Not HVC instr.
185
186
187
188
189
190 mrrc p15, 6, r0, r2, c2
191 lsr r2, r2, #16
192 and r2, r2, #0xff
193 cmp r2, #0
194 bne guest_hvc_trap @ Guest called HVC
195
196
197
198
199
200 pop {r0, r1, r2}
201
202
203
204
205
206 cmp r0, #HVC_STUB_HCALL_NR
207 bhs 1f
208
209
210
211
212
213
214
215 push {r1}
216 ldr r1, =kimage_voffset
217 ldr r1, [r1]
218 ldr ip, =__kvm_handle_stub_hvc
219 sub ip, ip, r1
220 pop {r1}
221
222 bx ip
223
224 1:
225
226
227
228
229
230
231
232 push {r2, lr}
233
234 mov lr, r0
235 mov r0, r1
236 mov r1, r2
237 mov r2, r3
238
239 THUMB( orr lr, #1)
240 blx lr @ Call the HYP function
241
242 pop {r2, lr}
243 eret
244
245 guest_hvc_trap:
246 movw r2, #:lower16:ARM_SMCCC_ARCH_WORKAROUND_1
247 movt r2, #:upper16:ARM_SMCCC_ARCH_WORKAROUND_1
248 ldr r0, [sp] @ Guest's r0
249 teq r0, r2
250 bne guest_trap
251 add sp, sp, #12
252 @ Returns:
253 @ r0 = 0
254 @ r1 = HSR value (perfectly predictable)
255 @ r2 = ARM_SMCCC_ARCH_WORKAROUND_1
256 mov r0, #0
257 eret
258
259 guest_trap:
260 load_vcpu r0 @ Load VCPU pointer to r0
261
262 #ifdef CONFIG_VFPv3
263 @ Check for a VFP access
264 lsr r1, r1, #HSR_EC_SHIFT
265 cmp r1, #HSR_EC_CP_0_13
266 beq __vfp_guest_restore
267 #endif
268
269 mov r1, #ARM_EXCEPTION_HVC
270 b __guest_exit
271
272 hyp_irq:
273 push {r0, r1, r2}
274 mov r1, #ARM_EXCEPTION_IRQ
275 load_vcpu r0 @ Load VCPU pointer to r0
276 b __guest_exit
277
278 hyp_dabt:
279 push {r0, r1}
280 mrs r0, ELR_hyp
281 ldr r1, =abort_guest_exit_start
282 THUMB( add r1, r1, #1)
283 cmp r0, r1
284 ldrne r1, =abort_guest_exit_end
285 THUMB( addne r1, r1, #1)
286 cmpne r0, r1
287 pop {r0, r1}
288 bne __hyp_panic
289
290 orr r0, r0, #(1 << ARM_EXIT_WITH_ABORT_BIT)
291 eret
292
293 .ltorg
294
295 .popsection