nvmm_x86_vmxfunc.S revision 1.3.2.2 1 1.3.2.2 christos /* $NetBSD: nvmm_x86_vmxfunc.S,v 1.3.2.2 2019/06/10 22:07:14 christos Exp $ */
2 1.3.2.2 christos
3 1.3.2.2 christos /*
4 1.3.2.2 christos * Copyright (c) 2018 The NetBSD Foundation, Inc.
5 1.3.2.2 christos * All rights reserved.
6 1.3.2.2 christos *
7 1.3.2.2 christos * This code is derived from software contributed to The NetBSD Foundation
8 1.3.2.2 christos * by Maxime Villard.
9 1.3.2.2 christos *
10 1.3.2.2 christos * Redistribution and use in source and binary forms, with or without
11 1.3.2.2 christos * modification, are permitted provided that the following conditions
12 1.3.2.2 christos * are met:
13 1.3.2.2 christos * 1. Redistributions of source code must retain the above copyright
14 1.3.2.2 christos * notice, this list of conditions and the following disclaimer.
15 1.3.2.2 christos * 2. Redistributions in binary form must reproduce the above copyright
16 1.3.2.2 christos * notice, this list of conditions and the following disclaimer in the
17 1.3.2.2 christos * documentation and/or other materials provided with the distribution.
18 1.3.2.2 christos *
19 1.3.2.2 christos * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 1.3.2.2 christos * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 1.3.2.2 christos * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 1.3.2.2 christos * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 1.3.2.2 christos * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 1.3.2.2 christos * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 1.3.2.2 christos * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 1.3.2.2 christos * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 1.3.2.2 christos * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 1.3.2.2 christos * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 1.3.2.2 christos * POSSIBILITY OF SUCH DAMAGE.
30 1.3.2.2 christos */
31 1.3.2.2 christos
32 1.3.2.2 christos /* Override user-land alignment before including asm.h */
33 1.3.2.2 christos #define ALIGN_DATA .align 8
34 1.3.2.2 christos #define ALIGN_TEXT .align 16,0x90
35 1.3.2.2 christos #define _ALIGN_TEXT ALIGN_TEXT
36 1.3.2.2 christos
37 1.3.2.2 christos #define _LOCORE
38 1.3.2.2 christos #include "assym.h"
39 1.3.2.2 christos #include <machine/asm.h>
40 1.3.2.2 christos #include <machine/segments.h>
41 1.3.2.2 christos #include <x86/specialreg.h>
42 1.3.2.2 christos
43 1.3.2.2 christos #define ASM_NVMM
44 1.3.2.2 christos #include <dev/nvmm/x86/nvmm_x86.h>
45 1.3.2.2 christos
46 1.3.2.2 christos .text
47 1.3.2.2 christos
48 1.3.2.2 christos /*
49 1.3.2.2 christos * %rdi = *pa
50 1.3.2.2 christos */
51 1.3.2.2 christos ENTRY(_vmx_vmxon)
52 1.3.2.2 christos vmxon (%rdi)
53 1.3.2.2 christos jz .Lfail_vmxon
54 1.3.2.2 christos jc .Lfail_vmxon
55 1.3.2.2 christos xorq %rax,%rax
56 1.3.2.2 christos retq
57 1.3.2.2 christos .Lfail_vmxon:
58 1.3.2.2 christos movq $-1,%rax
59 1.3.2.2 christos retq
60 1.3.2.2 christos END(_vmx_vmxon)
61 1.3.2.2 christos
62 1.3.2.2 christos /*
63 1.3.2.2 christos * no arg
64 1.3.2.2 christos */
65 1.3.2.2 christos ENTRY(_vmx_vmxoff)
66 1.3.2.2 christos vmxoff
67 1.3.2.2 christos jz .Lfail_vmxoff
68 1.3.2.2 christos jc .Lfail_vmxoff
69 1.3.2.2 christos xorq %rax,%rax
70 1.3.2.2 christos retq
71 1.3.2.2 christos .Lfail_vmxoff:
72 1.3.2.2 christos movq $-1,%rax
73 1.3.2.2 christos retq
74 1.3.2.2 christos END(_vmx_vmxoff)
75 1.3.2.2 christos
76 1.3.2.2 christos /* redef */
77 1.3.2.2 christos #define VMCS_HOST_RSP 0x00006C14
78 1.3.2.2 christos
79 1.3.2.2 christos #define HOST_SAVE_GPRS \
80 1.3.2.2 christos pushq %rbx ;\
81 1.3.2.2 christos pushq %rbp ;\
82 1.3.2.2 christos pushq %r12 ;\
83 1.3.2.2 christos pushq %r13 ;\
84 1.3.2.2 christos pushq %r14 ;\
85 1.3.2.2 christos pushq %r15
86 1.3.2.2 christos
87 1.3.2.2 christos #define HOST_RESTORE_GPRS \
88 1.3.2.2 christos popq %r15 ;\
89 1.3.2.2 christos popq %r14 ;\
90 1.3.2.2 christos popq %r13 ;\
91 1.3.2.2 christos popq %r12 ;\
92 1.3.2.2 christos popq %rbp ;\
93 1.3.2.2 christos popq %rbx
94 1.3.2.2 christos
95 1.3.2.2 christos #define HOST_SAVE_RAX \
96 1.3.2.2 christos pushq %rax
97 1.3.2.2 christos
98 1.3.2.2 christos #define HOST_RESTORE_RAX \
99 1.3.2.2 christos popq %rax
100 1.3.2.2 christos
101 1.3.2.2 christos #define HOST_SAVE_LDT \
102 1.3.2.2 christos sldtw %ax ;\
103 1.3.2.2 christos pushw %ax
104 1.3.2.2 christos
105 1.3.2.2 christos #define HOST_RESTORE_LDT \
106 1.3.2.2 christos popw %ax ;\
107 1.3.2.2 christos lldtw %ax
108 1.3.2.2 christos
109 1.3.2.2 christos /*
110 1.3.2.2 christos * We don't save RAX (done manually), but we do restore it.
111 1.3.2.2 christos */
112 1.3.2.2 christos
113 1.3.2.2 christos #define GUEST_SAVE_GPRS(reg) \
114 1.3.2.2 christos movq %rcx,(NVMM_X64_GPR_RCX * 8)(reg) ;\
115 1.3.2.2 christos movq %rdx,(NVMM_X64_GPR_RDX * 8)(reg) ;\
116 1.3.2.2 christos movq %rbx,(NVMM_X64_GPR_RBX * 8)(reg) ;\
117 1.3.2.2 christos movq %rbp,(NVMM_X64_GPR_RBP * 8)(reg) ;\
118 1.3.2.2 christos movq %rsi,(NVMM_X64_GPR_RSI * 8)(reg) ;\
119 1.3.2.2 christos movq %rdi,(NVMM_X64_GPR_RDI * 8)(reg) ;\
120 1.3.2.2 christos movq %r8,(NVMM_X64_GPR_R8 * 8)(reg) ;\
121 1.3.2.2 christos movq %r9,(NVMM_X64_GPR_R9 * 8)(reg) ;\
122 1.3.2.2 christos movq %r10,(NVMM_X64_GPR_R10 * 8)(reg) ;\
123 1.3.2.2 christos movq %r11,(NVMM_X64_GPR_R11 * 8)(reg) ;\
124 1.3.2.2 christos movq %r12,(NVMM_X64_GPR_R12 * 8)(reg) ;\
125 1.3.2.2 christos movq %r13,(NVMM_X64_GPR_R13 * 8)(reg) ;\
126 1.3.2.2 christos movq %r14,(NVMM_X64_GPR_R14 * 8)(reg) ;\
127 1.3.2.2 christos movq %r15,(NVMM_X64_GPR_R15 * 8)(reg)
128 1.3.2.2 christos
129 1.3.2.2 christos #define GUEST_RESTORE_GPRS(reg) \
130 1.3.2.2 christos movq (NVMM_X64_GPR_RCX * 8)(reg),%rcx ;\
131 1.3.2.2 christos movq (NVMM_X64_GPR_RDX * 8)(reg),%rdx ;\
132 1.3.2.2 christos movq (NVMM_X64_GPR_RBX * 8)(reg),%rbx ;\
133 1.3.2.2 christos movq (NVMM_X64_GPR_RBP * 8)(reg),%rbp ;\
134 1.3.2.2 christos movq (NVMM_X64_GPR_RSI * 8)(reg),%rsi ;\
135 1.3.2.2 christos movq (NVMM_X64_GPR_RDI * 8)(reg),%rdi ;\
136 1.3.2.2 christos movq (NVMM_X64_GPR_R8 * 8)(reg),%r8 ;\
137 1.3.2.2 christos movq (NVMM_X64_GPR_R9 * 8)(reg),%r9 ;\
138 1.3.2.2 christos movq (NVMM_X64_GPR_R10 * 8)(reg),%r10 ;\
139 1.3.2.2 christos movq (NVMM_X64_GPR_R11 * 8)(reg),%r11 ;\
140 1.3.2.2 christos movq (NVMM_X64_GPR_R12 * 8)(reg),%r12 ;\
141 1.3.2.2 christos movq (NVMM_X64_GPR_R13 * 8)(reg),%r13 ;\
142 1.3.2.2 christos movq (NVMM_X64_GPR_R14 * 8)(reg),%r14 ;\
143 1.3.2.2 christos movq (NVMM_X64_GPR_R15 * 8)(reg),%r15 ;\
144 1.3.2.2 christos movq (NVMM_X64_GPR_RAX * 8)(reg),%rax
145 1.3.2.2 christos
146 1.3.2.2 christos /*
147 1.3.2.2 christos * %rdi = VA of guest GPR state
148 1.3.2.2 christos */
149 1.3.2.2 christos ENTRY(vmx_vmlaunch)
150 1.3.2.2 christos /* Save the Host GPRs. */
151 1.3.2.2 christos HOST_SAVE_GPRS
152 1.3.2.2 christos
153 1.3.2.2 christos /* Disable Host interrupts. */
154 1.3.2.2 christos cli
155 1.3.2.2 christos
156 1.3.2.2 christos /* Save the Host LDT. */
157 1.3.2.2 christos HOST_SAVE_LDT
158 1.3.2.2 christos
159 1.3.2.2 christos /* Save the Host RAX. */
160 1.3.2.2 christos movq %rdi,%rax
161 1.3.2.2 christos pushq %rax
162 1.3.2.2 christos
163 1.3.2.2 christos /* Save the Host RSP. */
164 1.3.2.2 christos movq $VMCS_HOST_RSP,%rdi
165 1.3.2.2 christos movq %rsp,%rsi
166 1.3.2.2 christos vmwrite %rsi,%rdi
167 1.3.2.2 christos
168 1.3.2.2 christos /* Restore the Guest GPRs. */
169 1.3.2.2 christos GUEST_RESTORE_GPRS(%rax)
170 1.3.2.2 christos
171 1.3.2.2 christos /* Run the VM. */
172 1.3.2.2 christos vmlaunch
173 1.3.2.2 christos
174 1.3.2.2 christos /* Failure. */
175 1.3.2.2 christos addq $8,%rsp
176 1.3.2.2 christos HOST_RESTORE_LDT
177 1.3.2.2 christos sti
178 1.3.2.2 christos HOST_RESTORE_GPRS
179 1.3.2.2 christos movq $-1,%rax
180 1.3.2.2 christos retq
181 1.3.2.2 christos END(vmx_vmlaunch)
182 1.3.2.2 christos
183 1.3.2.2 christos /*
184 1.3.2.2 christos * %rdi = VA of guest GPR state
185 1.3.2.2 christos */
186 1.3.2.2 christos ENTRY(vmx_vmresume)
187 1.3.2.2 christos /* Save the Host GPRs. */
188 1.3.2.2 christos HOST_SAVE_GPRS
189 1.3.2.2 christos
190 1.3.2.2 christos /* Disable Host interrupts. */
191 1.3.2.2 christos cli
192 1.3.2.2 christos
193 1.3.2.2 christos /* Save the Host LDT. */
194 1.3.2.2 christos HOST_SAVE_LDT
195 1.3.2.2 christos
196 1.3.2.2 christos /* Save the Host RAX. */
197 1.3.2.2 christos movq %rdi,%rax
198 1.3.2.2 christos pushq %rax
199 1.3.2.2 christos
200 1.3.2.2 christos /* Save the Host RSP. */
201 1.3.2.2 christos movq $VMCS_HOST_RSP,%rdi
202 1.3.2.2 christos movq %rsp,%rsi
203 1.3.2.2 christos vmwrite %rsi,%rdi
204 1.3.2.2 christos
205 1.3.2.2 christos /* Restore the Guest GPRs. */
206 1.3.2.2 christos GUEST_RESTORE_GPRS(%rax)
207 1.3.2.2 christos
208 1.3.2.2 christos /* Run the VM. */
209 1.3.2.2 christos vmresume
210 1.3.2.2 christos
211 1.3.2.2 christos /* Failure. */
212 1.3.2.2 christos addq $8,%rsp
213 1.3.2.2 christos HOST_RESTORE_LDT
214 1.3.2.2 christos sti
215 1.3.2.2 christos HOST_RESTORE_GPRS
216 1.3.2.2 christos movq $-1,%rax
217 1.3.2.2 christos retq
218 1.3.2.2 christos END(vmx_vmresume)
219 1.3.2.2 christos
220 1.3.2.2 christos /*
221 1.3.2.2 christos * The CPU jumps here after a #VMEXIT.
222 1.3.2.2 christos */
223 1.3.2.2 christos ENTRY(vmx_resume_rip)
224 1.3.2.2 christos /* Save the Guest GPRs. RAX done manually. */
225 1.3.2.2 christos pushq %rax
226 1.3.2.2 christos movq 8(%rsp),%rax
227 1.3.2.2 christos GUEST_SAVE_GPRS(%rax)
228 1.3.2.2 christos popq %rbx
229 1.3.2.2 christos movq %rbx,(NVMM_X64_GPR_RAX * 8)(%rax)
230 1.3.2.2 christos addq $8,%rsp
231 1.3.2.2 christos
232 1.3.2.2 christos /* Restore the Host LDT. */
233 1.3.2.2 christos HOST_RESTORE_LDT
234 1.3.2.2 christos
235 1.3.2.2 christos /* Enable Host interrupts. */
236 1.3.2.2 christos sti
237 1.3.2.2 christos
238 1.3.2.2 christos /* Restore the Host GPRs. */
239 1.3.2.2 christos HOST_RESTORE_GPRS
240 1.3.2.2 christos
241 1.3.2.2 christos xorq %rax,%rax
242 1.3.2.2 christos retq
243 1.3.2.2 christos END(vmx_resume_rip)
244 1.3.2.2 christos
245 1.3.2.2 christos ENTRY(vmx_insn_failvalid)
246 1.3.2.2 christos movq $.Lvmx_validstr,%rdi
247 1.3.2.2 christos call _C_LABEL(panic)
248 1.3.2.2 christos END(vmx_insn_failvalid)
249 1.3.2.2 christos
250 1.3.2.2 christos ENTRY(vmx_insn_failinvalid)
251 1.3.2.2 christos movq $.Lvmx_invalidstr,%rdi
252 1.3.2.2 christos call _C_LABEL(panic)
253 1.3.2.2 christos END(vmx_insn_failinvalid)
254 1.3.2.2 christos
255 1.3.2.2 christos .section ".rodata"
256 1.3.2.2 christos
257 1.3.2.2 christos .Lvmx_validstr:
258 1.3.2.2 christos .string "VMX fail valid\0"
259 1.3.2.2 christos .Lvmx_invalidstr:
260 1.3.2.2 christos .string "VMX fail invalid\0"
261