VirtualBox

source: vbox/trunk/include/VBox/vmm/cpumctx.h@ 73768

Last change on this file since 73768 was 73606, checked in by vboxsync, 6 years ago

VMM: Nested VMX: bugref:9180 Various bits:

  • IEM: Started VMXON, VMXOFF implementation, use IEM_OPCODE_GET_NEXT_RM.
  • IEM: Fixed INVPCID C impl, removed unused IEMExecDecodedInvpcid.
  • IEM: Updated iemCImpl_load_CrX to check for CR0/CR4 fixed bits in VMX.
  • IEM: Update offModRm to reset/re-initialize where needed.
  • CPUM: Added VMX root, non-root mode and other bits and updated a few places where they're used.
  • HM: Started adding fine-grained VMX instruction failure diagnostics.
  • HM: Made VM instruction error an enum.
  • HM: Added HMVMXAll.cpp for all context VMX code.
  • Ensure building with VBOX_WITH_NESTED_HWVIRT_[SVM|VMX] does the right thing based on host CPU.
  • CPUM: Added dumping of nested-VMX CPUMCTX state.
  • HMVMXR0: Added memory operand decoding.
  • HMVMXR0: VMX instr. privilege checks (CR0/CR4 read shadows are not consulted, so we need to do them)
  • HM: Added some more bit-field representaions.
  • Recompiler: Refuse to run when in nested-VMX guest code.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 46.3 KB
Line 
1/** @file
2 * CPUM - CPU Monitor(/ Manager), Context Structures.
3 */
4
5/*
6 * Copyright (C) 2006-2017 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___VBox_vmm_cpumctx_h
27#define ___VBox_vmm_cpumctx_h
28
29#ifndef VBOX_FOR_DTRACE_LIB
30# include <iprt/x86.h>
31# include <VBox/types.h>
32# include <VBox/vmm/hm_svm.h>
33# include <VBox/vmm/hm_vmx.h>
34#else
35# pragma D depends_on library x86.d
36#endif
37
38
39RT_C_DECLS_BEGIN
40
41/** @defgroup grp_cpum_ctx The CPUM Context Structures
42 * @ingroup grp_cpum
43 * @{
44 */
45
46/**
47 * Selector hidden registers.
48 */
49typedef struct CPUMSELREG
50{
51 /** The selector register. */
52 RTSEL Sel;
53 /** Padding, don't use. */
54 RTSEL PaddingSel;
55 /** The selector which info resides in u64Base, u32Limit and Attr, provided
56 * that CPUMSELREG_FLAGS_VALID is set. */
57 RTSEL ValidSel;
58 /** Flags, see CPUMSELREG_FLAGS_XXX. */
59 uint16_t fFlags;
60
61 /** Base register.
62 *
63 * Long mode remarks:
64 * - Unused in long mode for CS, DS, ES, SS
65 * - 32 bits for FS & GS; FS(GS)_BASE msr used for the base address
66 * - 64 bits for TR & LDTR
67 */
68 uint64_t u64Base;
69 /** Limit (expanded). */
70 uint32_t u32Limit;
71 /** Flags.
72 * This is the high 32-bit word of the descriptor entry.
73 * Only the flags, dpl and type are used. */
74 X86DESCATTR Attr;
75} CPUMSELREG;
76#ifndef VBOX_FOR_DTRACE_LIB
77AssertCompileSize(CPUMSELREG, 24);
78#endif
79
80/** @name CPUMSELREG_FLAGS_XXX - CPUMSELREG::fFlags values.
81 * @{ */
82#define CPUMSELREG_FLAGS_VALID UINT16_C(0x0001)
83#define CPUMSELREG_FLAGS_STALE UINT16_C(0x0002)
84#define CPUMSELREG_FLAGS_VALID_MASK UINT16_C(0x0003)
85/** @} */
86
87/** Checks if the hidden parts of the selector register are valid. */
88#ifdef VBOX_WITH_RAW_MODE_NOT_R0
89# define CPUMSELREG_ARE_HIDDEN_PARTS_VALID(a_pVCpu, a_pSelReg) \
90 ( ((a_pSelReg)->fFlags & CPUMSELREG_FLAGS_VALID) \
91 && ( (a_pSelReg)->ValidSel == (a_pSelReg)->Sel \
92 || ( (a_pVCpu) /*!= NULL*/ \
93 && (a_pSelReg)->ValidSel == ((a_pSelReg)->Sel & X86_SEL_MASK_OFF_RPL) \
94 && ((a_pSelReg)->Sel & X86_SEL_RPL) == 1 \
95 && ((a_pSelReg)->ValidSel & X86_SEL_RPL) == 0 \
96 && CPUMIsGuestInRawMode(a_pVCpu) \
97 ) \
98 ) \
99 )
100#else
101# define CPUMSELREG_ARE_HIDDEN_PARTS_VALID(a_pVCpu, a_pSelReg) \
102 ( ((a_pSelReg)->fFlags & CPUMSELREG_FLAGS_VALID) \
103 && (a_pSelReg)->ValidSel == (a_pSelReg)->Sel )
104#endif
105
106/** Old type used for the hidden register part.
107 * @deprecated */
108typedef CPUMSELREG CPUMSELREGHID;
109
110/**
111 * The sysenter register set.
112 */
113typedef struct CPUMSYSENTER
114{
115 /** Ring 0 cs.
116 * This value + 8 is the Ring 0 ss.
117 * This value + 16 is the Ring 3 cs.
118 * This value + 24 is the Ring 3 ss.
119 */
120 uint64_t cs;
121 /** Ring 0 eip. */
122 uint64_t eip;
123 /** Ring 0 esp. */
124 uint64_t esp;
125} CPUMSYSENTER;
126
127/** @def CPUM_UNION_NM
128 * For compilers (like DTrace) that does not grok nameless unions, we have a
129 * little hack to make them palatable.
130 */
131/** @def CPUM_STRUCT_NM
132 * For compilers (like DTrace) that does not grok nameless structs (it is
133 * non-standard C++), we have a little hack to make them palatable.
134 */
135#ifdef VBOX_FOR_DTRACE_LIB
136# define CPUM_UNION_NM(a_Nm) a_Nm
137# define CPUM_STRUCT_NM(a_Nm) a_Nm
138#elif defined(IPRT_WITHOUT_NAMED_UNIONS_AND_STRUCTS)
139# define CPUM_UNION_NM(a_Nm) a_Nm
140# define CPUM_STRUCT_NM(a_Nm) a_Nm
141#else
142# define CPUM_UNION_NM(a_Nm)
143# define CPUM_STRUCT_NM(a_Nm)
144#endif
145/** @def CPUM_UNION_STRUCT_NM
146 * Combines CPUM_UNION_NM and CPUM_STRUCT_NM to avoid hitting the right side of
147 * the screen in the compile time assertions.
148 */
149#define CPUM_UNION_STRUCT_NM(a_UnionNm, a_StructNm) CPUM_UNION_NM(a_UnionNm .) CPUM_STRUCT_NM(a_StructNm)
150
151/** A general register (union). */
152typedef union CPUMCTXGREG
153{
154 /** Natural unsigned integer view. */
155 uint64_t u;
156 /** 64-bit view. */
157 uint64_t u64;
158 /** 32-bit view. */
159 uint32_t u32;
160 /** 16-bit view. */
161 uint16_t u16;
162 /** 8-bit view. */
163 uint8_t u8;
164 /** 8-bit low/high view. */
165 RT_GCC_EXTENSION struct
166 {
167 /** Low byte (al, cl, dl, bl, ++). */
168 uint8_t bLo;
169 /** High byte in the first word - ah, ch, dh, bh. */
170 uint8_t bHi;
171 } CPUM_STRUCT_NM(s);
172} CPUMCTXGREG;
173#ifndef VBOX_FOR_DTRACE_LIB
174AssertCompileSize(CPUMCTXGREG, 8);
175AssertCompileMemberOffset(CPUMCTXGREG, CPUM_STRUCT_NM(s.) bLo, 0);
176AssertCompileMemberOffset(CPUMCTXGREG, CPUM_STRUCT_NM(s.) bHi, 1);
177#endif
178
179
180
181/**
182 * CPU context core.
183 *
184 * @todo Eliminate this structure!
185 * @deprecated We don't push any context cores any more in TRPM.
186 */
187#pragma pack(1)
188typedef struct CPUMCTXCORE
189{
190 /** @name General Register.
191 * @note These follow the encoding order (X86_GREG_XXX) and can be accessed as
192 * an array starting a rax.
193 * @{ */
194 union
195 {
196 uint8_t al;
197 uint16_t ax;
198 uint32_t eax;
199 uint64_t rax;
200 } CPUM_UNION_NM(rax);
201 union
202 {
203 uint8_t cl;
204 uint16_t cx;
205 uint32_t ecx;
206 uint64_t rcx;
207 } CPUM_UNION_NM(rcx);
208 union
209 {
210 uint8_t dl;
211 uint16_t dx;
212 uint32_t edx;
213 uint64_t rdx;
214 } CPUM_UNION_NM(rdx);
215 union
216 {
217 uint8_t bl;
218 uint16_t bx;
219 uint32_t ebx;
220 uint64_t rbx;
221 } CPUM_UNION_NM(rbx);
222 union
223 {
224 uint16_t sp;
225 uint32_t esp;
226 uint64_t rsp;
227 } CPUM_UNION_NM(rsp);
228 union
229 {
230 uint16_t bp;
231 uint32_t ebp;
232 uint64_t rbp;
233 } CPUM_UNION_NM(rbp);
234 union
235 {
236 uint8_t sil;
237 uint16_t si;
238 uint32_t esi;
239 uint64_t rsi;
240 } CPUM_UNION_NM(rsi);
241 union
242 {
243 uint8_t dil;
244 uint16_t di;
245 uint32_t edi;
246 uint64_t rdi;
247 } CPUM_UNION_NM(rdi);
248 uint64_t r8;
249 uint64_t r9;
250 uint64_t r10;
251 uint64_t r11;
252 uint64_t r12;
253 uint64_t r13;
254 uint64_t r14;
255 uint64_t r15;
256 /** @} */
257
258 /** @name Segment registers.
259 * @note These follow the encoding order (X86_SREG_XXX) and can be accessed as
260 * an array starting a es.
261 * @{ */
262 CPUMSELREG es;
263 CPUMSELREG cs;
264 CPUMSELREG ss;
265 CPUMSELREG ds;
266 CPUMSELREG fs;
267 CPUMSELREG gs;
268 /** @} */
269
270 /** The program counter. */
271 union
272 {
273 uint16_t ip;
274 uint32_t eip;
275 uint64_t rip;
276 } CPUM_UNION_NM(rip);
277
278 /** The flags register. */
279 union
280 {
281 X86EFLAGS eflags;
282 X86RFLAGS rflags;
283 } CPUM_UNION_NM(rflags);
284
285} CPUMCTXCORE;
286#pragma pack()
287
288
289/**
290 * SVM Host-state area (Nested Hw.virt - VirtualBox's layout).
291 *
292 * @warning Exercise caution while modifying the layout of this struct. It's
293 * part of VM saved states.
294 */
295#pragma pack(1)
296typedef struct SVMHOSTSTATE
297{
298 uint64_t uEferMsr;
299 uint64_t uCr0;
300 uint64_t uCr4;
301 uint64_t uCr3;
302 uint64_t uRip;
303 uint64_t uRsp;
304 uint64_t uRax;
305 X86RFLAGS rflags;
306 CPUMSELREG es;
307 CPUMSELREG cs;
308 CPUMSELREG ss;
309 CPUMSELREG ds;
310 VBOXGDTR gdtr;
311 VBOXIDTR idtr;
312 uint8_t abPadding[4];
313} SVMHOSTSTATE;
314#pragma pack()
315/** Pointer to the SVMHOSTSTATE structure. */
316typedef SVMHOSTSTATE *PSVMHOSTSTATE;
317/** Pointer to a const SVMHOSTSTATE structure. */
318typedef const SVMHOSTSTATE *PCSVMHOSTSTATE;
319#ifndef VBOX_FOR_DTRACE_LIB
320AssertCompileSizeAlignment(SVMHOSTSTATE, 8);
321AssertCompileSize(SVMHOSTSTATE, 184);
322#endif
323
324
325/**
326 * CPU context.
327 */
328#pragma pack(1) /* for VBOXIDTR / VBOXGDTR. */
329typedef struct CPUMCTX
330{
331 /** CPUMCTXCORE Part.
332 * @{ */
333
334 /** General purpose registers. */
335 union /* no tag! */
336 {
337 /** The general purpose register array view, indexed by X86_GREG_XXX. */
338 CPUMCTXGREG aGRegs[16];
339
340 /** 64-bit general purpose register view. */
341 RT_GCC_EXTENSION struct /* no tag! */
342 {
343 uint64_t rax, rcx, rdx, rbx, rsp, rbp, rsi, rdi, r8, r9, r10, r11, r12, r13, r14, r15;
344 } CPUM_STRUCT_NM(qw);
345 /** 64-bit general purpose register view. */
346 RT_GCC_EXTENSION struct /* no tag! */
347 {
348 uint64_t r0, r1, r2, r3, r4, r5, r6, r7;
349 } CPUM_STRUCT_NM(qw2);
350 /** 32-bit general purpose register view. */
351 RT_GCC_EXTENSION struct /* no tag! */
352 {
353 uint32_t eax, u32Pad00, ecx, u32Pad01, edx, u32Pad02, ebx, u32Pad03,
354 esp, u32Pad04, ebp, u32Pad05, esi, u32Pad06, edi, u32Pad07,
355 r8d, u32Pad08, r9d, u32Pad09, r10d, u32Pad10, r11d, u32Pad11,
356 r12d, u32Pad12, r13d, u32Pad13, r14d, u32Pad14, r15d, u32Pad15;
357 } CPUM_STRUCT_NM(dw);
358 /** 16-bit general purpose register view. */
359 RT_GCC_EXTENSION struct /* no tag! */
360 {
361 uint16_t ax, au16Pad00[3], cx, au16Pad01[3], dx, au16Pad02[3], bx, au16Pad03[3],
362 sp, au16Pad04[3], bp, au16Pad05[3], si, au16Pad06[3], di, au16Pad07[3],
363 r8w, au16Pad08[3], r9w, au16Pad09[3], r10w, au16Pad10[3], r11w, au16Pad11[3],
364 r12w, au16Pad12[3], r13w, au16Pad13[3], r14w, au16Pad14[3], r15w, au16Pad15[3];
365 } CPUM_STRUCT_NM(w);
366 RT_GCC_EXTENSION struct /* no tag! */
367 {
368 uint8_t al, ah, abPad00[6], cl, ch, abPad01[6], dl, dh, abPad02[6], bl, bh, abPad03[6],
369 spl, abPad04[7], bpl, abPad05[7], sil, abPad06[7], dil, abPad07[7],
370 r8l, abPad08[7], r9l, abPad09[7], r10l, abPad10[7], r11l, abPad11[7],
371 r12l, abPad12[7], r13l, abPad13[7], r14l, abPad14[7], r15l, abPad15[7];
372 } CPUM_STRUCT_NM(b);
373 } CPUM_UNION_NM(g);
374
375 /** Segment registers. */
376 union /* no tag! */
377 {
378 /** The segment register array view, indexed by X86_SREG_XXX. */
379 CPUMSELREG aSRegs[6];
380 /** The named segment register view. */
381 RT_GCC_EXTENSION struct /* no tag! */
382 {
383 CPUMSELREG es, cs, ss, ds, fs, gs;
384 } CPUM_STRUCT_NM(n);
385 } CPUM_UNION_NM(s);
386
387 /** The program counter. */
388 union
389 {
390 uint16_t ip;
391 uint32_t eip;
392 uint64_t rip;
393 } CPUM_UNION_NM(rip);
394
395 /** The flags register. */
396 union
397 {
398 X86EFLAGS eflags;
399 X86RFLAGS rflags;
400 } CPUM_UNION_NM(rflags);
401
402 /** @} */ /*(CPUMCTXCORE)*/
403
404
405 /** @name Control registers.
406 * @{ */
407 uint64_t cr0;
408 uint64_t cr2;
409 uint64_t cr3;
410 uint64_t cr4;
411 /** @} */
412
413 /** Debug registers.
414 * @remarks DR4 and DR5 should not be used since they are aliases for
415 * DR6 and DR7 respectively on both AMD and Intel CPUs.
416 * @remarks DR8-15 are currently not supported by AMD or Intel, so
417 * neither do we.
418 */
419 uint64_t dr[8];
420
421 /** Padding before the structure so the 64-bit member is correctly aligned.
422 * @todo fix this structure! */
423 uint16_t gdtrPadding[3];
424 /** Global Descriptor Table register. */
425 VBOXGDTR gdtr;
426
427 /** Padding before the structure so the 64-bit member is correctly aligned.
428 * @todo fix this structure! */
429 uint16_t idtrPadding[3];
430 /** Interrupt Descriptor Table register. */
431 VBOXIDTR idtr;
432
433 /** The task register.
434 * Only the guest context uses all the members. */
435 CPUMSELREG ldtr;
436 /** The task register.
437 * Only the guest context uses all the members. */
438 CPUMSELREG tr;
439
440 /** The sysenter msr registers.
441 * This member is not used by the hypervisor context. */
442 CPUMSYSENTER SysEnter;
443
444 /** @name System MSRs.
445 * @{ */
446 uint64_t msrEFER;
447 uint64_t msrSTAR; /**< Legacy syscall eip, cs & ss. */
448 uint64_t msrPAT; /**< Page attribute table. */
449 uint64_t msrLSTAR; /**< 64 bits mode syscall rip. */
450 uint64_t msrCSTAR; /**< Compatibility mode syscall rip. */
451 uint64_t msrSFMASK; /**< syscall flag mask. */
452 uint64_t msrKERNELGSBASE; /**< swapgs exchange value. */
453 uint64_t uMsrPadding0; /**< no longer used (used to hold a copy of APIC base MSR). */
454 /** @} */
455
456 /** The XCR0..XCR1 registers. */
457 uint64_t aXcr[2];
458 /** The mask to pass to XSAVE/XRSTOR in EDX:EAX. If zero we use
459 * FXSAVE/FXRSTOR (since bit 0 will always be set, we only need to test it). */
460 uint64_t fXStateMask;
461
462 /** Pointer to the FPU/SSE/AVX/XXXX state ring-0 mapping. */
463 R0PTRTYPE(PX86XSAVEAREA) pXStateR0;
464#if HC_ARCH_BITS == 32
465 uint32_t uXStateR0Padding;
466#endif
467 /** Pointer to the FPU/SSE/AVX/XXXX state ring-3 mapping. */
468 R3PTRTYPE(PX86XSAVEAREA) pXStateR3;
469#if HC_ARCH_BITS == 32
470 uint32_t uXStateR3Padding;
471#endif
472 /** Pointer to the FPU/SSE/AVX/XXXX state raw-mode mapping. */
473 RCPTRTYPE(PX86XSAVEAREA) pXStateRC;
474 /** State component offsets into pXState, UINT16_MAX if not present. */
475 uint16_t aoffXState[64];
476
477 /** 0x2d4 - World switcher flags, CPUMCTX_WSF_XXX. */
478 uint32_t fWorldSwitcher;
479 /** 0x2d8 - Externalized state tracker, CPUMCTX_EXTRN_XXX.
480 * Currently only used internally in NEM/win. */
481 uint64_t fExtrn;
482
483 /** 0x2e0 - Hardware virtualization state. */
484 struct
485 {
486 union /* no tag! */
487 {
488 struct
489 {
490 /** 0x2e0 - MSR holding physical address of the Guest's Host-state. */
491 uint64_t uMsrHSavePa;
492 /** 0x2e8 - Guest physical address of the nested-guest VMCB. */
493 RTGCPHYS GCPhysVmcb;
494 /** 0x2f0 - Cache of the nested-guest VMCB - R0 ptr. */
495 R0PTRTYPE(PSVMVMCB) pVmcbR0;
496#if HC_ARCH_BITS == 32
497 uint32_t uVmcbR0Padding;
498#endif
499 /** 0x2f8 - Cache of the nested-guest VMCB - R3 ptr. */
500 R3PTRTYPE(PSVMVMCB) pVmcbR3;
501#if HC_ARCH_BITS == 32
502 uint32_t uVmcbR3Padding;
503#endif
504 /** 0x300 - Guest's host-state save area. */
505 SVMHOSTSTATE HostState;
506 /** 0x3b8 - Guest TSC time-stamp of when the previous PAUSE instr. was executed. */
507 uint64_t uPrevPauseTick;
508 /** 0x3c0 - Pause filter count. */
509 uint16_t cPauseFilter;
510 /** 0x3c2 - Pause filter threshold. */
511 uint16_t cPauseFilterThreshold;
512 /** 0x3c4 - Whether the injected event is subject to event intercepts. */
513 bool fInterceptEvents;
514 /** 0x3c5 - Padding. */
515 bool afPadding[3];
516 /** 0x3c8 - MSR permission bitmap - R0 ptr. */
517 R0PTRTYPE(void *) pvMsrBitmapR0;
518#if HC_ARCH_BITS == 32
519 uint32_t uvMsrBitmapR0Padding;
520#endif
521 /** 0x3d0 - MSR permission bitmap - R3 ptr. */
522 R3PTRTYPE(void *) pvMsrBitmapR3;
523#if HC_ARCH_BITS == 32
524 uint32_t uvMsrBitmapR3Padding;
525#endif
526 /** 0x3d8 - IO permission bitmap - R0 ptr. */
527 R0PTRTYPE(void *) pvIoBitmapR0;
528#if HC_ARCH_BITS == 32
529 uint32_t uIoBitmapR0Padding;
530#endif
531 /** 0x3e0 - IO permission bitmap - R3 ptr. */
532 R3PTRTYPE(void *) pvIoBitmapR3;
533#if HC_ARCH_BITS == 32
534 uint32_t uIoBitmapR3Padding;
535#endif
536 /** 0x3e8 - Host physical address of the nested-guest VMCB. */
537 RTHCPHYS HCPhysVmcb;
538 } svm;
539
540 struct
541 {
542 /** 0x2e4 - Guest physical address of the VMXON region. */
543 RTGCPHYS GCPhysVmxon;
544 /** 0x2e8 - Guest physical address of the current VMCS pointer. */
545 RTGCPHYS GCPhysVmcs;
546 /** 0x2f0 - Last emulated VMX instruction diagnostic. */
547 VMXVINSTRDIAG enmInstrDiag;
548 /** 0x2f4 - Whether the guest is in VMX root mode. */
549 bool fInVmxRootMode;
550 /** 0x2f5 - Whether the guest is in VMX non-root mode. */
551 bool fInVmxNonRootMode;
552 /** 0x2f6 - Padding. */
553 bool afPadding[2];
554 /** 0x2f8 - Cache of the nested-guest current VMCS - R0 ptr. */
555 R0PTRTYPE(PVMXVVMCS) pVmcsR0;
556#if HC_ARCH_BITS == 32
557 uint32_t uVmcsR0Padding;
558#endif
559 /** 0x300 - Cache of the nested-guest curent VMCS - R3 ptr. */
560 R3PTRTYPE(PVMXVVMCS) pVmcsR3;
561#if HC_ARCH_BITS == 32
562 uint32_t uVmcsR3Padding;
563#endif
564 /** 0x308 - Padding. */
565 uint8_t abPadding[0x3f0 - 0x308];
566 } vmx;
567 } CPUM_UNION_NM(s);
568
569 /** 0x3f0 - A subset of force flags that are preserved while running the nested-guest. */
570 uint32_t fLocalForcedActions;
571 /** 0x3f4 - Global interrupt flag (always true on nested VMX). */
572 bool fGif;
573 /** 0x3f5 - Padding. */
574 uint8_t abPadding1[11];
575 } hwvirt;
576 /** @} */
577} CPUMCTX;
578#pragma pack()
579
580#ifndef VBOX_FOR_DTRACE_LIB
581AssertCompileSizeAlignment(CPUMCTX, 64);
582AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) rax, 0);
583AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) rcx, 8);
584AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) rdx, 16);
585AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) rbx, 24);
586AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) rsp, 32);
587AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) rbp, 40);
588AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) rsi, 48);
589AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) rdi, 56);
590AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) r8, 64);
591AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) r9, 72);
592AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) r10, 80);
593AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) r11, 88);
594AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) r12, 96);
595AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) r13, 104);
596AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) r14, 112);
597AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(g.) CPUM_STRUCT_NM(qw.) r15, 120);
598AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(s.) CPUM_STRUCT_NM(n.) es, 128);
599AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(s.) CPUM_STRUCT_NM(n.) cs, 152);
600AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(s.) CPUM_STRUCT_NM(n.) ss, 176);
601AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(s.) CPUM_STRUCT_NM(n.) ds, 200);
602AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(s.) CPUM_STRUCT_NM(n.) fs, 224);
603AssertCompileMemberOffset(CPUMCTX, CPUM_UNION_NM(s.) CPUM_STRUCT_NM(n.) gs, 248);
604AssertCompileMemberOffset(CPUMCTX, rip, 272);
605AssertCompileMemberOffset(CPUMCTX, rflags, 280);
606AssertCompileMemberOffset(CPUMCTX, cr0, 288);
607AssertCompileMemberOffset(CPUMCTX, cr2, 296);
608AssertCompileMemberOffset(CPUMCTX, cr3, 304);
609AssertCompileMemberOffset(CPUMCTX, cr4, 312);
610AssertCompileMemberOffset(CPUMCTX, dr, 320);
611AssertCompileMemberOffset(CPUMCTX, gdtr, 384+6);
612AssertCompileMemberOffset(CPUMCTX, idtr, 400+6);
613AssertCompileMemberOffset(CPUMCTX, ldtr, 416);
614AssertCompileMemberOffset(CPUMCTX, tr, 440);
615AssertCompileMemberOffset(CPUMCTX, SysEnter, 464);
616AssertCompileMemberOffset(CPUMCTX, msrEFER, 488);
617AssertCompileMemberOffset(CPUMCTX, msrSTAR, 496);
618AssertCompileMemberOffset(CPUMCTX, msrPAT, 504);
619AssertCompileMemberOffset(CPUMCTX, msrLSTAR, 512);
620AssertCompileMemberOffset(CPUMCTX, msrCSTAR, 520);
621AssertCompileMemberOffset(CPUMCTX, msrSFMASK, 528);
622AssertCompileMemberOffset(CPUMCTX, msrKERNELGSBASE, 536);
623AssertCompileMemberOffset(CPUMCTX, aXcr, 552);
624AssertCompileMemberOffset(CPUMCTX, fXStateMask, 568);
625AssertCompileMemberOffset(CPUMCTX, pXStateR0, 576);
626AssertCompileMemberOffset(CPUMCTX, pXStateR3, 584);
627AssertCompileMemberOffset(CPUMCTX, pXStateRC, 592);
628AssertCompileMemberOffset(CPUMCTX, aoffXState, 596);
629AssertCompileMemberOffset(CPUMCTX, hwvirt, 0x2e0);
630AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.uMsrHSavePa, 0x2e0);
631AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR0, 0x2f0);
632AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR3, 0x2f8);
633AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.HostState, 0x300);
634AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.cPauseFilter, 0x3c0);
635AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvMsrBitmapR0, 0x3c8);
636AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvIoBitmapR3, 0x3e0);
637AssertCompileMemberOffset(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.HCPhysVmcb, 0x3e8);
638AssertCompileMemberOffset(CPUMCTX, hwvirt.fLocalForcedActions, 0x3f0);
639AssertCompileMemberAlignment(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pVmcbR0, 8);
640AssertCompileMemberAlignment(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvMsrBitmapR0, 8);
641AssertCompileMemberAlignment(CPUMCTX, hwvirt.CPUM_UNION_NM(s.) svm.pvIoBitmapR0, 8);
642
643AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rax, CPUMCTX, CPUM_UNION_NM(g.) aGRegs);
644AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rax, CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw2.) r0);
645AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rcx, CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw2.) r1);
646AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rdx, CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw2.) r2);
647AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rbx, CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw2.) r3);
648AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rsp, CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw2.) r4);
649AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rbp, CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw2.) r5);
650AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rsi, CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw2.) r6);
651AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rdi, CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw2.) r7);
652AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rax, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) eax);
653AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rcx, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) ecx);
654AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rdx, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) edx);
655AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rbx, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) ebx);
656AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rsp, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) esp);
657AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rbp, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) ebp);
658AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rsi, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) esi);
659AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rdi, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) edi);
660AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r8, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) r8d);
661AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r9, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) r9d);
662AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r10, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) r10d);
663AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r11, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) r11d);
664AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r12, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) r12d);
665AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r13, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) r13d);
666AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r14, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) r14d);
667AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r15, CPUMCTX, CPUM_UNION_STRUCT_NM(g,dw.) r15d);
668AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rax, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) ax);
669AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rcx, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) cx);
670AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rdx, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) dx);
671AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rbx, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) bx);
672AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rsp, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) sp);
673AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rbp, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) bp);
674AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rsi, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) si);
675AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rdi, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) di);
676AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r8, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) r8w);
677AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r9, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) r9w);
678AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r10, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) r10w);
679AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r11, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) r11w);
680AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r12, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) r12w);
681AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r13, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) r13w);
682AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r14, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) r14w);
683AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r15, CPUMCTX, CPUM_UNION_STRUCT_NM(g,w.) r15w);
684AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rax, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) al);
685AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rcx, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) cl);
686AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rdx, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) dl);
687AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rbx, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) bl);
688AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rsp, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) spl);
689AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rbp, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) bpl);
690AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rsi, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) sil);
691AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rdi, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) dil);
692AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r8, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) r8l);
693AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r9, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) r9l);
694AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r10, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) r10l);
695AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r11, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) r11l);
696AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r12, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) r12l);
697AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r13, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) r13l);
698AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r14, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) r14l);
699AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r15, CPUMCTX, CPUM_UNION_STRUCT_NM(g,b.) r15l);
700AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_NM(s.) CPUM_STRUCT_NM(n.) es, CPUMCTX, CPUM_UNION_NM(s.) aSRegs);
701# ifndef _MSC_VER
702AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rax, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_xAX]);
703AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rcx, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_xCX]);
704AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rdx, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_xDX]);
705AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rbx, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_xBX]);
706AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rsp, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_xSP]);
707AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rbp, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_xBP]);
708AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rsi, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_xSI]);
709AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) rdi, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_xDI]);
710AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r8, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_x8]);
711AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r9, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_x9]);
712AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r10, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_x10]);
713AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r11, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_x11]);
714AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r12, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_x12]);
715AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r13, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_x13]);
716AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r14, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_x14]);
717AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(g,qw.) r15, CPUMCTX, CPUM_UNION_NM(g.) aGRegs[X86_GREG_x15]);
718AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(s,n.) es, CPUMCTX, CPUM_UNION_NM(s.) aSRegs[X86_SREG_ES]);
719AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(s,n.) cs, CPUMCTX, CPUM_UNION_NM(s.) aSRegs[X86_SREG_CS]);
720AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(s,n.) ss, CPUMCTX, CPUM_UNION_NM(s.) aSRegs[X86_SREG_SS]);
721AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(s,n.) ds, CPUMCTX, CPUM_UNION_NM(s.) aSRegs[X86_SREG_DS]);
722AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(s,n.) fs, CPUMCTX, CPUM_UNION_NM(s.) aSRegs[X86_SREG_FS]);
723AssertCompileMembersAtSameOffset(CPUMCTX, CPUM_UNION_STRUCT_NM(s,n.) gs, CPUMCTX, CPUM_UNION_NM(s.) aSRegs[X86_SREG_GS]);
724# endif
725
726/**
727 * Calculates the pointer to the given extended state component.
728 *
729 * @returns Pointer of type @a a_PtrType
730 * @param a_pCtx Pointer to the context.
731 * @param a_iCompBit The extended state component bit number. This bit
732 * must be set in CPUMCTX::fXStateMask.
733 * @param a_PtrType The pointer type of the extended state component.
734 *
735 */
736#if defined(VBOX_STRICT) && defined(RT_COMPILER_SUPPORTS_LAMBDA)
737# define CPUMCTX_XSAVE_C_PTR(a_pCtx, a_iCompBit, a_PtrType) \
738 ([](PCCPUMCTX a_pLambdaCtx) -> a_PtrType \
739 { \
740 AssertCompile((a_iCompBit) < 64U); \
741 AssertMsg(a_pLambdaCtx->fXStateMask & RT_BIT_64(a_iCompBit), (#a_iCompBit "\n")); \
742 AssertMsg(a_pLambdaCtx->aoffXState[(a_iCompBit)] != UINT16_MAX, (#a_iCompBit "\n")); \
743 return (a_PtrType)((uint8_t *)a_pLambdaCtx->CTX_SUFF(pXState) + a_pLambdaCtx->aoffXState[(a_iCompBit)]); \
744 }(a_pCtx))
745#elif defined(VBOX_STRICT) && defined(__GNUC__)
746# define CPUMCTX_XSAVE_C_PTR(a_pCtx, a_iCompBit, a_PtrType) \
747 __extension__ (\
748 { \
749 AssertCompile((a_iCompBit) < 64U); \
750 AssertMsg((a_pCtx)->fXStateMask & RT_BIT_64(a_iCompBit), (#a_iCompBit "\n")); \
751 AssertMsg((a_pCtx)->aoffXState[(a_iCompBit)] != UINT16_MAX, (#a_iCompBit "\n")); \
752 (a_PtrType)((uint8_t *)(a_pCtx)->CTX_SUFF(pXState) + (a_pCtx)->aoffXState[(a_iCompBit)]); \
753 })
754#else
755# define CPUMCTX_XSAVE_C_PTR(a_pCtx, a_iCompBit, a_PtrType) \
756 ((a_PtrType)((uint8_t *)(a_pCtx)->CTX_SUFF(pXState) + (a_pCtx)->aoffXState[(a_iCompBit)]))
757#endif
758
759/**
760 * Gets the CPUMCTXCORE part of a CPUMCTX.
761 */
762# define CPUMCTX2CORE(pCtx) ((PCPUMCTXCORE)(void *)&(pCtx)->rax)
763
764/**
765 * Gets the CPUMCTX part from a CPUMCTXCORE.
766 */
767# define CPUMCTX_FROM_CORE(a_pCtxCore) RT_FROM_MEMBER(a_pCtxCore, CPUMCTX, rax)
768
769/**
770 * Gets the first selector register of a CPUMCTX.
771 *
772 * Use this with X86_SREG_COUNT to loop thru the selector registers.
773 */
774# define CPUMCTX_FIRST_SREG(a_pCtx) (&(a_pCtx)->es)
775
776#endif /* !VBOX_FOR_DTRACE_LIB */
777
778
779/** @name CPUMCTX_WSF_XXX
780 * @{ */
781/** Touch IA32_PRED_CMD.IBPB on VM exit. */
782#define CPUMCTX_WSF_IBPB_EXIT RT_BIT_32(0)
783/** Touch IA32_PRED_CMD.IBPB on VM entry. */
784#define CPUMCTX_WSF_IBPB_ENTRY RT_BIT_32(1)
785/** @} */
786
787/** @name CPUMCTX_EXTRN_XXX
788 * Used for parts of the CPUM state that is externalized and needs fetching
789 * before use.
790 *
791 * @{ */
792/** External state keeper: Invalid. */
793#define CPUMCTX_EXTRN_KEEPER_INVALID UINT64_C(0x0000000000000000)
794/** External state keeper: HM. */
795#define CPUMCTX_EXTRN_KEEPER_HM UINT64_C(0x0000000000000001)
796/** External state keeper: NEM. */
797#define CPUMCTX_EXTRN_KEEPER_NEM UINT64_C(0x0000000000000002)
798/** External state keeper: REM. */
799#define CPUMCTX_EXTRN_KEEPER_REM UINT64_C(0x0000000000000003)
800/** External state keeper mask. */
801#define CPUMCTX_EXTRN_KEEPER_MASK UINT64_C(0x0000000000000003)
802
803/** The RIP register value is kept externally. */
804#define CPUMCTX_EXTRN_RIP UINT64_C(0x0000000000000004)
805/** The RFLAGS register values are kept externally. */
806#define CPUMCTX_EXTRN_RFLAGS UINT64_C(0x0000000000000008)
807
808/** The RAX register value is kept externally. */
809#define CPUMCTX_EXTRN_RAX UINT64_C(0x0000000000000010)
810/** The RCX register value is kept externally. */
811#define CPUMCTX_EXTRN_RCX UINT64_C(0x0000000000000020)
812/** The RDX register value is kept externally. */
813#define CPUMCTX_EXTRN_RDX UINT64_C(0x0000000000000040)
814/** The RBX register value is kept externally. */
815#define CPUMCTX_EXTRN_RBX UINT64_C(0x0000000000000080)
816/** The RSP register value is kept externally. */
817#define CPUMCTX_EXTRN_RSP UINT64_C(0x0000000000000100)
818/** The RBP register value is kept externally. */
819#define CPUMCTX_EXTRN_RBP UINT64_C(0x0000000000000200)
820/** The RSI register value is kept externally. */
821#define CPUMCTX_EXTRN_RSI UINT64_C(0x0000000000000400)
822/** The RDI register value is kept externally. */
823#define CPUMCTX_EXTRN_RDI UINT64_C(0x0000000000000800)
824/** The R8 thru R15 register values are kept externally. */
825#define CPUMCTX_EXTRN_R8_R15 UINT64_C(0x0000000000001000)
826/** General purpose registers mask. */
827#define CPUMCTX_EXTRN_GPRS_MASK UINT64_C(0x0000000000001ff0)
828
829/** The ES register values are kept externally. */
830#define CPUMCTX_EXTRN_ES UINT64_C(0x0000000000002000)
831/** The CS register values are kept externally. */
832#define CPUMCTX_EXTRN_CS UINT64_C(0x0000000000004000)
833/** The SS register values are kept externally. */
834#define CPUMCTX_EXTRN_SS UINT64_C(0x0000000000008000)
835/** The DS register values are kept externally. */
836#define CPUMCTX_EXTRN_DS UINT64_C(0x0000000000010000)
837/** The FS register values are kept externally. */
838#define CPUMCTX_EXTRN_FS UINT64_C(0x0000000000020000)
839/** The GS register values are kept externally. */
840#define CPUMCTX_EXTRN_GS UINT64_C(0x0000000000040000)
841/** Segment registers (includes CS). */
842#define CPUMCTX_EXTRN_SREG_MASK UINT64_C(0x000000000007e000)
843/** Converts a X86_XREG_XXX index to a CPUMCTX_EXTRN_xS mask. */
844#define CPUMCTX_EXTRN_SREG_FROM_IDX(a_SRegIdx) RT_BIT_64((a_SRegIdx) + 13)
845#ifndef VBOX_FOR_DTRACE_LIB
846AssertCompile(CPUMCTX_EXTRN_SREG_FROM_IDX(X86_SREG_ES) == CPUMCTX_EXTRN_ES);
847AssertCompile(CPUMCTX_EXTRN_SREG_FROM_IDX(X86_SREG_CS) == CPUMCTX_EXTRN_CS);
848AssertCompile(CPUMCTX_EXTRN_SREG_FROM_IDX(X86_SREG_DS) == CPUMCTX_EXTRN_DS);
849AssertCompile(CPUMCTX_EXTRN_SREG_FROM_IDX(X86_SREG_FS) == CPUMCTX_EXTRN_FS);
850AssertCompile(CPUMCTX_EXTRN_SREG_FROM_IDX(X86_SREG_GS) == CPUMCTX_EXTRN_GS);
851#endif
852
853/** The GDTR register values are kept externally. */
854#define CPUMCTX_EXTRN_GDTR UINT64_C(0x0000000000080000)
855/** The IDTR register values are kept externally. */
856#define CPUMCTX_EXTRN_IDTR UINT64_C(0x0000000000100000)
857/** The LDTR register values are kept externally. */
858#define CPUMCTX_EXTRN_LDTR UINT64_C(0x0000000000200000)
859/** The TR register values are kept externally. */
860#define CPUMCTX_EXTRN_TR UINT64_C(0x0000000000400000)
861/** Table register mask. */
862#define CPUMCTX_EXTRN_TABLE_MASK UINT64_C(0x0000000000780000)
863
864/** The CR0 register value is kept externally. */
865#define CPUMCTX_EXTRN_CR0 UINT64_C(0x0000000000800000)
866/** The CR2 register value is kept externally. */
867#define CPUMCTX_EXTRN_CR2 UINT64_C(0x0000000001000000)
868/** The CR3 register value is kept externally. */
869#define CPUMCTX_EXTRN_CR3 UINT64_C(0x0000000002000000)
870/** The CR4 register value is kept externally. */
871#define CPUMCTX_EXTRN_CR4 UINT64_C(0x0000000004000000)
872/** Control register mask. */
873#define CPUMCTX_EXTRN_CR_MASK UINT64_C(0x0000000007800000)
874/** The TPR/CR8 register value is kept externally. */
875#define CPUMCTX_EXTRN_APIC_TPR UINT64_C(0x0000000008000000)
876/** The EFER register value is kept externally. */
877#define CPUMCTX_EXTRN_EFER UINT64_C(0x0000000010000000)
878
879/** The DR0, DR1, DR2 and DR3 register values are kept externally. */
880#define CPUMCTX_EXTRN_DR0_DR3 UINT64_C(0x0000000020000000)
881/** The DR6 register value is kept externally. */
882#define CPUMCTX_EXTRN_DR6 UINT64_C(0x0000000040000000)
883/** The DR7 register value is kept externally. */
884#define CPUMCTX_EXTRN_DR7 UINT64_C(0x0000000080000000)
885/** Debug register mask. */
886#define CPUMCTX_EXTRN_DR_MASK UINT64_C(0x00000000e0000000)
887
888/** The XSAVE_C_X87 state is kept externally. */
889#define CPUMCTX_EXTRN_X87 UINT64_C(0x0000000100000000)
890/** The XSAVE_C_SSE, XSAVE_C_YMM, XSAVE_C_ZMM_HI256, XSAVE_C_ZMM_16HI and
891 * XSAVE_C_OPMASK state is kept externally. */
892#define CPUMCTX_EXTRN_SSE_AVX UINT64_C(0x0000000200000000)
893/** The state of XSAVE components not covered by CPUMCTX_EXTRN_X87 and
894 * CPUMCTX_EXTRN_SEE_AVX is kept externally. */
895#define CPUMCTX_EXTRN_OTHER_XSAVE UINT64_C(0x0000000400000000)
896/** The state of XCR0 and XCR1 register values are kept externally. */
897#define CPUMCTX_EXTRN_XCRx UINT64_C(0x0000000800000000)
898
899
900/** The KERNEL GS BASE MSR value is kept externally. */
901#define CPUMCTX_EXTRN_KERNEL_GS_BASE UINT64_C(0x0000001000000000)
902/** The STAR, LSTAR, CSTAR and SFMASK MSR values are kept externally. */
903#define CPUMCTX_EXTRN_SYSCALL_MSRS UINT64_C(0x0000002000000000)
904/** The SYSENTER_CS, SYSENTER_EIP and SYSENTER_ESP MSR values are kept externally. */
905#define CPUMCTX_EXTRN_SYSENTER_MSRS UINT64_C(0x0000004000000000)
906/** The TSC_AUX MSR is kept externally. */
907#define CPUMCTX_EXTRN_TSC_AUX UINT64_C(0x0000008000000000)
908/** All other stateful MSRs not covered by CPUMCTX_EXTRN_EFER,
909 * CPUMCTX_EXTRN_KERNEL_GS_BASE, CPUMCTX_EXTRN_SYSCALL_MSRS,
910 * CPUMCTX_EXTRN_SYSENTER_MSRS, and CPUMCTX_EXTRN_TSC_AUX. */
911#define CPUMCTX_EXTRN_OTHER_MSRS UINT64_C(0x0000010000000000)
912
913/** Mask of all the MSRs. */
914#define CPUMCTX_EXTRN_ALL_MSRS ( CPUMCTX_EXTRN_EFER | CPUMCTX_EXTRN_KERNEL_GS_BASE | CPUMCTX_EXTRN_SYSCALL_MSRS \
915 | CPUMCTX_EXTRN_SYSENTER_MSRS | CPUMCTX_EXTRN_TSC_AUX | CPUMCTX_EXTRN_OTHER_MSRS)
916
917/** Hardware-virtualization (SVM or VMX) state is kept externally. */
918#define CPUMCTX_EXTRN_HWVIRT UINT64_C(0x0000020000000000)
919
920/** Mask of bits the keepers can use for state tracking. */
921#define CPUMCTX_EXTRN_KEEPER_STATE_MASK UINT64_C(0xffff000000000000)
922
923/** NEM/Win: Event injection (known was interruption) pending state. */
924#define CPUMCTX_EXTRN_NEM_WIN_EVENT_INJECT UINT64_C(0x0001000000000000)
925/** NEM/Win: Inhibit maskable interrupts (VMCPU_FF_INHIBIT_INTERRUPTS). */
926#define CPUMCTX_EXTRN_NEM_WIN_INHIBIT_INT UINT64_C(0x0002000000000000)
927/** NEM/Win: Inhibit non-maskable interrupts (VMCPU_FF_BLOCK_NMIS). */
928#define CPUMCTX_EXTRN_NEM_WIN_INHIBIT_NMI UINT64_C(0x0004000000000000)
929/** NEM/Win: Mask. */
930#define CPUMCTX_EXTRN_NEM_WIN_MASK UINT64_C(0x0007000000000000)
931
932/** HM/SVM: Inhibit maskable interrupts (VMCPU_FF_INHIBIT_INTERRUPTS). */
933#define CPUMCTX_EXTRN_HM_SVM_INT_SHADOW UINT64_C(0x0001000000000000)
934/** HM/SVM: Nested-guest interrupt pending (VMCPU_FF_INTERRUPT_NESTED_GUEST). */
935#define CPUMCTX_EXTRN_HM_SVM_HWVIRT_VIRQ UINT64_C(0x0002000000000000)
936/** HM/SVM: Mask. */
937#define CPUMCTX_EXTRN_HM_SVM_MASK UINT64_C(0x0003000000000000)
938
939/** HM/VMX: Guest-interruptibility state (VMCPU_FF_INHIBIT_INTERRUPTS,
940 * VMCPU_FF_BLOCK_NMIS). */
941#define CPUMCTX_EXTRN_HM_VMX_INT_STATE UINT64_C(0x0001000000000000)
942/** HM/VMX: Mask. */
943#define CPUMCTX_EXTRN_HM_VMX_MASK UINT64_C(0x0001000000000000)
944
945/** All CPUM state bits, not including keeper specific ones. */
946#define CPUMCTX_EXTRN_ALL UINT64_C(0x000003fffffffffc)
947/** All CPUM state bits, including keeper specific ones. */
948#define CPUMCTX_EXTRN_ABSOLUTELY_ALL UINT64_C(0xfffffffffffffffc)
949/** @} */
950
951
952/**
953 * Additional guest MSRs (i.e. not part of the CPU context structure).
954 *
955 * @remarks Never change the order here because of the saved stated! The size
956 * can in theory be changed, but keep older VBox versions in mind.
957 */
958typedef union CPUMCTXMSRS
959{
960 struct
961 {
962 uint64_t TscAux; /**< MSR_K8_TSC_AUX */
963 uint64_t MiscEnable; /**< MSR_IA32_MISC_ENABLE */
964 uint64_t MtrrDefType; /**< IA32_MTRR_DEF_TYPE */
965 uint64_t MtrrFix64K_00000; /**< IA32_MTRR_FIX16K_80000 */
966 uint64_t MtrrFix16K_80000; /**< IA32_MTRR_FIX16K_80000 */
967 uint64_t MtrrFix16K_A0000; /**< IA32_MTRR_FIX16K_A0000 */
968 uint64_t MtrrFix4K_C0000; /**< IA32_MTRR_FIX4K_C0000 */
969 uint64_t MtrrFix4K_C8000; /**< IA32_MTRR_FIX4K_C8000 */
970 uint64_t MtrrFix4K_D0000; /**< IA32_MTRR_FIX4K_D0000 */
971 uint64_t MtrrFix4K_D8000; /**< IA32_MTRR_FIX4K_D8000 */
972 uint64_t MtrrFix4K_E0000; /**< IA32_MTRR_FIX4K_E0000 */
973 uint64_t MtrrFix4K_E8000; /**< IA32_MTRR_FIX4K_E8000 */
974 uint64_t MtrrFix4K_F0000; /**< IA32_MTRR_FIX4K_F0000 */
975 uint64_t MtrrFix4K_F8000; /**< IA32_MTRR_FIX4K_F8000 */
976 uint64_t PkgCStateCfgCtrl; /**< MSR_PKG_CST_CONFIG_CONTROL */
977 uint64_t SpecCtrl; /**< IA32_SPEC_CTRL */
978 uint64_t ArchCaps; /**< IA32_ARCH_CAPABILITIES */
979 } msr;
980 uint64_t au64[64];
981} CPUMCTXMSRS;
982/** Pointer to the guest MSR state. */
983typedef CPUMCTXMSRS *PCPUMCTXMSRS;
984/** Pointer to the const guest MSR state. */
985typedef const CPUMCTXMSRS *PCCPUMCTXMSRS;
986
987/**
988 * The register set returned by a CPUID operation.
989 */
990typedef struct CPUMCPUID
991{
992 uint32_t uEax;
993 uint32_t uEbx;
994 uint32_t uEcx;
995 uint32_t uEdx;
996} CPUMCPUID;
997/** Pointer to a CPUID leaf. */
998typedef CPUMCPUID *PCPUMCPUID;
999/** Pointer to a const CPUID leaf. */
1000typedef const CPUMCPUID *PCCPUMCPUID;
1001
1002/** @} */
1003
1004RT_C_DECLS_END
1005
1006#endif
1007
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use