diff options
author | Marc Zyngier <marc.zyngier@arm.com> | 2015-10-22 03:32:18 -0400 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2015-12-14 06:30:40 -0500 |
commit | b97b66c14b96ab562e4fd516d804c5cd05c0529e (patch) | |
tree | 9ff79f98811d57e79e34781bfdf7c7938e8312b9 /arch/arm64/kvm | |
parent | 8eb992674c9e69d57af199f36b6455dbc00ac9f9 (diff) |
arm64: KVM: Implement guest entry
Contrary to the previous patch, the guest entry is fairly different
from its assembly counterpart, mostly because it is only concerned
with saving/restoring the GP registers, and nothing else.
Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
Diffstat (limited to 'arch/arm64/kvm')
-rw-r--r-- | arch/arm64/kvm/hyp/Makefile | 1 | ||||
-rw-r--r-- | arch/arm64/kvm/hyp/entry.S | 130 | ||||
-rw-r--r-- | arch/arm64/kvm/hyp/hyp.h | 2 |
3 files changed, 133 insertions, 0 deletions
diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile index ec14cacc21a6..1e1ff06348cd 100644 --- a/arch/arm64/kvm/hyp/Makefile +++ b/arch/arm64/kvm/hyp/Makefile | |||
@@ -7,3 +7,4 @@ obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o | |||
7 | obj-$(CONFIG_KVM_ARM_HOST) += timer-sr.o | 7 | obj-$(CONFIG_KVM_ARM_HOST) += timer-sr.o |
8 | obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o | 8 | obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o |
9 | obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o | 9 | obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o |
10 | obj-$(CONFIG_KVM_ARM_HOST) += entry.o | ||
diff --git a/arch/arm64/kvm/hyp/entry.S b/arch/arm64/kvm/hyp/entry.S new file mode 100644 index 000000000000..ff196951e63b --- /dev/null +++ b/arch/arm64/kvm/hyp/entry.S | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2015 - 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/asm-offsets.h> | ||
21 | #include <asm/assembler.h> | ||
22 | #include <asm/fpsimdmacros.h> | ||
23 | #include <asm/kvm.h> | ||
24 | #include <asm/kvm_arm.h> | ||
25 | #include <asm/kvm_asm.h> | ||
26 | #include <asm/kvm_mmu.h> | ||
27 | |||
28 | #define CPU_GP_REG_OFFSET(x) (CPU_GP_REGS + x) | ||
29 | #define CPU_XREG_OFFSET(x) CPU_GP_REG_OFFSET(CPU_USER_PT_REGS + 8*x) | ||
30 | |||
31 | .text | ||
32 | .pushsection .hyp.text, "ax" | ||
33 | |||
34 | .macro save_callee_saved_regs ctxt | ||
35 | stp x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)] | ||
36 | stp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)] | ||
37 | stp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)] | ||
38 | stp x25, x26, [\ctxt, #CPU_XREG_OFFSET(25)] | ||
39 | stp x27, x28, [\ctxt, #CPU_XREG_OFFSET(27)] | ||
40 | stp x29, lr, [\ctxt, #CPU_XREG_OFFSET(29)] | ||
41 | .endm | ||
42 | |||
43 | .macro restore_callee_saved_regs ctxt | ||
44 | ldp x19, x20, [\ctxt, #CPU_XREG_OFFSET(19)] | ||
45 | ldp x21, x22, [\ctxt, #CPU_XREG_OFFSET(21)] | ||
46 | ldp x23, x24, [\ctxt, #CPU_XREG_OFFSET(23)] | ||
47 | ldp x25, x26, [\ctxt, #CPU_XREG_OFFSET(25)] | ||
48 | ldp x27, x28, [\ctxt, #CPU_XREG_OFFSET(27)] | ||
49 | ldp x29, lr, [\ctxt, #CPU_XREG_OFFSET(29)] | ||
50 | .endm | ||
51 | |||
52 | /* | ||
53 | * u64 __guest_enter(struct kvm_vcpu *vcpu, | ||
54 | * struct kvm_cpu_context *host_ctxt); | ||
55 | */ | ||
56 | ENTRY(__guest_enter) | ||
57 | // x0: vcpu | ||
58 | // x1: host/guest context | ||
59 | // x2-x18: clobbered by macros | ||
60 | |||
61 | // Store the host regs | ||
62 | save_callee_saved_regs x1 | ||
63 | |||
64 | // Preserve vcpu & host_ctxt for use at exit time | ||
65 | stp x0, x1, [sp, #-16]! | ||
66 | |||
67 | add x1, x0, #VCPU_CONTEXT | ||
68 | |||
69 | // Prepare x0-x1 for later restore by pushing them onto the stack | ||
70 | ldp x2, x3, [x1, #CPU_XREG_OFFSET(0)] | ||
71 | stp x2, x3, [sp, #-16]! | ||
72 | |||
73 | // x2-x18 | ||
74 | ldp x2, x3, [x1, #CPU_XREG_OFFSET(2)] | ||
75 | ldp x4, x5, [x1, #CPU_XREG_OFFSET(4)] | ||
76 | ldp x6, x7, [x1, #CPU_XREG_OFFSET(6)] | ||
77 | ldp x8, x9, [x1, #CPU_XREG_OFFSET(8)] | ||
78 | ldp x10, x11, [x1, #CPU_XREG_OFFSET(10)] | ||
79 | ldp x12, x13, [x1, #CPU_XREG_OFFSET(12)] | ||
80 | ldp x14, x15, [x1, #CPU_XREG_OFFSET(14)] | ||
81 | ldp x16, x17, [x1, #CPU_XREG_OFFSET(16)] | ||
82 | ldr x18, [x1, #CPU_XREG_OFFSET(18)] | ||
83 | |||
84 | // x19-x29, lr | ||
85 | restore_callee_saved_regs x1 | ||
86 | |||
87 | // Last bits of the 64bit state | ||
88 | ldp x0, x1, [sp], #16 | ||
89 | |||
90 | // Do not touch any register after this! | ||
91 | eret | ||
92 | ENDPROC(__guest_enter) | ||
93 | |||
94 | ENTRY(__guest_exit) | ||
95 | // x0: vcpu | ||
96 | // x1: return code | ||
97 | // x2-x3: free | ||
98 | // x4-x29,lr: vcpu regs | ||
99 | // vcpu x0-x3 on the stack | ||
100 | |||
101 | add x2, x0, #VCPU_CONTEXT | ||
102 | |||
103 | stp x4, x5, [x2, #CPU_XREG_OFFSET(4)] | ||
104 | stp x6, x7, [x2, #CPU_XREG_OFFSET(6)] | ||
105 | stp x8, x9, [x2, #CPU_XREG_OFFSET(8)] | ||
106 | stp x10, x11, [x2, #CPU_XREG_OFFSET(10)] | ||
107 | stp x12, x13, [x2, #CPU_XREG_OFFSET(12)] | ||
108 | stp x14, x15, [x2, #CPU_XREG_OFFSET(14)] | ||
109 | stp x16, x17, [x2, #CPU_XREG_OFFSET(16)] | ||
110 | str x18, [x2, #CPU_XREG_OFFSET(18)] | ||
111 | |||
112 | ldp x6, x7, [sp], #16 // x2, x3 | ||
113 | ldp x4, x5, [sp], #16 // x0, x1 | ||
114 | |||
115 | stp x4, x5, [x2, #CPU_XREG_OFFSET(0)] | ||
116 | stp x6, x7, [x2, #CPU_XREG_OFFSET(2)] | ||
117 | |||
118 | save_callee_saved_regs x2 | ||
119 | |||
120 | // Restore vcpu & host_ctxt from the stack | ||
121 | // (preserving return code in x1) | ||
122 | ldp x0, x2, [sp], #16 | ||
123 | // Now restore the host regs | ||
124 | restore_callee_saved_regs x2 | ||
125 | |||
126 | mov x0, x1 | ||
127 | ret | ||
128 | ENDPROC(__guest_exit) | ||
129 | |||
130 | /* Insert fault handling here */ | ||
diff --git a/arch/arm64/kvm/hyp/hyp.h b/arch/arm64/kvm/hyp/hyp.h index 454e46f9c15e..080965348def 100644 --- a/arch/arm64/kvm/hyp/hyp.h +++ b/arch/arm64/kvm/hyp/hyp.h | |||
@@ -52,5 +52,7 @@ void __debug_restore_state(struct kvm_vcpu *vcpu, | |||
52 | void __debug_cond_save_host_state(struct kvm_vcpu *vcpu); | 52 | void __debug_cond_save_host_state(struct kvm_vcpu *vcpu); |
53 | void __debug_cond_restore_host_state(struct kvm_vcpu *vcpu); | 53 | void __debug_cond_restore_host_state(struct kvm_vcpu *vcpu); |
54 | 54 | ||
55 | u64 __guest_enter(struct kvm_vcpu *vcpu, struct kvm_cpu_context *host_ctxt); | ||
56 | |||
55 | #endif /* __ARM64_KVM_HYP_H__ */ | 57 | #endif /* __ARM64_KVM_HYP_H__ */ |
56 | 58 | ||