aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Zyngier <marc.zyngier@arm.com>2016-01-05 13:40:51 -0500
committerMarc Zyngier <marc.zyngier@arm.com>2016-02-29 13:34:13 -0500
commit89ef2b21ed2173e01995371261a9f9789bc1e47a (patch)
treea082baca9cc3ae93a67e840178757b16b49f1fc7
parent33280b4cd1dc0bc7df8d6d3bd1b64c377c9e44d9 (diff)
ARM: KVM: Add guest entry code
Add the very minimal piece of code that is now required to jump into the guest (and return from it). This code is only concerned with save/restoring the USR registers (r0-r12+lr for the guest, r4-r12+lr for the host), as everything else is dealt with in C (VFP is another matter though). Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r--arch/arm/kvm/hyp/Makefile1
-rw-r--r--arch/arm/kvm/hyp/entry.S70
-rw-r--r--arch/arm/kvm/hyp/hyp.h2
3 files changed, 73 insertions, 0 deletions
diff --git a/arch/arm/kvm/hyp/Makefile b/arch/arm/kvm/hyp/Makefile
index 173bd1dd77e7..c77969008665 100644
--- a/arch/arm/kvm/hyp/Makefile
+++ b/arch/arm/kvm/hyp/Makefile
@@ -8,3 +8,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += timer-sr.o
8obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o 8obj-$(CONFIG_KVM_ARM_HOST) += vgic-v2-sr.o
9obj-$(CONFIG_KVM_ARM_HOST) += vfp.o 9obj-$(CONFIG_KVM_ARM_HOST) += vfp.o
10obj-$(CONFIG_KVM_ARM_HOST) += banked-sr.o 10obj-$(CONFIG_KVM_ARM_HOST) += banked-sr.o
11obj-$(CONFIG_KVM_ARM_HOST) += entry.o
diff --git a/arch/arm/kvm/hyp/entry.S b/arch/arm/kvm/hyp/entry.S
new file mode 100644
index 000000000000..32f79b090040
--- /dev/null
+++ b/arch/arm/kvm/hyp/entry.S
@@ -0,0 +1,70 @@
1/*
2 * Copyright (C) 2016 - 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#include <asm/asm-offsets.h>
20#include <asm/kvm_arm.h>
21
22 .arch_extension virt
23
24 .text
25 .pushsection .hyp.text, "ax"
26
27#define USR_REGS_OFFSET (CPU_CTXT_GP_REGS + GP_REGS_USR)
28
29/* int __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host) */
30ENTRY(__guest_enter)
31 @ Save host registers
32 add r1, r1, #(USR_REGS_OFFSET + S_R4)
33 stm r1!, {r4-r12}
34 str lr, [r1, #4] @ Skip SP_usr (already saved)
35
36 @ Restore guest registers
37 add r0, r0, #(VCPU_GUEST_CTXT + USR_REGS_OFFSET + S_R0)
38 ldr lr, [r0, #S_LR]
39 ldm r0, {r0-r12}
40
41 clrex
42 eret
43ENDPROC(__guest_enter)
44
45ENTRY(__guest_exit)
46 /*
47 * return convention:
48 * guest r0, r1, r2 saved on the stack
49 * r0: vcpu pointer
50 * r1: exception code
51 */
52
53 add r2, r0, #(VCPU_GUEST_CTXT + USR_REGS_OFFSET + S_R3)
54 stm r2!, {r3-r12}
55 str lr, [r2, #4]
56 add r2, r0, #(VCPU_GUEST_CTXT + USR_REGS_OFFSET + S_R0)
57 pop {r3, r4, r5} @ r0, r1, r2
58 stm r2, {r3-r5}
59
60 ldr r0, [r0, #VCPU_HOST_CTXT]
61 add r0, r0, #(USR_REGS_OFFSET + S_R4)
62 ldm r0!, {r4-r12}
63 ldr lr, [r0, #4]
64
65 mov r0, r1
66 bx lr
67ENDPROC(__guest_exit)
68
69 .popsection
70
diff --git a/arch/arm/kvm/hyp/hyp.h b/arch/arm/kvm/hyp/hyp.h
index 278eb1fa5231..b3f6ed233564 100644
--- a/arch/arm/kvm/hyp/hyp.h
+++ b/arch/arm/kvm/hyp/hyp.h
@@ -110,4 +110,6 @@ static inline bool __vfp_enabled(void)
110void __hyp_text __banked_save_state(struct kvm_cpu_context *ctxt); 110void __hyp_text __banked_save_state(struct kvm_cpu_context *ctxt);
111void __hyp_text __banked_restore_state(struct kvm_cpu_context *ctxt); 111void __hyp_text __banked_restore_state(struct kvm_cpu_context *ctxt);
112 112
113int asmlinkage __guest_enter(struct kvm_vcpu *vcpu,
114 struct kvm_cpu_context *host);
113#endif /* __ARM_KVM_HYP_H__ */ 115#endif /* __ARM_KVM_HYP_H__ */