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