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