interrupts.S revision b20c9f29c5c25921c6ad18b50d4b61e6d181c3cc
1749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall/*
2749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall * Copyright (C) 2012 - Virtual Open Systems and Columbia University
3749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall * Author: Christoffer Dall <c.dall@virtualopensystems.com>
4749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall *
5749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall * This program is free software; you can redistribute it and/or modify
6749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall * it under the terms of the GNU General Public License, version 2, as
7749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall * published by the Free Software Foundation.
8749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall *
9749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall * This program is distributed in the hope that it will be useful,
10749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall * but WITHOUT ANY WARRANTY; without even the implied warranty of
11749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall * GNU General Public License for more details.
13749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall *
14749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall * You should have received a copy of the GNU General Public License
15749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall * along with this program; if not, write to the Free Software
16749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall */
18342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall
19342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall#include <linux/linkage.h>
20342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall#include <linux/const.h>
21342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall#include <asm/unified.h>
22342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall#include <asm/page.h>
23f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall#include <asm/ptrace.h>
24749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall#include <asm/asm-offsets.h>
25749cf76c5a363e1383108a914ea09530bfa0bd43Christoffer Dall#include <asm/kvm_asm.h>
26342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall#include <asm/kvm_arm.h>
27f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall#include <asm/vfpmacros.h>
28f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall#include "interrupts_head.S"
29342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall
30342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall	.text
31342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall
32342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall__kvm_hyp_code_start:
33342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall	.globl __kvm_hyp_code_start
34342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall
35342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall/********************************************************************
36342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * Flush per-VMID TLBs
37f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *
3848762767e1c150d58c250650f8202b7d4ad65ec4Marc Zyngier * void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
39f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *
40f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * We rely on the hardware to broadcast the TLB invalidation to all CPUs
41f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * inside the inner-shareable domain (which is the case for all v7
42f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * implementations).  If we come across a non-IS SMP implementation, we'll
43f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * have to use an IPI based mechanism. Until then, we stick to the simple
44f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * hardware assisted version.
4548762767e1c150d58c250650f8202b7d4ad65ec4Marc Zyngier *
4648762767e1c150d58c250650f8202b7d4ad65ec4Marc Zyngier * As v7 does not support flushing per IPA, just nuke the whole TLB
4748762767e1c150d58c250650f8202b7d4ad65ec4Marc Zyngier * instead, ignoring the ipa value.
48342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall */
4948762767e1c150d58c250650f8202b7d4ad65ec4Marc ZyngierENTRY(__kvm_tlb_flush_vmid_ipa)
50f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	push	{r2, r3}
51f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
52479c5ae2f8a55509b691494cd13691d3dc31d102Marc Zyngier	dsb	ishst
53f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	add	r0, r0, #KVM_VTTBR
54f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	ldrd	r2, r3, [r0]
55f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcrr	p15, 6, r2, r3, c2	@ Write VTTBR
56f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	isb
57f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcr     p15, 0, r0, c8, c3, 0	@ TLBIALLIS (rt ignored)
58e3ab547f57bd626201d4b715b696c80ad1ef4ba2Will Deacon	dsb	ish
59f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	isb
60f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	r2, #0
61f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	r3, #0
62f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcrr	p15, 6, r2, r3, c2	@ Back to VMID #0
63f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	isb				@ Not necessary if followed by eret
64f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
65f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	pop	{r2, r3}
66d5d8184d35c990b1324d9b30bcd0e4e8aa08f56dChristoffer Dall	bx	lr
6748762767e1c150d58c250650f8202b7d4ad65ec4Marc ZyngierENDPROC(__kvm_tlb_flush_vmid_ipa)
68d5d8184d35c990b1324d9b30bcd0e4e8aa08f56dChristoffer Dall
69d5d8184d35c990b1324d9b30bcd0e4e8aa08f56dChristoffer Dall/********************************************************************
70f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * Flush TLBs and instruction caches of all CPUs inside the inner-shareable
71f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * domain, for all VMIDs
72f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *
73f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * void __kvm_flush_vm_context(void);
74d5d8184d35c990b1324d9b30bcd0e4e8aa08f56dChristoffer Dall */
75342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer DallENTRY(__kvm_flush_vm_context)
76f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	r0, #0			@ rn parameter for c15 flushes is SBZ
77f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
78f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	/* Invalidate NS Non-Hyp TLB Inner Shareable (TLBIALLNSNHIS) */
79f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcr     p15, 4, r0, c8, c3, 4
80f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	/* Invalidate instruction caches Inner Shareable (ICIALLUIS) */
81f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcr     p15, 0, r0, c7, c1, 0
82e3ab547f57bd626201d4b715b696c80ad1ef4ba2Will Deacon	dsb	ish
83f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	isb				@ Not necessary if followed by eret
84f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
85342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall	bx	lr
86342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer DallENDPROC(__kvm_flush_vm_context)
87342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall
88f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
89342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall/********************************************************************
90342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall *  Hypervisor world-switch code
91f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *
92f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *
93f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * int __kvm_vcpu_run(struct kvm_vcpu *vcpu)
94342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall */
95342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer DallENTRY(__kvm_vcpu_run)
96f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Save the vcpu pointer
97f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcr	p15, 4, vcpu, c13, c0, 2	@ HTPIDR
98f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
99f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	save_host_regs
100f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
1011a89dd9113badd7487313410a5f2e09b2944f92bMarc Zyngier	restore_vgic_state
10253e724067a4ee9373972079e225d0d5f683b9c5aMarc Zyngier	restore_timer_state
1031a89dd9113badd7487313410a5f2e09b2944f92bMarc Zyngier
104f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Store hardware CP15 state and load guest state
105f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	read_cp15_state store_to_vcpu = 0
106f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	write_cp15_state read_from_vcpu = 1
107f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
108f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ If the host kernel has not been configured with VFPv3 support,
109f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ then it is safer if we deny guests from using it as well.
110f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall#ifdef CONFIG_VFPv3
111f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Set FPEXC_EN so the guest doesn't trap floating point instructions
112f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	VFPFMRX r2, FPEXC		@ VMRS
113f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	push	{r2}
114f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	orr	r2, r2, #FPEXC_EN
115f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	VFPFMXR FPEXC, r2		@ VMSR
116f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall#endif
117f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
118f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Configure Hyp-role
119f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	configure_hyp_role vmentry
120f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
121f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Trap coprocessor CRx accesses
122f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	set_hstr vmentry
123f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	set_hcptr vmentry, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11))
124f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	set_hdcr vmentry
125f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
126f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Write configured ID register into MIDR alias
127f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	ldr	r1, [vcpu, #VCPU_MIDR]
128f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcr	p15, 4, r1, c0, c0, 0
129f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
130f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Write guest view of MPIDR into VMPIDR
131f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	ldr	r1, [vcpu, #CP15_OFFSET(c0_MPIDR)]
132f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcr	p15, 4, r1, c0, c0, 5
133f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
134f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Set up guest memory translation
135f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	ldr	r1, [vcpu, #VCPU_KVM]
136f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	add	r1, r1, #KVM_VTTBR
137f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	ldrd	r2, r3, [r1]
138f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcrr	p15, 6, r2, r3, c2	@ Write VTTBR
139f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
140f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ We're all done, just restore the GPRs and go to the guest
141f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	restore_guest_regs
142f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	clrex				@ Clear exclusive monitor
143f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	eret
144f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
145f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall__kvm_vcpu_return:
146f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	/*
147f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * return convention:
148f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * guest r0, r1, r2 saved on the stack
149f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * r0: vcpu pointer
150f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * r1: exception code
151f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 */
152f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	save_guest_regs
153f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
154f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Set VMID == 0
155f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	r2, #0
156f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	r3, #0
157f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcrr	p15, 6, r2, r3, c2	@ Write VTTBR
158f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
159f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Don't trap coprocessor accesses for host kernel
160f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	set_hstr vmexit
161f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	set_hdcr vmexit
162f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	set_hcptr vmexit, (HCPTR_TTA | HCPTR_TCP(10) | HCPTR_TCP(11))
163f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
164f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall#ifdef CONFIG_VFPv3
165f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Save floating point registers we if let guest use them.
166f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	tst	r2, #(HCPTR_TCP(10) | HCPTR_TCP(11))
167f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	bne	after_vfp_restore
168f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
169f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Switch VFP/NEON hardware state to the host's
170f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	add	r7, vcpu, #VCPU_VFP_GUEST
171f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	store_vfp_state r7
172f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	add	r7, vcpu, #VCPU_VFP_HOST
173f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	ldr	r7, [r7]
174f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	restore_vfp_state r7
175f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
176f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallafter_vfp_restore:
177f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Restore FPEXC_EN which we clobbered on entry
178f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	pop	{r2}
179f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	VFPFMXR FPEXC, r2
180f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall#endif
181f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
182f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Reset Hyp-role
183f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	configure_hyp_role vmexit
184f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
185f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Let host read hardware MIDR
186f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrc	p15, 0, r2, c0, c0, 0
187f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcr	p15, 4, r2, c0, c0, 0
188f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
189f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Back to hardware MPIDR
190f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrc	p15, 0, r2, c0, c0, 5
191f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcr	p15, 4, r2, c0, c0, 5
192f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
193f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Store guest CP15 state and restore host state
194f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	read_cp15_state store_to_vcpu = 1
195f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	write_cp15_state read_from_vcpu = 0
196f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
19753e724067a4ee9373972079e225d0d5f683b9c5aMarc Zyngier	save_timer_state
1981a89dd9113badd7487313410a5f2e09b2944f92bMarc Zyngier	save_vgic_state
1991a89dd9113badd7487313410a5f2e09b2944f92bMarc Zyngier
200f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	restore_host_regs
201f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	clrex				@ Clear exclusive monitor
202f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	r0, r1			@ Return the return code
203f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	r1, #0			@ Clear upper bits in return value
204f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	bx	lr			@ return to IOCTL
205342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall
206342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall/********************************************************************
207342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall *  Call function in Hyp mode
208342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall *
209342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall *
210342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * u64 kvm_call_hyp(void *hypfn, ...);
211342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall *
212342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * This is not really a variadic function in the classic C-way and care must
213342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * be taken when calling this to ensure parameters are passed in registers
214342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * only, since the stack will change between the caller and the callee.
215342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall *
216342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * Call the function with the first argument containing a pointer to the
217342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * function you wish to call in Hyp mode, and subsequent arguments will be
218342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * passed as r0, r1, and r2 (a maximum of 3 arguments in addition to the
219342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * function pointer can be passed).  The function being called must be mapped
220342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c).  Return values are
221342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * passed in r0 and r1.
222342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall *
223b20c9f29c5c25921c6ad18b50d4b61e6d181c3ccMarc Zyngier * A function pointer with a value of 0xffffffff has a special meaning,
224b20c9f29c5c25921c6ad18b50d4b61e6d181c3ccMarc Zyngier * and is used to implement __hyp_get_vectors in the same way as in
225b20c9f29c5c25921c6ad18b50d4b61e6d181c3ccMarc Zyngier * arch/arm/kernel/hyp_stub.S.
226b20c9f29c5c25921c6ad18b50d4b61e6d181c3ccMarc Zyngier *
227342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * The calling convention follows the standard AAPCS:
228342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall *   r0 - r3: caller save
229342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall *   r12:     caller save
230342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall *   rest:    callee save
231342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall */
232342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer DallENTRY(kvm_call_hyp)
233342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall	hvc	#0
234342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall	bx	lr
235342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall
236342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall/********************************************************************
237342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall * Hypervisor exception vector and handlers
238f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *
239f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *
240f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * The KVM/ARM Hypervisor ABI is defined as follows:
241f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *
242f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * Entry to Hyp mode from the host kernel will happen _only_ when an HVC
243f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * instruction is issued since all traps are disabled when running the host
244f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * kernel as per the Hyp-mode initialization at boot time.
245f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *
2460b5e3bac30c545720f7e6b026241b5f8dd832df2Jonghwan Choi * HVC instructions cause a trap to the vector page + offset 0x14 (see hyp_hvc
247f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * below) when the HVC instruction is called from SVC mode (i.e. a guest or the
2480b5e3bac30c545720f7e6b026241b5f8dd832df2Jonghwan Choi * host kernel) and they cause a trap to the vector page + offset 0x8 when HVC
249f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * instructions are called from within Hyp-mode.
250f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *
251f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * Hyp-ABI: Calling HYP-mode functions from host (in SVC mode):
252f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *    Switching to Hyp mode is done through a simple HVC #0 instruction. The
253f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *    exception vector code will check that the HVC comes from VMID==0 and if
254f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *    so will push the necessary state (SPSR, lr_usr) on the Hyp stack.
255f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *    - r0 contains a pointer to a HYP function
256f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *    - r1, r2, and r3 contain arguments to the above function.
257f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *    - The HYP function will be called with its arguments in r0, r1 and r2.
258f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *    On HYP function return, we return directly to SVC.
259f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall *
260f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * Note that the above is used to execute code in Hyp-mode from a host-kernel
261f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * point of view, and is a different concept from performing a world-switch and
262f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * executing guest code SVC mode (with a VMID != 0).
263342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall */
264342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall
265f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall/* Handle undef, svc, pabt, or dabt by crashing with a user notice */
266f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall.macro bad_exception exception_code, panic_str
267f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	push	{r0-r2}
268f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrrc	p15, 6, r0, r1, c2	@ Read VTTBR
269f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	lsr	r1, r1, #16
270f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	ands	r1, r1, #0xff
271f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	beq	99f
272f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
273f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	load_vcpu			@ Load VCPU pointer
274f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.if \exception_code == ARM_EXCEPTION_DATA_ABORT
275f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrc	p15, 4, r2, c5, c2, 0	@ HSR
276f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrc	p15, 4, r1, c6, c0, 0	@ HDFAR
277f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	str	r2, [vcpu, #VCPU_HSR]
278f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	str	r1, [vcpu, #VCPU_HxFAR]
279f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.endif
280f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.if \exception_code == ARM_EXCEPTION_PREF_ABORT
281f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrc	p15, 4, r2, c5, c2, 0	@ HSR
282f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrc	p15, 4, r1, c6, c0, 2	@ HIFAR
283f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	str	r2, [vcpu, #VCPU_HSR]
284f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	str	r1, [vcpu, #VCPU_HxFAR]
285f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.endif
286f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	r1, #\exception_code
287f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	b	__kvm_vcpu_return
288f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
289f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ We were in the host already. Let's craft a panic-ing return to SVC.
290f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall99:	mrs	r2, cpsr
291f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	bic	r2, r2, #MODE_MASK
292f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	orr	r2, r2, #SVC_MODE
293f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer DallTHUMB(	orr	r2, r2, #PSR_T_BIT	)
294f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	msr	spsr_cxsf, r2
295f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrs	r1, ELR_hyp
296f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	ldr	r2, =BSYM(panic)
297f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	msr	ELR_hyp, r2
298f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	ldr	r0, =\panic_str
29922cfbb6d730ca2fda236b507d9fba17bf002736cMarc Zyngier	clrex				@ Clear exclusive monitor
300f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	eret
301f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall.endm
302f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
303f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.text
304f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
305342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall	.align 5
306342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall__kvm_hyp_vector:
307342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall	.globl __kvm_hyp_vector
308f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
309f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Hyp-mode exception vector
310f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	W(b)	hyp_reset
311f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	W(b)	hyp_undef
312f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	W(b)	hyp_svc
313f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	W(b)	hyp_pabt
314f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	W(b)	hyp_dabt
315f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	W(b)	hyp_hvc
316f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	W(b)	hyp_irq
317f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	W(b)	hyp_fiq
318f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
319f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.align
320f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallhyp_reset:
321f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	b	hyp_reset
322f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
323f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.align
324f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallhyp_undef:
325f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	bad_exception ARM_EXCEPTION_UNDEFINED, und_die_str
326f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
327f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.align
328f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallhyp_svc:
329f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	bad_exception ARM_EXCEPTION_HVC, svc_die_str
330f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
331f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.align
332f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallhyp_pabt:
333f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	bad_exception ARM_EXCEPTION_PREF_ABORT, pabt_die_str
334f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
335f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.align
336f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallhyp_dabt:
337f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	bad_exception ARM_EXCEPTION_DATA_ABORT, dabt_die_str
338f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
339f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.align
340f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallhyp_hvc:
341f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	/*
342f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * Getting here is either becuase of a trap from a guest or from calling
343f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * HVC from the host kernel, which means "switch to Hyp mode".
344f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 */
345f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	push	{r0, r1, r2}
346f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
347f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Check syndrome register
348f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrc	p15, 4, r1, c5, c2, 0	@ HSR
349f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	lsr	r0, r1, #HSR_EC_SHIFT
350f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall#ifdef CONFIG_VFPv3
351f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	cmp	r0, #HSR_EC_CP_0_13
352f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	beq	switch_to_guest_vfp
353f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall#endif
354f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	cmp	r0, #HSR_EC_HVC
355f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	bne	guest_trap		@ Not HVC instr.
356f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
357f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	/*
358f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * Let's check if the HVC came from VMID 0 and allow simple
359f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * switch to Hyp mode
360f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 */
361f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrrc    p15, 6, r0, r2, c2
362f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	lsr     r2, r2, #16
363f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	and     r2, r2, #0xff
364f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	cmp     r2, #0
365f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	bne	guest_trap		@ Guest called HVC
366f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
367f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallhost_switch_to_hyp:
368f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	pop	{r0, r1, r2}
369f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
370b20c9f29c5c25921c6ad18b50d4b61e6d181c3ccMarc Zyngier	/* Check for __hyp_get_vectors */
371b20c9f29c5c25921c6ad18b50d4b61e6d181c3ccMarc Zyngier	cmp	r0, #-1
372b20c9f29c5c25921c6ad18b50d4b61e6d181c3ccMarc Zyngier	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
373b20c9f29c5c25921c6ad18b50d4b61e6d181c3ccMarc Zyngier	beq	1f
374b20c9f29c5c25921c6ad18b50d4b61e6d181c3ccMarc Zyngier
375f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	push	{lr}
376f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrs	lr, SPSR
377f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	push	{lr}
378f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
379f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	lr, r0
380f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	r0, r1
381f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	r1, r2
382f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	r2, r3
383f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
384f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer DallTHUMB(	orr	lr, #1)
385f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	blx	lr			@ Call the HYP function
386f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
387f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	pop	{lr}
388f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	msr	SPSR_csxf, lr
389f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	pop	{lr}
390b20c9f29c5c25921c6ad18b50d4b61e6d181c3ccMarc Zyngier1:	eret
391f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
392f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallguest_trap:
393f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	load_vcpu			@ Load VCPU pointer to r0
394f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	str	r1, [vcpu, #VCPU_HSR]
395f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
396f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Check if we need the fault information
397f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	lsr	r1, r1, #HSR_EC_SHIFT
398f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	cmp	r1, #HSR_EC_IABT
399f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrceq	p15, 4, r2, c6, c0, 2	@ HIFAR
400f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	beq	2f
401f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	cmp	r1, #HSR_EC_DABT
402f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	bne	1f
403f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrc	p15, 4, r2, c6, c0, 0	@ HDFAR
404f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
405f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall2:	str	r2, [vcpu, #VCPU_HxFAR]
406f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
407f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	/*
408f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * B3.13.5 Reporting exceptions taken to the Non-secure PL2 mode:
409f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 *
410f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * Abort on the stage 2 translation for a memory access from a
411f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * Non-secure PL1 or PL0 mode:
412f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 *
413f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * For any Access flag fault or Translation fault, and also for any
414f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * Permission fault on the stage 2 translation of a memory access
415f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * made as part of a translation table walk for a stage 1 translation,
416f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * the HPFAR holds the IPA that caused the fault. Otherwise, the HPFAR
417f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 * is UNKNOWN.
418f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	 */
419f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
420f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	/* Check for permission fault, and S1PTW */
421f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrc	p15, 4, r1, c5, c2, 0	@ HSR
422f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	and	r0, r1, #HSR_FSC_TYPE
423f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	cmp	r0, #FSC_PERM
424f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	tsteq	r1, #(1 << 7)		@ S1PTW
425f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrcne	p15, 4, r2, c6, c0, 4	@ HPFAR
426f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	bne	3f
427f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
4286a077e4ab9cbfbf279fb955bae05b03781c97013Marc Zyngier	/* Preserve PAR */
4296a077e4ab9cbfbf279fb955bae05b03781c97013Marc Zyngier	mrrc	p15, 0, r0, r1, c7	@ PAR
4306a077e4ab9cbfbf279fb955bae05b03781c97013Marc Zyngier	push	{r0, r1}
4316a077e4ab9cbfbf279fb955bae05b03781c97013Marc Zyngier
432f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	/* Resolve IPA using the xFAR */
433f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mcr	p15, 0, r2, c7, c8, 0	@ ATS1CPR
434f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	isb
435f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mrrc	p15, 0, r0, r1, c7	@ PAR
436f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	tst	r0, #1
437f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	bne	4f			@ Failed translation
438f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	ubfx	r2, r0, #12, #20
439f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	lsl	r2, r2, #4
440f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	orr	r2, r2, r1, lsl #24
441f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
4426a077e4ab9cbfbf279fb955bae05b03781c97013Marc Zyngier	/* Restore PAR */
4436a077e4ab9cbfbf279fb955bae05b03781c97013Marc Zyngier	pop	{r0, r1}
4446a077e4ab9cbfbf279fb955bae05b03781c97013Marc Zyngier	mcrr	p15, 0, r0, r1, c7	@ PAR
4456a077e4ab9cbfbf279fb955bae05b03781c97013Marc Zyngier
446f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall3:	load_vcpu			@ Load VCPU pointer to r0
447f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	str	r2, [r0, #VCPU_HPFAR]
448f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
449f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall1:	mov	r1, #ARM_EXCEPTION_HVC
450f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	b	__kvm_vcpu_return
451f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
4526a077e4ab9cbfbf279fb955bae05b03781c97013Marc Zyngier4:	pop	{r0, r1}		@ Failed translation, return to guest
4536a077e4ab9cbfbf279fb955bae05b03781c97013Marc Zyngier	mcrr	p15, 0, r0, r1, c7	@ PAR
45422cfbb6d730ca2fda236b507d9fba17bf002736cMarc Zyngier	clrex
4556a077e4ab9cbfbf279fb955bae05b03781c97013Marc Zyngier	pop	{r0, r1, r2}
456f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	eret
457f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
458f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall/*
459f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * If VFPv3 support is not available, then we will not switch the VFP
460f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * registers; however cp10 and cp11 accesses will still trap and fallback
461f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * to the regular coprocessor emulation code, which currently will
462f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall * inject an undefined exception to the guest.
463f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall */
464f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall#ifdef CONFIG_VFPv3
465f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallswitch_to_guest_vfp:
466f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	load_vcpu			@ Load VCPU pointer to r0
467f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	push	{r3-r7}
468f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
469f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ NEON/VFP used.  Turn on VFP access.
470f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	set_hcptr vmexit, (HCPTR_TCP(10) | HCPTR_TCP(11))
471f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
472f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	@ Switch VFP/NEON hardware state to the guest's
473f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	add	r7, r0, #VCPU_VFP_HOST
474f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	ldr	r7, [r7]
475f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	store_vfp_state r7
476f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	add	r7, r0, #VCPU_VFP_GUEST
477f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	restore_vfp_state r7
478f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
479f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	pop	{r3-r7}
480f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	pop	{r0-r2}
48122cfbb6d730ca2fda236b507d9fba17bf002736cMarc Zyngier	clrex
482f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	eret
483f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall#endif
484f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
485f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.align
486f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallhyp_irq:
487f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	push	{r0, r1, r2}
488f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	mov	r1, #ARM_EXCEPTION_IRQ
489f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	load_vcpu			@ Load VCPU pointer to r0
490f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	b	__kvm_vcpu_return
491f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
492f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.align
493f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallhyp_fiq:
494f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	b	hyp_fiq
495f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
496f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.ltorg
497342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall
498342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall__kvm_hyp_code_end:
499342cd0ab0e6ca3fe7c88a78890352748b8e894a9Christoffer Dall	.globl	__kvm_hyp_code_end
500f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
501f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall	.section ".rodata"
502f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dall
503f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallund_die_str:
5041fe40f6d39d23f39e643607a3e1883bfc74f1244Christoffer Dall	.ascii	"unexpected undefined exception in Hyp mode at: %#08x\n"
505f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallpabt_die_str:
5061fe40f6d39d23f39e643607a3e1883bfc74f1244Christoffer Dall	.ascii	"unexpected prefetch abort in Hyp mode at: %#08x\n"
507f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dalldabt_die_str:
5081fe40f6d39d23f39e643607a3e1883bfc74f1244Christoffer Dall	.ascii	"unexpected data abort in Hyp mode at: %#08x\n"
509f7ed45be3ba524e06a6d933f0517dc7ad2d06703Christoffer Dallsvc_die_str:
5101fe40f6d39d23f39e643607a3e1883bfc74f1244Christoffer Dall	.ascii	"unexpected HVC/SVC trap in Hyp mode at: %#08x\n"
511