nvmm_x86.h revision 1.17 1 /* $NetBSD: nvmm_x86.h,v 1.17 2019/10/27 10:28:55 maxv Exp $ */
2
3 /*
4 * Copyright (c) 2018-2019 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Maxime Villard.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #ifndef _NVMM_X86_H_
33 #define _NVMM_X86_H_
34
35 /* -------------------------------------------------------------------------- */
36
37 #ifndef ASM_NVMM
38
39 struct nvmm_x86_exit_memory {
40 int prot;
41 gpaddr_t gpa;
42 uint8_t inst_len;
43 uint8_t inst_bytes[15];
44 };
45
46 struct nvmm_x86_exit_io {
47 bool in;
48 uint16_t port;
49 int8_t seg;
50 uint8_t address_size;
51 uint8_t operand_size;
52 bool rep;
53 bool str;
54 uint64_t npc;
55 };
56
57 struct nvmm_x86_exit_rdmsr {
58 uint32_t msr;
59 uint64_t npc;
60 };
61
62 struct nvmm_x86_exit_wrmsr {
63 uint32_t msr;
64 uint64_t val;
65 uint64_t npc;
66 };
67
68 struct nvmm_x86_exit_insn {
69 uint64_t npc;
70 };
71
72 struct nvmm_x86_exit_invalid {
73 uint64_t hwcode;
74 };
75
76 /* Generic. */
77 #define NVMM_VCPU_EXIT_NONE 0x0000000000000000ULL
78 #define NVMM_VCPU_EXIT_INVALID 0xFFFFFFFFFFFFFFFFULL
79 /* x86: operations. */
80 #define NVMM_VCPU_EXIT_MEMORY 0x0000000000000001ULL
81 #define NVMM_VCPU_EXIT_IO 0x0000000000000002ULL
82 /* x86: changes in VCPU state. */
83 #define NVMM_VCPU_EXIT_SHUTDOWN 0x0000000000001000ULL
84 #define NVMM_VCPU_EXIT_INT_READY 0x0000000000001001ULL
85 #define NVMM_VCPU_EXIT_NMI_READY 0x0000000000001002ULL
86 #define NVMM_VCPU_EXIT_HALTED 0x0000000000001003ULL
87 #define NVMM_VCPU_EXIT_TPR_CHANGED 0x0000000000001004ULL
88 /* x86: instructions. */
89 #define NVMM_VCPU_EXIT_RDMSR 0x0000000000002000ULL
90 #define NVMM_VCPU_EXIT_WRMSR 0x0000000000002001ULL
91 #define NVMM_VCPU_EXIT_MONITOR 0x0000000000002002ULL
92 #define NVMM_VCPU_EXIT_MWAIT 0x0000000000002003ULL
93 #define NVMM_VCPU_EXIT_CPUID 0x0000000000002004ULL
94
95 struct nvmm_x86_exit {
96 uint64_t reason;
97 union {
98 struct nvmm_x86_exit_memory mem;
99 struct nvmm_x86_exit_io io;
100 struct nvmm_x86_exit_rdmsr rdmsr;
101 struct nvmm_x86_exit_wrmsr wrmsr;
102 struct nvmm_x86_exit_insn insn;
103 struct nvmm_x86_exit_invalid inv;
104 } u;
105 uint64_t exitstate[8];
106 };
107
108 #define NVMM_VCPU_EVENT_EXCP 0
109 #define NVMM_VCPU_EVENT_INTR 1
110
111 struct nvmm_x86_event {
112 u_int type;
113 uint8_t vector;
114 union {
115 struct {
116 uint64_t error;
117 } excp;
118 } u;
119 };
120
121 struct nvmm_cap_md {
122 uint64_t mach_conf_support;
123
124 uint64_t vcpu_conf_support;
125 #define NVMM_CAP_ARCH_VCPU_CONF_CPUID __BIT(0)
126 #define NVMM_CAP_ARCH_VCPU_CONF_TPR __BIT(1)
127
128 uint64_t xcr0_mask;
129 uint32_t mxcsr_mask;
130 uint32_t conf_cpuid_maxops;
131 uint64_t rsvd[4];
132 };
133
134 #endif
135
136 /* -------------------------------------------------------------------------- */
137
138 /*
139 * Segment state indexes. We use X64 as naming convention, not to confuse with
140 * X86 which originally implied 32bit.
141 */
142
143 /* Segments. */
144 #define NVMM_X64_SEG_ES 0
145 #define NVMM_X64_SEG_CS 1
146 #define NVMM_X64_SEG_SS 2
147 #define NVMM_X64_SEG_DS 3
148 #define NVMM_X64_SEG_FS 4
149 #define NVMM_X64_SEG_GS 5
150 #define NVMM_X64_SEG_GDT 6
151 #define NVMM_X64_SEG_IDT 7
152 #define NVMM_X64_SEG_LDT 8
153 #define NVMM_X64_SEG_TR 9
154 #define NVMM_X64_NSEG 10
155
156 /* General Purpose Registers. */
157 #define NVMM_X64_GPR_RAX 0
158 #define NVMM_X64_GPR_RCX 1
159 #define NVMM_X64_GPR_RDX 2
160 #define NVMM_X64_GPR_RBX 3
161 #define NVMM_X64_GPR_RSP 4
162 #define NVMM_X64_GPR_RBP 5
163 #define NVMM_X64_GPR_RSI 6
164 #define NVMM_X64_GPR_RDI 7
165 #define NVMM_X64_GPR_R8 8
166 #define NVMM_X64_GPR_R9 9
167 #define NVMM_X64_GPR_R10 10
168 #define NVMM_X64_GPR_R11 11
169 #define NVMM_X64_GPR_R12 12
170 #define NVMM_X64_GPR_R13 13
171 #define NVMM_X64_GPR_R14 14
172 #define NVMM_X64_GPR_R15 15
173 #define NVMM_X64_GPR_RIP 16
174 #define NVMM_X64_GPR_RFLAGS 17
175 #define NVMM_X64_NGPR 18
176
177 /* Control Registers. */
178 #define NVMM_X64_CR_CR0 0
179 #define NVMM_X64_CR_CR2 1
180 #define NVMM_X64_CR_CR3 2
181 #define NVMM_X64_CR_CR4 3
182 #define NVMM_X64_CR_CR8 4
183 #define NVMM_X64_CR_XCR0 5
184 #define NVMM_X64_NCR 6
185
186 /* Debug Registers. */
187 #define NVMM_X64_DR_DR0 0
188 #define NVMM_X64_DR_DR1 1
189 #define NVMM_X64_DR_DR2 2
190 #define NVMM_X64_DR_DR3 3
191 #define NVMM_X64_DR_DR6 4
192 #define NVMM_X64_DR_DR7 5
193 #define NVMM_X64_NDR 6
194
195 /* MSRs. */
196 #define NVMM_X64_MSR_EFER 0
197 #define NVMM_X64_MSR_STAR 1
198 #define NVMM_X64_MSR_LSTAR 2
199 #define NVMM_X64_MSR_CSTAR 3
200 #define NVMM_X64_MSR_SFMASK 4
201 #define NVMM_X64_MSR_KERNELGSBASE 5
202 #define NVMM_X64_MSR_SYSENTER_CS 6
203 #define NVMM_X64_MSR_SYSENTER_ESP 7
204 #define NVMM_X64_MSR_SYSENTER_EIP 8
205 #define NVMM_X64_MSR_PAT 9
206 #define NVMM_X64_MSR_TSC 10
207 #define NVMM_X64_NMSR 11
208
209 #ifndef ASM_NVMM
210
211 #include <sys/types.h>
212 #include <x86/cpu_extended_state.h>
213
214 struct nvmm_x64_state_seg {
215 uint16_t selector;
216 struct { /* hidden */
217 uint16_t type:4;
218 uint16_t s:1;
219 uint16_t dpl:2;
220 uint16_t p:1;
221 uint16_t avl:1;
222 uint16_t l:1;
223 uint16_t def:1;
224 uint16_t g:1;
225 uint16_t rsvd:4;
226 } attrib;
227 uint32_t limit; /* hidden */
228 uint64_t base; /* hidden */
229 };
230
231 struct nvmm_x64_state_intr {
232 uint64_t int_shadow:1;
233 uint64_t int_window_exiting:1;
234 uint64_t nmi_window_exiting:1;
235 uint64_t evt_pending:1;
236 uint64_t rsvd:60;
237 };
238
239 /* VM exit state indexes. */
240 #define NVMM_X64_EXITSTATE_CR8 0
241 #define NVMM_X64_EXITSTATE_RFLAGS 1
242 #define NVMM_X64_EXITSTATE_INT_SHADOW 2
243 #define NVMM_X64_EXITSTATE_INT_WINDOW_EXIT 3
244 #define NVMM_X64_EXITSTATE_NMI_WINDOW_EXIT 4
245 #define NVMM_X64_EXITSTATE_EVT_PENDING 5
246
247 /* Flags. */
248 #define NVMM_X64_STATE_SEGS 0x01
249 #define NVMM_X64_STATE_GPRS 0x02
250 #define NVMM_X64_STATE_CRS 0x04
251 #define NVMM_X64_STATE_DRS 0x08
252 #define NVMM_X64_STATE_MSRS 0x10
253 #define NVMM_X64_STATE_INTR 0x20
254 #define NVMM_X64_STATE_FPU 0x40
255 #define NVMM_X64_STATE_ALL \
256 (NVMM_X64_STATE_SEGS | NVMM_X64_STATE_GPRS | NVMM_X64_STATE_CRS | \
257 NVMM_X64_STATE_DRS | NVMM_X64_STATE_MSRS | NVMM_X64_STATE_INTR | \
258 NVMM_X64_STATE_FPU)
259
260 struct nvmm_x64_state {
261 struct nvmm_x64_state_seg segs[NVMM_X64_NSEG];
262 uint64_t gprs[NVMM_X64_NGPR];
263 uint64_t crs[NVMM_X64_NCR];
264 uint64_t drs[NVMM_X64_NDR];
265 uint64_t msrs[NVMM_X64_NMSR];
266 struct nvmm_x64_state_intr intr;
267 struct fxsave fpu;
268 };
269
270 #define NVMM_VCPU_CONF_CPUID NVMM_VCPU_CONF_MD_BEGIN
271 #define NVMM_VCPU_CONF_TPR (NVMM_VCPU_CONF_MD_BEGIN + 1)
272
273 struct nvmm_vcpu_conf_cpuid {
274 /* The options. */
275 uint32_t mask:1;
276 uint32_t exit:1;
277 uint32_t rsvd:30;
278
279 /* The leaf. */
280 uint32_t leaf;
281
282 /* The params. */
283 union {
284 struct {
285 struct {
286 uint32_t eax;
287 uint32_t ebx;
288 uint32_t ecx;
289 uint32_t edx;
290 } set;
291 struct {
292 uint32_t eax;
293 uint32_t ebx;
294 uint32_t ecx;
295 uint32_t edx;
296 } del;
297 } mask;
298 } u;
299 };
300
301 struct nvmm_vcpu_conf_tpr {
302 uint32_t exit_changed:1;
303 uint32_t rsvd:31;
304 };
305
306 #define nvmm_vcpu_exit nvmm_x86_exit
307 #define nvmm_vcpu_event nvmm_x86_event
308 #define nvmm_vcpu_state nvmm_x64_state
309
310 #ifdef _KERNEL
311 #define NVMM_X86_MACH_NCONF 0
312 #define NVMM_X86_VCPU_NCONF 2
313 struct nvmm_x86_cpuid_mask {
314 uint32_t eax;
315 uint32_t ebx;
316 uint32_t ecx;
317 uint32_t edx;
318 };
319 extern const struct nvmm_x64_state nvmm_x86_reset_state;
320 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000001;
321 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000007;
322 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000001;
323 bool nvmm_x86_pat_validate(uint64_t);
324 #endif
325
326 #endif /* ASM_NVMM */
327
328 #endif /* _NVMM_X86_H_ */
329