arm64: KVM: implement lazy world switch for debug registers
[deliverable/linux.git] / arch / arm64 / kvm / hyp.S
CommitLineData
55c7401d
MZ
1/*
2 * Copyright (C) 2012,2013 - ARM Ltd
3 * Author: Marc Zyngier <marc.zyngier@arm.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, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <linux/linkage.h>
55c7401d
MZ
19
20#include <asm/assembler.h>
21#include <asm/memory.h>
22#include <asm/asm-offsets.h>
b0e626b3 23#include <asm/debug-monitors.h>
55c7401d
MZ
24#include <asm/fpsimdmacros.h>
25#include <asm/kvm.h>
26#include <asm/kvm_asm.h>
27#include <asm/kvm_arm.h>
28#include <asm/kvm_mmu.h>
29
30#define CPU_GP_REG_OFFSET(x) (CPU_GP_REGS + x)
31#define CPU_XREG_OFFSET(x) CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 8*x)
32#define CPU_SPSR_OFFSET(x) CPU_GP_REG_OFFSET(CPU_SPSR + 8*x)
33#define CPU_SYSREG_OFFSET(x) (CPU_SYSREGS + 8*x)
34
35 .text
36 .pushsection .hyp.text, "ax"
37 .align PAGE_SHIFT
38
55c7401d
MZ
39.macro save_common_regs
40 // x2: base address for cpu context
41 // x3: tmp register
42
43 add x3, x2, #CPU_XREG_OFFSET(19)
44 stp x19, x20, [x3]
45 stp x21, x22, [x3, #16]
46 stp x23, x24, [x3, #32]
47 stp x25, x26, [x3, #48]
48 stp x27, x28, [x3, #64]
49 stp x29, lr, [x3, #80]
50
51 mrs x19, sp_el0
52 mrs x20, elr_el2 // EL1 PC
53 mrs x21, spsr_el2 // EL1 pstate
54
55 stp x19, x20, [x3, #96]
56 str x21, [x3, #112]
57
58 mrs x22, sp_el1
59 mrs x23, elr_el1
60 mrs x24, spsr_el1
61
62 str x22, [x2, #CPU_GP_REG_OFFSET(CPU_SP_EL1)]
63 str x23, [x2, #CPU_GP_REG_OFFSET(CPU_ELR_EL1)]
64 str x24, [x2, #CPU_SPSR_OFFSET(KVM_SPSR_EL1)]
65.endm
66
67.macro restore_common_regs
68 // x2: base address for cpu context
69 // x3: tmp register
70
71 ldr x22, [x2, #CPU_GP_REG_OFFSET(CPU_SP_EL1)]
72 ldr x23, [x2, #CPU_GP_REG_OFFSET(CPU_ELR_EL1)]
73 ldr x24, [x2, #CPU_SPSR_OFFSET(KVM_SPSR_EL1)]
74
75 msr sp_el1, x22
76 msr elr_el1, x23
77 msr spsr_el1, x24
78
79 add x3, x2, #CPU_XREG_OFFSET(31) // SP_EL0
80 ldp x19, x20, [x3]
81 ldr x21, [x3, #16]
82
83 msr sp_el0, x19
84 msr elr_el2, x20 // EL1 PC
85 msr spsr_el2, x21 // EL1 pstate
86
87 add x3, x2, #CPU_XREG_OFFSET(19)
88 ldp x19, x20, [x3]
89 ldp x21, x22, [x3, #16]
90 ldp x23, x24, [x3, #32]
91 ldp x25, x26, [x3, #48]
92 ldp x27, x28, [x3, #64]
93 ldp x29, lr, [x3, #80]
94.endm
95
96.macro save_host_regs
97 save_common_regs
98.endm
99
100.macro restore_host_regs
101 restore_common_regs
102.endm
103
104.macro save_fpsimd
105 // x2: cpu context address
106 // x3, x4: tmp regs
107 add x3, x2, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
108 fpsimd_save x3, 4
109.endm
110
111.macro restore_fpsimd
112 // x2: cpu context address
113 // x3, x4: tmp regs
114 add x3, x2, #CPU_GP_REG_OFFSET(CPU_FP_REGS)
115 fpsimd_restore x3, 4
116.endm
117
118.macro save_guest_regs
119 // x0 is the vcpu address
120 // x1 is the return code, do not corrupt!
121 // x2 is the cpu context
122 // x3 is a tmp register
123 // Guest's x0-x3 are on the stack
124
125 // Compute base to save registers
126 add x3, x2, #CPU_XREG_OFFSET(4)
127 stp x4, x5, [x3]
128 stp x6, x7, [x3, #16]
129 stp x8, x9, [x3, #32]
130 stp x10, x11, [x3, #48]
131 stp x12, x13, [x3, #64]
132 stp x14, x15, [x3, #80]
133 stp x16, x17, [x3, #96]
134 str x18, [x3, #112]
135
136 pop x6, x7 // x2, x3
137 pop x4, x5 // x0, x1
138
139 add x3, x2, #CPU_XREG_OFFSET(0)
140 stp x4, x5, [x3]
141 stp x6, x7, [x3, #16]
142
143 save_common_regs
144.endm
145
146.macro restore_guest_regs
147 // x0 is the vcpu address.
148 // x2 is the cpu context
149 // x3 is a tmp register
150
151 // Prepare x0-x3 for later restore
152 add x3, x2, #CPU_XREG_OFFSET(0)
153 ldp x4, x5, [x3]
154 ldp x6, x7, [x3, #16]
155 push x4, x5 // Push x0-x3 on the stack
156 push x6, x7
157
158 // x4-x18
159 ldp x4, x5, [x3, #32]
160 ldp x6, x7, [x3, #48]
161 ldp x8, x9, [x3, #64]
162 ldp x10, x11, [x3, #80]
163 ldp x12, x13, [x3, #96]
164 ldp x14, x15, [x3, #112]
165 ldp x16, x17, [x3, #128]
166 ldr x18, [x3, #144]
167
168 // x19-x29, lr, sp*, elr*, spsr*
169 restore_common_regs
170
171 // Last bits of the 64bit state
172 pop x2, x3
173 pop x0, x1
174
175 // Do not touch any register after this!
176.endm
177
178/*
179 * Macros to perform system register save/restore.
180 *
181 * Ordering here is absolutely critical, and must be kept consistent
182 * in {save,restore}_sysregs, {save,restore}_guest_32bit_state,
183 * and in kvm_asm.h.
184 *
185 * In other words, don't touch any of these unless you know what
186 * you are doing.
187 */
188.macro save_sysregs
189 // x2: base address for cpu context
190 // x3: tmp register
191
192 add x3, x2, #CPU_SYSREG_OFFSET(MPIDR_EL1)
193
194 mrs x4, vmpidr_el2
195 mrs x5, csselr_el1
196 mrs x6, sctlr_el1
197 mrs x7, actlr_el1
198 mrs x8, cpacr_el1
199 mrs x9, ttbr0_el1
200 mrs x10, ttbr1_el1
201 mrs x11, tcr_el1
202 mrs x12, esr_el1
203 mrs x13, afsr0_el1
204 mrs x14, afsr1_el1
205 mrs x15, far_el1
206 mrs x16, mair_el1
207 mrs x17, vbar_el1
208 mrs x18, contextidr_el1
209 mrs x19, tpidr_el0
210 mrs x20, tpidrro_el0
211 mrs x21, tpidr_el1
212 mrs x22, amair_el1
213 mrs x23, cntkctl_el1
1bbd8054 214 mrs x24, par_el1
b0e626b3 215 mrs x25, mdscr_el1
55c7401d
MZ
216
217 stp x4, x5, [x3]
218 stp x6, x7, [x3, #16]
219 stp x8, x9, [x3, #32]
220 stp x10, x11, [x3, #48]
221 stp x12, x13, [x3, #64]
222 stp x14, x15, [x3, #80]
223 stp x16, x17, [x3, #96]
224 stp x18, x19, [x3, #112]
225 stp x20, x21, [x3, #128]
226 stp x22, x23, [x3, #144]
b0e626b3
MZ
227 stp x24, x25, [x3, #160]
228.endm
229
230.macro save_debug
231 // x2: base address for cpu context
232 // x3: tmp register
233
234 mrs x26, id_aa64dfr0_el1
235 ubfx x24, x26, #12, #4 // Extract BRPs
236 ubfx x25, x26, #20, #4 // Extract WRPs
237 mov w26, #15
238 sub w24, w26, w24 // How many BPs to skip
239 sub w25, w26, w25 // How many WPs to skip
240
241 add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
242
243 adr x26, 1f
244 add x26, x26, x24, lsl #2
245 br x26
2461:
247 mrs x20, dbgbcr15_el1
248 mrs x19, dbgbcr14_el1
249 mrs x18, dbgbcr13_el1
250 mrs x17, dbgbcr12_el1
251 mrs x16, dbgbcr11_el1
252 mrs x15, dbgbcr10_el1
253 mrs x14, dbgbcr9_el1
254 mrs x13, dbgbcr8_el1
255 mrs x12, dbgbcr7_el1
256 mrs x11, dbgbcr6_el1
257 mrs x10, dbgbcr5_el1
258 mrs x9, dbgbcr4_el1
259 mrs x8, dbgbcr3_el1
260 mrs x7, dbgbcr2_el1
261 mrs x6, dbgbcr1_el1
262 mrs x5, dbgbcr0_el1
263
264 adr x26, 1f
265 add x26, x26, x24, lsl #2
266 br x26
267
2681:
269 str x20, [x3, #(15 * 8)]
270 str x19, [x3, #(14 * 8)]
271 str x18, [x3, #(13 * 8)]
272 str x17, [x3, #(12 * 8)]
273 str x16, [x3, #(11 * 8)]
274 str x15, [x3, #(10 * 8)]
275 str x14, [x3, #(9 * 8)]
276 str x13, [x3, #(8 * 8)]
277 str x12, [x3, #(7 * 8)]
278 str x11, [x3, #(6 * 8)]
279 str x10, [x3, #(5 * 8)]
280 str x9, [x3, #(4 * 8)]
281 str x8, [x3, #(3 * 8)]
282 str x7, [x3, #(2 * 8)]
283 str x6, [x3, #(1 * 8)]
284 str x5, [x3, #(0 * 8)]
285
286 add x3, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
287
288 adr x26, 1f
289 add x26, x26, x24, lsl #2
290 br x26
2911:
292 mrs x20, dbgbvr15_el1
293 mrs x19, dbgbvr14_el1
294 mrs x18, dbgbvr13_el1
295 mrs x17, dbgbvr12_el1
296 mrs x16, dbgbvr11_el1
297 mrs x15, dbgbvr10_el1
298 mrs x14, dbgbvr9_el1
299 mrs x13, dbgbvr8_el1
300 mrs x12, dbgbvr7_el1
301 mrs x11, dbgbvr6_el1
302 mrs x10, dbgbvr5_el1
303 mrs x9, dbgbvr4_el1
304 mrs x8, dbgbvr3_el1
305 mrs x7, dbgbvr2_el1
306 mrs x6, dbgbvr1_el1
307 mrs x5, dbgbvr0_el1
308
309 adr x26, 1f
310 add x26, x26, x24, lsl #2
311 br x26
312
3131:
314 str x20, [x3, #(15 * 8)]
315 str x19, [x3, #(14 * 8)]
316 str x18, [x3, #(13 * 8)]
317 str x17, [x3, #(12 * 8)]
318 str x16, [x3, #(11 * 8)]
319 str x15, [x3, #(10 * 8)]
320 str x14, [x3, #(9 * 8)]
321 str x13, [x3, #(8 * 8)]
322 str x12, [x3, #(7 * 8)]
323 str x11, [x3, #(6 * 8)]
324 str x10, [x3, #(5 * 8)]
325 str x9, [x3, #(4 * 8)]
326 str x8, [x3, #(3 * 8)]
327 str x7, [x3, #(2 * 8)]
328 str x6, [x3, #(1 * 8)]
329 str x5, [x3, #(0 * 8)]
330
331 add x3, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
332
333 adr x26, 1f
334 add x26, x26, x25, lsl #2
335 br x26
3361:
337 mrs x20, dbgwcr15_el1
338 mrs x19, dbgwcr14_el1
339 mrs x18, dbgwcr13_el1
340 mrs x17, dbgwcr12_el1
341 mrs x16, dbgwcr11_el1
342 mrs x15, dbgwcr10_el1
343 mrs x14, dbgwcr9_el1
344 mrs x13, dbgwcr8_el1
345 mrs x12, dbgwcr7_el1
346 mrs x11, dbgwcr6_el1
347 mrs x10, dbgwcr5_el1
348 mrs x9, dbgwcr4_el1
349 mrs x8, dbgwcr3_el1
350 mrs x7, dbgwcr2_el1
351 mrs x6, dbgwcr1_el1
352 mrs x5, dbgwcr0_el1
353
354 adr x26, 1f
355 add x26, x26, x25, lsl #2
356 br x26
357
3581:
359 str x20, [x3, #(15 * 8)]
360 str x19, [x3, #(14 * 8)]
361 str x18, [x3, #(13 * 8)]
362 str x17, [x3, #(12 * 8)]
363 str x16, [x3, #(11 * 8)]
364 str x15, [x3, #(10 * 8)]
365 str x14, [x3, #(9 * 8)]
366 str x13, [x3, #(8 * 8)]
367 str x12, [x3, #(7 * 8)]
368 str x11, [x3, #(6 * 8)]
369 str x10, [x3, #(5 * 8)]
370 str x9, [x3, #(4 * 8)]
371 str x8, [x3, #(3 * 8)]
372 str x7, [x3, #(2 * 8)]
373 str x6, [x3, #(1 * 8)]
374 str x5, [x3, #(0 * 8)]
375
376 add x3, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1)
377
378 adr x26, 1f
379 add x26, x26, x25, lsl #2
380 br x26
3811:
382 mrs x20, dbgwvr15_el1
383 mrs x19, dbgwvr14_el1
384 mrs x18, dbgwvr13_el1
385 mrs x17, dbgwvr12_el1
386 mrs x16, dbgwvr11_el1
387 mrs x15, dbgwvr10_el1
388 mrs x14, dbgwvr9_el1
389 mrs x13, dbgwvr8_el1
390 mrs x12, dbgwvr7_el1
391 mrs x11, dbgwvr6_el1
392 mrs x10, dbgwvr5_el1
393 mrs x9, dbgwvr4_el1
394 mrs x8, dbgwvr3_el1
395 mrs x7, dbgwvr2_el1
396 mrs x6, dbgwvr1_el1
397 mrs x5, dbgwvr0_el1
398
399 adr x26, 1f
400 add x26, x26, x25, lsl #2
401 br x26
402
4031:
404 str x20, [x3, #(15 * 8)]
405 str x19, [x3, #(14 * 8)]
406 str x18, [x3, #(13 * 8)]
407 str x17, [x3, #(12 * 8)]
408 str x16, [x3, #(11 * 8)]
409 str x15, [x3, #(10 * 8)]
410 str x14, [x3, #(9 * 8)]
411 str x13, [x3, #(8 * 8)]
412 str x12, [x3, #(7 * 8)]
413 str x11, [x3, #(6 * 8)]
414 str x10, [x3, #(5 * 8)]
415 str x9, [x3, #(4 * 8)]
416 str x8, [x3, #(3 * 8)]
417 str x7, [x3, #(2 * 8)]
418 str x6, [x3, #(1 * 8)]
419 str x5, [x3, #(0 * 8)]
420
421 mrs x21, mdccint_el1
422 str x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)]
55c7401d
MZ
423.endm
424
425.macro restore_sysregs
426 // x2: base address for cpu context
427 // x3: tmp register
428
429 add x3, x2, #CPU_SYSREG_OFFSET(MPIDR_EL1)
430
431 ldp x4, x5, [x3]
432 ldp x6, x7, [x3, #16]
433 ldp x8, x9, [x3, #32]
434 ldp x10, x11, [x3, #48]
435 ldp x12, x13, [x3, #64]
436 ldp x14, x15, [x3, #80]
437 ldp x16, x17, [x3, #96]
438 ldp x18, x19, [x3, #112]
439 ldp x20, x21, [x3, #128]
440 ldp x22, x23, [x3, #144]
b0e626b3 441 ldp x24, x25, [x3, #160]
55c7401d
MZ
442
443 msr vmpidr_el2, x4
444 msr csselr_el1, x5
445 msr sctlr_el1, x6
446 msr actlr_el1, x7
447 msr cpacr_el1, x8
448 msr ttbr0_el1, x9
449 msr ttbr1_el1, x10
450 msr tcr_el1, x11
451 msr esr_el1, x12
452 msr afsr0_el1, x13
453 msr afsr1_el1, x14
454 msr far_el1, x15
455 msr mair_el1, x16
456 msr vbar_el1, x17
457 msr contextidr_el1, x18
458 msr tpidr_el0, x19
459 msr tpidrro_el0, x20
460 msr tpidr_el1, x21
461 msr amair_el1, x22
462 msr cntkctl_el1, x23
1bbd8054 463 msr par_el1, x24
b0e626b3
MZ
464 msr mdscr_el1, x25
465.endm
466
467.macro restore_debug
468 // x2: base address for cpu context
469 // x3: tmp register
470
471 mrs x26, id_aa64dfr0_el1
472 ubfx x24, x26, #12, #4 // Extract BRPs
473 ubfx x25, x26, #20, #4 // Extract WRPs
474 mov w26, #15
475 sub w24, w26, w24 // How many BPs to skip
476 sub w25, w26, w25 // How many WPs to skip
477
478 add x3, x2, #CPU_SYSREG_OFFSET(DBGBCR0_EL1)
479
480 adr x26, 1f
481 add x26, x26, x24, lsl #2
482 br x26
4831:
484 ldr x20, [x3, #(15 * 8)]
485 ldr x19, [x3, #(14 * 8)]
486 ldr x18, [x3, #(13 * 8)]
487 ldr x17, [x3, #(12 * 8)]
488 ldr x16, [x3, #(11 * 8)]
489 ldr x15, [x3, #(10 * 8)]
490 ldr x14, [x3, #(9 * 8)]
491 ldr x13, [x3, #(8 * 8)]
492 ldr x12, [x3, #(7 * 8)]
493 ldr x11, [x3, #(6 * 8)]
494 ldr x10, [x3, #(5 * 8)]
495 ldr x9, [x3, #(4 * 8)]
496 ldr x8, [x3, #(3 * 8)]
497 ldr x7, [x3, #(2 * 8)]
498 ldr x6, [x3, #(1 * 8)]
499 ldr x5, [x3, #(0 * 8)]
500
501 adr x26, 1f
502 add x26, x26, x24, lsl #2
503 br x26
5041:
505 msr dbgbcr15_el1, x20
506 msr dbgbcr14_el1, x19
507 msr dbgbcr13_el1, x18
508 msr dbgbcr12_el1, x17
509 msr dbgbcr11_el1, x16
510 msr dbgbcr10_el1, x15
511 msr dbgbcr9_el1, x14
512 msr dbgbcr8_el1, x13
513 msr dbgbcr7_el1, x12
514 msr dbgbcr6_el1, x11
515 msr dbgbcr5_el1, x10
516 msr dbgbcr4_el1, x9
517 msr dbgbcr3_el1, x8
518 msr dbgbcr2_el1, x7
519 msr dbgbcr1_el1, x6
520 msr dbgbcr0_el1, x5
521
522 add x3, x2, #CPU_SYSREG_OFFSET(DBGBVR0_EL1)
523
524 adr x26, 1f
525 add x26, x26, x24, lsl #2
526 br x26
5271:
528 ldr x20, [x3, #(15 * 8)]
529 ldr x19, [x3, #(14 * 8)]
530 ldr x18, [x3, #(13 * 8)]
531 ldr x17, [x3, #(12 * 8)]
532 ldr x16, [x3, #(11 * 8)]
533 ldr x15, [x3, #(10 * 8)]
534 ldr x14, [x3, #(9 * 8)]
535 ldr x13, [x3, #(8 * 8)]
536 ldr x12, [x3, #(7 * 8)]
537 ldr x11, [x3, #(6 * 8)]
538 ldr x10, [x3, #(5 * 8)]
539 ldr x9, [x3, #(4 * 8)]
540 ldr x8, [x3, #(3 * 8)]
541 ldr x7, [x3, #(2 * 8)]
542 ldr x6, [x3, #(1 * 8)]
543 ldr x5, [x3, #(0 * 8)]
544
545 adr x26, 1f
546 add x26, x26, x24, lsl #2
547 br x26
5481:
549 msr dbgbvr15_el1, x20
550 msr dbgbvr14_el1, x19
551 msr dbgbvr13_el1, x18
552 msr dbgbvr12_el1, x17
553 msr dbgbvr11_el1, x16
554 msr dbgbvr10_el1, x15
555 msr dbgbvr9_el1, x14
556 msr dbgbvr8_el1, x13
557 msr dbgbvr7_el1, x12
558 msr dbgbvr6_el1, x11
559 msr dbgbvr5_el1, x10
560 msr dbgbvr4_el1, x9
561 msr dbgbvr3_el1, x8
562 msr dbgbvr2_el1, x7
563 msr dbgbvr1_el1, x6
564 msr dbgbvr0_el1, x5
565
566 add x3, x2, #CPU_SYSREG_OFFSET(DBGWCR0_EL1)
567
568 adr x26, 1f
569 add x26, x26, x25, lsl #2
570 br x26
5711:
572 ldr x20, [x3, #(15 * 8)]
573 ldr x19, [x3, #(14 * 8)]
574 ldr x18, [x3, #(13 * 8)]
575 ldr x17, [x3, #(12 * 8)]
576 ldr x16, [x3, #(11 * 8)]
577 ldr x15, [x3, #(10 * 8)]
578 ldr x14, [x3, #(9 * 8)]
579 ldr x13, [x3, #(8 * 8)]
580 ldr x12, [x3, #(7 * 8)]
581 ldr x11, [x3, #(6 * 8)]
582 ldr x10, [x3, #(5 * 8)]
583 ldr x9, [x3, #(4 * 8)]
584 ldr x8, [x3, #(3 * 8)]
585 ldr x7, [x3, #(2 * 8)]
586 ldr x6, [x3, #(1 * 8)]
587 ldr x5, [x3, #(0 * 8)]
588
589 adr x26, 1f
590 add x26, x26, x25, lsl #2
591 br x26
5921:
593 msr dbgwcr15_el1, x20
594 msr dbgwcr14_el1, x19
595 msr dbgwcr13_el1, x18
596 msr dbgwcr12_el1, x17
597 msr dbgwcr11_el1, x16
598 msr dbgwcr10_el1, x15
599 msr dbgwcr9_el1, x14
600 msr dbgwcr8_el1, x13
601 msr dbgwcr7_el1, x12
602 msr dbgwcr6_el1, x11
603 msr dbgwcr5_el1, x10
604 msr dbgwcr4_el1, x9
605 msr dbgwcr3_el1, x8
606 msr dbgwcr2_el1, x7
607 msr dbgwcr1_el1, x6
608 msr dbgwcr0_el1, x5
609
610 add x3, x2, #CPU_SYSREG_OFFSET(DBGWVR0_EL1)
611
612 adr x26, 1f
613 add x26, x26, x25, lsl #2
614 br x26
6151:
616 ldr x20, [x3, #(15 * 8)]
617 ldr x19, [x3, #(14 * 8)]
618 ldr x18, [x3, #(13 * 8)]
619 ldr x17, [x3, #(12 * 8)]
620 ldr x16, [x3, #(11 * 8)]
621 ldr x15, [x3, #(10 * 8)]
622 ldr x14, [x3, #(9 * 8)]
623 ldr x13, [x3, #(8 * 8)]
624 ldr x12, [x3, #(7 * 8)]
625 ldr x11, [x3, #(6 * 8)]
626 ldr x10, [x3, #(5 * 8)]
627 ldr x9, [x3, #(4 * 8)]
628 ldr x8, [x3, #(3 * 8)]
629 ldr x7, [x3, #(2 * 8)]
630 ldr x6, [x3, #(1 * 8)]
631 ldr x5, [x3, #(0 * 8)]
632
633 adr x26, 1f
634 add x26, x26, x25, lsl #2
635 br x26
6361:
637 msr dbgwvr15_el1, x20
638 msr dbgwvr14_el1, x19
639 msr dbgwvr13_el1, x18
640 msr dbgwvr12_el1, x17
641 msr dbgwvr11_el1, x16
642 msr dbgwvr10_el1, x15
643 msr dbgwvr9_el1, x14
644 msr dbgwvr8_el1, x13
645 msr dbgwvr7_el1, x12
646 msr dbgwvr6_el1, x11
647 msr dbgwvr5_el1, x10
648 msr dbgwvr4_el1, x9
649 msr dbgwvr3_el1, x8
650 msr dbgwvr2_el1, x7
651 msr dbgwvr1_el1, x6
652 msr dbgwvr0_el1, x5
653
654 ldr x21, [x2, #CPU_SYSREG_OFFSET(MDCCINT_EL1)]
655 msr mdccint_el1, x21
55c7401d
MZ
656.endm
657
b4afad06
MZ
658.macro skip_32bit_state tmp, target
659 // Skip 32bit state if not needed
660 mrs \tmp, hcr_el2
661 tbnz \tmp, #HCR_RW_SHIFT, \target
662.endm
663
664.macro skip_tee_state tmp, target
665 // Skip ThumbEE state if not needed
666 mrs \tmp, id_pfr0_el1
667 tbz \tmp, #12, \target
668.endm
669
b0e626b3
MZ
670.macro skip_debug_state tmp, target
671 ldr \tmp, [x0, #VCPU_DEBUG_FLAGS]
672 tbz \tmp, #KVM_ARM64_DEBUG_DIRTY_SHIFT, \target
673.endm
674
675.macro compute_debug_state target
676 // Compute debug state: If any of KDE, MDE or KVM_ARM64_DEBUG_DIRTY
677 // is set, we do a full save/restore cycle and disable trapping.
678 add x25, x0, #VCPU_CONTEXT
679
680 // Check the state of MDSCR_EL1
681 ldr x25, [x25, #CPU_SYSREG_OFFSET(MDSCR_EL1)]
682 and x26, x25, #DBG_MDSCR_KDE
683 and x25, x25, #DBG_MDSCR_MDE
684 adds xzr, x25, x26
685 b.eq 9998f // Nothing to see there
686
687 // If any interesting bits was set, we must set the flag
688 mov x26, #KVM_ARM64_DEBUG_DIRTY
689 str x26, [x0, #VCPU_DEBUG_FLAGS]
690 b 9999f // Don't skip restore
691
6929998:
693 // Otherwise load the flags from memory in case we recently
694 // trapped
695 skip_debug_state x25, \target
6969999:
697.endm
698
b4afad06
MZ
699.macro save_guest_32bit_state
700 skip_32bit_state x3, 1f
701
702 add x3, x2, #CPU_SPSR_OFFSET(KVM_SPSR_ABT)
703 mrs x4, spsr_abt
704 mrs x5, spsr_und
705 mrs x6, spsr_irq
706 mrs x7, spsr_fiq
707 stp x4, x5, [x3]
708 stp x6, x7, [x3, #16]
709
710 add x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
711 mrs x4, dacr32_el2
712 mrs x5, ifsr32_el2
713 mrs x6, fpexc32_el2
b4afad06 714 stp x4, x5, [x3]
b0e626b3 715 str x6, [x3, #16]
b4afad06 716
b0e626b3
MZ
717 skip_debug_state x8, 2f
718 mrs x7, dbgvcr32_el2
719 str x7, [x3, #24]
7202:
b4afad06
MZ
721 skip_tee_state x8, 1f
722
723 add x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1)
724 mrs x4, teecr32_el1
725 mrs x5, teehbr32_el1
726 stp x4, x5, [x3]
7271:
728.endm
729
730.macro restore_guest_32bit_state
731 skip_32bit_state x3, 1f
732
733 add x3, x2, #CPU_SPSR_OFFSET(KVM_SPSR_ABT)
734 ldp x4, x5, [x3]
735 ldp x6, x7, [x3, #16]
736 msr spsr_abt, x4
737 msr spsr_und, x5
738 msr spsr_irq, x6
739 msr spsr_fiq, x7
740
741 add x3, x2, #CPU_SYSREG_OFFSET(DACR32_EL2)
742 ldp x4, x5, [x3]
b0e626b3 743 ldr x6, [x3, #16]
b4afad06
MZ
744 msr dacr32_el2, x4
745 msr ifsr32_el2, x5
746 msr fpexc32_el2, x6
b4afad06 747
b0e626b3
MZ
748 skip_debug_state x8, 2f
749 ldr x7, [x3, #24]
750 msr dbgvcr32_el2, x7
7512:
b4afad06
MZ
752 skip_tee_state x8, 1f
753
754 add x3, x2, #CPU_SYSREG_OFFSET(TEECR32_EL1)
755 ldp x4, x5, [x3]
756 msr teecr32_el1, x4
757 msr teehbr32_el1, x5
7581:
759.endm
760
55c7401d 761.macro activate_traps
ac3c3747
MZ
762 ldr x2, [x0, #VCPU_HCR_EL2]
763 msr hcr_el2, x2
55c7401d
MZ
764 ldr x2, =(CPTR_EL2_TTA)
765 msr cptr_el2, x2
766
767 ldr x2, =(1 << 15) // Trap CP15 Cr=15
768 msr hstr_el2, x2
769
770 mrs x2, mdcr_el2
771 and x2, x2, #MDCR_EL2_HPMN_MASK
772 orr x2, x2, #(MDCR_EL2_TPM | MDCR_EL2_TPMCR)
773 msr mdcr_el2, x2
774.endm
775
776.macro deactivate_traps
777 mov x2, #HCR_RW
778 msr hcr_el2, x2
779 msr cptr_el2, xzr
780 msr hstr_el2, xzr
781
782 mrs x2, mdcr_el2
783 and x2, x2, #MDCR_EL2_HPMN_MASK
784 msr mdcr_el2, x2
785.endm
786
787.macro activate_vm
788 ldr x1, [x0, #VCPU_KVM]
789 kern_hyp_va x1
790 ldr x2, [x1, #KVM_VTTBR]
791 msr vttbr_el2, x2
792.endm
793
794.macro deactivate_vm
795 msr vttbr_el2, xzr
796.endm
797
1f17f3b6 798/*
1a9b1305 799 * Call into the vgic backend for state saving
1f17f3b6
MZ
800 */
801.macro save_vgic_state
1a9b1305
MZ
802 adr x24, __vgic_sr_vectors
803 ldr x24, [x24, VGIC_SAVE_FN]
804 kern_hyp_va x24
805 blr x24
ac3c3747
MZ
806 mrs x24, hcr_el2
807 mov x25, #HCR_INT_OVERRIDE
808 neg x25, x25
809 and x24, x24, x25
810 msr hcr_el2, x24
1f17f3b6
MZ
811.endm
812
813/*
1a9b1305 814 * Call into the vgic backend for state restoring
1f17f3b6
MZ
815 */
816.macro restore_vgic_state
ac3c3747
MZ
817 mrs x24, hcr_el2
818 ldr x25, [x0, #VCPU_IRQ_LINES]
819 orr x24, x24, #HCR_INT_OVERRIDE
820 orr x24, x24, x25
821 msr hcr_el2, x24
1a9b1305
MZ
822 adr x24, __vgic_sr_vectors
823 ldr x24, [x24, #VGIC_RESTORE_FN]
824 kern_hyp_va x24
825 blr x24
1f17f3b6
MZ
826.endm
827
003300de
MZ
828.macro save_timer_state
829 // x0: vcpu pointer
830 ldr x2, [x0, #VCPU_KVM]
831 kern_hyp_va x2
832 ldr w3, [x2, #KVM_TIMER_ENABLED]
833 cbz w3, 1f
834
835 mrs x3, cntv_ctl_el0
836 and x3, x3, #3
837 str w3, [x0, #VCPU_TIMER_CNTV_CTL]
838 bic x3, x3, #1 // Clear Enable
839 msr cntv_ctl_el0, x3
840
841 isb
842
843 mrs x3, cntv_cval_el0
844 str x3, [x0, #VCPU_TIMER_CNTV_CVAL]
845
8461:
847 // Allow physical timer/counter access for the host
848 mrs x2, cnthctl_el2
849 orr x2, x2, #3
850 msr cnthctl_el2, x2
851
852 // Clear cntvoff for the host
853 msr cntvoff_el2, xzr
854.endm
855
856.macro restore_timer_state
857 // x0: vcpu pointer
858 // Disallow physical timer access for the guest
859 // Physical counter access is allowed
860 mrs x2, cnthctl_el2
861 orr x2, x2, #1
862 bic x2, x2, #2
863 msr cnthctl_el2, x2
864
865 ldr x2, [x0, #VCPU_KVM]
866 kern_hyp_va x2
867 ldr w3, [x2, #KVM_TIMER_ENABLED]
868 cbz w3, 1f
869
870 ldr x3, [x2, #KVM_TIMER_CNTVOFF]
871 msr cntvoff_el2, x3
872 ldr x2, [x0, #VCPU_TIMER_CNTV_CVAL]
873 msr cntv_cval_el0, x2
874 isb
875
876 ldr w2, [x0, #VCPU_TIMER_CNTV_CTL]
877 and x2, x2, #3
878 msr cntv_ctl_el0, x2
8791:
880.endm
881
55c7401d
MZ
882__save_sysregs:
883 save_sysregs
884 ret
885
886__restore_sysregs:
887 restore_sysregs
888 ret
889
b0e626b3
MZ
890__save_debug:
891 save_debug
892 ret
893
894__restore_debug:
895 restore_debug
896 ret
897
55c7401d
MZ
898__save_fpsimd:
899 save_fpsimd
900 ret
901
902__restore_fpsimd:
903 restore_fpsimd
904 ret
905
906/*
907 * u64 __kvm_vcpu_run(struct kvm_vcpu *vcpu);
908 *
909 * This is the world switch. The first half of the function
910 * deals with entering the guest, and anything from __kvm_vcpu_return
911 * to the end of the function deals with reentering the host.
912 * On the enter path, only x0 (vcpu pointer) must be preserved until
913 * the last moment. On the exit path, x0 (vcpu pointer) and x1 (exception
914 * code) must both be preserved until the epilogue.
915 * In both cases, x2 points to the CPU context we're saving/restoring from/to.
916 */
917ENTRY(__kvm_vcpu_run)
918 kern_hyp_va x0
919 msr tpidr_el2, x0 // Save the vcpu register
920
921 // Host context
922 ldr x2, [x0, #VCPU_HOST_CONTEXT]
923 kern_hyp_va x2
924
925 save_host_regs
926 bl __save_fpsimd
927 bl __save_sysregs
928
b0e626b3
MZ
929 compute_debug_state 1f
930 bl __save_debug
9311:
55c7401d
MZ
932 activate_traps
933 activate_vm
934
1f17f3b6 935 restore_vgic_state
003300de 936 restore_timer_state
1f17f3b6 937
55c7401d
MZ
938 // Guest context
939 add x2, x0, #VCPU_CONTEXT
940
941 bl __restore_sysregs
942 bl __restore_fpsimd
b0e626b3
MZ
943
944 skip_debug_state x3, 1f
945 bl __restore_debug
9461:
b4afad06 947 restore_guest_32bit_state
55c7401d
MZ
948 restore_guest_regs
949
950 // That's it, no more messing around.
951 eret
952
953__kvm_vcpu_return:
954 // Assume x0 is the vcpu pointer, x1 the return code
955 // Guest's x0-x3 are on the stack
956
957 // Guest context
958 add x2, x0, #VCPU_CONTEXT
959
960 save_guest_regs
961 bl __save_fpsimd
962 bl __save_sysregs
b0e626b3
MZ
963
964 skip_debug_state x3, 1f
965 bl __save_debug
9661:
b4afad06 967 save_guest_32bit_state
55c7401d 968
003300de 969 save_timer_state
1f17f3b6
MZ
970 save_vgic_state
971
55c7401d
MZ
972 deactivate_traps
973 deactivate_vm
974
975 // Host context
976 ldr x2, [x0, #VCPU_HOST_CONTEXT]
977 kern_hyp_va x2
978
979 bl __restore_sysregs
980 bl __restore_fpsimd
b0e626b3
MZ
981
982 skip_debug_state x3, 1f
983 // Clear the dirty flag for the next run, as all the state has
984 // already been saved. Note that we nuke the whole 64bit word.
985 // If we ever add more flags, we'll have to be more careful...
986 str xzr, [x0, #VCPU_DEBUG_FLAGS]
987 bl __restore_debug
9881:
55c7401d
MZ
989 restore_host_regs
990
991 mov x0, x1
992 ret
993END(__kvm_vcpu_run)
994
995// void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
996ENTRY(__kvm_tlb_flush_vmid_ipa)
f142e5ee
MZ
997 dsb ishst
998
55c7401d
MZ
999 kern_hyp_va x0
1000 ldr x2, [x0, #KVM_VTTBR]
1001 msr vttbr_el2, x2
1002 isb
1003
1004 /*
1005 * We could do so much better if we had the VA as well.
1006 * Instead, we invalidate Stage-2 for this IPA, and the
1007 * whole of Stage-1. Weep...
1008 */
1009 tlbi ipas2e1is, x1
ee9e101c
WD
1010 /*
1011 * We have to ensure completion of the invalidation at Stage-2,
1012 * since a table walk on another CPU could refill a TLB with a
1013 * complete (S1 + S2) walk based on the old Stage-2 mapping if
1014 * the Stage-1 invalidation happened first.
1015 */
1016 dsb ish
55c7401d 1017 tlbi vmalle1is
ee9e101c 1018 dsb ish
55c7401d
MZ
1019 isb
1020
1021 msr vttbr_el2, xzr
1022 ret
1023ENDPROC(__kvm_tlb_flush_vmid_ipa)
1024
1025ENTRY(__kvm_flush_vm_context)
f142e5ee 1026 dsb ishst
55c7401d
MZ
1027 tlbi alle1is
1028 ic ialluis
ee9e101c 1029 dsb ish
55c7401d
MZ
1030 ret
1031ENDPROC(__kvm_flush_vm_context)
1032
1a9b1305
MZ
1033 // struct vgic_sr_vectors __vgi_sr_vectors;
1034 .align 3
1035ENTRY(__vgic_sr_vectors)
1036 .skip VGIC_SR_VECTOR_SZ
1037ENDPROC(__vgic_sr_vectors)
1038
55c7401d
MZ
1039__kvm_hyp_panic:
1040 // Guess the context by looking at VTTBR:
1041 // If zero, then we're already a host.
1042 // Otherwise restore a minimal host context before panicing.
1043 mrs x0, vttbr_el2
1044 cbz x0, 1f
1045
1046 mrs x0, tpidr_el2
1047
1048 deactivate_traps
1049 deactivate_vm
1050
1051 ldr x2, [x0, #VCPU_HOST_CONTEXT]
1052 kern_hyp_va x2
1053
1054 bl __restore_sysregs
1055
10561: adr x0, __hyp_panic_str
1057 adr x1, 2f
1058 ldp x2, x3, [x1]
1059 sub x0, x0, x2
1060 add x0, x0, x3
1061 mrs x1, spsr_el2
1062 mrs x2, elr_el2
1063 mrs x3, esr_el2
1064 mrs x4, far_el2
1065 mrs x5, hpfar_el2
1066 mrs x6, par_el1
1067 mrs x7, tpidr_el2
1068
1069 mov lr, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT |\
1070 PSR_MODE_EL1h)
1071 msr spsr_el2, lr
1072 ldr lr, =panic
1073 msr elr_el2, lr
1074 eret
1075
1076 .align 3
10772: .quad HYP_PAGE_OFFSET
1078 .quad PAGE_OFFSET
1079ENDPROC(__kvm_hyp_panic)
1080
1081__hyp_panic_str:
1082 .ascii "HYP panic:\nPS:%08x PC:%p ESR:%p\nFAR:%p HPFAR:%p PAR:%p\nVCPU:%p\n\0"
1083
1084 .align 2
1085
b20c9f29
MZ
1086/*
1087 * u64 kvm_call_hyp(void *hypfn, ...);
1088 *
1089 * This is not really a variadic function in the classic C-way and care must
1090 * be taken when calling this to ensure parameters are passed in registers
1091 * only, since the stack will change between the caller and the callee.
1092 *
1093 * Call the function with the first argument containing a pointer to the
1094 * function you wish to call in Hyp mode, and subsequent arguments will be
1095 * passed as x0, x1, and x2 (a maximum of 3 arguments in addition to the
1096 * function pointer can be passed). The function being called must be mapped
1097 * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c). Return values are
1098 * passed in r0 and r1.
1099 *
1100 * A function pointer with a value of 0 has a special meaning, and is
1101 * used to implement __hyp_get_vectors in the same way as in
1102 * arch/arm64/kernel/hyp_stub.S.
1103 */
55c7401d
MZ
1104ENTRY(kvm_call_hyp)
1105 hvc #0
1106 ret
1107ENDPROC(kvm_call_hyp)
1108
1109.macro invalid_vector label, target
1110 .align 2
1111\label:
1112 b \target
1113ENDPROC(\label)
1114.endm
1115
1116 /* None of these should ever happen */
1117 invalid_vector el2t_sync_invalid, __kvm_hyp_panic
1118 invalid_vector el2t_irq_invalid, __kvm_hyp_panic
1119 invalid_vector el2t_fiq_invalid, __kvm_hyp_panic
1120 invalid_vector el2t_error_invalid, __kvm_hyp_panic
1121 invalid_vector el2h_sync_invalid, __kvm_hyp_panic
1122 invalid_vector el2h_irq_invalid, __kvm_hyp_panic
1123 invalid_vector el2h_fiq_invalid, __kvm_hyp_panic
1124 invalid_vector el2h_error_invalid, __kvm_hyp_panic
1125 invalid_vector el1_sync_invalid, __kvm_hyp_panic
1126 invalid_vector el1_irq_invalid, __kvm_hyp_panic
1127 invalid_vector el1_fiq_invalid, __kvm_hyp_panic
1128 invalid_vector el1_error_invalid, __kvm_hyp_panic
1129
1130el1_sync: // Guest trapped into EL2
1131 push x0, x1
1132 push x2, x3
1133
1134 mrs x1, esr_el2
1135 lsr x2, x1, #ESR_EL2_EC_SHIFT
1136
1137 cmp x2, #ESR_EL2_EC_HVC64
1138 b.ne el1_trap
1139
1140 mrs x3, vttbr_el2 // If vttbr is valid, the 64bit guest
1141 cbnz x3, el1_trap // called HVC
1142
1143 /* Here, we're pretty sure the host called HVC. */
1144 pop x2, x3
1145 pop x0, x1
1146
b20c9f29
MZ
1147 /* Check for __hyp_get_vectors */
1148 cbnz x0, 1f
1149 mrs x0, vbar_el2
1150 b 2f
1151
11521: push lr, xzr
55c7401d
MZ
1153
1154 /*
1155 * Compute the function address in EL2, and shuffle the parameters.
1156 */
1157 kern_hyp_va x0
1158 mov lr, x0
1159 mov x0, x1
1160 mov x1, x2
1161 mov x2, x3
1162 blr lr
1163
1164 pop lr, xzr
b20c9f29 11652: eret
55c7401d
MZ
1166
1167el1_trap:
1168 /*
1169 * x1: ESR
1170 * x2: ESR_EC
1171 */
1172 cmp x2, #ESR_EL2_EC_DABT
1173 mov x0, #ESR_EL2_EC_IABT
1174 ccmp x2, x0, #4, ne
1175 b.ne 1f // Not an abort we care about
1176
1177 /* This is an abort. Check for permission fault */
1178 and x2, x1, #ESR_EL2_FSC_TYPE
1179 cmp x2, #FSC_PERM
1180 b.ne 1f // Not a permission fault
1181
1182 /*
1183 * Check for Stage-1 page table walk, which is guaranteed
1184 * to give a valid HPFAR_EL2.
1185 */
1186 tbnz x1, #7, 1f // S1PTW is set
1187
1bbd8054
MZ
1188 /* Preserve PAR_EL1 */
1189 mrs x3, par_el1
1190 push x3, xzr
1191
55c7401d
MZ
1192 /*
1193 * Permission fault, HPFAR_EL2 is invalid.
1194 * Resolve the IPA the hard way using the guest VA.
1195 * Stage-1 translation already validated the memory access rights.
1196 * As such, we can use the EL1 translation regime, and don't have
1197 * to distinguish between EL0 and EL1 access.
1198 */
1199 mrs x2, far_el2
1200 at s1e1r, x2
1201 isb
1202
1203 /* Read result */
1204 mrs x3, par_el1
1bbd8054
MZ
1205 pop x0, xzr // Restore PAR_EL1 from the stack
1206 msr par_el1, x0
55c7401d
MZ
1207 tbnz x3, #0, 3f // Bail out if we failed the translation
1208 ubfx x3, x3, #12, #36 // Extract IPA
1209 lsl x3, x3, #4 // and present it like HPFAR
1210 b 2f
1211
12121: mrs x3, hpfar_el2
1213 mrs x2, far_el2
1214
12152: mrs x0, tpidr_el2
ba083d20 1216 str w1, [x0, #VCPU_ESR_EL2]
55c7401d
MZ
1217 str x2, [x0, #VCPU_FAR_EL2]
1218 str x3, [x0, #VCPU_HPFAR_EL2]
1219
1220 mov x1, #ARM_EXCEPTION_TRAP
1221 b __kvm_vcpu_return
1222
1223 /*
1224 * Translation failed. Just return to the guest and
1225 * let it fault again. Another CPU is probably playing
1226 * behind our back.
1227 */
12283: pop x2, x3
1229 pop x0, x1
1230
1231 eret
1232
1233el1_irq:
1234 push x0, x1
1235 push x2, x3
1236 mrs x0, tpidr_el2
1237 mov x1, #ARM_EXCEPTION_IRQ
1238 b __kvm_vcpu_return
1239
1240 .ltorg
1241
1242 .align 11
1243
1244ENTRY(__kvm_hyp_vector)
1245 ventry el2t_sync_invalid // Synchronous EL2t
1246 ventry el2t_irq_invalid // IRQ EL2t
1247 ventry el2t_fiq_invalid // FIQ EL2t
1248 ventry el2t_error_invalid // Error EL2t
1249
1250 ventry el2h_sync_invalid // Synchronous EL2h
1251 ventry el2h_irq_invalid // IRQ EL2h
1252 ventry el2h_fiq_invalid // FIQ EL2h
1253 ventry el2h_error_invalid // Error EL2h
1254
1255 ventry el1_sync // Synchronous 64-bit EL1
1256 ventry el1_irq // IRQ 64-bit EL1
1257 ventry el1_fiq_invalid // FIQ 64-bit EL1
1258 ventry el1_error_invalid // Error 64-bit EL1
1259
1260 ventry el1_sync // Synchronous 32-bit EL1
1261 ventry el1_irq // IRQ 32-bit EL1
1262 ventry el1_fiq_invalid // FIQ 32-bit EL1
1263 ventry el1_error_invalid // Error 32-bit EL1
1264ENDPROC(__kvm_hyp_vector)
1265
55c7401d 1266 .popsection
This page took 0.126683 seconds and 5 git commands to generate.