Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[firefly-linux-kernel-4.4.55.git] / arch / arm / kvm / interrupts.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 <linux/const.h>
21 #include <asm/unified.h>
22 #include <asm/page.h>
23 #include <asm/ptrace.h>
24 #include <asm/asm-offsets.h>
25 #include <asm/kvm_asm.h>
26 #include <asm/kvm_arm.h>
27 #include <asm/vfpmacros.h>
28 #include "interrupts_head.S"
29
30         .text
31
32 __kvm_hyp_code_start:
33         .globl __kvm_hyp_code_start
34
35 /********************************************************************
36  * Flush per-VMID TLBs
37  *
38  * void __kvm_tlb_flush_vmid(struct kvm *kvm);
39  *
40  * We rely on the hardware to broadcast the TLB invalidation to all CPUs
41  * inside the inner-shareable domain (which is the case for all v7
42  * implementations).  If we come across a non-IS SMP implementation, we'll
43  * have to use an IPI based mechanism. Until then, we stick to the simple
44  * hardware assisted version.
45  */
46 ENTRY(__kvm_tlb_flush_vmid)
47         push    {r2, r3}
48
49         add     r0, r0, #KVM_VTTBR
50         ldrd    r2, r3, [r0]
51         mcrr    p15, 6, r2, r3, c2      @ Write VTTBR
52         isb
53         mcr     p15, 0, r0, c8, c3, 0   @ TLBIALLIS (rt ignored)
54         dsb
55         isb
56         mov     r2, #0
57         mov     r3, #0
58         mcrr    p15, 6, r2, r3, c2      @ Back to VMID #0
59         isb                             @ Not necessary if followed by eret
60
61         pop     {r2, r3}
62         bx      lr
63 ENDPROC(__kvm_tlb_flush_vmid)
64
65 /********************************************************************
66  * Flush TLBs and instruction caches of all CPUs inside the inner-shareable
67  * domain, for all VMIDs
68  *
69  * void __kvm_flush_vm_context(void);
70  */
71 ENTRY(__kvm_flush_vm_context)
72         mov     r0, #0                  @ rn parameter for c15 flushes is SBZ
73
74         /* Invalidate NS Non-Hyp TLB Inner Shareable (TLBIALLNSNHIS) */
75         mcr     p15, 4, r0, c8, c3, 4
76         /* Invalidate instruction caches Inner Shareable (ICIALLUIS) */
77         mcr     p15, 0, r0, c7, c1, 0
78         dsb
79         isb                             @ Not necessary if followed by eret
80
81         bx      lr
82 ENDPROC(__kvm_flush_vm_context)
83
84
85 /********************************************************************
86  *  Hypervisor world-switch code
87  *
88  *
89  * int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
90  */
91 ENTRY(__kvm_vcpu_run)
92         @ Save the vcpu pointer
93         mcr     p15, 4, vcpu, c13, c0, 2        @ HTPIDR
94
95         save_host_regs
96
97         restore_vgic_state
98         restore_timer_state
99
100         @ Store hardware CP15 state and load guest state
101         read_cp15_state store_to_vcpu = 0
102         write_cp15_state read_from_vcpu = 1
103
104         @ If the host kernel has not been configured with VFPv3 support,
105         @ then it is safer if we deny guests from using it as well.
106 #ifdef CONFIG_VFPv3
107         @ Set FPEXC_EN so the guest doesn't trap floating point instructions
108         VFPFMRX r2, FPEXC               @ VMRS
109         push    {r2}
110         orr     r2, r2, #FPEXC_EN
111         VFPFMXR FPEXC, r2               @ VMSR
112 #endif
113
114         @ Configure Hyp-role
115         configure_hyp_role vmentry
116
117         @ Trap coprocessor CRx accesses
118         set_hstr vmentry
119         set_hcptr vmentry, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11))
120         set_hdcr vmentry
121
122         @ Write configured ID register into MIDR alias
123         ldr     r1, [vcpu, #VCPU_MIDR]
124         mcr     p15, 4, r1, c0, c0, 0
125
126         @ Write guest view of MPIDR into VMPIDR
127         ldr     r1, [vcpu, #CP15_OFFSET(c0_MPIDR)]
128         mcr     p15, 4, r1, c0, c0, 5
129
130         @ Set up guest memory translation
131         ldr     r1, [vcpu, #VCPU_KVM]
132         add     r1, r1, #KVM_VTTBR
133         ldrd    r2, r3, [r1]
134         mcrr    p15, 6, r2, r3, c2      @ Write VTTBR
135
136         @ We're all done, just restore the GPRs and go to the guest
137         restore_guest_regs
138         clrex                           @ Clear exclusive monitor
139         eret
140
141 __kvm_vcpu_return:
142         /*
143          * return convention:
144          * guest r0, r1, r2 saved on the stack
145          * r0: vcpu pointer
146          * r1: exception code
147          */
148         save_guest_regs
149
150         @ Set VMID == 0
151         mov     r2, #0
152         mov     r3, #0
153         mcrr    p15, 6, r2, r3, c2      @ Write VTTBR
154
155         @ Don't trap coprocessor accesses for host kernel
156         set_hstr vmexit
157         set_hdcr vmexit
158         set_hcptr vmexit, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11))
159
160 #ifdef CONFIG_VFPv3
161         @ Save floating point registers we if let guest use them.
162         tst     r2, #(HCPTR_TCP(10) | HCPTR_TCP(11))
163         bne     after_vfp_restore
164
165         @ Switch VFP/NEON hardware state to the host's
166         add     r7, vcpu, #VCPU_VFP_GUEST
167         store_vfp_state r7
168         add     r7, vcpu, #VCPU_VFP_HOST
169         ldr     r7, [r7]
170         restore_vfp_state r7
171
172 after_vfp_restore:
173         @ Restore FPEXC_EN which we clobbered on entry
174         pop     {r2}
175         VFPFMXR FPEXC, r2
176 #endif
177
178         @ Reset Hyp-role
179         configure_hyp_role vmexit
180
181         @ Let host read hardware MIDR
182         mrc     p15, 0, r2, c0, c0, 0
183         mcr     p15, 4, r2, c0, c0, 0
184
185         @ Back to hardware MPIDR
186         mrc     p15, 0, r2, c0, c0, 5
187         mcr     p15, 4, r2, c0, c0, 5
188
189         @ Store guest CP15 state and restore host state
190         read_cp15_state store_to_vcpu = 1
191         write_cp15_state read_from_vcpu = 0
192
193         save_timer_state
194         save_vgic_state
195
196         restore_host_regs
197         clrex                           @ Clear exclusive monitor
198         mov     r0, r1                  @ Return the return code
199         mov     r1, #0                  @ Clear upper bits in return value
200         bx      lr                      @ return to IOCTL
201
202 /********************************************************************
203  *  Call function in Hyp mode
204  *
205  *
206  * u64 kvm_call_hyp(void *hypfn, ...);
207  *
208  * This is not really a variadic function in the classic C-way and care must
209  * be taken when calling this to ensure parameters are passed in registers
210  * only, since the stack will change between the caller and the callee.
211  *
212  * Call the function with the first argument containing a pointer to the
213  * function you wish to call in Hyp mode, and subsequent arguments will be
214  * passed as r0, r1, and r2 (a maximum of 3 arguments in addition to the
215  * function pointer can be passed).  The function being called must be mapped
216  * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c).  Return values are
217  * passed in r0 and r1.
218  *
219  * The calling convention follows the standard AAPCS:
220  *   r0 - r3: caller save
221  *   r12:     caller save
222  *   rest:    callee save
223  */
224 ENTRY(kvm_call_hyp)
225         hvc     #0
226         bx      lr
227
228 /********************************************************************
229  * Hypervisor exception vector and handlers
230  *
231  *
232  * The KVM/ARM Hypervisor ABI is defined as follows:
233  *
234  * Entry to Hyp mode from the host kernel will happen _only_ when an HVC
235  * instruction is issued since all traps are disabled when running the host
236  * kernel as per the Hyp-mode initialization at boot time.
237  *
238  * HVC instructions cause a trap to the vector page + offset 0x18 (see hyp_hvc
239  * below) when the HVC instruction is called from SVC mode (i.e. a guest or the
240  * host kernel) and they cause a trap to the vector page + offset 0xc when HVC
241  * instructions are called from within Hyp-mode.
242  *
243  * Hyp-ABI: Calling HYP-mode functions from host (in SVC mode):
244  *    Switching to Hyp mode is done through a simple HVC #0 instruction. The
245  *    exception vector code will check that the HVC comes from VMID==0 and if
246  *    so will push the necessary state (SPSR, lr_usr) on the Hyp stack.
247  *    - r0 contains a pointer to a HYP function
248  *    - r1, r2, and r3 contain arguments to the above function.
249  *    - The HYP function will be called with its arguments in r0, r1 and r2.
250  *    On HYP function return, we return directly to SVC.
251  *
252  * Note that the above is used to execute code in Hyp-mode from a host-kernel
253  * point of view, and is a different concept from performing a world-switch and
254  * executing guest code SVC mode (with a VMID != 0).
255  */
256
257 /* Handle undef, svc, pabt, or dabt by crashing with a user notice */
258 .macro bad_exception exception_code, panic_str
259         push    {r0-r2}
260         mrrc    p15, 6, r0, r1, c2      @ Read VTTBR
261         lsr     r1, r1, #16
262         ands    r1, r1, #0xff
263         beq     99f
264
265         load_vcpu                       @ Load VCPU pointer
266         .if \exception_code == ARM_EXCEPTION_DATA_ABORT
267         mrc     p15, 4, r2, c5, c2, 0   @ HSR
268         mrc     p15, 4, r1, c6, c0, 0   @ HDFAR
269         str     r2, [vcpu, #VCPU_HSR]
270         str     r1, [vcpu, #VCPU_HxFAR]
271         .endif
272         .if \exception_code == ARM_EXCEPTION_PREF_ABORT
273         mrc     p15, 4, r2, c5, c2, 0   @ HSR
274         mrc     p15, 4, r1, c6, c0, 2   @ HIFAR
275         str     r2, [vcpu, #VCPU_HSR]
276         str     r1, [vcpu, #VCPU_HxFAR]
277         .endif
278         mov     r1, #\exception_code
279         b       __kvm_vcpu_return
280
281         @ We were in the host already. Let's craft a panic-ing return to SVC.
282 99:     mrs     r2, cpsr
283         bic     r2, r2, #MODE_MASK
284         orr     r2, r2, #SVC_MODE
285 THUMB(  orr     r2, r2, #PSR_T_BIT      )
286         msr     spsr_cxsf, r2
287         mrs     r1, ELR_hyp
288         ldr     r2, =BSYM(panic)
289         msr     ELR_hyp, r2
290         ldr     r0, =\panic_str
291         eret
292 .endm
293
294         .text
295
296         .align 5
297 __kvm_hyp_vector:
298         .globl __kvm_hyp_vector
299
300         @ Hyp-mode exception vector
301         W(b)    hyp_reset
302         W(b)    hyp_undef
303         W(b)    hyp_svc
304         W(b)    hyp_pabt
305         W(b)    hyp_dabt
306         W(b)    hyp_hvc
307         W(b)    hyp_irq
308         W(b)    hyp_fiq
309
310         .align
311 hyp_reset:
312         b       hyp_reset
313
314         .align
315 hyp_undef:
316         bad_exception ARM_EXCEPTION_UNDEFINED, und_die_str
317
318         .align
319 hyp_svc:
320         bad_exception ARM_EXCEPTION_HVC, svc_die_str
321
322         .align
323 hyp_pabt:
324         bad_exception ARM_EXCEPTION_PREF_ABORT, pabt_die_str
325
326         .align
327 hyp_dabt:
328         bad_exception ARM_EXCEPTION_DATA_ABORT, dabt_die_str
329
330         .align
331 hyp_hvc:
332         /*
333          * Getting here is either becuase of a trap from a guest or from calling
334          * HVC from the host kernel, which means "switch to Hyp mode".
335          */
336         push    {r0, r1, r2}
337
338         @ Check syndrome register
339         mrc     p15, 4, r1, c5, c2, 0   @ HSR
340         lsr     r0, r1, #HSR_EC_SHIFT
341 #ifdef CONFIG_VFPv3
342         cmp     r0, #HSR_EC_CP_0_13
343         beq     switch_to_guest_vfp
344 #endif
345         cmp     r0, #HSR_EC_HVC
346         bne     guest_trap              @ Not HVC instr.
347
348         /*
349          * Let's check if the HVC came from VMID 0 and allow simple
350          * switch to Hyp mode
351          */
352         mrrc    p15, 6, r0, r2, c2
353         lsr     r2, r2, #16
354         and     r2, r2, #0xff
355         cmp     r2, #0
356         bne     guest_trap              @ Guest called HVC
357
358 host_switch_to_hyp:
359         pop     {r0, r1, r2}
360
361         push    {lr}
362         mrs     lr, SPSR
363         push    {lr}
364
365         mov     lr, r0
366         mov     r0, r1
367         mov     r1, r2
368         mov     r2, r3
369
370 THUMB(  orr     lr, #1)
371         blx     lr                      @ Call the HYP function
372
373         pop     {lr}
374         msr     SPSR_csxf, lr
375         pop     {lr}
376         eret
377
378 guest_trap:
379         load_vcpu                       @ Load VCPU pointer to r0
380         str     r1, [vcpu, #VCPU_HSR]
381
382         @ Check if we need the fault information
383         lsr     r1, r1, #HSR_EC_SHIFT
384         cmp     r1, #HSR_EC_IABT
385         mrceq   p15, 4, r2, c6, c0, 2   @ HIFAR
386         beq     2f
387         cmp     r1, #HSR_EC_DABT
388         bne     1f
389         mrc     p15, 4, r2, c6, c0, 0   @ HDFAR
390
391 2:      str     r2, [vcpu, #VCPU_HxFAR]
392
393         /*
394          * B3.13.5 Reporting exceptions taken to the Non-secure PL2 mode:
395          *
396          * Abort on the stage 2 translation for a memory access from a
397          * Non-secure PL1 or PL0 mode:
398          *
399          * For any Access flag fault or Translation fault, and also for any
400          * Permission fault on the stage 2 translation of a memory access
401          * made as part of a translation table walk for a stage 1 translation,
402          * the HPFAR holds the IPA that caused the fault. Otherwise, the HPFAR
403          * is UNKNOWN.
404          */
405
406         /* Check for permission fault, and S1PTW */
407         mrc     p15, 4, r1, c5, c2, 0   @ HSR
408         and     r0, r1, #HSR_FSC_TYPE
409         cmp     r0, #FSC_PERM
410         tsteq   r1, #(1 << 7)           @ S1PTW
411         mrcne   p15, 4, r2, c6, c0, 4   @ HPFAR
412         bne     3f
413
414         /* Resolve IPA using the xFAR */
415         mcr     p15, 0, r2, c7, c8, 0   @ ATS1CPR
416         isb
417         mrrc    p15, 0, r0, r1, c7      @ PAR
418         tst     r0, #1
419         bne     4f                      @ Failed translation
420         ubfx    r2, r0, #12, #20
421         lsl     r2, r2, #4
422         orr     r2, r2, r1, lsl #24
423
424 3:      load_vcpu                       @ Load VCPU pointer to r0
425         str     r2, [r0, #VCPU_HPFAR]
426
427 1:      mov     r1, #ARM_EXCEPTION_HVC
428         b       __kvm_vcpu_return
429
430 4:      pop     {r0, r1, r2}            @ Failed translation, return to guest
431         eret
432
433 /*
434  * If VFPv3 support is not available, then we will not switch the VFP
435  * registers; however cp10 and cp11 accesses will still trap and fallback
436  * to the regular coprocessor emulation code, which currently will
437  * inject an undefined exception to the guest.
438  */
439 #ifdef CONFIG_VFPv3
440 switch_to_guest_vfp:
441         load_vcpu                       @ Load VCPU pointer to r0
442         push    {r3-r7}
443
444         @ NEON/VFP used.  Turn on VFP access.
445         set_hcptr vmexit, (HCPTR_TCP(10) | HCPTR_TCP(11))
446
447         @ Switch VFP/NEON hardware state to the guest's
448         add     r7, r0, #VCPU_VFP_HOST
449         ldr     r7, [r7]
450         store_vfp_state r7
451         add     r7, r0, #VCPU_VFP_GUEST
452         restore_vfp_state r7
453
454         pop     {r3-r7}
455         pop     {r0-r2}
456         eret
457 #endif
458
459         .align
460 hyp_irq:
461         push    {r0, r1, r2}
462         mov     r1, #ARM_EXCEPTION_IRQ
463         load_vcpu                       @ Load VCPU pointer to r0
464         b       __kvm_vcpu_return
465
466         .align
467 hyp_fiq:
468         b       hyp_fiq
469
470         .ltorg
471
472 __kvm_hyp_code_end:
473         .globl  __kvm_hyp_code_end
474
475         .section ".rodata"
476
477 und_die_str:
478         .ascii  "unexpected undefined exception in Hyp mode at: %#08x"
479 pabt_die_str:
480         .ascii  "unexpected prefetch abort in Hyp mode at: %#08x"
481 dabt_die_str:
482         .ascii  "unexpected data abort in Hyp mode at: %#08x"
483 svc_die_str:
484         .ascii  "unexpected HVC/SVC trap in Hyp mode at: %#08x"