xref: /dragonfly/sys/dev/virtual/nvmm/x86/nvmm_x86.h (revision b3f7271ce8a6736910e3e66d2fff5ddf4bd2c570)
1 /*
2  * Copyright (c) 2018-2021 Maxime Villard, m00nbsd.net
3  * All rights reserved.
4  *
5  * This code is part of the NVMM hypervisor.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #ifndef _NVMM_X86_H_
30 #define _NVMM_X86_H_
31 
32 #if defined(__NetBSD__)
33 #include <x86/specialreg.h>
34 #elif defined(__DragonFly__)
35 #include <machine/specialreg.h>
36 #endif
37 
38 /* -------------------------------------------------------------------------- */
39 
40 #ifndef ASM_NVMM
41 
42 struct nvmm_x86_exit_memory {
43           int prot;
44           gpaddr_t gpa;
45           uint8_t inst_len;
46           uint8_t inst_bytes[15];
47 };
48 
49 struct nvmm_x86_exit_io {
50           bool in;
51           uint16_t port;
52           int8_t seg;
53           uint8_t address_size;
54           uint8_t operand_size;
55           bool rep;
56           bool str;
57           uint64_t npc;
58 };
59 
60 struct nvmm_x86_exit_rdmsr {
61           uint32_t msr;
62           uint64_t npc;
63 };
64 
65 struct nvmm_x86_exit_wrmsr {
66           uint32_t msr;
67           uint64_t val;
68           uint64_t npc;
69 };
70 
71 struct nvmm_x86_exit_insn {
72           uint64_t npc;
73 };
74 
75 struct nvmm_x86_exit_invalid {
76           uint64_t hwcode;
77 };
78 
79 /* Generic. */
80 #define NVMM_VCPU_EXIT_NONE             0x0000000000000000ULL
81 #define NVMM_VCPU_EXIT_INVALID                    0xFFFFFFFFFFFFFFFFULL
82 /* x86: operations. */
83 #define NVMM_VCPU_EXIT_MEMORY           0x0000000000000001ULL
84 #define NVMM_VCPU_EXIT_IO               0x0000000000000002ULL
85 /* x86: changes in VCPU state. */
86 #define NVMM_VCPU_EXIT_SHUTDOWN                   0x0000000000001000ULL
87 #define NVMM_VCPU_EXIT_INT_READY        0x0000000000001001ULL
88 #define NVMM_VCPU_EXIT_NMI_READY        0x0000000000001002ULL
89 #define NVMM_VCPU_EXIT_HALTED           0x0000000000001003ULL
90 #define NVMM_VCPU_EXIT_TPR_CHANGED      0x0000000000001004ULL
91 /* x86: instructions. */
92 #define NVMM_VCPU_EXIT_RDMSR            0x0000000000002000ULL
93 #define NVMM_VCPU_EXIT_WRMSR            0x0000000000002001ULL
94 #define NVMM_VCPU_EXIT_MONITOR                    0x0000000000002002ULL
95 #define NVMM_VCPU_EXIT_MWAIT            0x0000000000002003ULL
96 #define NVMM_VCPU_EXIT_CPUID            0x0000000000002004ULL
97 
98 struct nvmm_x86_exit {
99           uint64_t reason;
100           union {
101                     struct nvmm_x86_exit_memory mem;
102                     struct nvmm_x86_exit_io io;
103                     struct nvmm_x86_exit_rdmsr rdmsr;
104                     struct nvmm_x86_exit_wrmsr wrmsr;
105                     struct nvmm_x86_exit_insn insn;
106                     struct nvmm_x86_exit_invalid inv;
107           } u;
108           struct {
109                     uint64_t rflags;
110                     uint64_t cr8;
111                     uint64_t int_shadow:1;
112                     uint64_t int_window_exiting:1;
113                     uint64_t nmi_window_exiting:1;
114                     uint64_t evt_pending:1;
115                     uint64_t rsvd:60;
116           } exitstate;
117 };
118 #define nvmm_vcpu_exit                  nvmm_x86_exit
119 
120 #define NVMM_VCPU_EVENT_EXCP  0
121 #define NVMM_VCPU_EVENT_INTR  1
122 
123 struct nvmm_x86_event {
124           u_int type;
125           uint8_t vector;
126           union {
127                     struct {
128                               uint64_t error;
129                     } excp;
130           } u;
131 };
132 #define nvmm_vcpu_event                 nvmm_x86_event
133 
134 struct nvmm_cap_md {
135           uint64_t mach_conf_support;
136 
137           uint64_t vcpu_conf_support;
138 #define NVMM_CAP_ARCH_VCPU_CONF_CPUID   __BIT(0)
139 #define NVMM_CAP_ARCH_VCPU_CONF_TPR     __BIT(1)
140 
141           uint64_t xcr0_mask;
142           uint32_t mxcsr_mask;
143           uint32_t conf_cpuid_maxops;
144           uint64_t rsvd[6];
145 };
146 
147 #endif /* ASM_NVMM */
148 
149 /* -------------------------------------------------------------------------- */
150 
151 /*
152  * State indexes. We use X64 as naming convention, not to confuse with X86
153  * which originally implied 32bit.
154  */
155 
156 /* Segments. */
157 #define NVMM_X64_SEG_ES                           0
158 #define NVMM_X64_SEG_CS                           1
159 #define NVMM_X64_SEG_SS                           2
160 #define NVMM_X64_SEG_DS                           3
161 #define NVMM_X64_SEG_FS                           4
162 #define NVMM_X64_SEG_GS                           5
163 #define NVMM_X64_SEG_GDT                6
164 #define NVMM_X64_SEG_IDT                7
165 #define NVMM_X64_SEG_LDT                8
166 #define NVMM_X64_SEG_TR                           9
167 #define NVMM_X64_NSEG                             10
168 
169 /* General Purpose Registers. */
170 #define NVMM_X64_GPR_RAX                0
171 #define NVMM_X64_GPR_RCX                1
172 #define NVMM_X64_GPR_RDX                2
173 #define NVMM_X64_GPR_RBX                3
174 #define NVMM_X64_GPR_RSP                4
175 #define NVMM_X64_GPR_RBP                5
176 #define NVMM_X64_GPR_RSI                6
177 #define NVMM_X64_GPR_RDI                7
178 #define NVMM_X64_GPR_R8                           8
179 #define NVMM_X64_GPR_R9                           9
180 #define NVMM_X64_GPR_R10                10
181 #define NVMM_X64_GPR_R11                11
182 #define NVMM_X64_GPR_R12                12
183 #define NVMM_X64_GPR_R13                13
184 #define NVMM_X64_GPR_R14                14
185 #define NVMM_X64_GPR_R15                15
186 #define NVMM_X64_GPR_RIP                16
187 #define NVMM_X64_GPR_RFLAGS             17
188 #define NVMM_X64_NGPR                             18
189 
190 /* Control Registers. */
191 #define NVMM_X64_CR_CR0                           0
192 #define NVMM_X64_CR_CR2                           1
193 #define NVMM_X64_CR_CR3                           2
194 #define NVMM_X64_CR_CR4                           3
195 #define NVMM_X64_CR_CR8                           4
196 #define NVMM_X64_CR_XCR0                5
197 #define NVMM_X64_NCR                              6
198 
199 /* Debug Registers. */
200 #define NVMM_X64_DR_DR0                           0
201 #define NVMM_X64_DR_DR1                           1
202 #define NVMM_X64_DR_DR2                           2
203 #define NVMM_X64_DR_DR3                           3
204 #define NVMM_X64_DR_DR6                           4
205 #define NVMM_X64_DR_DR7                           5
206 #define NVMM_X64_NDR                              6
207 
208 /* MSRs. */
209 #define NVMM_X64_MSR_EFER               0
210 #define NVMM_X64_MSR_STAR               1
211 #define NVMM_X64_MSR_LSTAR              2
212 #define NVMM_X64_MSR_CSTAR              3
213 #define NVMM_X64_MSR_SFMASK             4
214 #define NVMM_X64_MSR_KERNELGSBASE       5
215 #define NVMM_X64_MSR_SYSENTER_CS        6
216 #define NVMM_X64_MSR_SYSENTER_ESP       7
217 #define NVMM_X64_MSR_SYSENTER_EIP       8
218 #define NVMM_X64_MSR_PAT                9
219 #define NVMM_X64_MSR_TSC                10
220 #define NVMM_X64_NMSR                             11
221 
222 #ifndef ASM_NVMM
223 
224 #include <sys/types.h>
225 #include <sys/bitops.h>
226 #if defined(__DragonFly__)
227 #ifdef __x86_64__
228 #undef  __BIT
229 #define __BIT(__n)            __BIT64(__n)
230 #undef  __BITS
231 #define __BITS(__m, __n)      __BITS64(__m, __n)
232 #endif /* __x86_64__ */
233 #endif
234 
235 /* Segment state. */
236 struct nvmm_x64_state_seg {
237           uint16_t selector;
238           struct {            /* hidden */
239                     uint16_t type:4;
240                     uint16_t s:1;
241                     uint16_t dpl:2;
242                     uint16_t p:1;
243                     uint16_t avl:1;
244                     uint16_t l:1;
245                     uint16_t def:1;
246                     uint16_t g:1;
247                     uint16_t rsvd:4;
248           } attrib;
249           uint32_t limit;               /* hidden */
250           uint64_t base;                /* hidden */
251 };
252 
253 /* Interrupt state. */
254 struct nvmm_x64_state_intr {
255           uint64_t int_shadow:1;
256           uint64_t int_window_exiting:1;
257           uint64_t nmi_window_exiting:1;
258           uint64_t evt_pending:1;
259           uint64_t rsvd:60;
260 };
261 
262 /* FPU state structures. */
263 union nvmm_x64_state_fpu_addr {
264           uint64_t fa_64;
265           struct {
266                     uint32_t fa_off;
267                     uint16_t fa_seg;
268                     uint16_t fa_opcode;
269           } fa_32;
270 };
271 CTASSERT(sizeof(union nvmm_x64_state_fpu_addr) == 8);
272 struct nvmm_x64_state_fpu_mmreg {
273           uint64_t mm_significand;
274           uint16_t mm_exp_sign;
275           uint8_t  mm_rsvd[6];
276 };
277 CTASSERT(sizeof(struct nvmm_x64_state_fpu_mmreg) == 16);
278 struct nvmm_x64_state_fpu_xmmreg {
279           uint8_t xmm_bytes[16];
280 };
281 CTASSERT(sizeof(struct nvmm_x64_state_fpu_xmmreg) == 16);
282 
283 /* FPU state (x87 + SSE). */
284 struct nvmm_x64_state_fpu {
285           uint16_t fx_cw;               /* Control Word */
286           uint16_t fx_sw;               /* Status Word */
287           uint8_t fx_tw;                /* Tag Word */
288           uint8_t fx_zero;
289           uint16_t fx_opcode;
290           union nvmm_x64_state_fpu_addr fx_ip;    /* Instruction Pointer */
291           union nvmm_x64_state_fpu_addr fx_dp;    /* Data pointer */
292           uint32_t fx_mxcsr;
293           uint32_t fx_mxcsr_mask;
294           struct nvmm_x64_state_fpu_mmreg fx_87_ac[8];      /* x87 registers */
295           struct nvmm_x64_state_fpu_xmmreg fx_xmm[16];      /* XMM registers */
296           uint8_t fx_rsvd[96];
297 } __aligned(16);
298 CTASSERT(sizeof(struct nvmm_x64_state_fpu) == 512);
299 
300 /* Flags. */
301 #define NVMM_X64_STATE_SEGS   0x01
302 #define NVMM_X64_STATE_GPRS   0x02
303 #define NVMM_X64_STATE_CRS    0x04
304 #define NVMM_X64_STATE_DRS    0x08
305 #define NVMM_X64_STATE_MSRS   0x10
306 #define NVMM_X64_STATE_INTR   0x20
307 #define NVMM_X64_STATE_FPU    0x40
308 #define NVMM_X64_STATE_ALL    \
309           (NVMM_X64_STATE_SEGS | NVMM_X64_STATE_GPRS | NVMM_X64_STATE_CRS | \
310            NVMM_X64_STATE_DRS | NVMM_X64_STATE_MSRS | NVMM_X64_STATE_INTR | \
311            NVMM_X64_STATE_FPU)
312 
313 struct nvmm_x64_state {
314           struct nvmm_x64_state_seg segs[NVMM_X64_NSEG];
315           uint64_t gprs[NVMM_X64_NGPR];
316           uint64_t crs[NVMM_X64_NCR];
317           uint64_t drs[NVMM_X64_NDR];
318           uint64_t msrs[NVMM_X64_NMSR];
319           struct nvmm_x64_state_intr intr;
320           struct nvmm_x64_state_fpu fpu;
321 };
322 #define nvmm_vcpu_state                 nvmm_x64_state
323 
324 /* -------------------------------------------------------------------------- */
325 
326 #define NVMM_VCPU_CONF_CPUID  NVMM_VCPU_CONF_MD_BEGIN
327 #define NVMM_VCPU_CONF_TPR    (NVMM_VCPU_CONF_MD_BEGIN + 1)
328 
329 struct nvmm_vcpu_conf_cpuid {
330           /* The options. */
331           uint32_t mask:1;
332           uint32_t exit:1;
333           uint32_t rsvd:30;
334 
335           /* The leaf. */
336           uint32_t leaf;
337 
338           /* The params. */
339           union {
340                     struct {
341                               struct {
342                                         uint32_t eax;
343                                         uint32_t ebx;
344                                         uint32_t ecx;
345                                         uint32_t edx;
346                               } set;
347                               struct {
348                                         uint32_t eax;
349                                         uint32_t ebx;
350                                         uint32_t ecx;
351                                         uint32_t edx;
352                               } del;
353                     } mask;
354           } u;
355 };
356 
357 struct nvmm_vcpu_conf_tpr {
358           uint32_t exit_changed:1;
359           uint32_t rsvd:31;
360 };
361 
362 /* -------------------------------------------------------------------------- */
363 
364 /*
365  * CPUID defines.
366  */
367 
368 /* Fn0000_0001:EBX */
369 #define CPUID_0_01_EBX_BRAND_INDEX      __BITS(7,0)
370 #define CPUID_0_01_EBX_CLFLUSH_SIZE     __BITS(15,8)
371 #define CPUID_0_01_EBX_HTT_CORES        __BITS(23,16)
372 #define CPUID_0_01_EBX_LOCAL_APIC_ID    __BITS(31,24)
373 /* Fn0000_0001:ECX */
374 #define CPUID_0_01_ECX_SSE3             __BIT(0)
375 #define CPUID_0_01_ECX_PCLMULQDQ        __BIT(1)
376 #define CPUID_0_01_ECX_DTES64           __BIT(2)
377 #define CPUID_0_01_ECX_MONITOR                    __BIT(3)
378 #define CPUID_0_01_ECX_DS_CPL           __BIT(4)
379 #define CPUID_0_01_ECX_VMX              __BIT(5)
380 #define CPUID_0_01_ECX_SMX              __BIT(6)
381 #define CPUID_0_01_ECX_EIST             __BIT(7)
382 #define CPUID_0_01_ECX_TM2              __BIT(8)
383 #define CPUID_0_01_ECX_SSSE3            __BIT(9)
384 #define CPUID_0_01_ECX_CNXTID           __BIT(10)
385 #define CPUID_0_01_ECX_SDBG             __BIT(11)
386 #define CPUID_0_01_ECX_FMA              __BIT(12)
387 #define CPUID_0_01_ECX_CX16             __BIT(13)
388 #define CPUID_0_01_ECX_XTPR             __BIT(14)
389 #define CPUID_0_01_ECX_PDCM             __BIT(15)
390 #define CPUID_0_01_ECX_PCID             __BIT(17)
391 #define CPUID_0_01_ECX_DCA              __BIT(18)
392 #define CPUID_0_01_ECX_SSE41            __BIT(19)
393 #define CPUID_0_01_ECX_SSE42            __BIT(20)
394 #define CPUID_0_01_ECX_X2APIC           __BIT(21)
395 #define CPUID_0_01_ECX_MOVBE            __BIT(22)
396 #define CPUID_0_01_ECX_POPCNT           __BIT(23)
397 #define CPUID_0_01_ECX_TSC_DEADLINE     __BIT(24)
398 #define CPUID_0_01_ECX_AESNI            __BIT(25)
399 #define CPUID_0_01_ECX_XSAVE            __BIT(26)
400 #define CPUID_0_01_ECX_OSXSAVE                    __BIT(27)
401 #define CPUID_0_01_ECX_AVX              __BIT(28)
402 #define CPUID_0_01_ECX_F16C             __BIT(29)
403 #define CPUID_0_01_ECX_RDRAND           __BIT(30)
404 #define CPUID_0_01_ECX_RAZ              __BIT(31)
405 /* Fn0000_0001:EDX */
406 #define CPUID_0_01_EDX_FPU              __BIT(0)
407 #define CPUID_0_01_EDX_VME              __BIT(1)
408 #define CPUID_0_01_EDX_DE               __BIT(2)
409 #define CPUID_0_01_EDX_PSE              __BIT(3)
410 #define CPUID_0_01_EDX_TSC              __BIT(4)
411 #define CPUID_0_01_EDX_MSR              __BIT(5)
412 #define CPUID_0_01_EDX_PAE              __BIT(6)
413 #define CPUID_0_01_EDX_MCE              __BIT(7)
414 #define CPUID_0_01_EDX_CX8              __BIT(8)
415 #define CPUID_0_01_EDX_APIC             __BIT(9)
416 #define CPUID_0_01_EDX_SEP              __BIT(11)
417 #define CPUID_0_01_EDX_MTRR             __BIT(12)
418 #define CPUID_0_01_EDX_PGE              __BIT(13)
419 #define CPUID_0_01_EDX_MCA              __BIT(14)
420 #define CPUID_0_01_EDX_CMOV             __BIT(15)
421 #define CPUID_0_01_EDX_PAT              __BIT(16)
422 #define CPUID_0_01_EDX_PSE36            __BIT(17)
423 #define CPUID_0_01_EDX_PSN              __BIT(18)
424 #define CPUID_0_01_EDX_CLFSH            __BIT(19)
425 #define CPUID_0_01_EDX_DS               __BIT(21)
426 #define CPUID_0_01_EDX_ACPI             __BIT(22)
427 #define CPUID_0_01_EDX_MMX              __BIT(23)
428 #define CPUID_0_01_EDX_FXSR             __BIT(24)
429 #define CPUID_0_01_EDX_SSE              __BIT(25)
430 #define CPUID_0_01_EDX_SSE2             __BIT(26)
431 #define CPUID_0_01_EDX_SS               __BIT(27)
432 #define CPUID_0_01_EDX_HTT              __BIT(28)
433 #define CPUID_0_01_EDX_TM               __BIT(29)
434 #define CPUID_0_01_EDX_PBE              __BIT(31)
435 
436 /* Fn0000_0004:EAX (Intel Deterministic Cache Parameter Leaf) */
437 #define CPUID_0_04_EAX_CACHETYPE        __BITS(4, 0)
438 #define CPUID_0_04_EAX_CACHETYPE_NULL             0
439 #define CPUID_0_04_EAX_CACHETYPE_DATA             1
440 #define CPUID_0_04_EAX_CACHETYPE_INSN             2
441 #define CPUID_0_04_EAX_CACHETYPE_UNIFIED          3
442 #define CPUID_0_04_EAX_CACHELEVEL       __BITS(7, 5)
443 #define CPUID_0_04_EAX_SELFINITCL       __BIT(8)
444 #define CPUID_0_04_EAX_FULLASSOC        __BIT(9)
445 #define CPUID_0_04_EAX_SHARING                    __BITS(25, 14)
446 #define CPUID_0_04_EAX_CORE_P_PKG       __BITS(31, 26)
447 
448 /* [ECX=0] Fn0000_0007:EBX (Structured Extended Features) */
449 #define CPUID_0_07_EBX_FSGSBASE                   __BIT(0)
450 #define CPUID_0_07_EBX_TSC_ADJUST       __BIT(1)
451 #define CPUID_0_07_EBX_SGX              __BIT(2)
452 #define CPUID_0_07_EBX_BMI1             __BIT(3)
453 #define CPUID_0_07_EBX_HLE              __BIT(4)
454 #define CPUID_0_07_EBX_AVX2             __BIT(5)
455 #define CPUID_0_07_EBX_FDPEXONLY        __BIT(6)
456 #define CPUID_0_07_EBX_SMEP             __BIT(7)
457 #define CPUID_0_07_EBX_BMI2             __BIT(8)
458 #define CPUID_0_07_EBX_ERMS             __BIT(9)
459 #define CPUID_0_07_EBX_INVPCID                    __BIT(10)
460 #define CPUID_0_07_EBX_RTM              __BIT(11)
461 #define CPUID_0_07_EBX_QM               __BIT(12)
462 #define CPUID_0_07_EBX_FPUCSDS                    __BIT(13)
463 #define CPUID_0_07_EBX_MPX              __BIT(14)
464 #define CPUID_0_07_EBX_PQE              __BIT(15)
465 #define CPUID_0_07_EBX_AVX512F                    __BIT(16)
466 #define CPUID_0_07_EBX_AVX512DQ                   __BIT(17)
467 #define CPUID_0_07_EBX_RDSEED           __BIT(18)
468 #define CPUID_0_07_EBX_ADX              __BIT(19)
469 #define CPUID_0_07_EBX_SMAP             __BIT(20)
470 #define CPUID_0_07_EBX_AVX512_IFMA      __BIT(21)
471 #define CPUID_0_07_EBX_CLFLUSHOPT       __BIT(23)
472 #define CPUID_0_07_EBX_CLWB             __BIT(24)
473 #define CPUID_0_07_EBX_PT               __BIT(25)
474 #define CPUID_0_07_EBX_AVX512PF                   __BIT(26)
475 #define CPUID_0_07_EBX_AVX512ER                   __BIT(27)
476 #define CPUID_0_07_EBX_AVX512CD                   __BIT(28)
477 #define CPUID_0_07_EBX_SHA              __BIT(29)
478 #define CPUID_0_07_EBX_AVX512BW                   __BIT(30)
479 #define CPUID_0_07_EBX_AVX512VL                   __BIT(31)
480 /* [ECX=0] Fn0000_0007:ECX (Structured Extended Features) */
481 #define CPUID_0_07_ECX_PREFETCHWT1      __BIT(0)
482 #define CPUID_0_07_ECX_AVX512_VBMI      __BIT(1)
483 #define CPUID_0_07_ECX_UMIP             __BIT(2)
484 #define CPUID_0_07_ECX_PKU              __BIT(3)
485 #define CPUID_0_07_ECX_OSPKE            __BIT(4)
486 #define CPUID_0_07_ECX_WAITPKG                    __BIT(5)
487 #define CPUID_0_07_ECX_AVX512_VBMI2     __BIT(6)
488 #define CPUID_0_07_ECX_CET_SS           __BIT(7)
489 #define CPUID_0_07_ECX_GFNI             __BIT(8)
490 #define CPUID_0_07_ECX_VAES             __BIT(9)
491 #define CPUID_0_07_ECX_VPCLMULQDQ       __BIT(10)
492 #define CPUID_0_07_ECX_AVX512_VNNI      __BIT(11)
493 #define CPUID_0_07_ECX_AVX512_BITALG    __BIT(12)
494 #define CPUID_0_07_ECX_AVX512_VPOPCNTDQ __BIT(14)
495 #define CPUID_0_07_ECX_LA57             __BIT(16)
496 #define CPUID_0_07_ECX_MAWAU            __BITS(21, 17)
497 #define CPUID_0_07_ECX_RDPID            __BIT(22)
498 #define CPUID_0_07_ECX_KL               __BIT(23)
499 #define CPUID_0_07_ECX_CLDEMOTE                   __BIT(25)
500 #define CPUID_0_07_ECX_MOVDIRI                    __BIT(27)
501 #define CPUID_0_07_ECX_MOVDIR64B        __BIT(28)
502 #define CPUID_0_07_ECX_SGXLC            __BIT(30)
503 #define CPUID_0_07_ECX_PKS              __BIT(31)
504 /* [ECX=0] Fn0000_0007:EDX (Structured Extended Features) */
505 #define CPUID_0_07_EDX_AVX512_4VNNIW    __BIT(2)
506 #define CPUID_0_07_EDX_AVX512_4FMAPS    __BIT(3)
507 #define CPUID_0_07_EDX_FSREP_MOV        __BIT(4)
508 #define CPUID_0_07_EDX_AVX512_VP2INTERSECT __BIT(8)
509 #define CPUID_0_07_EDX_SRBDS_CTRL       __BIT(9)
510 #define CPUID_0_07_EDX_MD_CLEAR                   __BIT(10)
511 #define CPUID_0_07_EDX_TSX_FORCE_ABORT  __BIT(13)
512 #define CPUID_0_07_EDX_SERIALIZE        __BIT(14)
513 #define CPUID_0_07_EDX_HYBRID           __BIT(15)
514 #define CPUID_0_07_EDX_TSXLDTRK                   __BIT(16)
515 #define CPUID_0_07_EDX_CET_IBT                    __BIT(20)
516 #define CPUID_0_07_EDX_IBRS             __BIT(26)
517 #define CPUID_0_07_EDX_STIBP            __BIT(27)
518 #define CPUID_0_07_EDX_L1D_FLUSH        __BIT(28)
519 #define CPUID_0_07_EDX_ARCH_CAP                   __BIT(29)
520 #define CPUID_0_07_EDX_CORE_CAP                   __BIT(30)
521 #define CPUID_0_07_EDX_SSBD             __BIT(31)
522 
523 /* Fn0000_000B:EAX (Extended Topology Enumeration) */
524 #define CPUID_0_0B_EAX_SHIFTNUM                   __BITS(4, 0)
525 /* Fn0000_000B:ECX (Extended Topology Enumeration) */
526 #define CPUID_0_0B_ECX_LVLNUM           __BITS(7, 0)
527 #define CPUID_0_0B_ECX_LVLTYPE                    __BITS(15, 8)
528 #define CPUID_0_0B_ECX_LVLTYPE_INVAL              0
529 #define CPUID_0_0B_ECX_LVLTYPE_SMT                1
530 #define CPUID_0_0B_ECX_LVLTYPE_CORE               2
531 
532 /* [ECX=1] Fn0000_000D:EAX (Processor Extended State Enumeration) */
533 #define CPUID_0_0D_ECX1_EAX_XSAVEOPT    __BIT(0)
534 #define CPUID_0_0D_ECX1_EAX_XSAVEC      __BIT(1)
535 #define CPUID_0_0D_ECX1_EAX_XGETBV      __BIT(2)
536 #define CPUID_0_0D_ECX1_EAX_XSAVES      __BIT(3)
537 
538 /* Fn8000_0001:ECX */
539 #define CPUID_8_01_ECX_LAHF             __BIT(0)
540 #define CPUID_8_01_ECX_CMPLEGACY        __BIT(1)
541 #define CPUID_8_01_ECX_SVM              __BIT(2)
542 #define CPUID_8_01_ECX_EAPIC            __BIT(3)
543 #define CPUID_8_01_ECX_ALTMOVCR8        __BIT(4)
544 #define CPUID_8_01_ECX_ABM              __BIT(5)
545 #define CPUID_8_01_ECX_SSE4A            __BIT(6)
546 #define CPUID_8_01_ECX_MISALIGNSSE      __BIT(7)
547 #define CPUID_8_01_ECX_3DNOWPF                    __BIT(8)
548 #define CPUID_8_01_ECX_OSVW             __BIT(9)
549 #define CPUID_8_01_ECX_IBS              __BIT(10)
550 #define CPUID_8_01_ECX_XOP              __BIT(11)
551 #define CPUID_8_01_ECX_SKINIT           __BIT(12)
552 #define CPUID_8_01_ECX_WDT              __BIT(13)
553 #define CPUID_8_01_ECX_LWP              __BIT(15)
554 #define CPUID_8_01_ECX_FMA4             __BIT(16)
555 #define CPUID_8_01_ECX_TCE              __BIT(17)
556 #define CPUID_8_01_ECX_NODEID           __BIT(19)
557 #define CPUID_8_01_ECX_TBM              __BIT(21)
558 #define CPUID_8_01_ECX_TOPOEXT                    __BIT(22)
559 #define CPUID_8_01_ECX_PCEC             __BIT(23)
560 #define CPUID_8_01_ECX_PCENB            __BIT(24)
561 #define CPUID_8_01_ECX_DBE              __BIT(26)
562 #define CPUID_8_01_ECX_PERFTSC                    __BIT(27)
563 #define CPUID_8_01_ECX_PERFEXTLLC       __BIT(28)
564 #define CPUID_8_01_ECX_MWAITX           __BIT(29)
565 /* Fn8000_0001:EDX */
566 #define CPUID_8_01_EDX_FPU              __BIT(0)
567 #define CPUID_8_01_EDX_VME              __BIT(1)
568 #define CPUID_8_01_EDX_DE               __BIT(2)
569 #define CPUID_8_01_EDX_PSE              __BIT(3)
570 #define CPUID_8_01_EDX_TSC              __BIT(4)
571 #define CPUID_8_01_EDX_MSR              __BIT(5)
572 #define CPUID_8_01_EDX_PAE              __BIT(6)
573 #define CPUID_8_01_EDX_MCE              __BIT(7)
574 #define CPUID_8_01_EDX_CX8              __BIT(8)
575 #define CPUID_8_01_EDX_APIC             __BIT(9)
576 #define CPUID_8_01_EDX_SYSCALL                    __BIT(11)
577 #define CPUID_8_01_EDX_MTRR             __BIT(12)
578 #define CPUID_8_01_EDX_PGE              __BIT(13)
579 #define CPUID_8_01_EDX_MCA              __BIT(14)
580 #define CPUID_8_01_EDX_CMOV             __BIT(15)
581 #define CPUID_8_01_EDX_PAT              __BIT(16)
582 #define CPUID_8_01_EDX_PSE36            __BIT(17)
583 #define CPUID_8_01_EDX_XD               __BIT(20)
584 #define CPUID_8_01_EDX_MMXEXT           __BIT(22)
585 #define CPUID_8_01_EDX_MMX              __BIT(23)
586 #define CPUID_8_01_EDX_FXSR             __BIT(24)
587 #define CPUID_8_01_EDX_FFXSR            __BIT(25)
588 #define CPUID_8_01_EDX_PAGE1GB                    __BIT(26)
589 #define CPUID_8_01_EDX_RDTSCP           __BIT(27)
590 #define CPUID_8_01_EDX_LM               __BIT(29)
591 #define CPUID_8_01_EDX_3DNOWEXT                   __BIT(30)
592 #define CPUID_8_01_EDX_3DNOW            __BIT(31)
593 
594 /* Fn8000_0007:EDX (Advanced Power Management) */
595 #define CPUID_8_07_EDX_TS               __BIT(0)
596 #define CPUID_8_07_EDX_FID              __BIT(1)
597 #define CPUID_8_07_EDX_VID              __BIT(2)
598 #define CPUID_8_07_EDX_TTP              __BIT(3)
599 #define CPUID_8_07_EDX_TM               __BIT(4)
600 #define CPUID_8_07_EDX_100MHzSteps      __BIT(6)
601 #define CPUID_8_07_EDX_HwPstate                   __BIT(7)
602 #define CPUID_8_07_EDX_TscInvariant     __BIT(8)
603 #define CPUID_8_07_EDX_CPB              __BIT(9)
604 #define CPUID_8_07_EDX_EffFreqRO        __BIT(10)
605 #define CPUID_8_07_EDX_ProcFeedbackIntf __BIT(11)
606 #define CPUID_8_07_EDX_ProcPowerReport  __BIT(12)
607 
608 /* Fn8000_0008:EBX */
609 #define CPUID_8_08_EBX_CLZERO           __BIT(0)
610 #define CPUID_8_08_EBX_InstRetCntMsr    __BIT(1)
611 #define CPUID_8_08_EBX_RstrFpErrPtrs    __BIT(2)
612 #define CPUID_8_08_EBX_INVLPGB                    __BIT(3)
613 #define CPUID_8_08_EBX_RDPRU            __BIT(4)
614 #define CPUID_8_08_EBX_MCOMMIT                    __BIT(8)
615 #define CPUID_8_08_EBX_WBNOINVD                   __BIT(9)
616 #define CPUID_8_08_EBX_IBPB             __BIT(12)
617 #define CPUID_8_08_EBX_INT_WBINVD       __BIT(13)
618 #define CPUID_8_08_EBX_IBRS             __BIT(14)
619 #define CPUID_8_08_EBX_STIBP            __BIT(15)
620 #define CPUID_8_08_EBX_IBRS_ALWAYSON    __BIT(16)
621 #define CPUID_8_08_EBX_STIBP_ALWAYSON   __BIT(17)
622 #define CPUID_8_08_EBX_PREFER_IBRS      __BIT(18)
623 #define CPUID_8_08_EBX_EferLmsleUnsupp  __BIT(20)
624 #define CPUID_8_08_EBX_INVLPGBnestedPg  __BIT(21)
625 #define CPUID_8_08_EBX_SSBD             __BIT(24)
626 #define CPUID_8_08_EBX_VIRT_SSBD        __BIT(25)
627 #define CPUID_8_08_EBX_SSB_NO           __BIT(26)
628 /* Fn8000_0008:ECX */
629 #define CPUID_8_08_ECX_NC               __BITS(7,0)
630 #define CPUID_8_08_ECX_ApicIdSize       __BITS(15,12)
631 #define CPUID_8_08_ECX_PerfTscSize      __BITS(17,16)
632 
633 /* Fn8000_000A:EAX (SVM features) */
634 #define CPUID_8_0A_EAX_SvmRev           __BITS(7,0)
635 /* Fn8000_000A:EDX (SVM features) */
636 #define CPUID_8_0A_EDX_NP               __BIT(0)
637 #define CPUID_8_0A_EDX_LbrVirt                    __BIT(1)
638 #define CPUID_8_0A_EDX_SVML             __BIT(2)
639 #define CPUID_8_0A_EDX_NRIPS            __BIT(3)
640 #define CPUID_8_0A_EDX_TscRateMsr       __BIT(4)
641 #define CPUID_8_0A_EDX_VmcbClean        __BIT(5)
642 #define CPUID_8_0A_EDX_FlushByASID      __BIT(6)
643 #define CPUID_8_0A_EDX_DecodeAssists    __BIT(7)
644 #define CPUID_8_0A_EDX_PauseFilter      __BIT(10)
645 #define CPUID_8_0A_EDX_PFThreshold      __BIT(12)
646 #define CPUID_8_0A_EDX_AVIC             __BIT(13)
647 #define CPUID_8_0A_EDX_VMSAVEvirt       __BIT(15)
648 #define CPUID_8_0A_EDX_VGIF             __BIT(16)
649 #define CPUID_8_0A_EDX_GMET             __BIT(17)
650 #define CPUID_8_0A_EDX_SSSCheck                   __BIT(19)
651 #define CPUID_8_0A_EDX_SpecCtrl                   __BIT(20)
652 #define CPUID_8_0A_EDX_TlbiCtl                    __BIT(24)
653 
654 /* -------------------------------------------------------------------------- */
655 
656 /*
657  * Register defines. We mainly rely on the already-existing OS definitions.
658  */
659 
660 #if defined(__DragonFly__)
661 
662 #define XCR0_X87              CPU_XFEATURE_X87    /* 0x00000001 */
663 #define XCR0_SSE              CPU_XFEATURE_SSE    /* 0x00000002 */
664 
665 #define MSR_MISC_ENABLE                 MSR_IA32_MISC_ENABLE          /* 0x1a0 */
666 #define MSR_CR_PAT            MSR_PAT                       /* 0x277 */
667 #define MSR_SFMASK            MSR_SF_MASK                   /* 0xc0000084 */
668 #define MSR_KERNELGSBASE      MSR_KGSBASE                   /* 0xc0000102 */
669 #define MSR_NB_CFG            MSR_AMD_NB_CFG                /* 0xc001001f */
670 #define MSR_IC_CFG            MSR_AMD_IC_CFG                /* 0xc0011021 */
671 #define MSR_DE_CFG            MSR_AMD_DE_CFG                /* 0xc0011029 */
672 #define MSR_UCODE_AMD_PATCHLEVEL MSR_AMD_PATCH_LEVEL        /* 0x0000008b */
673 
674 /* MSR_IA32_ARCH_CAPABILITIES (0x10a) */
675 #define   IA32_ARCH_RDCL_NO   IA32_ARCH_CAP_RDCL_NO
676 #define   IA32_ARCH_IBRS_ALL  IA32_ARCH_CAP_IBRS_ALL
677 #define   IA32_ARCH_RSBA                IA32_ARCH_CAP_RSBA
678 #define   IA32_ARCH_SKIP_L1DFL_VMENTRY  IA32_ARCH_CAP_SKIP_L1DFL_VMENTRY
679 #define   IA32_ARCH_SSB_NO    IA32_ARCH_CAP_SSB_NO
680 #define   IA32_ARCH_MDS_NO    IA32_ARCH_CAP_MDS_NO
681 #define   IA32_ARCH_IF_PSCHANGE_MC_NO   IA32_ARCH_CAP_IF_PSCHANGE_MC_NO
682 #define   IA32_ARCH_TSX_CTRL  IA32_ARCH_CAP_TSX_CTRL
683 #define   IA32_ARCH_TAA_NO    IA32_ARCH_CAP_TAA_NO
684 
685 /* MSR_IA32_FLUSH_CMD (0x10b) */
686 #define   IA32_FLUSH_CMD_L1D_FLUSH      IA32_FLUSH_CMD_L1D
687 
688 #endif /* __DragonFly__ */
689 
690 /* -------------------------------------------------------------------------- */
691 
692 #ifdef _KERNEL
693 #define NVMM_X86_MACH_NCONF   0
694 #define NVMM_X86_VCPU_NCONF   2
695 
696 struct nvmm_x86_cpuid_mask {
697           uint32_t eax;
698           uint32_t ebx;
699           uint32_t ecx;
700           uint32_t edx;
701 };
702 
703 /* FPU area + XSAVE header. */
704 struct nvmm_x86_xsave {
705           struct nvmm_x64_state_fpu fpu;
706           uint64_t xstate_bv;
707           uint64_t xcomp_bv;
708           uint8_t rsvd0[8];
709           uint8_t rsvd[40];
710 };
711 CTASSERT(sizeof(struct nvmm_x86_xsave) == 512 + 64);
712 
713 extern const struct nvmm_x64_state nvmm_x86_reset_state;
714 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000001;
715 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_00000007;
716 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000001;
717 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000007;
718 extern const struct nvmm_x86_cpuid_mask nvmm_cpuid_80000008;
719 
720 bool nvmm_x86_pat_validate(uint64_t);
721 uint32_t nvmm_x86_xsave_size(uint64_t);
722 
723 /* -------------------------------------------------------------------------- */
724 
725 /*
726  * ASM defines. We mainly rely on the already-existing OS definitions.
727  */
728 
729 #if defined(__NetBSD__)
730 #include <x86/cpufunc.h>
731 #include <x86/fpu.h>
732 #elif defined(__DragonFly__)
733 #include <machine/cpufunc.h>
734 #include <machine/npx.h>
735 #endif
736 
737 /* CPUID. */
738 typedef struct {
739           uint32_t eax, ebx, ecx, edx;
740 } cpuid_desc_t;
741 
742 #if defined(__NetBSD__)
743 #define x86_get_cpuid(l, d)   x86_cpuid(l, (uint32_t *)d)
744 #define x86_get_cpuid2(l, c, d)         x86_cpuid2(l, c, (uint32_t *)d)
745 #elif defined(__DragonFly__)
746 #define x86_get_cpuid(l, d)   do_cpuid(l, (uint32_t *)d)
747 #define x86_get_cpuid2(l, c, d)         cpuid_count(l, c, (uint32_t *)d)
748 #endif
749 
750 /* Control registers. */
751 #if defined(__NetBSD__)
752 #define x86_get_cr0()                   rcr0()
753 #define x86_get_cr2()                   rcr2()
754 #define x86_get_cr3()                   rcr3()
755 #define x86_get_cr4()                   rcr4()
756 #define x86_set_cr0(v)                  lcr0(v)
757 #define x86_set_cr2(v)                  lcr2(v)
758 #define x86_set_cr4(v)                  lcr4(v)
759 #elif defined(__DragonFly__)
760 #define x86_get_cr0()                   rcr0()
761 #define x86_get_cr2()                   rcr2()
762 #define x86_get_cr3()                   rcr3()
763 #define x86_get_cr4()                   rcr4()
764 #define x86_set_cr0(v)                  load_cr0(v)
765 #define x86_set_cr2(v)                  load_cr2(v)
766 #define x86_set_cr4(v)                  load_cr4(v)
767 #endif
768 
769 /* Debug registers. */
770 #if defined(__NetBSD__)
771 #include <x86/dbregs.h>
772 static inline void
x86_curthread_save_dbregs(uint64_t * drs __unused)773 x86_curthread_save_dbregs(uint64_t *drs __unused)
774 {
775           x86_dbregs_save(curlwp);
776 }
777 static inline void
x86_curthread_restore_dbregs(uint64_t * drs __unused)778 x86_curthread_restore_dbregs(uint64_t *drs __unused)
779 {
780           x86_dbregs_restore(curlwp);
781 }
782 #define x86_get_dr0()                   rdr0()
783 #define x86_get_dr1()                   rdr1()
784 #define x86_get_dr2()                   rdr2()
785 #define x86_get_dr3()                   rdr3()
786 #define x86_get_dr6()                   rdr6()
787 #define x86_get_dr7()                   rdr7()
788 #define x86_set_dr0(v)                  ldr0(v)
789 #define x86_set_dr1(v)                  ldr1(v)
790 #define x86_set_dr2(v)                  ldr2(v)
791 #define x86_set_dr3(v)                  ldr3(v)
792 #define x86_set_dr6(v)                  ldr6(v)
793 #define x86_set_dr7(v)                  ldr7(v)
794 #elif defined(__DragonFly__)
795 #include <sys/proc.h> /* struct lwp */
796 static inline void
x86_curthread_save_dbregs(uint64_t * drs)797 x86_curthread_save_dbregs(uint64_t *drs)
798 {
799           struct pcb *pcb = curthread->td_lwp->lwp_thread->td_pcb;
800 
801           if (__predict_true(!(pcb->pcb_flags & PCB_DBREGS)))
802                     return;
803 
804           drs[NVMM_X64_DR_DR0] = rdr0();
805           drs[NVMM_X64_DR_DR1] = rdr1();
806           drs[NVMM_X64_DR_DR2] = rdr2();
807           drs[NVMM_X64_DR_DR3] = rdr3();
808           drs[NVMM_X64_DR_DR6] = rdr6();
809           drs[NVMM_X64_DR_DR7] = rdr7();
810 }
811 static inline void
x86_curthread_restore_dbregs(uint64_t * drs)812 x86_curthread_restore_dbregs(uint64_t *drs)
813 {
814           struct pcb *pcb = curthread->td_lwp->lwp_thread->td_pcb;
815 
816           if (__predict_true(!(pcb->pcb_flags & PCB_DBREGS)))
817                     return;
818 
819           load_dr0(drs[NVMM_X64_DR_DR0]);
820           load_dr1(drs[NVMM_X64_DR_DR1]);
821           load_dr2(drs[NVMM_X64_DR_DR2]);
822           load_dr3(drs[NVMM_X64_DR_DR3]);
823           load_dr6(drs[NVMM_X64_DR_DR6]);
824           load_dr7(drs[NVMM_X64_DR_DR7]);
825 }
826 #define x86_get_dr0()                   rdr0()
827 #define x86_get_dr1()                   rdr1()
828 #define x86_get_dr2()                   rdr2()
829 #define x86_get_dr3()                   rdr3()
830 #define x86_get_dr6()                   rdr6()
831 #define x86_get_dr7()                   rdr7()
832 #define x86_set_dr0(v)                  load_dr0(v)
833 #define x86_set_dr1(v)                  load_dr1(v)
834 #define x86_set_dr2(v)                  load_dr2(v)
835 #define x86_set_dr3(v)                  load_dr3(v)
836 #define x86_set_dr6(v)                  load_dr6(v)
837 #define x86_set_dr7(v)                  load_dr7(v)
838 #endif
839 
840 /* FPU. */
841 #if defined(__NetBSD__)
842 #define x86_curthread_save_fpu()        fpu_kern_enter()
843 #define x86_curthread_restore_fpu()     fpu_kern_leave()
844 #define x86_save_fpu(a, m)              fpu_area_save(a, m, true)
845 #define x86_restore_fpu(a, m)           fpu_area_restore(a, m, true)
846 #elif defined(__DragonFly__)
847 #define x86_curthread_save_fpu()        /* TODO */
848 #define x86_curthread_restore_fpu()     /* TODO */
849 #define x86_save_fpu(a, m)                                  \
850           ({                                                          \
851                     fpusave((union savefpu *)(a), m);       \
852                     load_cr0(rcr0() | CR0_TS);              \
853           })
854 #define x86_restore_fpu(a, m)                               \
855           ({                                                          \
856                     __asm volatile("clts" ::: "memory");    \
857                     fpurstor((union savefpu *)(a), m);      \
858           })
859 #endif
860 
861 /* XCRs. */
862 static inline uint64_t
x86_get_xcr(uint32_t xcr)863 x86_get_xcr(uint32_t xcr)
864 {
865           uint32_t low, high;
866 
867           __asm volatile (
868                     "xgetbv"
869                     : "=a" (low), "=d" (high)
870                     : "c" (xcr)
871           );
872 
873           return (low | ((uint64_t)high << 32));
874 }
875 
876 static inline void
x86_set_xcr(uint32_t xcr,uint64_t val)877 x86_set_xcr(uint32_t xcr, uint64_t val)
878 {
879           uint32_t low, high;
880 
881           low = val;
882           high = val >> 32;
883           __asm volatile (
884                     "xsetbv"
885                     :
886                     : "a" (low), "d" (high), "c" (xcr)
887                     : "memory"
888           );
889 }
890 
891 #if defined(__DragonFly__)
892 #define x86_xsave_features    npx_xcr0_mask
893 #define x86_fpu_mxcsr_mask    npx_mxcsr_mask
894 #endif
895 
896 #endif /* _KERNEL */
897 
898 #endif /* ASM_NVMM */
899 
900 #endif /* _NVMM_X86_H_ */
901