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