VirtualBox

source: vbox/trunk/include/VBox/vmm/hm_vmx.h@ 46197

Last change on this file since 46197 was 46004, checked in by vboxsync, 12 years ago

VMM/HMVMXR0: DR7 is 32-bit in reality, upper bits are reserved MBZ, so avoid complicated guest-natural width writes and going through the VMCS cache unnecessarily.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 74.8 KB
Line 
1/** @file
2 * HM - VMX Structures and Definitions. (VMM)
3 */
4
5/*
6 * Copyright (C) 2006-2013 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_vmx_h
27#define ___VBox_vmm_vmx_h
28
29#include <VBox/types.h>
30#include <VBox/err.h>
31#include <iprt/x86.h>
32#include <iprt/assert.h>
33
34/** @defgroup grp_vmx vmx Types and Definitions
35 * @ingroup grp_hm
36 * @{
37 */
38
39/** @name VMX VMCS-Read cache indices.
40 * @{
41 */
42#ifndef VBOX_WITH_OLD_VTX_CODE
43# define VMX_VMCS_GUEST_ES_BASE_CACHE_IDX 0
44# define VMX_VMCS_GUEST_CS_BASE_CACHE_IDX 1
45# define VMX_VMCS_GUEST_SS_BASE_CACHE_IDX 2
46# define VMX_VMCS_GUEST_DS_BASE_CACHE_IDX 3
47# define VMX_VMCS_GUEST_FS_BASE_CACHE_IDX 4
48# define VMX_VMCS_GUEST_GS_BASE_CACHE_IDX 5
49# define VMX_VMCS_GUEST_LDTR_BASE_CACHE_IDX 6
50# define VMX_VMCS_GUEST_TR_BASE_CACHE_IDX 7
51# define VMX_VMCS_GUEST_GDTR_BASE_CACHE_IDX 8
52# define VMX_VMCS_GUEST_IDTR_BASE_CACHE_IDX 9
53# define VMX_VMCS_GUEST_RSP_CACHE_IDX 10
54# define VMX_VMCS_GUEST_RIP_CACHE_IDX 11
55# define VMX_VMCS_GUEST_SYSENTER_ESP_CACHE_IDX 12
56# define VMX_VMCS_GUEST_SYSENTER_EIP_CACHE_IDX 13
57# define VMX_VMCS_RO_EXIT_QUALIFICATION_CACHE_IDX 14
58# define VMX_VMCS_MAX_CACHE_IDX (VMX_VMCS_RO_EXIT_QUALIFICATION_CACHE_IDX + 1)
59# define VMX_VMCS_GUEST_CR3_CACHE_IDX 15
60# define VMX_VMCS_MAX_NESTED_PAGING_CACHE_IDX (VMX_VMCS_GUEST_CR3_CACHE_IDX + 1)
61#else /* VBOX_WITH_OLD_VTX_CODE */
62# define VMX_VMCS_GUEST_RIP_CACHE_IDX 0
63# define VMX_VMCS_GUEST_RSP_CACHE_IDX 1
64# define VMX_VMCS_GUEST_RFLAGS_CACHE_IDX 2
65# define VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE_CACHE_IDX 3
66# define VMX_VMCS_CTRL_CR0_READ_SHADOW_CACHE_IDX 4
67# define VMX_VMCS_GUEST_CR0_CACHE_IDX 5
68# define VMX_VMCS_CTRL_CR4_READ_SHADOW_CACHE_IDX 6
69# define VMX_VMCS_GUEST_CR4_CACHE_IDX 7
70# define VMX_VMCS_GUEST_DR7_CACHE_IDX 8
71# define VMX_VMCS32_GUEST_SYSENTER_CS_CACHE_IDX 9
72# define VMX_VMCS_GUEST_SYSENTER_EIP_CACHE_IDX 10
73# define VMX_VMCS_GUEST_SYSENTER_ESP_CACHE_IDX 11
74# define VMX_VMCS32_GUEST_GDTR_LIMIT_CACHE_IDX 12
75# define VMX_VMCS_GUEST_GDTR_BASE_CACHE_IDX 13
76# define VMX_VMCS32_GUEST_IDTR_LIMIT_CACHE_IDX 14
77# define VMX_VMCS_GUEST_IDTR_BASE_CACHE_IDX 15
78# define VMX_VMCS16_GUEST_FIELD_CS_CACHE_IDX 16
79# define VMX_VMCS32_GUEST_CS_LIMIT_CACHE_IDX 17
80# define VMX_VMCS_GUEST_CS_BASE_CACHE_IDX 18
81# define VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS_CACHE_IDX 19
82# define VMX_VMCS16_GUEST_FIELD_DS_CACHE_IDX 20
83# define VMX_VMCS32_GUEST_DS_LIMIT_CACHE_IDX 21
84# define VMX_VMCS_GUEST_DS_BASE_CACHE_IDX 22
85# define VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS_CACHE_IDX 23
86# define VMX_VMCS16_GUEST_FIELD_ES_CACHE_IDX 24
87# define VMX_VMCS32_GUEST_ES_LIMIT_CACHE_IDX 25
88# define VMX_VMCS_GUEST_ES_BASE_CACHE_IDX 26
89# define VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS_CACHE_IDX 27
90# define VMX_VMCS16_GUEST_FIELD_FS_CACHE_IDX 28
91# define VMX_VMCS32_GUEST_FS_LIMIT_CACHE_IDX 29
92# define VMX_VMCS_GUEST_FS_BASE_CACHE_IDX 30
93# define VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS_CACHE_IDX 31
94# define VMX_VMCS16_GUEST_FIELD_GS_CACHE_IDX 32
95# define VMX_VMCS32_GUEST_GS_LIMIT_CACHE_IDX 33
96# define VMX_VMCS_GUEST_GS_BASE_CACHE_IDX 34
97# define VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS_CACHE_IDX 35
98# define VMX_VMCS16_GUEST_FIELD_SS_CACHE_IDX 36
99# define VMX_VMCS32_GUEST_SS_LIMIT_CACHE_IDX 37
100# define VMX_VMCS_GUEST_SS_BASE_CACHE_IDX 38
101# define VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS_CACHE_IDX 39
102# define VMX_VMCS16_GUEST_FIELD_TR_CACHE_IDX 40
103# define VMX_VMCS32_GUEST_TR_LIMIT_CACHE_IDX 41
104# define VMX_VMCS_GUEST_TR_BASE_CACHE_IDX 42
105# define VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS_CACHE_IDX 43
106# define VMX_VMCS16_GUEST_FIELD_LDTR_CACHE_IDX 44
107# define VMX_VMCS32_GUEST_LDTR_LIMIT_CACHE_IDX 45
108# define VMX_VMCS_GUEST_LDTR_BASE_CACHE_IDX 46
109# define VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS_CACHE_IDX 47
110# define VMX_VMCS32_RO_EXIT_REASON_CACHE_IDX 48
111# define VMX_VMCS32_RO_VM_INSTR_ERROR_CACHE_IDX 49
112# define VMX_VMCS32_RO_EXIT_INSTR_LENGTH_CACHE_IDX 50
113# define VMX_VMCS32_RO_EXIT_INTERRUPTION_ERROR_CODE_CACHE_IDX 51
114# define VMX_VMCS32_RO_EXIT_INSTR_INFO_CACHE_IDX 52
115# define VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO_CACHE_IDX 53
116# define VMX_VMCS_RO_EXIT_QUALIFICATION_CACHE_IDX 54
117# define VMX_VMCS32_RO_IDT_INFO_CACHE_IDX 55
118# define VMX_VMCS32_RO_IDT_ERROR_CODE_CACHE_IDX 56
119# define VMX_VMCS_MAX_CACHE_IDX (VMX_VMCS32_RO_IDT_ERROR_CODE_CACHE_IDX + 1)
120# define VMX_VMCS_GUEST_CR3_CACHE_IDX 57
121# define VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_FULL_CACHE_IDX 58
122# define VMX_VMCS_MAX_NESTED_PAGING_CACHE_IDX (VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_FULL_CACHE_IDX + 1)
123#endif /* VBOX_WITH_OLD_VTX_CODE */
124/** @} */
125
126
127/** @name VMX EPT paging structures
128 * @{
129 */
130
131/**
132 * Number of page table entries in the EPT. (PDPTE/PDE/PTE)
133 */
134#define EPT_PG_ENTRIES X86_PG_PAE_ENTRIES
135
136/**
137 * EPT Page Directory Pointer Entry. Bit view.
138 * @todo uint64_t isn't safe for bitfields (gcc pedantic warnings, and IIRC,
139 * this did cause trouble with one compiler/version).
140 */
141#pragma pack(1)
142typedef struct EPTPML4EBITS
143{
144 /** Present bit. */
145 uint64_t u1Present : 1;
146 /** Writable bit. */
147 uint64_t u1Write : 1;
148 /** Executable bit. */
149 uint64_t u1Execute : 1;
150 /** Reserved (must be 0). */
151 uint64_t u5Reserved : 5;
152 /** Available for software. */
153 uint64_t u4Available : 4;
154 /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */
155 uint64_t u40PhysAddr : 40;
156 /** Availabe for software. */
157 uint64_t u12Available : 12;
158} EPTPML4EBITS;
159#pragma pack()
160AssertCompileSize(EPTPML4EBITS, 8);
161
162/** Bits 12-51 - - EPT - Physical Page number of the next level. */
163#define EPT_PML4E_PG_MASK X86_PML4E_PG_MASK
164/** The page shift to get the PML4 index. */
165#define EPT_PML4_SHIFT X86_PML4_SHIFT
166/** The PML4 index mask (apply to a shifted page address). */
167#define EPT_PML4_MASK X86_PML4_MASK
168
169/**
170 * EPT PML4E.
171 */
172#pragma pack(1)
173typedef union EPTPML4E
174{
175 /** Normal view. */
176 EPTPML4EBITS n;
177 /** Unsigned integer view. */
178 X86PGPAEUINT u;
179 /** 64 bit unsigned integer view. */
180 uint64_t au64[1];
181 /** 32 bit unsigned integer view. */
182 uint32_t au32[2];
183} EPTPML4E;
184#pragma pack()
185/** Pointer to a PML4 table entry. */
186typedef EPTPML4E *PEPTPML4E;
187/** Pointer to a const PML4 table entry. */
188typedef const EPTPML4E *PCEPTPML4E;
189AssertCompileSize(EPTPML4E, 8);
190
191/**
192 * EPT PML4 Table.
193 */
194#pragma pack(1)
195typedef struct EPTPML4
196{
197 EPTPML4E a[EPT_PG_ENTRIES];
198} EPTPML4;
199#pragma pack()
200/** Pointer to an EPT PML4 Table. */
201typedef EPTPML4 *PEPTPML4;
202/** Pointer to a const EPT PML4 Table. */
203typedef const EPTPML4 *PCEPTPML4;
204
205/**
206 * EPT Page Directory Pointer Entry. Bit view.
207 */
208#pragma pack(1)
209typedef struct EPTPDPTEBITS
210{
211 /** Present bit. */
212 uint64_t u1Present : 1;
213 /** Writable bit. */
214 uint64_t u1Write : 1;
215 /** Executable bit. */
216 uint64_t u1Execute : 1;
217 /** Reserved (must be 0). */
218 uint64_t u5Reserved : 5;
219 /** Available for software. */
220 uint64_t u4Available : 4;
221 /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */
222 uint64_t u40PhysAddr : 40;
223 /** Availabe for software. */
224 uint64_t u12Available : 12;
225} EPTPDPTEBITS;
226#pragma pack()
227AssertCompileSize(EPTPDPTEBITS, 8);
228
229/** Bits 12-51 - - EPT - Physical Page number of the next level. */
230#define EPT_PDPTE_PG_MASK X86_PDPE_PG_MASK
231/** The page shift to get the PDPT index. */
232#define EPT_PDPT_SHIFT X86_PDPT_SHIFT
233/** The PDPT index mask (apply to a shifted page address). */
234#define EPT_PDPT_MASK X86_PDPT_MASK_AMD64
235
236/**
237 * EPT Page Directory Pointer.
238 */
239#pragma pack(1)
240typedef union EPTPDPTE
241{
242 /** Normal view. */
243 EPTPDPTEBITS n;
244 /** Unsigned integer view. */
245 X86PGPAEUINT u;
246 /** 64 bit unsigned integer view. */
247 uint64_t au64[1];
248 /** 32 bit unsigned integer view. */
249 uint32_t au32[2];
250} EPTPDPTE;
251#pragma pack()
252/** Pointer to an EPT Page Directory Pointer Entry. */
253typedef EPTPDPTE *PEPTPDPTE;
254/** Pointer to a const EPT Page Directory Pointer Entry. */
255typedef const EPTPDPTE *PCEPTPDPTE;
256AssertCompileSize(EPTPDPTE, 8);
257
258/**
259 * EPT Page Directory Pointer Table.
260 */
261#pragma pack(1)
262typedef struct EPTPDPT
263{
264 EPTPDPTE a[EPT_PG_ENTRIES];
265} EPTPDPT;
266#pragma pack()
267/** Pointer to an EPT Page Directory Pointer Table. */
268typedef EPTPDPT *PEPTPDPT;
269/** Pointer to a const EPT Page Directory Pointer Table. */
270typedef const EPTPDPT *PCEPTPDPT;
271
272
273/**
274 * EPT Page Directory Table Entry. Bit view.
275 */
276#pragma pack(1)
277typedef struct EPTPDEBITS
278{
279 /** Present bit. */
280 uint64_t u1Present : 1;
281 /** Writable bit. */
282 uint64_t u1Write : 1;
283 /** Executable bit. */
284 uint64_t u1Execute : 1;
285 /** Reserved (must be 0). */
286 uint64_t u4Reserved : 4;
287 /** Big page (must be 0 here). */
288 uint64_t u1Size : 1;
289 /** Available for software. */
290 uint64_t u4Available : 4;
291 /** Physical address of page table. Restricted by maximum physical address width of the cpu. */
292 uint64_t u40PhysAddr : 40;
293 /** Availabe for software. */
294 uint64_t u12Available : 12;
295} EPTPDEBITS;
296#pragma pack()
297AssertCompileSize(EPTPDEBITS, 8);
298
299/** Bits 12-51 - - EPT - Physical Page number of the next level. */
300#define EPT_PDE_PG_MASK X86_PDE_PAE_PG_MASK
301/** The page shift to get the PD index. */
302#define EPT_PD_SHIFT X86_PD_PAE_SHIFT
303/** The PD index mask (apply to a shifted page address). */
304#define EPT_PD_MASK X86_PD_PAE_MASK
305
306/**
307 * EPT 2MB Page Directory Table Entry. Bit view.
308 */
309#pragma pack(1)
310typedef struct EPTPDE2MBITS
311{
312 /** Present bit. */
313 uint64_t u1Present : 1;
314 /** Writable bit. */
315 uint64_t u1Write : 1;
316 /** Executable bit. */
317 uint64_t u1Execute : 1;
318 /** EPT Table Memory Type. MBZ for non-leaf nodes. */
319 uint64_t u3EMT : 3;
320 /** Ignore PAT memory type */
321 uint64_t u1IgnorePAT : 1;
322 /** Big page (must be 1 here). */
323 uint64_t u1Size : 1;
324 /** Available for software. */
325 uint64_t u4Available : 4;
326 /** Reserved (must be 0). */
327 uint64_t u9Reserved : 9;
328 /** Physical address of the 2MB page. Restricted by maximum physical address width of the cpu. */
329 uint64_t u31PhysAddr : 31;
330 /** Availabe for software. */
331 uint64_t u12Available : 12;
332} EPTPDE2MBITS;
333#pragma pack()
334AssertCompileSize(EPTPDE2MBITS, 8);
335
336/** Bits 21-51 - - EPT - Physical Page number of the next level. */
337#define EPT_PDE2M_PG_MASK X86_PDE2M_PAE_PG_MASK
338
339/**
340 * EPT Page Directory Table Entry.
341 */
342#pragma pack(1)
343typedef union EPTPDE
344{
345 /** Normal view. */
346 EPTPDEBITS n;
347 /** 2MB view (big). */
348 EPTPDE2MBITS b;
349 /** Unsigned integer view. */
350 X86PGPAEUINT u;
351 /** 64 bit unsigned integer view. */
352 uint64_t au64[1];
353 /** 32 bit unsigned integer view. */
354 uint32_t au32[2];
355} EPTPDE;
356#pragma pack()
357/** Pointer to an EPT Page Directory Table Entry. */
358typedef EPTPDE *PEPTPDE;
359/** Pointer to a const EPT Page Directory Table Entry. */
360typedef const EPTPDE *PCEPTPDE;
361AssertCompileSize(EPTPDE, 8);
362
363/**
364 * EPT Page Directory Table.
365 */
366#pragma pack(1)
367typedef struct EPTPD
368{
369 EPTPDE a[EPT_PG_ENTRIES];
370} EPTPD;
371#pragma pack()
372/** Pointer to an EPT Page Directory Table. */
373typedef EPTPD *PEPTPD;
374/** Pointer to a const EPT Page Directory Table. */
375typedef const EPTPD *PCEPTPD;
376
377
378/**
379 * EPT Page Table Entry. Bit view.
380 */
381#pragma pack(1)
382typedef struct EPTPTEBITS
383{
384 /** 0 - Present bit.
385 * @remark This is a convenience "misnomer". The bit actually indicates
386 * read access and the CPU will consider an entry with any of the
387 * first three bits set as present. Since all our valid entries
388 * will have this bit set, it can be used as a present indicator
389 * and allow some code sharing. */
390 uint64_t u1Present : 1;
391 /** 1 - Writable bit. */
392 uint64_t u1Write : 1;
393 /** 2 - Executable bit. */
394 uint64_t u1Execute : 1;
395 /** 5:3 - EPT Memory Type. MBZ for non-leaf nodes. */
396 uint64_t u3EMT : 3;
397 /** 6 - Ignore PAT memory type */
398 uint64_t u1IgnorePAT : 1;
399 /** 11:7 - Available for software. */
400 uint64_t u5Available : 5;
401 /** 51:12 - Physical address of page. Restricted by maximum physical
402 * address width of the cpu. */
403 uint64_t u40PhysAddr : 40;
404 /** 63:52 - Available for software. */
405 uint64_t u12Available : 12;
406} EPTPTEBITS;
407#pragma pack()
408AssertCompileSize(EPTPTEBITS, 8);
409
410/** Bits 12-51 - - EPT - Physical Page number of the next level. */
411#define EPT_PTE_PG_MASK X86_PTE_PAE_PG_MASK
412/** The page shift to get the EPT PTE index. */
413#define EPT_PT_SHIFT X86_PT_PAE_SHIFT
414/** The EPT PT index mask (apply to a shifted page address). */
415#define EPT_PT_MASK X86_PT_PAE_MASK
416
417/**
418 * EPT Page Table Entry.
419 */
420#pragma pack(1)
421typedef union EPTPTE
422{
423 /** Normal view. */
424 EPTPTEBITS n;
425 /** Unsigned integer view. */
426 X86PGPAEUINT u;
427 /** 64 bit unsigned integer view. */
428 uint64_t au64[1];
429 /** 32 bit unsigned integer view. */
430 uint32_t au32[2];
431} EPTPTE;
432#pragma pack()
433/** Pointer to an EPT Page Directory Table Entry. */
434typedef EPTPTE *PEPTPTE;
435/** Pointer to a const EPT Page Directory Table Entry. */
436typedef const EPTPTE *PCEPTPTE;
437AssertCompileSize(EPTPTE, 8);
438
439/**
440 * EPT Page Table.
441 */
442#pragma pack(1)
443typedef struct EPTPT
444{
445 EPTPTE a[EPT_PG_ENTRIES];
446} EPTPT;
447#pragma pack()
448/** Pointer to an extended page table. */
449typedef EPTPT *PEPTPT;
450/** Pointer to a const extended table. */
451typedef const EPTPT *PCEPTPT;
452
453/**
454 * VPID flush types.
455 */
456typedef enum
457{
458 /** Invalidate a specific page. */
459 VMX_FLUSH_VPID_INDIV_ADDR = 0,
460 /** Invalidate one context (specific VPID). */
461 VMX_FLUSH_VPID_SINGLE_CONTEXT = 1,
462 /** Invalidate all contexts (all VPIDs). */
463 VMX_FLUSH_VPID_ALL_CONTEXTS = 2,
464 /** Invalidate a single VPID context retaining global mappings. */
465 VMX_FLUSH_VPID_SINGLE_CONTEXT_RETAIN_GLOBALS = 3,
466 /** Unsupported by VirtualBox. */
467 VMX_FLUSH_VPID_NOT_SUPPORTED = 0xbad,
468 /** Unsupported by CPU. */
469 VMX_FLUSH_VPID_NONE = 0xb00,
470 /** 32bit hackishness. */
471 VMX_FLUSH_VPID_32BIT_HACK = 0x7fffffff
472} VMX_FLUSH_VPID;
473
474/**
475 * EPT flush types.
476 */
477typedef enum
478{
479 /** Invalidate one context (specific EPT). */
480 VMX_FLUSH_EPT_SINGLE_CONTEXT = 1,
481 /* Invalidate all contexts (all EPTs) */
482 VMX_FLUSH_EPT_ALL_CONTEXTS = 2,
483 /** Unsupported by VirtualBox. */
484 VMX_FLUSH_EPT_NOT_SUPPORTED = 0xbad,
485 /** Unsupported by CPU. */
486 VMX_FLUSH_EPT_NONE = 0xb00,
487 /** 32bit hackishness. */
488 VMX_FLUSH_EPT_32BIT_HACK = 0x7fffffff
489} VMX_FLUSH_EPT;
490/** @} */
491
492/** @name MSR autoload/store elements
493 * @{
494 */
495#pragma pack(1)
496typedef struct
497{
498 uint32_t u32IndexMSR;
499 uint32_t u32Reserved;
500 uint64_t u64Value;
501} VMXMSR;
502#pragma pack()
503/** Pointer to an MSR load/store element. */
504typedef VMXMSR *PVMXMSR;
505/** Pointer to a const MSR load/store element. */
506typedef const VMXMSR *PCVMXMSR;
507
508/** @} */
509
510
511/** @name VMX-capability qword
512 * @{
513 */
514#pragma pack(1)
515typedef union
516{
517 struct
518 {
519 /** Bits set here -must- be set in the correpsonding VM-execution controls. */
520 uint32_t disallowed0;
521 /** Bits cleared here -must- be cleared in the corresponding VM-execution
522 * controls. */
523 uint32_t allowed1;
524 } n;
525 uint64_t u;
526} VMX_CAPABILITY;
527#pragma pack()
528/** @} */
529
530/** @name VMX EFLAGS reserved bits.
531 * @{
532 */
533/** And-mask for setting reserved bits to zero */
534#define VMX_EFLAGS_RESERVED_0 (~0xffc08028)
535/** Or-mask for setting reserved bits to 1 */
536#define VMX_EFLAGS_RESERVED_1 0x00000002
537/** @} */
538
539/** @name VMX Basic Exit Reasons.
540 * @{
541 */
542/** -1 Invalid exit code */
543#define VMX_EXIT_INVALID -1
544/** 0 Exception or non-maskable interrupt (NMI). */
545#define VMX_EXIT_XCPT_NMI 0
546/** 1 External interrupt. */
547#define VMX_EXIT_EXT_INT 1
548/** 2 Triple fault. */
549#define VMX_EXIT_TRIPLE_FAULT 2
550/** 3 INIT signal. */
551#define VMX_EXIT_INIT_SIGNAL 3
552/** 4 Start-up IPI (SIPI). */
553#define VMX_EXIT_SIPI 4
554/** 5 I/O system-management interrupt (SMI). */
555#define VMX_EXIT_IO_SMI 5
556/** 6 Other SMI. */
557#define VMX_EXIT_SMI 6
558/** 7 Interrupt window exiting. */
559#define VMX_EXIT_INT_WINDOW 7
560/** 8 NMI window exiting. */
561#define VMX_EXIT_NMI_WINDOW 8
562/** 9 Task switch. */
563#define VMX_EXIT_TASK_SWITCH 9
564/** 10 Guest software attempted to execute CPUID. */
565#define VMX_EXIT_CPUID 10
566/** 10 Guest software attempted to execute GETSEC. */
567#define VMX_EXIT_GETSEC 11
568/** 12 Guest software attempted to execute HLT. */
569#define VMX_EXIT_HLT 12
570/** 13 Guest software attempted to execute INVD. */
571#define VMX_EXIT_INVD 13
572/** 14 Guest software attempted to execute INVLPG. */
573#define VMX_EXIT_INVLPG 14
574/** 15 Guest software attempted to execute RDPMC. */
575#define VMX_EXIT_RDPMC 15
576/** 16 Guest software attempted to execute RDTSC. */
577#define VMX_EXIT_RDTSC 16
578/** 17 Guest software attempted to execute RSM in SMM. */
579#define VMX_EXIT_RSM 17
580/** 18 Guest software executed VMCALL. */
581#define VMX_EXIT_VMCALL 18
582/** 19 Guest software executed VMCLEAR. */
583#define VMX_EXIT_VMCLEAR 19
584/** 20 Guest software executed VMLAUNCH. */
585#define VMX_EXIT_VMLAUNCH 20
586/** 21 Guest software executed VMPTRLD. */
587#define VMX_EXIT_VMPTRLD 21
588/** 22 Guest software executed VMPTRST. */
589#define VMX_EXIT_VMPTRST 22
590/** 23 Guest software executed VMREAD. */
591#define VMX_EXIT_VMREAD 23
592/** 24 Guest software executed VMRESUME. */
593#define VMX_EXIT_VMRESUME 24
594/** 25 Guest software executed VMWRITE. */
595#define VMX_EXIT_VMWRITE 25
596/** 26 Guest software executed VMXOFF. */
597#define VMX_EXIT_VMXOFF 26
598/** 27 Guest software executed VMXON. */
599#define VMX_EXIT_VMXON 27
600/** 28 Control-register accesses. */
601#define VMX_EXIT_MOV_CRX 28
602/** 29 Debug-register accesses. */
603#define VMX_EXIT_MOV_DRX 29
604/** 30 I/O instruction. */
605#define VMX_EXIT_IO_INSTR 30
606/** 31 RDMSR. Guest software attempted to execute RDMSR. */
607#define VMX_EXIT_RDMSR 31
608/** 32 WRMSR. Guest software attempted to execute WRMSR. */
609#define VMX_EXIT_WRMSR 32
610/** 33 VM-entry failure due to invalid guest state. */
611#define VMX_EXIT_ERR_INVALID_GUEST_STATE 33
612/** 34 VM-entry failure due to MSR loading. */
613#define VMX_EXIT_ERR_MSR_LOAD 34
614/** 36 Guest software executed MWAIT. */
615#define VMX_EXIT_MWAIT 36
616/** 37 VM exit due to monitor trap flag. */
617#define VMX_EXIT_MTF 37
618/** 39 Guest software attempted to execute MONITOR. */
619#define VMX_EXIT_MONITOR 39
620/** 40 Guest software attempted to execute PAUSE. */
621#define VMX_EXIT_PAUSE 40
622/** 41 VM-entry failure due to machine-check. */
623#define VMX_EXIT_ERR_MACHINE_CHECK 41
624/** 43 TPR below threshold. Guest software executed MOV to CR8. */
625#define VMX_EXIT_TPR_BELOW_THRESHOLD 43
626/** 44 APIC access. Guest software attempted to access memory at a physical address on the APIC-access page. */
627#define VMX_EXIT_APIC_ACCESS 44
628/** 46 Access to GDTR or IDTR. Guest software attempted to execute LGDT, LIDT, SGDT, or SIDT. */
629#define VMX_EXIT_XDTR_ACCESS 46
630/** 47 Access to LDTR or TR. Guest software attempted to execute LLDT, LTR, SLDT, or STR. */
631#define VMX_EXIT_TR_ACCESS 47
632/** 48 EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures. */
633#define VMX_EXIT_EPT_VIOLATION 48
634/** 49 EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry. */
635#define VMX_EXIT_EPT_MISCONFIG 49
636/** 50 INVEPT. Guest software attempted to execute INVEPT. */
637#define VMX_EXIT_INVEPT 50
638/** 51 RDTSCP. Guest software attempted to execute RDTSCP. */
639#define VMX_EXIT_RDTSCP 51
640/** 52 VMX-preemption timer expired. The preemption timer counted down to zero. */
641#define VMX_EXIT_PREEMPT_TIMER 52
642/** 53 INVVPID. Guest software attempted to execute INVVPID. */
643#define VMX_EXIT_INVVPID 53
644/** 54 WBINVD. Guest software attempted to execute WBINVD. */
645#define VMX_EXIT_WBINVD 54
646/** 55 XSETBV. Guest software attempted to execute XSETBV. */
647#define VMX_EXIT_XSETBV 55
648/** 57 RDRAND. Guest software attempted to execute RDRAND. */
649#define VMX_EXIT_RDRAND 57
650/** 58 INVPCID. Guest software attempted to execute INVPCID. */
651#define VMX_EXIT_INVPCID 58
652/** 59 VMFUNC. Guest software attempted to execute VMFUNC. */
653#define VMX_EXIT_VMFUNC 59
654/** The maximum exit value (inclusive). */
655#define VMX_EXIT_MAX (VMX_EXIT_VMFUNC)
656/** @} */
657
658
659/** @name VM Instruction Errors
660 * @{
661 */
662/** 1 VMCALL executed in VMX root operation. */
663#define VMX_ERROR_VMCALL 1
664/** 2 VMCLEAR with invalid physical address. */
665#define VMX_ERROR_VMCLEAR_INVALID_PHYS_ADDR 2
666/** 3 VMCLEAR with VMXON pointer. */
667#define VMX_ERROR_VMCLEAR_INVALID_VMXON_PTR 3
668/** 4 VMLAUNCH with non-clear VMCS. */
669#define VMX_ERROR_VMLAUCH_NON_CLEAR_VMCS 4
670/** 5 VMRESUME with non-launched VMCS. */
671#define VMX_ERROR_VMRESUME_NON_LAUNCHED_VMCS 5
672/** 6 VMRESUME with a corrupted VMCS (indicates corruption of the current VMCS). */
673#define VMX_ERROR_VMRESUME_CORRUPTED_VMCS 6
674/** 7 VM entry with invalid control field(s). */
675#define VMX_ERROR_VMENTRY_INVALID_CONTROL_FIELDS 7
676/** 8 VM entry with invalid host-state field(s). */
677#define VMX_ERROR_VMENTRY_INVALID_HOST_STATE 8
678/** 9 VMPTRLD with invalid physical address. */
679#define VMX_ERROR_VMPTRLD_INVALID_PHYS_ADDR 9
680/** 10 VMPTRLD with VMXON pointer. */
681#define VMX_ERROR_VMPTRLD_VMXON_PTR 10
682/** 11 VMPTRLD with incorrect VMCS revision identifier. */
683#define VMX_ERROR_VMPTRLD_WRONG_VMCS_REVISION 11
684/** 12 VMREAD/VMWRITE from/to unsupported VMCS component. */
685#define VMX_ERROR_VMREAD_INVALID_COMPONENT 12
686#define VMX_ERROR_VMWRITE_INVALID_COMPONENT VMX_ERROR_VMREAD_INVALID_COMPONENT
687/** 13 VMWRITE to read-only VMCS component. */
688#define VMX_ERROR_VMWRITE_READONLY_COMPONENT 13
689/** 15 VMXON executed in VMX root operation. */
690#define VMX_ERROR_VMXON_IN_VMX_ROOT_OP 15
691/** 16 VM entry with invalid executive-VMCS pointer. */
692#define VMX_ERROR_VMENTRY_INVALID_VMCS_EXEC_PTR 16
693/** 17 VM entry with non-launched executive VMCS. */
694#define VMX_ERROR_VMENTRY_NON_LAUNCHED_EXEC_VMCS 17
695/** 18 VM entry with executive-VMCS pointer not VMXON pointer. */
696#define VMX_ERROR_VMENTRY_EXEC_VMCS_PTR 18
697/** 19 VMCALL with non-clear VMCS. */
698#define VMX_ERROR_VMCALL_NON_CLEAR_VMCS 19
699/** 20 VMCALL with invalid VM-exit control fields. */
700#define VMX_ERROR_VMCALL_INVALID_VMEXIT_FIELDS 20
701/** 22 VMCALL with incorrect MSEG revision identifier. */
702#define VMX_ERROR_VMCALL_INVALID_MSEG_REVISION 22
703/** 23 VMXOFF under dual-monitor treatment of SMIs and SMM. */
704#define VMX_ERROR_VMXOFF_DUAL_MONITOR 23
705/** 24 VMCALL with invalid SMM-monitor features. */
706#define VMX_ERROR_VMCALL_INVALID_SMM_MONITOR 24
707/** 25 VM entry with invalid VM-execution control fields in executive VMCS. */
708#define VMX_ERROR_VMENTRY_INVALID_VM_EXEC_CTRL 25
709/** 26 VM entry with events blocked by MOV SS. */
710#define VMX_ERROR_VMENTRY_MOV_SS 26
711/** 26 Invalid operand to INVEPT/INVVPID. */
712#define VMX_ERROR_INVEPTVPID_INVALID_OPERAND 28
713
714/** @} */
715
716
717/** @name VMX MSRs - Basic VMX information.
718 * @{
719 */
720/** VMCS revision identifier used by the processor. */
721#define MSR_IA32_VMX_BASIC_INFO_VMCS_ID(a) (a & 0x7FFFFFFF)
722/** Size of the VMCS. */
723#define MSR_IA32_VMX_BASIC_INFO_VMCS_SIZE(a) (((a) >> 32) & 0xFFF)
724/** Width of physical address used for the VMCS.
725 * 0 -> limited to the available amount of physical ram
726 * 1 -> within the first 4 GB
727 */
728#define MSR_IA32_VMX_BASIC_INFO_VMCS_PHYS_WIDTH(a) (((a) >> 48) & 1)
729/** Whether the processor supports the dual-monitor treatment of system-management interrupts and system-management code. (always 1) */
730#define MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(a) (((a) >> 49) & 1)
731/** Memory type that must be used for the VMCS. */
732#define MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(a) (((a) >> 50) & 0xF)
733/** @} */
734
735
736/** @name VMX MSRs - Misc VMX info.
737 * @{
738 */
739/** Relationship between the preemption timer and tsc; count down every time bit x of the tsc changes. */
740#define MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(a) ((a) & 0x1f)
741/** Activity states supported by the implementation. */
742#define MSR_IA32_VMX_MISC_ACTIVITY_STATES(a) (((a) >> 6) & 0x7)
743/** Number of CR3 target values supported by the processor. (0-256) */
744#define MSR_IA32_VMX_MISC_CR3_TARGET(a) (((a) >> 16) & 0x1FF)
745/** Maximum nr of MSRs in the VMCS. (N+1)*512. */
746#define MSR_IA32_VMX_MISC_MAX_MSR(a) (((((a) >> 25) & 0x7) + 1) * 512)
747/** MSEG revision identifier used by the processor. */
748#define MSR_IA32_VMX_MISC_MSEG_ID(a) ((a) >> 32)
749/** @} */
750
751
752/** @name VMX MSRs - VMCS enumeration field info
753 * @{
754 */
755/** Highest field index. */
756#define MSR_IA32_VMX_VMCS_ENUM_HIGHEST_INDEX(a) (((a) >> 1) & 0x1FF)
757
758/** @} */
759
760
761/** @name MSR_IA32_VMX_EPT_VPID_CAPS; EPT capabilities MSR
762 * @{
763 */
764#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_X_ONLY RT_BIT_64(0)
765#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_W_ONLY RT_BIT_64(1)
766#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_WX_ONLY RT_BIT_64(2)
767#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_21_BITS RT_BIT_64(3)
768#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_30_BITS RT_BIT_64(4)
769#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_39_BITS RT_BIT_64(5)
770#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_48_BITS RT_BIT_64(6)
771#define MSR_IA32_VMX_EPT_VPID_CAP_GAW_57_BITS RT_BIT_64(7)
772#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_UC RT_BIT_64(8)
773#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WC RT_BIT_64(9)
774#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WT RT_BIT_64(12)
775#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WP RT_BIT_64(13)
776#define MSR_IA32_VMX_EPT_VPID_CAP_EMT_WB RT_BIT_64(14)
777#define MSR_IA32_VMX_EPT_VPID_CAP_SP_21_BITS RT_BIT_64(16)
778#define MSR_IA32_VMX_EPT_VPID_CAP_SP_30_BITS RT_BIT_64(17)
779#define MSR_IA32_VMX_EPT_VPID_CAP_SP_39_BITS RT_BIT_64(18)
780#define MSR_IA32_VMX_EPT_VPID_CAP_SP_48_BITS RT_BIT_64(19)
781#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT RT_BIT_64(20)
782#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_SINGLE_CONTEXT RT_BIT_64(25)
783#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_ALL_CONTEXTS RT_BIT_64(26)
784#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID RT_BIT_64(32)
785#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_INDIV_ADDR RT_BIT_64(40)
786#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT RT_BIT_64(41)
787#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_ALL_CONTEXTS RT_BIT_64(42)
788#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT_RETAIN_GLOBALS RT_BIT_64(43)
789
790/** @} */
791
792/** @name Extended Page Table Pointer (EPTP)
793 * @{
794 */
795/** Uncachable EPT paging structure memory type. */
796#define VMX_EPT_MEMTYPE_UC 0
797/** Write-back EPT paging structure memory type. */
798#define VMX_EPT_MEMTYPE_WB 6
799/** Shift value to get the EPT page walk length (bits 5-3) */
800#define VMX_EPT_PAGE_WALK_LENGTH_SHIFT 3
801/** Mask value to get the EPT page walk length (bits 5-3) */
802#define VMX_EPT_PAGE_WALK_LENGTH_MASK 7
803/** Default EPT page-walk length (1 less than the actual EPT page-walk
804 * length) */
805#define VMX_EPT_PAGE_WALK_LENGTH_DEFAULT 3
806/** @} */
807
808
809/** @name VMCS field encoding - 16 bits guest fields
810 * @{
811 */
812#define VMX_VMCS16_GUEST_FIELD_VPID 0x0
813#define VMX_VMCS16_GUEST_FIELD_ES 0x800
814#define VMX_VMCS16_GUEST_FIELD_CS 0x802
815#define VMX_VMCS16_GUEST_FIELD_SS 0x804
816#define VMX_VMCS16_GUEST_FIELD_DS 0x806
817#define VMX_VMCS16_GUEST_FIELD_FS 0x808
818#define VMX_VMCS16_GUEST_FIELD_GS 0x80A
819#define VMX_VMCS16_GUEST_FIELD_LDTR 0x80C
820#define VMX_VMCS16_GUEST_FIELD_TR 0x80E
821/** @} */
822
823/** @name VMCS field encoding - 16 bits host fields
824 * @{
825 */
826#define VMX_VMCS16_HOST_FIELD_ES 0xC00
827#define VMX_VMCS16_HOST_FIELD_CS 0xC02
828#define VMX_VMCS16_HOST_FIELD_SS 0xC04
829#define VMX_VMCS16_HOST_FIELD_DS 0xC06
830#define VMX_VMCS16_HOST_FIELD_FS 0xC08
831#define VMX_VMCS16_HOST_FIELD_GS 0xC0A
832#define VMX_VMCS16_HOST_FIELD_TR 0xC0C
833/** @} */
834
835/** @name VMCS field encoding - 64 bits host fields
836 * @{
837 */
838#define VMX_VMCS64_HOST_FIELD_PAT_FULL 0x2C00
839#define VMX_VMCS64_HOST_FIELD_PAT_HIGH 0x2C01
840#define VMX_VMCS64_HOST_FIELD_EFER_FULL 0x2C02
841#define VMX_VMCS64_HOST_FIELD_EFER_HIGH 0x2C03
842#define VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_FULL 0x2C04 /**< MSR IA32_PERF_GLOBAL_CTRL */
843#define VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_HIGH 0x2C05 /**< MSR IA32_PERF_GLOBAL_CTRL */
844/** @} */
845
846
847/** @name VMCS field encoding - 64 Bits control fields
848 * @{
849 */
850#define VMX_VMCS64_CTRL_IO_BITMAP_A_FULL 0x2000
851#define VMX_VMCS64_CTRL_IO_BITMAP_A_HIGH 0x2001
852#define VMX_VMCS64_CTRL_IO_BITMAP_B_FULL 0x2002
853#define VMX_VMCS64_CTRL_IO_BITMAP_B_HIGH 0x2003
854
855/* Optional */
856#define VMX_VMCS64_CTRL_MSR_BITMAP_FULL 0x2004
857#define VMX_VMCS64_CTRL_MSR_BITMAP_HIGH 0x2005
858
859#define VMX_VMCS64_CTRL_EXIT_MSR_STORE_FULL 0x2006
860#define VMX_VMCS64_CTRL_EXIT_MSR_STORE_HIGH 0x2007
861#define VMX_VMCS64_CTRL_EXIT_MSR_LOAD_FULL 0x2008
862#define VMX_VMCS64_CTRL_EXIT_MSR_LOAD_HIGH 0x2009
863
864#define VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_FULL 0x200A
865#define VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_HIGH 0x200B
866
867#define VMX_VMCS64_CTRL_EXEC_VMCS_PTR_FULL 0x200C
868#define VMX_VMCS64_CTRL_EXEC_VMCS_PTR_HIGH 0x200D
869
870#define VMX_VMCS64_CTRL_TSC_OFFSET_FULL 0x2010
871#define VMX_VMCS64_CTRL_TSC_OFFSET_HIGH 0x2011
872
873/** Optional (VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW) */
874#define VMX_VMCS64_CTRL_VAPIC_PAGEADDR_FULL 0x2012
875#define VMX_VMCS64_CTRL_VAPIC_PAGEADDR_HIGH 0x2013
876
877/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) */
878#define VMX_VMCS64_CTRL_APIC_ACCESSADDR_FULL 0x2014
879#define VMX_VMCS64_CTRL_APIC_ACCESSADDR_HIGH 0x2015
880
881/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VMFUNC) */
882#define VMX_VMCS64_CTRL_VMFUNC_CTRLS_FULL 0x2018
883#define VMX_VMCS64_CTRL_VMFUNC_CTRLS_HIGH 0x2019
884
885/** Extended page table pointer. */
886#define VMX_VMCS64_CTRL_EPTP_FULL 0x201a
887#define VMX_VMCS64_CTRL_EPTP_HIGH 0x201b
888
889/** Extended page table pointer lists. */
890#define VMX_VMCS64_CTRL_EPTP_LIST_FULL 0x2024
891#define VMX_VMCS64_CTRL_EPTP_LIST_HIGH 0x2025
892
893/** VM-exit guest phyiscal address. */
894#define VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_FULL 0x2400
895#define VMX_VMCS64_EXIT_GUEST_PHYS_ADDR_HIGH 0x2401
896/** @} */
897
898
899/** @name VMCS field encoding - 64 Bits guest fields
900 * @{
901 */
902#define VMX_VMCS64_GUEST_VMCS_LINK_PTR_FULL 0x2800
903#define VMX_VMCS64_GUEST_VMCS_LINK_PTR_HIGH 0x2801
904#define VMX_VMCS64_GUEST_DEBUGCTL_FULL 0x2802 /**< MSR IA32_DEBUGCTL */
905#define VMX_VMCS64_GUEST_DEBUGCTL_HIGH 0x2803 /**< MSR IA32_DEBUGCTL */
906#define VMX_VMCS64_GUEST_PAT_FULL 0x2804
907#define VMX_VMCS64_GUEST_PAT_HIGH 0x2805
908#define VMX_VMCS64_GUEST_EFER_FULL 0x2806
909#define VMX_VMCS64_GUEST_EFER_HIGH 0x2807
910#define VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_FULL 0x2808 /**< MSR IA32_PERF_GLOBAL_CTRL */
911#define VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_HIGH 0x2809 /**< MSR IA32_PERF_GLOBAL_CTRL */
912#define VMX_VMCS64_GUEST_PDPTE0_FULL 0x280A
913#define VMX_VMCS64_GUEST_PDPTE0_HIGH 0x280B
914#define VMX_VMCS64_GUEST_PDPTE1_FULL 0x280C
915#define VMX_VMCS64_GUEST_PDPTE1_HIGH 0x280D
916#define VMX_VMCS64_GUEST_PDPTE2_FULL 0x280E
917#define VMX_VMCS64_GUEST_PDPTE2_HIGH 0x280F
918#define VMX_VMCS64_GUEST_PDPTE3_FULL 0x2810
919#define VMX_VMCS64_GUEST_PDPTE3_HIGH 0x2811
920/** @} */
921
922
923/** @name VMCS field encoding - 32 Bits control fields
924 * @{
925 */
926#define VMX_VMCS32_CTRL_PIN_EXEC 0x4000
927#define VMX_VMCS32_CTRL_PROC_EXEC 0x4002
928#define VMX_VMCS32_CTRL_EXCEPTION_BITMAP 0x4004
929#define VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MASK 0x4006
930#define VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MATCH 0x4008
931#define VMX_VMCS32_CTRL_CR3_TARGET_COUNT 0x400A
932#define VMX_VMCS32_CTRL_EXIT 0x400C
933#define VMX_VMCS32_CTRL_EXIT_MSR_STORE_COUNT 0x400E
934#define VMX_VMCS32_CTRL_EXIT_MSR_LOAD_COUNT 0x4010
935#define VMX_VMCS32_CTRL_ENTRY 0x4012
936#define VMX_VMCS32_CTRL_ENTRY_MSR_LOAD_COUNT 0x4014
937#define VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO 0x4016
938#define VMX_VMCS32_CTRL_ENTRY_EXCEPTION_ERRCODE 0x4018
939#define VMX_VMCS32_CTRL_ENTRY_INSTR_LENGTH 0x401A
940#define VMX_VMCS32_CTRL_TPR_THRESHOLD 0x401C
941#define VMX_VMCS32_CTRL_PROC_EXEC2 0x401E
942/** @} */
943
944
945/** @name VMX_VMCS_CTRL_PIN_EXEC
946 * @{
947 */
948/** External interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */
949#define VMX_VMCS_CTRL_PIN_EXEC_EXT_INT_EXIT RT_BIT(0)
950/** Non-maskable interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */
951#define VMX_VMCS_CTRL_PIN_EXEC_NMI_EXIT RT_BIT(3)
952/** Virtual NMIs. */
953#define VMX_VMCS_CTRL_PIN_EXEC_VIRTUAL_NMI RT_BIT(5)
954/** Activate VMX preemption timer. */
955#define VMX_VMCS_CTRL_PIN_EXEC_PREEMPT_TIMER RT_BIT(6)
956/* All other bits are reserved and must be set according to MSR IA32_VMX_PROCBASED_CTLS. */
957/** @} */
958
959/** @name VMX_VMCS_CTRL_PROC_EXEC
960 * @{
961 */
962/** VM Exit as soon as RFLAGS.IF=1 and no blocking is active. */
963#define VMX_VMCS_CTRL_PROC_EXEC_INT_WINDOW_EXIT RT_BIT(2)
964/** Use timestamp counter offset. */
965#define VMX_VMCS_CTRL_PROC_EXEC_USE_TSC_OFFSETTING RT_BIT(3)
966/** VM Exit when executing the HLT instruction. */
967#define VMX_VMCS_CTRL_PROC_EXEC_HLT_EXIT RT_BIT(7)
968/** VM Exit when executing the INVLPG instruction. */
969#define VMX_VMCS_CTRL_PROC_EXEC_INVLPG_EXIT RT_BIT(9)
970/** VM Exit when executing the MWAIT instruction. */
971#define VMX_VMCS_CTRL_PROC_EXEC_MWAIT_EXIT RT_BIT(10)
972/** VM Exit when executing the RDPMC instruction. */
973#define VMX_VMCS_CTRL_PROC_EXEC_RDPMC_EXIT RT_BIT(11)
974/** VM Exit when executing the RDTSC/RDTSCP instruction. */
975#define VMX_VMCS_CTRL_PROC_EXEC_RDTSC_EXIT RT_BIT(12)
976/** VM Exit when executing the MOV to CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
977#define VMX_VMCS_CTRL_PROC_EXEC_CR3_LOAD_EXIT RT_BIT(15)
978/** VM Exit when executing the MOV from CR3 instruction. (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
979#define VMX_VMCS_CTRL_PROC_EXEC_CR3_STORE_EXIT RT_BIT(16)
980/** VM Exit on CR8 loads. */
981#define VMX_VMCS_CTRL_PROC_EXEC_CR8_LOAD_EXIT RT_BIT(19)
982/** VM Exit on CR8 stores. */
983#define VMX_VMCS_CTRL_PROC_EXEC_CR8_STORE_EXIT RT_BIT(20)
984/** Use TPR shadow. */
985#define VMX_VMCS_CTRL_PROC_EXEC_USE_TPR_SHADOW RT_BIT(21)
986/** VM Exit when virtual nmi blocking is disabled. */
987#define VMX_VMCS_CTRL_PROC_EXEC_NMI_WINDOW_EXIT RT_BIT(22)
988/** VM Exit when executing a MOV DRx instruction. */
989#define VMX_VMCS_CTRL_PROC_EXEC_MOV_DR_EXIT RT_BIT(23)
990/** VM Exit when executing IO instructions. */
991#define VMX_VMCS_CTRL_PROC_EXEC_UNCOND_IO_EXIT RT_BIT(24)
992/** Use IO bitmaps. */
993#define VMX_VMCS_CTRL_PROC_EXEC_USE_IO_BITMAPS RT_BIT(25)
994/** Monitor trap flag. */
995#define VMX_VMCS_CTRL_PROC_EXEC_MONITOR_TRAP_FLAG RT_BIT(27)
996/** Use MSR bitmaps. */
997#define VMX_VMCS_CTRL_PROC_EXEC_USE_MSR_BITMAPS RT_BIT(28)
998/** VM Exit when executing the MONITOR instruction. */
999#define VMX_VMCS_CTRL_PROC_EXEC_MONITOR_EXIT RT_BIT(29)
1000/** VM Exit when executing the PAUSE instruction. */
1001#define VMX_VMCS_CTRL_PROC_EXEC_PAUSE_EXIT RT_BIT(30)
1002/** Determines whether the secondary processor based VM-execution controls are used. */
1003#define VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL RT_BIT(31)
1004/** @} */
1005
1006/** @name VMX_VMCS_CTRL_PROC_EXEC2
1007 * @{
1008 */
1009/** Virtualize APIC access. */
1010#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC RT_BIT(0)
1011/** EPT supported/enabled. */
1012#define VMX_VMCS_CTRL_PROC_EXEC2_EPT RT_BIT(1)
1013/** Descriptor table instructions cause VM-exits. */
1014#define VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_TABLE_EXIT RT_BIT(2)
1015/** RDTSCP supported/enabled. */
1016#define VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP RT_BIT(3)
1017/** Virtualize x2APIC mode. */
1018#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_X2APIC RT_BIT(4)
1019/** VPID supported/enabled. */
1020#define VMX_VMCS_CTRL_PROC_EXEC2_VPID RT_BIT(5)
1021/** VM Exit when executing the WBINVD instruction. */
1022#define VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT RT_BIT(6)
1023/** Unrestricted guest execution. */
1024#define VMX_VMCS_CTRL_PROC_EXEC2_UNRESTRICTED_GUEST RT_BIT(7)
1025/** A specified nr of pause loops cause a VM-exit. */
1026#define VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT RT_BIT(10)
1027/** VM Exit when executing RDRAND instructions. */
1028#define VMX_VMCS_CTRL_PROC_EXEC2_RDRAND_EXIT RT_BIT(11)
1029/** Enables INVPCID instructions. */
1030#define VMX_VMCS_CTRL_PROC_EXEC2_INVPCID RT_BIT(12)
1031/** Enables VMFUNC instructions. */
1032#define VMX_VMCS_CTRL_PROC_EXEC2_VMFUNC RT_BIT(13)
1033/** @} */
1034
1035
1036/** @name VMX_VMCS_CTRL_ENTRY
1037 * @{
1038 */
1039/** Load guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
1040#define VMX_VMCS_CTRL_ENTRY_LOAD_DEBUG RT_BIT(2)
1041/** 64 bits guest mode. Must be 0 for CPUs that don't support AMD64. */
1042#define VMX_VMCS_CTRL_ENTRY_IA32E_MODE_GUEST RT_BIT(9)
1043/** In SMM mode after VM-entry. */
1044#define VMX_VMCS_CTRL_ENTRY_ENTRY_SMM RT_BIT(10)
1045/** Disable dual treatment of SMI and SMM; must be zero for VM-entry outside of SMM. */
1046#define VMX_VMCS_CTRL_ENTRY_DEACTIVATE_DUALMON RT_BIT(11)
1047/** This control determines whether the guest IA32_PERF_GLOBAL_CTRL MSR is loaded on VM entry. */
1048#define VMX_VMCS_CTRL_ENTRY_LOAD_GUEST_PERF_MSR RT_BIT(13)
1049/** This control determines whether the guest IA32_PAT MSR is loaded on VM entry. */
1050#define VMX_VMCS_CTRL_ENTRY_LOAD_GUEST_PAT_MSR RT_BIT(14)
1051/** This control determines whether the guest IA32_EFER MSR is loaded on VM entry. */
1052#define VMX_VMCS_CTRL_ENTRY_LOAD_GUEST_EFER_MSR RT_BIT(15)
1053/** @} */
1054
1055
1056/** @name VMX_VMCS_CTRL_EXIT
1057 * @{
1058 */
1059/** Save guest debug controls (dr7 & IA32_DEBUGCTL_MSR) (forced to 1 on the 'first' VT-x capable CPUs; this actually includes the newest Nehalem CPUs) */
1060#define VMX_VMCS_CTRL_EXIT_SAVE_DEBUG RT_BIT(2)
1061/** Return to long mode after a VM-exit. */
1062#define VMX_VMCS_CTRL_EXIT_HOST_ADDR_SPACE_SIZE RT_BIT(9)
1063/** This control determines whether the IA32_PERF_GLOBAL_CTRL MSR is loaded on VM exit. */
1064#define VMX_VMCS_CTRL_EXIT_LOAD_PERF_MSR RT_BIT(12)
1065/** Acknowledge external interrupts with the irq controller if one caused a VM-exit. */
1066#define VMX_VMCS_CTRL_EXIT_ACK_EXT_INT RT_BIT(15)
1067/** This control determines whether the guest IA32_PAT MSR is saved on VM exit. */
1068#define VMX_VMCS_CTRL_EXIT_SAVE_GUEST_PAT_MSR RT_BIT(18)
1069/** This control determines whether the host IA32_PAT MSR is loaded on VM exit. */
1070#define VMX_VMCS_CTRL_EXIT_LOAD_HOST_PAT_MSR RT_BIT(19)
1071/** This control determines whether the guest IA32_EFER MSR is saved on VM exit. */
1072#define VMX_VMCS_CTRL_EXIT_SAVE_GUEST_EFER_MSR RT_BIT(20)
1073/** This control determines whether the host IA32_EFER MSR is loaded on VM exit. */
1074#define VMX_VMCS_CTRL_EXIT_LOAD_HOST_EFER_MSR RT_BIT(21)
1075/** This control determines whether the value of the VMX preemption timer is
1076 * saved on every VM exit. */
1077#define VMX_VMCS_CTRL_EXIT_SAVE_VMX_PREEMPT_TIMER RT_BIT(22)
1078/** @} */
1079
1080/** @name VMCS field encoding - 32 Bits read-only fields
1081 * @{
1082 */
1083#define VMX_VMCS32_RO_VM_INSTR_ERROR 0x4400
1084#define VMX_VMCS32_RO_EXIT_REASON 0x4402
1085#define VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO 0x4404
1086#define VMX_VMCS32_RO_EXIT_INTERRUPTION_ERROR_CODE 0x4406
1087#define VMX_VMCS32_RO_IDT_INFO 0x4408
1088#define VMX_VMCS32_RO_IDT_ERROR_CODE 0x440A
1089#define VMX_VMCS32_RO_EXIT_INSTR_LENGTH 0x440C
1090#define VMX_VMCS32_RO_EXIT_INSTR_INFO 0x440E
1091/** @} */
1092
1093/** @name VMX_VMCS32_RO_EXIT_REASON
1094 * @{
1095 */
1096#define VMX_EXIT_REASON_BASIC(a) (a & 0xffff)
1097/** @} */
1098
1099/** @name VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO
1100 * @{
1101 */
1102#define VMX_ENTRY_INTERRUPTION_INFO_VALID(a) (a & RT_BIT(31))
1103/** @} */
1104
1105
1106/** @name VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO
1107 * @{
1108 */
1109#define VMX_EXIT_INTERRUPTION_INFO_VECTOR(a) (a & 0xff)
1110#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT 8
1111#define VMX_EXIT_INTERRUPTION_INFO_TYPE(a) ((a >> VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT) & 7)
1112#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID RT_BIT(11)
1113#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(a) (a & VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID)
1114#define VMX_EXIT_INTERRUPTION_INFO_NMI_UNBLOCK(a) (a & RT_BIT(12))
1115#ifdef VBOX_WITH_OLD_VTX_CODE
1116# define VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT 31
1117#endif
1118#define VMX_EXIT_INTERRUPTION_INFO_VALID RT_BIT(31)
1119#define VMX_EXIT_INTERRUPTION_INFO_IS_VALID(a) (a & RT_BIT(31))
1120/** Construct an irq event injection value from the exit interruption info value (same except that bit 12 is reserved). */
1121#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(a) (a & ~RT_BIT(12))
1122/** @} */
1123
1124/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO_TYPE
1125 * @{
1126 */
1127#define VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT_INT 0
1128#define VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI 2
1129#define VMX_EXIT_INTERRUPTION_INFO_TYPE_HW_XCPT 3
1130#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_INT 4 /**< int xx */
1131#define VMX_EXIT_INTERRUPTION_INFO_TYPE_DB_XCPT 5 /**< Why are we getting this one?? */
1132#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW_XCPT 6
1133/** @} */
1134
1135/** @name VMX_VMCS32_RO_IDT_VECTORING_INFO
1136 * @{
1137 */
1138#define VMX_IDT_VECTORING_INFO_VECTOR(a) (a & 0xff)
1139#define VMX_IDT_VECTORING_INFO_TYPE_SHIFT 8
1140#define VMX_IDT_VECTORING_INFO_TYPE(a) ((a >> VMX_IDT_VECTORING_INFO_TYPE_SHIFT) & 7)
1141#define VMX_IDT_VECTORING_INFO_ERROR_CODE_VALID RT_BIT(11)
1142#define VMX_IDT_VECTORING_INFO_ERROR_CODE_IS_VALID(a) (a & VMX_IDT_VECTORING_INFO_ERROR_CODE_VALID)
1143#define VMX_IDT_VECTORING_INFO_VALID(a) (a & RT_BIT(31))
1144#define VMX_ENTRY_INTR_INFO_FROM_EXIT_IDT_INFO(a) (a & ~RT_BIT(12))
1145/** @} */
1146
1147/** @name VMX_VMCS_RO_IDT_VECTORING_INFO_TYPE
1148 * @{
1149 */
1150#define VMX_IDT_VECTORING_INFO_TYPE_EXT_INT 0
1151#define VMX_IDT_VECTORING_INFO_TYPE_NMI 2
1152#define VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT 3
1153#define VMX_IDT_VECTORING_INFO_TYPE_SW_INT 4
1154#define VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT 5
1155#define VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT 6
1156/** @} */
1157
1158
1159/** @name VMCS field encoding - 32 Bits guest state fields
1160 * @{
1161 */
1162#define VMX_VMCS32_GUEST_ES_LIMIT 0x4800
1163#define VMX_VMCS32_GUEST_CS_LIMIT 0x4802
1164#define VMX_VMCS32_GUEST_SS_LIMIT 0x4804
1165#define VMX_VMCS32_GUEST_DS_LIMIT 0x4806
1166#define VMX_VMCS32_GUEST_FS_LIMIT 0x4808
1167#define VMX_VMCS32_GUEST_GS_LIMIT 0x480A
1168#define VMX_VMCS32_GUEST_LDTR_LIMIT 0x480C
1169#define VMX_VMCS32_GUEST_TR_LIMIT 0x480E
1170#define VMX_VMCS32_GUEST_GDTR_LIMIT 0x4810
1171#define VMX_VMCS32_GUEST_IDTR_LIMIT 0x4812
1172#define VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS 0x4814
1173#define VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS 0x4816
1174#define VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS 0x4818
1175#define VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS 0x481A
1176#define VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS 0x481C
1177#define VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS 0x481E
1178#define VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS 0x4820
1179#define VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS 0x4822
1180#define VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE 0x4824
1181#define VMX_VMCS32_GUEST_ACTIVITY_STATE 0x4826
1182#define VMX_VMCS32_GUEST_SYSENTER_CS 0x482A /**< MSR IA32_SYSENTER_CS */
1183#define VMX_VMCS32_GUEST_PREEMPT_TIMER_VALUE 0x482E
1184/** @} */
1185
1186
1187/** @name VMX_VMCS_GUEST_ACTIVITY_STATE
1188 * @{
1189 */
1190/** The logical processor is active. */
1191#define VMX_VMCS_GUEST_ACTIVITY_ACTIVE 0x0
1192/** The logical processor is inactive, because executed a HLT instruction. */
1193#define VMX_VMCS_GUEST_ACTIVITY_HLT 0x1
1194/** The logical processor is inactive, because of a triple fault or other
1195 * serious error. */
1196#define VMX_VMCS_GUEST_ACTIVITY_SHUTDOWN 0x2
1197/** The logical processor is inactive, because it's waiting for a startup-IPI */
1198#define VMX_VMCS_GUEST_ACTIVITY_SIPI_WAIT 0x3
1199/** @} */
1200
1201
1202/** @name VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE
1203 * @{
1204 */
1205#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI RT_BIT(0)
1206#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS RT_BIT(1)
1207#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_SMI RT_BIT(2)
1208#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_NMI RT_BIT(3)
1209/** @} */
1210
1211
1212/** @name VMCS field encoding - 32 Bits host state fields
1213 * @{
1214 */
1215#define VMX_VMCS32_HOST_SYSENTER_CS 0x4C00
1216/** @} */
1217
1218/** @name Natural width control fields
1219 * @{
1220 */
1221#define VMX_VMCS_CTRL_CR0_MASK 0x6000
1222#define VMX_VMCS_CTRL_CR4_MASK 0x6002
1223#define VMX_VMCS_CTRL_CR0_READ_SHADOW 0x6004
1224#define VMX_VMCS_CTRL_CR4_READ_SHADOW 0x6006
1225#define VMX_VMCS_CTRL_CR3_TARGET_VAL0 0x6008
1226#define VMX_VMCS_CTRL_CR3_TARGET_VAL1 0x600A
1227#define VMX_VMCS_CTRL_CR3_TARGET_VAL2 0x600C
1228#define VMX_VMCS_CTRL_CR3_TARGET_VAL31 0x600E
1229/** @} */
1230
1231
1232/** @name Natural width read-only data fields
1233 * @{
1234 */
1235#define VMX_VMCS_RO_EXIT_QUALIFICATION 0x6400
1236#define VMX_VMCS_RO_IO_RCX 0x6402
1237#define VMX_VMCS_RO_IO_RSX 0x6404
1238#define VMX_VMCS_RO_IO_RDI 0x6406
1239#define VMX_VMCS_RO_IO_RIP 0x6408
1240#define VMX_VMCS_RO_EXIT_GUEST_LINEAR_ADDR 0x640A
1241/** @} */
1242
1243
1244/** @name VMX_VMCS_RO_EXIT_QUALIFICATION
1245 * @{
1246 */
1247/** 0-2: Debug register number */
1248#define VMX_EXIT_QUALIFICATION_DRX_REGISTER(a) (a & 7)
1249/** 3: Reserved; cleared to 0. */
1250#define VMX_EXIT_QUALIFICATION_DRX_RES1(a) ((a >> 3) & 1)
1251/** 4: Direction of move (0 = write, 1 = read) */
1252#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION(a) ((a >> 4) & 1)
1253/** 5-7: Reserved; cleared to 0. */
1254#define VMX_EXIT_QUALIFICATION_DRX_RES2(a) ((a >> 5) & 7)
1255/** 8-11: General purpose register number. */
1256#define VMX_EXIT_QUALIFICATION_DRX_GENREG(a) ((a >> 8) & 0xF)
1257/** Rest: reserved. */
1258/** @} */
1259
1260/** @name VMX_EXIT_QUALIFICATION_DRX_DIRECTION values
1261 * @{
1262 */
1263#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE 0
1264#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_READ 1
1265/** @} */
1266
1267
1268
1269/** @name CRx accesses
1270 * @{
1271 */
1272/** 0-3: Control register number (0 for CLTS & LMSW) */
1273#define VMX_EXIT_QUALIFICATION_CRX_REGISTER(a) (a & 0xF)
1274/** 4-5: Access type. */
1275#define VMX_EXIT_QUALIFICATION_CRX_ACCESS(a) ((a >> 4) & 3)
1276/** 6: LMSW operand type */
1277#define VMX_EXIT_QUALIFICATION_CRX_LMSW_OP(a) ((a >> 6) & 1)
1278/** 7: Reserved; cleared to 0. */
1279#define VMX_EXIT_QUALIFICATION_CRX_RES1(a) ((a >> 7) & 1)
1280/** 8-11: General purpose register number (0 for CLTS & LMSW). */
1281#define VMX_EXIT_QUALIFICATION_CRX_GENREG(a) ((a >> 8) & 0xF)
1282/** 12-15: Reserved; cleared to 0. */
1283#define VMX_EXIT_QUALIFICATION_CRX_RES2(a) ((a >> 12) & 0xF)
1284/** 16-31: LMSW source data (else 0). */
1285#define VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(a) ((a >> 16) & 0xFFFF)
1286/** Rest: reserved. */
1287/** @} */
1288
1289/** @name VMX_EXIT_QUALIFICATION_CRX_ACCESS
1290 * @{
1291 */
1292#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE 0
1293#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ 1
1294#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS 2
1295#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW 3
1296/** @} */
1297
1298/** @name VMX_EXIT_QUALIFICATION_TASK_SWITCH
1299 * @{
1300 */
1301#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_SELECTOR(a) (a & 0xffff)
1302#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE(a) ((a >> 30)& 0x3)
1303/** Task switch caused by a call instruction. */
1304#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_CALL 0
1305/** Task switch caused by an iret instruction. */
1306#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IRET 1
1307/** Task switch caused by a jmp instruction. */
1308#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_JMP 2
1309/** Task switch caused by an interrupt gate. */
1310#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IDT 3
1311/** @} */
1312
1313
1314/** @name VMX_EXIT_EPT_VIOLATION
1315 * @{
1316 */
1317/** Set if the violation was caused by a data read. */
1318#define VMX_EXIT_QUALIFICATION_EPT_DATA_READ RT_BIT(0)
1319/** Set if the violation was caused by a data write. */
1320#define VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE RT_BIT(1)
1321/** Set if the violation was caused by an insruction fetch. */
1322#define VMX_EXIT_QUALIFICATION_EPT_INSTR_FETCH RT_BIT(2)
1323/** AND of the present bit of all EPT structures. */
1324#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT RT_BIT(3)
1325/** AND of the write bit of all EPT structures. */
1326#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_WRITE RT_BIT(4)
1327/** AND of the execute bit of all EPT structures. */
1328#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_EXECUTE RT_BIT(5)
1329/** Set if the guest linear address field contains the faulting address. */
1330#define VMX_EXIT_QUALIFICATION_EPT_GUEST_ADDR_VALID RT_BIT(7)
1331/** If bit 7 is one: (reserved otherwise)
1332 * 1 - violation due to physical address access.
1333 * 0 - violation caused by page walk or access/dirty bit updates
1334 */
1335#define VMX_EXIT_QUALIFICATION_EPT_TRANSLATED_ACCESS RT_BIT(8)
1336/** @} */
1337
1338
1339/** @name VMX_EXIT_PORT_IO
1340 * @{
1341 */
1342/** 0-2: IO operation width. */
1343#define VMX_EXIT_QUALIFICATION_IO_WIDTH(a) (a & 7)
1344/** 3: IO operation direction. */
1345#define VMX_EXIT_QUALIFICATION_IO_DIRECTION(a) ((a >> 3) & 1)
1346/** 4: String IO operation. */
1347#define VMX_EXIT_QUALIFICATION_IO_STRING(a) ((a >> 4) & 1)
1348/** 5: Repeated IO operation. */
1349#define VMX_EXIT_QUALIFICATION_IO_REP(a) ((a >> 5) & 1)
1350/** 6: Operand encoding. */
1351#define VMX_EXIT_QUALIFICATION_IO_ENCODING(a) ((a >> 6) & 1)
1352/** 16-31: IO Port (0-0xffff). */
1353#define VMX_EXIT_QUALIFICATION_IO_PORT(a) ((a >> 16) & 0xffff)
1354/* Rest reserved. */
1355/** @} */
1356
1357/** @name VMX_EXIT_QUALIFICATION_IO_DIRECTION
1358 * @{
1359 */
1360#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT 0
1361#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_IN 1
1362/** @} */
1363
1364
1365/** @name VMX_EXIT_QUALIFICATION_IO_ENCODING
1366 * @{
1367 */
1368#define VMX_EXIT_QUALIFICATION_IO_ENCODING_DX 0
1369#define VMX_EXIT_QUALIFICATION_IO_ENCODING_IMM 1
1370/** @} */
1371
1372/** @name VMX_EXIT_APIC_ACCESS
1373 * @{
1374 */
1375/** 0-11: If the APIC-access VM exit is due to a linear access, the offset of access within the APIC page. */
1376#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_OFFSET(a) ((a) & 0xfff)
1377/** 12-15: Access type. */
1378#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE(a) ((a) & 0xf000)
1379/* Rest reserved. */
1380/** @} */
1381
1382
1383/** @name VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE; access types
1384 * @{
1385 */
1386/** Linear read access. */
1387#define VMX_APIC_ACCESS_TYPE_LINEAR_READ 0
1388/** Linear write access. */
1389#define VMX_APIC_ACCESS_TYPE_LINEAR_WRITE 1
1390/** Linear instruction fetch access. */
1391#define VMX_APIC_ACCESS_TYPE_LINEAR_INSTR_FETCH 2
1392/** Linear read/write access during event delivery. */
1393#define VMX_APIC_ACCESS_TYPE_LINEAR_EVENT_DELIVERY 3
1394/** Physical read/write access during event delivery. */
1395#define VMX_APIC_ACCESS_TYPE_PHYSICAL_EVENT_DELIVERY 10
1396/** Physical access for an instruction fetch or during instruction execution. */
1397#define VMX_APIC_ACCESS_TYPE_PHYSICAL_INSTR 15
1398/** @} */
1399
1400/** @} */
1401
1402/** @name VMCS field encoding - Natural width guest state fields
1403 * @{
1404 */
1405#define VMX_VMCS_GUEST_CR0 0x6800
1406#define VMX_VMCS_GUEST_CR3 0x6802
1407#define VMX_VMCS_GUEST_CR4 0x6804
1408#define VMX_VMCS_GUEST_ES_BASE 0x6806
1409#define VMX_VMCS_GUEST_CS_BASE 0x6808
1410#define VMX_VMCS_GUEST_SS_BASE 0x680A
1411#define VMX_VMCS_GUEST_DS_BASE 0x680C
1412#define VMX_VMCS_GUEST_FS_BASE 0x680E
1413#define VMX_VMCS_GUEST_GS_BASE 0x6810
1414#define VMX_VMCS_GUEST_LDTR_BASE 0x6812
1415#define VMX_VMCS_GUEST_TR_BASE 0x6814
1416#define VMX_VMCS_GUEST_GDTR_BASE 0x6816
1417#define VMX_VMCS_GUEST_IDTR_BASE 0x6818
1418#define VMX_VMCS_GUEST_DR7 0x681A
1419#define VMX_VMCS_GUEST_RSP 0x681C
1420#define VMX_VMCS_GUEST_RIP 0x681E
1421#define VMX_VMCS_GUEST_RFLAGS 0x6820
1422#define VMX_VMCS_GUEST_PENDING_DEBUG_EXCEPTIONS 0x6822
1423#define VMX_VMCS_GUEST_SYSENTER_ESP 0x6824 /**< MSR IA32_SYSENTER_ESP */
1424#define VMX_VMCS_GUEST_SYSENTER_EIP 0x6826 /**< MSR IA32_SYSENTER_EIP */
1425/** @} */
1426
1427
1428/** @name VMX_VMCS_GUEST_DEBUG_EXCEPTIONS
1429 * @{
1430 */
1431/** Hardware breakpoint 0 was met. */
1432#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B0 RT_BIT(0)
1433/** Hardware breakpoint 1 was met. */
1434#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B1 RT_BIT(1)
1435/** Hardware breakpoint 2 was met. */
1436#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B2 RT_BIT(2)
1437/** Hardware breakpoint 3 was met. */
1438#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B3 RT_BIT(3)
1439/** At least one data or IO breakpoint was hit. */
1440#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BREAKPOINT_ENABLED RT_BIT(12)
1441/** A debug exception would have been triggered by single-step execution mode. */
1442#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS RT_BIT(14)
1443/** Bits 4-11, 13 and 15-63 are reserved. */
1444
1445/** @} */
1446
1447/** @name VMCS field encoding - Natural width host state fields
1448 * @{
1449 */
1450#define VMX_VMCS_HOST_CR0 0x6C00
1451#define VMX_VMCS_HOST_CR3 0x6C02
1452#define VMX_VMCS_HOST_CR4 0x6C04
1453#define VMX_VMCS_HOST_FS_BASE 0x6C06
1454#define VMX_VMCS_HOST_GS_BASE 0x6C08
1455#define VMX_VMCS_HOST_TR_BASE 0x6C0A
1456#define VMX_VMCS_HOST_GDTR_BASE 0x6C0C
1457#define VMX_VMCS_HOST_IDTR_BASE 0x6C0E
1458#define VMX_VMCS_HOST_SYSENTER_ESP 0x6C10
1459#define VMX_VMCS_HOST_SYSENTER_EIP 0x6C12
1460#define VMX_VMCS_HOST_RSP 0x6C14
1461#define VMX_VMCS_HOST_RIP 0x6C16
1462/** @} */
1463
1464/** @} */
1465
1466
1467#if RT_INLINE_ASM_GNU_STYLE
1468# define __STR(x) #x
1469# define STR(x) __STR(x)
1470#endif
1471
1472
1473/** @defgroup grp_vmx_asm vmx assembly helpers
1474 * @ingroup grp_vmx
1475 * @{
1476 */
1477
1478/**
1479 * Executes VMXON
1480 *
1481 * @returns VBox status code
1482 * @param pVMXOn Physical address of VMXON structure
1483 */
1484#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1485DECLASM(int) VMXEnable(RTHCPHYS pVMXOn);
1486#else
1487DECLINLINE(int) VMXEnable(RTHCPHYS pVMXOn)
1488{
1489 int rc = VINF_SUCCESS;
1490# if RT_INLINE_ASM_GNU_STYLE
1491 __asm__ __volatile__ (
1492 "push %3 \n\t"
1493 "push %2 \n\t"
1494 ".byte 0xF3, 0x0F, 0xC7, 0x34, 0x24 # VMXON [esp] \n\t"
1495 "ja 2f \n\t"
1496 "je 1f \n\t"
1497 "movl $"STR(VERR_VMX_INVALID_VMXON_PTR)", %0 \n\t"
1498 "jmp 2f \n\t"
1499 "1: \n\t"
1500 "movl $"STR(VERR_VMX_VMXON_FAILED)", %0 \n\t"
1501 "2: \n\t"
1502 "add $8, %%esp \n\t"
1503 :"=rm"(rc)
1504 :"0"(VINF_SUCCESS),
1505 "ir"((uint32_t)pVMXOn), /* don't allow direct memory reference here, */
1506 "ir"((uint32_t)(pVMXOn >> 32)) /* this would not work with -fomit-frame-pointer */
1507 :"memory"
1508 );
1509# else
1510 __asm
1511 {
1512 push dword ptr [pVMXOn+4]
1513 push dword ptr [pVMXOn]
1514 _emit 0xF3
1515 _emit 0x0F
1516 _emit 0xC7
1517 _emit 0x34
1518 _emit 0x24 /* VMXON [esp] */
1519 jnc vmxon_good
1520 mov dword ptr [rc], VERR_VMX_INVALID_VMXON_PTR
1521 jmp the_end
1522
1523vmxon_good:
1524 jnz the_end
1525 mov dword ptr [rc], VERR_VMX_VMXON_FAILED
1526the_end:
1527 add esp, 8
1528 }
1529# endif
1530 return rc;
1531}
1532#endif
1533
1534
1535/**
1536 * Executes VMXOFF
1537 */
1538#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1539DECLASM(void) VMXDisable(void);
1540#else
1541DECLINLINE(void) VMXDisable(void)
1542{
1543# if RT_INLINE_ASM_GNU_STYLE
1544 __asm__ __volatile__ (
1545 ".byte 0x0F, 0x01, 0xC4 # VMXOFF \n\t"
1546 );
1547# else
1548 __asm
1549 {
1550 _emit 0x0F
1551 _emit 0x01
1552 _emit 0xC4 /* VMXOFF */
1553 }
1554# endif
1555}
1556#endif
1557
1558
1559/**
1560 * Executes VMCLEAR
1561 *
1562 * @returns VBox status code
1563 * @param pVMCS Physical address of VM control structure
1564 */
1565#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1566DECLASM(int) VMXClearVMCS(RTHCPHYS pVMCS);
1567#else
1568DECLINLINE(int) VMXClearVMCS(RTHCPHYS pVMCS)
1569{
1570 int rc = VINF_SUCCESS;
1571# if RT_INLINE_ASM_GNU_STYLE
1572 __asm__ __volatile__ (
1573 "push %3 \n\t"
1574 "push %2 \n\t"
1575 ".byte 0x66, 0x0F, 0xC7, 0x34, 0x24 # VMCLEAR [esp] \n\t"
1576 "jnc 1f \n\t"
1577 "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
1578 "1: \n\t"
1579 "add $8, %%esp \n\t"
1580 :"=rm"(rc)
1581 :"0"(VINF_SUCCESS),
1582 "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */
1583 "ir"((uint32_t)(pVMCS >> 32)) /* this would not work with -fomit-frame-pointer */
1584 :"memory"
1585 );
1586# else
1587 __asm
1588 {
1589 push dword ptr [pVMCS+4]
1590 push dword ptr [pVMCS]
1591 _emit 0x66
1592 _emit 0x0F
1593 _emit 0xC7
1594 _emit 0x34
1595 _emit 0x24 /* VMCLEAR [esp] */
1596 jnc success
1597 mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
1598success:
1599 add esp, 8
1600 }
1601# endif
1602 return rc;
1603}
1604#endif
1605
1606
1607/**
1608 * Executes VMPTRLD
1609 *
1610 * @returns VBox status code
1611 * @param pVMCS Physical address of VMCS structure
1612 */
1613#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1614DECLASM(int) VMXActivateVMCS(RTHCPHYS pVMCS);
1615#else
1616DECLINLINE(int) VMXActivateVMCS(RTHCPHYS pVMCS)
1617{
1618 int rc = VINF_SUCCESS;
1619# if RT_INLINE_ASM_GNU_STYLE
1620 __asm__ __volatile__ (
1621 "push %3 \n\t"
1622 "push %2 \n\t"
1623 ".byte 0x0F, 0xC7, 0x34, 0x24 # VMPTRLD [esp] \n\t"
1624 "jnc 1f \n\t"
1625 "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
1626 "1: \n\t"
1627 "add $8, %%esp \n\t"
1628 :"=rm"(rc)
1629 :"0"(VINF_SUCCESS),
1630 "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */
1631 "ir"((uint32_t)(pVMCS >> 32)) /* this will not work with -fomit-frame-pointer */
1632 );
1633# else
1634 __asm
1635 {
1636 push dword ptr [pVMCS+4]
1637 push dword ptr [pVMCS]
1638 _emit 0x0F
1639 _emit 0xC7
1640 _emit 0x34
1641 _emit 0x24 /* VMPTRLD [esp] */
1642 jnc success
1643 mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
1644
1645success:
1646 add esp, 8
1647 }
1648# endif
1649 return rc;
1650}
1651#endif
1652
1653/**
1654 * Executes VMPTRST
1655 *
1656 * @returns VBox status code
1657 * @param pVMCS Address that will receive the current pointer
1658 */
1659DECLASM(int) VMXGetActivateVMCS(RTHCPHYS *pVMCS);
1660
1661/**
1662 * Executes VMWRITE
1663 *
1664 * @returns VBox status code
1665 * @param idxField VMCS index
1666 * @param u32Val 32 bits value
1667 */
1668#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1669DECLASM(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Val);
1670#else
1671DECLINLINE(int) VMXWriteVmcs32(uint32_t idxField, uint32_t u32Val)
1672{
1673 int rc = VINF_SUCCESS;
1674# if RT_INLINE_ASM_GNU_STYLE
1675 __asm__ __volatile__ (
1676 ".byte 0x0F, 0x79, 0xC2 # VMWRITE eax, edx \n\t"
1677 "ja 2f \n\t"
1678 "je 1f \n\t"
1679 "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
1680 "jmp 2f \n\t"
1681 "1: \n\t"
1682 "movl $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t"
1683 "2: \n\t"
1684 :"=rm"(rc)
1685 :"0"(VINF_SUCCESS),
1686 "a"(idxField),
1687 "d"(u32Val)
1688 );
1689# else
1690 __asm
1691 {
1692 push dword ptr [u32Val]
1693 mov eax, [idxField]
1694 _emit 0x0F
1695 _emit 0x79
1696 _emit 0x04
1697 _emit 0x24 /* VMWRITE eax, [esp] */
1698 jnc valid_vmcs
1699 mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
1700 jmp the_end
1701
1702valid_vmcs:
1703 jnz the_end
1704 mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD
1705the_end:
1706 add esp, 4
1707 }
1708# endif
1709 return rc;
1710}
1711#endif
1712
1713/**
1714 * Executes VMWRITE
1715 *
1716 * @returns VBox status code
1717 * @param idxField VMCS index
1718 * @param u64Val 16, 32 or 64 bits value
1719 */
1720#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1721DECLASM(int) VMXWriteVmcs64(uint32_t idxField, uint64_t u64Val);
1722#else
1723VMMR0DECL(int) VMXWriteVmcs64Ex(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val);
1724
1725#define VMXWriteVmcs64(idxField, u64Val) VMXWriteVmcs64Ex(pVCpu, idxField, u64Val)
1726#endif
1727
1728#ifdef VBOX_WITH_OLD_VTX_CODE
1729# if HC_ARCH_BITS == 64
1730# define VMXWriteVmcs VMXWriteVmcs64
1731# else
1732# define VMXWriteVmcs VMXWriteVmcs32
1733# endif
1734#else /* !VBOX_WITH_OLD_VTX_CODE */
1735# ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
1736# define VMXWriteVmcsHstN(idxField, uVal) HMVMX_IS_64BIT_HOST_MODE() ? \
1737 VMXWriteVmcs64(idxField, uVal) \
1738 : VMXWriteVmcs32(idxField, uVal)
1739# define VMXWriteVmcsGstN(idxField, u64Val) (pVCpu->CTX_SUFF(pVM)->hm.s.fAllow64BitGuests) ? \
1740 VMXWriteVmcs64(idxField, u64Val) \
1741 : VMXWriteVmcs32(idxField, u64Val)
1742# elif HC_ARCH_BITS == 32
1743# define VMXWriteVmcsHstN VMXWriteVmcs32
1744# define VMXWriteVmcsGstN(idxField, u64Val) VMXWriteVmcs64Ex(pVCpu, idxField, u64Val)
1745# else /* HC_ARCH_BITS == 64 */
1746# define VMXWriteVmcsHstN VMXWriteVmcs64
1747# define VMXWriteVmcsGstN VMXWriteVmcs64
1748# endif
1749#endif /* !VBOX_WITH_OLD_VTX_CODE */
1750
1751
1752/**
1753 * Invalidate a page using invept
1754 * @returns VBox status code
1755 * @param enmFlush Type of flush
1756 * @param pDescriptor Descriptor
1757 */
1758DECLASM(int) VMXR0InvEPT(VMX_FLUSH_EPT enmFlush, uint64_t *pDescriptor);
1759
1760/**
1761 * Invalidate a page using invvpid
1762 * @returns VBox status code
1763 * @param enmFlush Type of flush
1764 * @param pDescriptor Descriptor
1765 */
1766DECLASM(int) VMXR0InvVPID(VMX_FLUSH_VPID enmFlush, uint64_t *pDescriptor);
1767
1768/**
1769 * Executes VMREAD
1770 *
1771 * @returns VBox status code
1772 * @param idxField VMCS index
1773 * @param pData Ptr to store VM field value
1774 */
1775#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1776DECLASM(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pData);
1777#else
1778DECLINLINE(int) VMXReadVmcs32(uint32_t idxField, uint32_t *pData)
1779{
1780 int rc = VINF_SUCCESS;
1781# if RT_INLINE_ASM_GNU_STYLE
1782 __asm__ __volatile__ (
1783 "movl $"STR(VINF_SUCCESS)", %0 \n\t"
1784 ".byte 0x0F, 0x78, 0xc2 # VMREAD eax, edx \n\t"
1785 "ja 2f \n\t"
1786 "je 1f \n\t"
1787 "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
1788 "jmp 2f \n\t"
1789 "1: \n\t"
1790 "movl $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t"
1791 "2: \n\t"
1792 :"=&r"(rc),
1793 "=d"(*pData)
1794 :"a"(idxField),
1795 "d"(0)
1796 );
1797# else
1798 __asm
1799 {
1800 sub esp, 4
1801 mov dword ptr [esp], 0
1802 mov eax, [idxField]
1803 _emit 0x0F
1804 _emit 0x78
1805 _emit 0x04
1806 _emit 0x24 /* VMREAD eax, [esp] */
1807 mov edx, pData
1808 pop dword ptr [edx]
1809 jnc valid_vmcs
1810 mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
1811 jmp the_end
1812
1813valid_vmcs:
1814 jnz the_end
1815 mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD
1816the_end:
1817 }
1818# endif
1819 return rc;
1820}
1821#endif
1822
1823/**
1824 * Executes VMREAD
1825 *
1826 * @returns VBox status code
1827 * @param idxField VMCS index
1828 * @param pData Ptr to store VM field value
1829 */
1830#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
1831DECLASM(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData);
1832#else
1833DECLINLINE(int) VMXReadVmcs64(uint32_t idxField, uint64_t *pData)
1834{
1835 int rc;
1836
1837 uint32_t val_hi, val;
1838 rc = VMXReadVmcs32(idxField, &val);
1839 rc |= VMXReadVmcs32(idxField + 1, &val_hi);
1840 AssertRC(rc);
1841 *pData = RT_MAKE_U64(val, val_hi);
1842 return rc;
1843}
1844#endif
1845
1846#ifdef VBOX_WITH_OLD_VTX_CODE
1847# if HC_ARCH_BITS == 64
1848# define VMXReadVmcsField VMXReadVmcs64
1849# else
1850# define VMXReadVmcsField VMXReadVmcs32
1851# endif
1852#endif
1853
1854/**
1855 * Gets the last instruction error value from the current VMCS
1856 *
1857 * @returns error value
1858 */
1859DECLINLINE(uint32_t) VMXGetLastError(void)
1860{
1861#if HC_ARCH_BITS == 64
1862 uint64_t uLastError = 0;
1863 int rc = VMXReadVmcs64(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError);
1864 AssertRC(rc);
1865 return (uint32_t)uLastError;
1866
1867#else /* 32-bit host: */
1868 uint32_t uLastError = 0;
1869 int rc = VMXReadVmcs32(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError);
1870 AssertRC(rc);
1871 return uLastError;
1872#endif
1873}
1874
1875#ifdef IN_RING0
1876VMMR0DECL(int) VMXR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt);
1877VMMR0DECL(int) VMXR0InvalidatePhysPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys);
1878#endif /* IN_RING0 */
1879
1880/** @} */
1881
1882#endif
1883
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette