VirtualBox

source: vbox/trunk/include/VBox/hwacc_vmx.h@ 28065

Last change on this file since 28065 was 26700, checked in by vboxsync, 15 years ago

Deal with missing PDEs in SyncPage for SMP guests.
Deal with big PDEs in SyncPage for SMP guests (nested paging only).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 63.4 KB
Line 
1/** @file
2 * HWACCM - VMX Structures and Definitions. (VMM)
3 */
4
5/*
6 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
26 * Clara, CA 95054 USA or visit http://www.sun.com if you need
27 * additional information or have any questions.
28 */
29
30#ifndef ___VBox_vmx_h
31#define ___VBox_vmx_h
32
33#include <VBox/types.h>
34#include <VBox/err.h>
35#include <iprt/assert.h>
36#include <iprt/asm.h>
37#include <VBox/x86.h>
38
39/** @defgroup grp_vmx vmx Types and Definitions
40 * @ingroup grp_hwaccm
41 * @{
42 */
43
44/** @name VMX EPT paging structures
45 * @{
46 */
47
48/**
49 * Number of page table entries in the EPT. (PDPTE/PDE/PTE)
50 */
51#define EPT_PG_ENTRIES X86_PG_PAE_ENTRIES
52
53/**
54 * EPT Page Directory Pointer Entry. Bit view.
55 * @todo uint64_t isn't safe for bitfields (gcc pedantic warnings, and IIRC,
56 * this did cause trouble with one compiler/version).
57 */
58#pragma pack(1)
59typedef struct EPTPML4EBITS
60{
61 /** Present bit. */
62 uint64_t u1Present : 1;
63 /** Writable bit. */
64 uint64_t u1Write : 1;
65 /** Executable bit. */
66 uint64_t u1Execute : 1;
67 /** Reserved (must be 0). */
68 uint64_t u5Reserved : 5;
69 /** Available for software. */
70 uint64_t u4Available : 4;
71 /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */
72 uint64_t u40PhysAddr : 40;
73 /** Availabe for software. */
74 uint64_t u12Available : 12;
75} EPTPML4EBITS;
76#pragma pack()
77AssertCompileSize(EPTPML4EBITS, 8);
78
79/** Bits 12-51 - - EPT - Physical Page number of the next level. */
80#define EPT_PML4E_PG_MASK X86_PML4E_PG_MASK_FULL
81/** The page shift to get the PML4 index. */
82#define EPT_PML4_SHIFT X86_PML4_SHIFT
83/** The PML4 index mask (apply to a shifted page address). */
84#define EPT_PML4_MASK X86_PML4_MASK
85
86/**
87 * EPT PML4E.
88 */
89#pragma pack(1)
90typedef union EPTPML4E
91{
92 /** Normal view. */
93 EPTPML4EBITS n;
94 /** Unsigned integer view. */
95 X86PGPAEUINT u;
96 /** 64 bit unsigned integer view. */
97 uint64_t au64[1];
98 /** 32 bit unsigned integer view. */
99 uint32_t au32[2];
100} EPTPML4E;
101#pragma pack()
102/** Pointer to a PML4 table entry. */
103typedef EPTPML4E *PEPTPML4E;
104/** Pointer to a const PML4 table entry. */
105typedef const EPTPML4E *PCEPTPML4E;
106AssertCompileSize(EPTPML4E, 8);
107
108/**
109 * EPT PML4 Table.
110 */
111#pragma pack(1)
112typedef struct EPTPML4
113{
114 EPTPML4E a[EPT_PG_ENTRIES];
115} EPTPML4;
116#pragma pack()
117/** Pointer to an EPT PML4 Table. */
118typedef EPTPML4 *PEPTPML4;
119/** Pointer to a const EPT PML4 Table. */
120typedef const EPTPML4 *PCEPTPML4;
121
122/**
123 * EPT Page Directory Pointer Entry. Bit view.
124 */
125#pragma pack(1)
126typedef struct EPTPDPTEBITS
127{
128 /** Present bit. */
129 uint64_t u1Present : 1;
130 /** Writable bit. */
131 uint64_t u1Write : 1;
132 /** Executable bit. */
133 uint64_t u1Execute : 1;
134 /** Reserved (must be 0). */
135 uint64_t u5Reserved : 5;
136 /** Available for software. */
137 uint64_t u4Available : 4;
138 /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */
139 uint64_t u40PhysAddr : 40;
140 /** Availabe for software. */
141 uint64_t u12Available : 12;
142} EPTPDPTEBITS;
143#pragma pack()
144AssertCompileSize(EPTPDPTEBITS, 8);
145
146/** Bits 12-51 - - EPT - Physical Page number of the next level. */
147#define EPT_PDPTE_PG_MASK X86_PDPE_PG_MASK_FULL
148/** The page shift to get the PDPT index. */
149#define EPT_PDPT_SHIFT X86_PDPT_SHIFT
150/** The PDPT index mask (apply to a shifted page address). */
151#define EPT_PDPT_MASK X86_PDPT_MASK_AMD64
152
153/**
154 * EPT Page Directory Pointer.
155 */
156#pragma pack(1)
157typedef union EPTPDPTE
158{
159 /** Normal view. */
160 EPTPDPTEBITS n;
161 /** Unsigned integer view. */
162 X86PGPAEUINT u;
163 /** 64 bit unsigned integer view. */
164 uint64_t au64[1];
165 /** 32 bit unsigned integer view. */
166 uint32_t au32[2];
167} EPTPDPTE;
168#pragma pack()
169/** Pointer to an EPT Page Directory Pointer Entry. */
170typedef EPTPDPTE *PEPTPDPTE;
171/** Pointer to a const EPT Page Directory Pointer Entry. */
172typedef const EPTPDPTE *PCEPTPDPTE;
173AssertCompileSize(EPTPDPTE, 8);
174
175/**
176 * EPT Page Directory Pointer Table.
177 */
178#pragma pack(1)
179typedef struct EPTPDPT
180{
181 EPTPDPTE a[EPT_PG_ENTRIES];
182} EPTPDPT;
183#pragma pack()
184/** Pointer to an EPT Page Directory Pointer Table. */
185typedef EPTPDPT *PEPTPDPT;
186/** Pointer to a const EPT Page Directory Pointer Table. */
187typedef const EPTPDPT *PCEPTPDPT;
188
189
190/**
191 * EPT Page Directory Table Entry. Bit view.
192 */
193#pragma pack(1)
194typedef struct EPTPDEBITS
195{
196 /** Present bit. */
197 uint64_t u1Present : 1;
198 /** Writable bit. */
199 uint64_t u1Write : 1;
200 /** Executable bit. */
201 uint64_t u1Execute : 1;
202 /** Reserved (must be 0). */
203 uint64_t u4Reserved : 4;
204 /** Big page (must be 0 here). */
205 uint64_t u1Size : 1;
206 /** Available for software. */
207 uint64_t u4Available : 4;
208 /** Physical address of page table. Restricted by maximum physical address width of the cpu. */
209 uint64_t u40PhysAddr : 40;
210 /** Availabe for software. */
211 uint64_t u12Available : 12;
212} EPTPDEBITS;
213#pragma pack()
214AssertCompileSize(EPTPDEBITS, 8);
215
216/** Bits 12-51 - - EPT - Physical Page number of the next level. */
217#define EPT_PDE_PG_MASK X86_PDE_PAE_PG_MASK_FULL
218/** The page shift to get the PD index. */
219#define EPT_PD_SHIFT X86_PD_PAE_SHIFT
220/** The PD index mask (apply to a shifted page address). */
221#define EPT_PD_MASK X86_PD_PAE_MASK
222
223/**
224 * EPT 2MB Page Directory Table Entry. Bit view.
225 */
226#pragma pack(1)
227typedef struct EPTPDE2MBITS
228{
229 /** Present bit. */
230 uint64_t u1Present : 1;
231 /** Writable bit. */
232 uint64_t u1Write : 1;
233 /** Executable bit. */
234 uint64_t u1Execute : 1;
235 /** EPT Table Memory Type. MBZ for non-leaf nodes. */
236 uint64_t u3EMT : 3;
237 /** Ignore PAT memory type */
238 uint64_t u1IgnorePAT : 1;
239 /** Big page (must be 1 here). */
240 uint64_t u1Size : 1;
241 /** Available for software. */
242 uint64_t u4Available : 4;
243 /** Reserved (must be 0). */
244 uint64_t u9Reserved : 9;
245 /** Physical address of the 2MB page. Restricted by maximum physical address width of the cpu. */
246 uint64_t u31PhysAddr : 31;
247 /** Availabe for software. */
248 uint64_t u12Available : 12;
249} EPTPDE2MBITS;
250#pragma pack()
251AssertCompileSize(EPTPDE2MBITS, 8);
252
253/** Bits 21-51 - - EPT - Physical Page number of the next level. */
254#define EPT_PDE2M_PG_MASK ( 0x000fffffffe00000ULL )
255
256/**
257 * EPT Page Directory Table Entry.
258 */
259#pragma pack(1)
260typedef union EPTPDE
261{
262 /** Normal view. */
263 EPTPDEBITS n;
264 /** 2MB view (big). */
265 EPTPDE2MBITS b;
266 /** Unsigned integer view. */
267 X86PGPAEUINT u;
268 /** 64 bit unsigned integer view. */
269 uint64_t au64[1];
270 /** 32 bit unsigned integer view. */
271 uint32_t au32[2];
272} EPTPDE;
273#pragma pack()
274/** Pointer to an EPT Page Directory Table Entry. */
275typedef EPTPDE *PEPTPDE;
276/** Pointer to a const EPT Page Directory Table Entry. */
277typedef const EPTPDE *PCEPTPDE;
278AssertCompileSize(EPTPDE, 8);
279
280/**
281 * EPT Page Directory Table.
282 */
283#pragma pack(1)
284typedef struct EPTPD
285{
286 EPTPDE a[EPT_PG_ENTRIES];
287} EPTPD;
288#pragma pack()
289/** Pointer to an EPT Page Directory Table. */
290typedef EPTPD *PEPTPD;
291/** Pointer to a const EPT Page Directory Table. */
292typedef const EPTPD *PCEPTPD;
293
294
295/**
296 * EPT Page Table Entry. Bit view.
297 */
298#pragma pack(1)
299typedef struct EPTPTEBITS
300{
301 /** Present bit. */
302 uint64_t u1Present : 1;
303 /** Writable bit. */
304 uint64_t u1Write : 1;
305 /** Executable bit. */
306 uint64_t u1Execute : 1;
307 /** EPT Table Memory Type. MBZ for non-leaf nodes. */
308 uint64_t u3EMT : 3;
309 /** Ignore PAT memory type */
310 uint64_t u1IgnorePAT : 1;
311 /** Available for software. */
312 uint64_t u5Available : 5;
313 /** Physical address of page. Restricted by maximum physical address width of the cpu. */
314 uint64_t u40PhysAddr : 40;
315 /** Availabe for software. */
316 uint64_t u12Available : 12;
317} EPTPTEBITS;
318#pragma pack()
319AssertCompileSize(EPTPTEBITS, 8);
320
321/** Bits 12-51 - - EPT - Physical Page number of the next level. */
322#define EPT_PTE_PG_MASK X86_PTE_PAE_PG_MASK_FULL
323/** The page shift to get the EPT PTE index. */
324#define EPT_PT_SHIFT X86_PT_PAE_SHIFT
325/** The EPT PT index mask (apply to a shifted page address). */
326#define EPT_PT_MASK X86_PT_PAE_MASK
327
328/**
329 * EPT Page Table Entry.
330 */
331#pragma pack(1)
332typedef union EPTPTE
333{
334 /** Normal view. */
335 EPTPTEBITS n;
336 /** Unsigned integer view. */
337 X86PGPAEUINT u;
338 /** 64 bit unsigned integer view. */
339 uint64_t au64[1];
340 /** 32 bit unsigned integer view. */
341 uint32_t au32[2];
342} EPTPTE;
343#pragma pack()
344/** Pointer to an EPT Page Directory Table Entry. */
345typedef EPTPTE *PEPTPTE;
346/** Pointer to a const EPT Page Directory Table Entry. */
347typedef const EPTPTE *PCEPTPTE;
348AssertCompileSize(EPTPTE, 8);
349
350/**
351 * EPT Page Table.
352 */
353#pragma pack(1)
354typedef struct EPTPT
355{
356 EPTPTE a[EPT_PG_ENTRIES];
357} EPTPT;
358#pragma pack()
359/** Pointer to an extended page table. */
360typedef EPTPT *PEPTPT;
361/** Pointer to a const extended table. */
362typedef const EPTPT *PCEPTPT;
363
364/**
365 * VPID and EPT flush types
366 */
367typedef enum
368{
369 /* Invalidate a specific page. */
370 VMX_FLUSH_PAGE = 0,
371 /* Invalidate one context (VPID or EPT) */
372 VMX_FLUSH_SINGLE_CONTEXT = 1,
373 /* Invalidate all contexts (VPIDs or EPTs) */
374 VMX_FLUSH_ALL_CONTEXTS = 2,
375 /* Invalidate a single VPID context retaining global mappings. */
376 VMX_FLUSH_SINGLE_CONTEXT_WITHOUT_GLOBAL = 3,
377 /** 32bit hackishness. */
378 VMX_FLUSH_32BIT_HACK = 0x7fffffff
379} VMX_FLUSH;
380/** @} */
381
382/** @name MSR load/store elements
383 * @{
384 */
385#pragma pack(1)
386typedef struct
387{
388 uint32_t u32IndexMSR;
389 uint32_t u32Reserved;
390 uint64_t u64Value;
391} VMXMSR;
392#pragma pack()
393/** Pointer to an MSR load/store element. */
394typedef VMXMSR *PVMXMSR;
395/** Pointer to a const MSR load/store element. */
396typedef const VMXMSR *PCVMXMSR;
397
398/** @} */
399
400
401/** @name VT-x capability qword
402 * @{
403 */
404#pragma pack(1)
405typedef union
406{
407 struct
408 {
409 uint32_t disallowed0;
410 uint32_t allowed1;
411 } n;
412 uint64_t u;
413} VMX_CAPABILITY;
414#pragma pack()
415/** @} */
416
417/** @name VMX Basic Exit Reasons.
418 * @{
419 */
420/** And-mask for setting reserved bits to zero */
421#define VMX_EFLAGS_RESERVED_0 (~0xffc08028)
422/** Or-mask for setting reserved bits to 1 */
423#define VMX_EFLAGS_RESERVED_1 0x00000002
424/** @} */
425
426/** @name VMX Basic Exit Reasons.
427 * @{
428 */
429/** -1 Invalid exit code */
430#define VMX_EXIT_INVALID -1
431/** 0 Exception or non-maskable interrupt (NMI). */
432#define VMX_EXIT_EXCEPTION 0
433/** 1 External interrupt. */
434#define VMX_EXIT_EXTERNAL_IRQ 1
435/** 2 Triple fault. */
436#define VMX_EXIT_TRIPLE_FAULT 2
437/** 3 INIT signal. */
438#define VMX_EXIT_INIT_SIGNAL 3
439/** 4 Start-up IPI (SIPI). */
440#define VMX_EXIT_SIPI 4
441/** 5 I/O system-management interrupt (SMI). */
442#define VMX_EXIT_IO_SMI_IRQ 5
443/** 6 Other SMI. */
444#define VMX_EXIT_SMI_IRQ 6
445/** 7 Interrupt window. */
446#define VMX_EXIT_IRQ_WINDOW 7
447/** 9 Task switch. */
448#define VMX_EXIT_TASK_SWITCH 9
449/** 10 Guest software attempted to execute CPUID. */
450#define VMX_EXIT_CPUID 10
451/** 12 Guest software attempted to execute HLT. */
452#define VMX_EXIT_HLT 12
453/** 13 Guest software attempted to execute INVD. */
454#define VMX_EXIT_INVD 13
455/** 14 Guest software attempted to execute INVPG. */
456#define VMX_EXIT_INVPG 14
457/** 15 Guest software attempted to execute RDPMC. */
458#define VMX_EXIT_RDPMC 15
459/** 16 Guest software attempted to execute RDTSC. */
460#define VMX_EXIT_RDTSC 16
461/** 17 Guest software attempted to execute RSM in SMM. */
462#define VMX_EXIT_RSM 17
463/** 18 Guest software executed VMCALL. */
464#define VMX_EXIT_VMCALL 18
465/** 19 Guest software executed VMCLEAR. */
466#define VMX_EXIT_VMCLEAR 19
467/** 20 Guest software executed VMLAUNCH. */
468#define VMX_EXIT_VMLAUNCH 20
469/** 21 Guest software executed VMPTRLD. */
470#define VMX_EXIT_VMPTRLD 21
471/** 22 Guest software executed VMPTRST. */
472#define VMX_EXIT_VMPTRST 22
473/** 23 Guest software executed VMREAD. */
474#define VMX_EXIT_VMREAD 23
475/** 24 Guest software executed VMRESUME. */
476#define VMX_EXIT_VMRESUME 24
477/** 25 Guest software executed VMWRITE. */
478#define VMX_EXIT_VMWRITE 25
479/** 26 Guest software executed VMXOFF. */
480#define VMX_EXIT_VMXOFF 26
481/** 27 Guest software executed VMXON. */
482#define VMX_EXIT_VMXON 27
483/** 28 Control-register accesses. */
484#define VMX_EXIT_CRX_MOVE 28
485/** 29 Debug-register accesses. */
486#define VMX_EXIT_DRX_MOVE 29
487/** 30 I/O instruction. */
488#define VMX_EXIT_PORT_IO 30
489/** 31 RDMSR. Guest software attempted to execute RDMSR. */
490#define VMX_EXIT_RDMSR 31
491/** 32 WRMSR. Guest software attempted to execute WRMSR. */
492#define VMX_EXIT_WRMSR 32
493/** 33 VM-entry failure due to invalid guest state. */
494#define VMX_EXIT_ERR_INVALID_GUEST_STATE 33
495/** 34 VM-entry failure due to MSR loading. */
496#define VMX_EXIT_ERR_MSR_LOAD 34
497/** 36 Guest software executed MWAIT. */
498#define VMX_EXIT_MWAIT 36
499/** 39 Guest software attempted to execute MONITOR. */
500#define VMX_EXIT_MONITOR 39
501/** 40 Guest software attempted to execute PAUSE. */
502#define VMX_EXIT_PAUSE 40
503/** 41 VM-entry failure due to machine-check. */
504#define VMX_EXIT_ERR_MACHINE_CHECK 41
505/** 43 TPR below threshold. Guest software executed MOV to CR8. */
506#define VMX_EXIT_TPR 43
507/** 44 APIC access. Guest software attempted to access memory at a physical address on the APIC-access page. */
508#define VMX_EXIT_APIC_ACCESS 44
509/** 46 Access to GDTR or IDTR. Guest software attempted to execute LGDT, LIDT, SGDT, or SIDT. */
510#define VMX_EXIT_XDTR_ACCESS 46
511/** 47 Access to LDTR or TR. Guest software attempted to execute LLDT, LTR, SLDT, or STR. */
512#define VMX_EXIT_TR_ACCESS 47
513/** 48 EPT violation. An attempt to access memory with a guest-physical address was disallowed by the configuration of the EPT paging structures. */
514#define VMX_EXIT_EPT_VIOLATION 48
515/** 49 EPT misconfiguration. An attempt to access memory with a guest-physical address encountered a misconfigured EPT paging-structure entry. */
516#define VMX_EXIT_EPT_MISCONFIG 49
517/** 50 INVEPT. Guest software attempted to execute INVEPT. */
518#define VMX_EXIT_INVEPT 50
519/** 52 VMX-preemption timer expired. The preemption timer counted down to zero. */
520#define VMX_EXIT_PREEMPTION_TIMER 52
521/** 53 INVVPID. Guest software attempted to execute INVVPID. */
522#define VMX_EXIT_INVVPID 53
523/** 54 WBINVD. Guest software attempted to execute WBINVD. */
524#define VMX_EXIT_WBINVD 54
525/** 55 XSETBV. Guest software attempted to execute XSETBV. */
526#define VMX_EXIT_XSETBV 55
527/** @} */
528
529
530/** @name VM Instruction Errors
531 * @{
532 */
533/** 1 VMCALL executed in VMX root operation. */
534#define VMX_ERROR_VMCALL 1
535/** 2 VMCLEAR with invalid physical address. */
536#define VMX_ERROR_VMCLEAR_INVALID_PHYS_ADDR 2
537/** 3 VMCLEAR with VMXON pointer. */
538#define VMX_ERROR_VMCLEAR_INVALID_VMXON_PTR 3
539/** 4 VMLAUNCH with non-clear VMCS. */
540#define VMX_ERROR_VMLAUCH_NON_CLEAR_VMCS 4
541/** 5 VMRESUME with non-launched VMCS. */
542#define VMX_ERROR_VMRESUME_NON_LAUNCHED_VMCS 5
543/** 6 VMRESUME with a corrupted VMCS (indicates corruption of the current VMCS). */
544#define VMX_ERROR_VMRESUME_CORRUPTED_VMCS 6
545/** 7 VM entry with invalid control field(s). */
546#define VMX_ERROR_VMENTRY_INVALID_CONTROL_FIELDS 7
547/** 8 VM entry with invalid host-state field(s). */
548#define VMX_ERROR_VMENTRY_INVALID_HOST_STATE 8
549/** 9 VMPTRLD with invalid physical address. */
550#define VMX_ERROR_VMPTRLD_INVALID_PHYS_ADDR 9
551/** 10 VMPTRLD with VMXON pointer. */
552#define VMX_ERROR_VMPTRLD_VMXON_PTR 10
553/** 11 VMPTRLD with incorrect VMCS revision identifier. */
554#define VMX_ERROR_VMPTRLD_WRONG_VMCS_REVISION 11
555/** 12 VMREAD/VMWRITE from/to unsupported VMCS component. */
556#define VMX_ERROR_VMREAD_INVALID_COMPONENT 12
557#define VMX_ERROR_VMWRITE_INVALID_COMPONENT VMX_ERROR_VMREAD_INVALID_COMPONENT
558/** 13 VMWRITE to read-only VMCS component. */
559#define VMX_ERROR_VMWRITE_READONLY_COMPONENT 13
560/** 15 VMXON executed in VMX root operation. */
561#define VMX_ERROR_VMXON_IN_VMX_ROOT_OP 15
562/** 16 VM entry with invalid executive-VMCS pointer. */
563#define VMX_ERROR_VMENTRY_INVALID_VMCS_EXEC_PTR 16
564/** 17 VM entry with non-launched executive VMCS. */
565#define VMX_ERROR_VMENTRY_NON_LAUNCHED_EXEC_VMCS 17
566/** 18 VM entry with executive-VMCS pointer not VMXON pointer. */
567#define VMX_ERROR_VMENTRY_EXEC_VMCS_PTR 18
568/** 19 VMCALL with non-clear VMCS. */
569#define VMX_ERROR_VMCALL_NON_CLEAR_VMCS 19
570/** 20 VMCALL with invalid VM-exit control fields. */
571#define VMX_ERROR_VMCALL_INVALID_VMEXIT_FIELDS 20
572/** 22 VMCALL with incorrect MSEG revision identifier. */
573#define VMX_ERROR_VMCALL_INVALID_MSEG_REVISION 22
574/** 23 VMXOFF under dual-monitor treatment of SMIs and SMM. */
575#define VMX_ERROR_VMXOFF_DUAL_MONITOR 23
576/** 24 VMCALL with invalid SMM-monitor features. */
577#define VMX_ERROR_VMCALL_INVALID_SMM_MONITOR 24
578/** 25 VM entry with invalid VM-execution control fields in executive VMCS. */
579#define VMX_ERROR_VMENTRY_INVALID_VM_EXEC_CTRL 25
580/** 26 VM entry with events blocked by MOV SS. */
581#define VMX_ERROR_VMENTRY_MOV_SS 26
582/** 26 Invalid operand to INVEPT/INVVPID. */
583#define VMX_ERROR_INVEPTVPID_INVALID_OPERAND 28
584
585/** @} */
586
587
588/** @name VMX MSRs - Basic VMX information.
589 * @{
590 */
591/** VMCS revision identifier used by the processor. */
592#define MSR_IA32_VMX_BASIC_INFO_VMCS_ID(a) (a & 0x7FFFFFFF)
593/** Size of the VMCS. */
594#define MSR_IA32_VMX_BASIC_INFO_VMCS_SIZE(a) ((a >> 32ULL) & 0xFFF)
595/** Width of physical address used for the VMCS.
596 * 0 -> limited to the available amount of physical ram
597 * 1 -> within the first 4 GB
598 */
599#define MSR_IA32_VMX_BASIC_INFO_VMCS_PHYS_WIDTH(a) ((a >> 48ULL) & 1)
600/** Whether the processor supports the dual-monitor treatment of system-management interrupts and system-management code. (always 1) */
601#define MSR_IA32_VMX_BASIC_INFO_VMCS_DUAL_MON(a) ((a >> 49ULL) & 1)
602/** Memory type that must be used for the VMCS. */
603#define MSR_IA32_VMX_BASIC_INFO_VMCS_MEM_TYPE(a) ((a >> 50ULL) & 0xF)
604/** @} */
605
606
607/** @name VMX MSRs - Misc VMX info.
608 * @{
609 */
610/** Relationship between the preemption timer and tsc; count down every time bit x of the tsc changes. */
611#define MSR_IA32_VMX_MISC_PREEMPT_TSC_BIT(a) (a & 0x1f)
612/** Activity states supported by the implementation. */
613#define MSR_IA32_VMX_MISC_ACTIVITY_STATES(a) ((a >> 6ULL) & 0x7)
614/** Number of CR3 target values supported by the processor. (0-256) */
615#define MSR_IA32_VMX_MISC_CR3_TARGET(a) ((a >> 16ULL) & 0x1FF)
616/** Maximum nr of MSRs in the VMCS. (N+1)*512. */
617#define MSR_IA32_VMX_MISC_MAX_MSR(a) ((((a >> 25ULL) & 0x7) + 1) * 512)
618/** MSEG revision identifier used by the processor. */
619#define MSR_IA32_VMX_MISC_MSEG_ID(a) (a >> 32ULL)
620/** @} */
621
622
623/** @name VMX MSRs - VMCS enumeration field info
624 * @{
625 */
626/** Highest field index. */
627#define MSR_IA32_VMX_VMCS_ENUM_HIGHEST_INDEX(a) ((a >> 1ULL) & 0x1FF)
628
629/** @} */
630
631
632/** @name MSR_IA32_VMX_EPT_CAPS; EPT capabilities MSR
633 * @{
634 */
635#define MSR_IA32_VMX_EPT_CAPS_RWX_X_ONLY RT_BIT_64(0)
636#define MSR_IA32_VMX_EPT_CAPS_RWX_W_ONLY RT_BIT_64(1)
637#define MSR_IA32_VMX_EPT_CAPS_RWX_WX_ONLY RT_BIT_64(2)
638#define MSR_IA32_VMX_EPT_CAPS_GAW_21_BITS RT_BIT_64(3)
639#define MSR_IA32_VMX_EPT_CAPS_GAW_30_BITS RT_BIT_64(4)
640#define MSR_IA32_VMX_EPT_CAPS_GAW_39_BITS RT_BIT_64(5)
641#define MSR_IA32_VMX_EPT_CAPS_GAW_48_BITS RT_BIT_64(6)
642#define MSR_IA32_VMX_EPT_CAPS_GAW_57_BITS RT_BIT_64(7)
643#define MSR_IA32_VMX_EPT_CAPS_EMT_UC RT_BIT_64(8)
644#define MSR_IA32_VMX_EPT_CAPS_EMT_WC RT_BIT_64(9)
645#define MSR_IA32_VMX_EPT_CAPS_EMT_WT RT_BIT_64(12)
646#define MSR_IA32_VMX_EPT_CAPS_EMT_WP RT_BIT_64(13)
647#define MSR_IA32_VMX_EPT_CAPS_EMT_WB RT_BIT_64(14)
648#define MSR_IA32_VMX_EPT_CAPS_SP_21_BITS RT_BIT_64(16)
649#define MSR_IA32_VMX_EPT_CAPS_SP_30_BITS RT_BIT_64(17)
650#define MSR_IA32_VMX_EPT_CAPS_SP_39_BITS RT_BIT_64(18)
651#define MSR_IA32_VMX_EPT_CAPS_SP_48_BITS RT_BIT_64(19)
652#define MSR_IA32_VMX_EPT_CAPS_INVEPT RT_BIT_64(20)
653#define MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_INDIV RT_BIT_64(24)
654#define MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_CONTEXT RT_BIT_64(25)
655#define MSR_IA32_VMX_EPT_CAPS_INVEPT_CAPS_ALL RT_BIT_64(26)
656#define MSR_IA32_VMX_EPT_CAPS_INVVPID RT_BIT_64(32)
657#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_INDIV RT_BIT_64(40)
658#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_CONTEXT RT_BIT_64(41)
659#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_ALL RT_BIT_64(42)
660#define MSR_IA32_VMX_EPT_CAPS_INVVPID_CAPS_CONTEXT_GLOBAL RT_BIT_64(43)
661
662/** @} */
663
664/** @name Extended Page Table Pointer (EPTP)
665 * @{
666 */
667/** Uncachable EPT paging structure memory type. */
668#define VMX_EPT_MEMTYPE_UC 0
669/** Write-back EPT paging structure memory type. */
670#define VMX_EPT_MEMTYPE_WB 6
671/** Shift value to get the EPT page walk length (bits 5-3) */
672#define VMX_EPT_PAGE_WALK_LENGTH_SHIFT 3
673/** Mask value to get the EPT page walk length (bits 5-3) */
674#define VMX_EPT_PAGE_WALK_LENGTH_MASK 7
675/** Default EPT page walk length */
676#define VMX_EPT_PAGE_WALK_LENGTH_DEFAULT 3
677/** @} */
678
679
680/** @name VMCS field encoding - 16 bits guest fields
681 * @{
682 */
683#define VMX_VMCS16_GUEST_FIELD_VPID 0x0
684#define VMX_VMCS16_GUEST_FIELD_ES 0x800
685#define VMX_VMCS16_GUEST_FIELD_CS 0x802
686#define VMX_VMCS16_GUEST_FIELD_SS 0x804
687#define VMX_VMCS16_GUEST_FIELD_DS 0x806
688#define VMX_VMCS16_GUEST_FIELD_FS 0x808
689#define VMX_VMCS16_GUEST_FIELD_GS 0x80A
690#define VMX_VMCS16_GUEST_FIELD_LDTR 0x80C
691#define VMX_VMCS16_GUEST_FIELD_TR 0x80E
692/** @} */
693
694/** @name VMCS field encoding - 16 bits host fields
695 * @{
696 */
697#define VMX_VMCS16_HOST_FIELD_ES 0xC00
698#define VMX_VMCS16_HOST_FIELD_CS 0xC02
699#define VMX_VMCS16_HOST_FIELD_SS 0xC04
700#define VMX_VMCS16_HOST_FIELD_DS 0xC06
701#define VMX_VMCS16_HOST_FIELD_FS 0xC08
702#define VMX_VMCS16_HOST_FIELD_GS 0xC0A
703#define VMX_VMCS16_HOST_FIELD_TR 0xC0C
704/** @} */
705
706/** @name VMCS field encoding - 64 bits host fields
707 * @{
708 */
709#define VMX_VMCS_HOST_FIELD_PAT_FULL 0x2C00
710#define VMX_VMCS_HOST_FIELD_PAT_HIGH 0x2C01
711#define VMX_VMCS_HOST_FIELD_EFER_FULL 0x2C02
712#define VMX_VMCS_HOST_FIELD_EFER_HIGH 0x2C03
713#define VMX_VMCS_HOST_PERF_GLOBAL_CTRL_FULL 0x2C04 /**< MSR IA32_PERF_GLOBAL_CTRL */
714#define VMX_VMCS_HOST_PERF_GLOBAL_CTRL_HIGH 0x2C05 /**< MSR IA32_PERF_GLOBAL_CTRL */
715/** @} */
716
717
718/** @name VMCS field encoding - 64 Bits control fields
719 * @{
720 */
721#define VMX_VMCS_CTRL_IO_BITMAP_A_FULL 0x2000
722#define VMX_VMCS_CTRL_IO_BITMAP_A_HIGH 0x2001
723#define VMX_VMCS_CTRL_IO_BITMAP_B_FULL 0x2002
724#define VMX_VMCS_CTRL_IO_BITMAP_B_HIGH 0x2003
725
726/* Optional */
727#define VMX_VMCS_CTRL_MSR_BITMAP_FULL 0x2004
728#define VMX_VMCS_CTRL_MSR_BITMAP_HIGH 0x2005
729
730#define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_FULL 0x2006
731#define VMX_VMCS_CTRL_VMEXIT_MSR_STORE_HIGH 0x2007
732#define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_FULL 0x2008
733#define VMX_VMCS_CTRL_VMEXIT_MSR_LOAD_HIGH 0x2009
734
735#define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_FULL 0x200A
736#define VMX_VMCS_CTRL_VMENTRY_MSR_LOAD_HIGH 0x200B
737
738#define VMX_VMCS_CTRL_EXEC_VMCS_PTR_FULL 0x200C
739#define VMX_VMCS_CTRL_EXEC_VMCS_PTR_HIGH 0x200D
740
741#define VMX_VMCS_CTRL_TSC_OFFSET_FULL 0x2010
742#define VMX_VMCS_CTRL_TSC_OFFSET_HIGH 0x2011
743
744/** Optional (VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW) */
745#define VMX_VMCS_CTRL_VAPIC_PAGEADDR_FULL 0x2012
746#define VMX_VMCS_CTRL_VAPIC_PAGEADDR_HIGH 0x2013
747
748/** Optional (VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC) */
749#define VMX_VMCS_CTRL_APIC_ACCESSADDR_FULL 0x2014
750#define VMX_VMCS_CTRL_APIC_ACCESSADDR_HIGH 0x2015
751
752/** Extended page table pointer. */
753#define VMX_VMCS_CTRL_EPTP_FULL 0x201a
754#define VMX_VMCS_CTRL_EPTP_HIGH 0x201b
755
756/** VM-exit phyiscal address. */
757#define VMX_VMCS_EXIT_PHYS_ADDR_FULL 0x2400
758#define VMX_VMCS_EXIT_PHYS_ADDR_HIGH 0x2401
759/** @} */
760
761
762/** @name VMCS field encoding - 64 Bits guest fields
763 * @{
764 */
765#define VMX_VMCS_GUEST_LINK_PTR_FULL 0x2800
766#define VMX_VMCS_GUEST_LINK_PTR_HIGH 0x2801
767#define VMX_VMCS_GUEST_DEBUGCTL_FULL 0x2802 /**< MSR IA32_DEBUGCTL */
768#define VMX_VMCS_GUEST_DEBUGCTL_HIGH 0x2803 /**< MSR IA32_DEBUGCTL */
769#define VMX_VMCS_GUEST_PAT_FULL 0x2804
770#define VMX_VMCS_GUEST_PAT_HIGH 0x2805
771#define VMX_VMCS_GUEST_EFER_FULL 0x2806
772#define VMX_VMCS_GUEST_EFER_HIGH 0x2807
773#define VMX_VMCS_GUEST_PERF_GLOBAL_CTRL_FULL 0x2808 /**< MSR IA32_PERF_GLOBAL_CTRL */
774#define VMX_VMCS_GUEST_PERF_GLOBAL_CTRL_HIGH 0x2809 /**< MSR IA32_PERF_GLOBAL_CTRL */
775#define VMX_VMCS_GUEST_PDPTR0_FULL 0x280A
776#define VMX_VMCS_GUEST_PDPTR0_HIGH 0x280B
777#define VMX_VMCS_GUEST_PDPTR1_FULL 0x280C
778#define VMX_VMCS_GUEST_PDPTR1_HIGH 0x280D
779#define VMX_VMCS_GUEST_PDPTR2_FULL 0x280E
780#define VMX_VMCS_GUEST_PDPTR2_HIGH 0x280F
781#define VMX_VMCS_GUEST_PDPTR3_FULL 0x2810
782#define VMX_VMCS_GUEST_PDPTR3_HIGH 0x2811
783/** @} */
784
785
786/** @name VMCS field encoding - 32 Bits control fields
787 * @{
788 */
789#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS 0x4000
790#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS 0x4002
791#define VMX_VMCS_CTRL_EXCEPTION_BITMAP 0x4004
792#define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MASK 0x4006
793#define VMX_VMCS_CTRL_PAGEFAULT_ERROR_MATCH 0x4008
794#define VMX_VMCS_CTRL_CR3_TARGET_COUNT 0x400A
795#define VMX_VMCS_CTRL_EXIT_CONTROLS 0x400C
796#define VMX_VMCS_CTRL_EXIT_MSR_STORE_COUNT 0x400E
797#define VMX_VMCS_CTRL_EXIT_MSR_LOAD_COUNT 0x4010
798#define VMX_VMCS_CTRL_ENTRY_CONTROLS 0x4012
799#define VMX_VMCS_CTRL_ENTRY_MSR_LOAD_COUNT 0x4014
800#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO 0x4016
801#define VMX_VMCS_CTRL_ENTRY_EXCEPTION_ERRCODE 0x4018
802#define VMX_VMCS_CTRL_ENTRY_INSTR_LENGTH 0x401A
803/** This field exists only on processors that support the 1-setting of the “use TPR shadow” VM-execution control. */
804#define VMX_VMCS_CTRL_TPR_THRESHOLD 0x401C
805/** This field exists only on processors that support the 1-setting of the “activate secondary controls” VM-execution control. */
806#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2 0x401E
807/** @} */
808
809
810/** @name VMX_VMCS_CTRL_PIN_EXEC_CONTROLS
811 * @{
812 */
813/** External interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */
814#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_EXT_INT_EXIT RT_BIT(0)
815/** Non-maskable interrupts cause VM exits if set; otherwise dispatched through the guest's IDT. */
816#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_NMI_EXIT RT_BIT(3)
817/** Virtual NMIs. */
818#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_VIRTUAL_NMI RT_BIT(5)
819/** Activate VMX preemption timer. */
820#define VMX_VMCS_CTRL_PIN_EXEC_CONTROLS_PREEMPT_TIMER RT_BIT(6)
821/* All other bits are reserved and must be set according to MSR IA32_VMX_PROCBASED_CTLS. */
822/** @} */
823
824/** @name VMX_VMCS_CTRL_PROC_EXEC_CONTROLS
825 * @{
826 */
827/** VM Exit as soon as RFLAGS.IF=1 and no blocking is active. */
828#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_IRQ_WINDOW_EXIT RT_BIT(2)
829/** Use timestamp counter offset. */
830#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_TSC_OFFSET RT_BIT(3)
831/** VM Exit when executing the HLT instruction. */
832#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_HLT_EXIT RT_BIT(7)
833/** VM Exit when executing the INVLPG instruction. */
834#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_INVLPG_EXIT RT_BIT(9)
835/** VM Exit when executing the MWAIT instruction. */
836#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MWAIT_EXIT RT_BIT(10)
837/** VM Exit when executing the RDPMC instruction. */
838#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDPMC_EXIT RT_BIT(11)
839/** VM Exit when executing the RDTSC instruction. */
840#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_RDTSC_EXIT RT_BIT(12)
841/** 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) */
842#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_LOAD_EXIT RT_BIT(15)
843/** 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) */
844#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR3_STORE_EXIT RT_BIT(16)
845/** VM Exit on CR8 loads. */
846#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_LOAD_EXIT RT_BIT(19)
847/** VM Exit on CR8 stores. */
848#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_CR8_STORE_EXIT RT_BIT(20)
849/** Use TPR shadow. */
850#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_TPR_SHADOW RT_BIT(21)
851/** VM Exit when virtual nmi blocking is disabled. */
852#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_NMI_WINDOW_EXIT RT_BIT(22)
853/** VM Exit when executing a MOV DRx instruction. */
854#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MOV_DR_EXIT RT_BIT(23)
855/** VM Exit when executing IO instructions. */
856#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_UNCOND_IO_EXIT RT_BIT(24)
857/** Use IO bitmaps. */
858#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_IO_BITMAPS RT_BIT(25)
859/** Monitor trap flag. */
860#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_TRAP_FLAG RT_BIT(27)
861/** Use MSR bitmaps. */
862#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_USE_MSR_BITMAPS RT_BIT(28)
863/** VM Exit when executing the MONITOR instruction. */
864#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_MONITOR_EXIT RT_BIT(29)
865/** VM Exit when executing the PAUSE instruction. */
866#define VMX_VMCS_CTRL_PROC_EXEC_CONTROLS_PAUSE_EXIT RT_BIT(30)
867/** Determines whether the secondary processor based VM-execution controls are used. */
868#define VMX_VMCS_CTRL_PROC_EXEC_USE_SECONDARY_EXEC_CTRL RT_BIT(31)
869/** @} */
870
871/** @name VMX_VMCS_CTRL_PROC_EXEC_CONTROLS2
872 * @{
873 */
874/** Virtualize APIC access. */
875#define VMX_VMCS_CTRL_PROC_EXEC2_VIRT_APIC RT_BIT(0)
876/** EPT supported/enabled. */
877#define VMX_VMCS_CTRL_PROC_EXEC2_EPT RT_BIT(1)
878/** Descriptor table instructions cause VM-exits. */
879#define VMX_VMCS_CTRL_PROC_EXEC2_DESCRIPTOR_INSTR_EXIT RT_BIT(2)
880/** RDTSCP causes a VM-exit. */
881#define VMX_VMCS_CTRL_PROC_EXEC2_RDTSCP_EXIT RT_BIT(3)
882/** Virtualize x2APIC mode. */
883#define VMX_VMCS_CTRL_PROC_EXEC2_X2APIC RT_BIT(4)
884/** VPID supported/enabled. */
885#define VMX_VMCS_CTRL_PROC_EXEC2_VPID RT_BIT(5)
886/** VM Exit when executing the WBINVD instruction. */
887#define VMX_VMCS_CTRL_PROC_EXEC2_WBINVD_EXIT RT_BIT(6)
888/** Unrestricted guest execution. */
889#define VMX_VMCS_CTRL_PROC_EXEC2_REAL_MODE RT_BIT(7)
890/** A specified nr of pause loops cause a VM-exit. */
891#define VMX_VMCS_CTRL_PROC_EXEC2_PAUSE_LOOP_EXIT RT_BIT(10)
892/** @} */
893
894
895/** @name VMX_VMCS_CTRL_ENTRY_CONTROLS
896 * @{
897 */
898/** 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) */
899#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_DEBUG RT_BIT(2)
900/** 64 bits guest mode. Must be 0 for CPUs that don't support AMD64. */
901#define VMX_VMCS_CTRL_ENTRY_CONTROLS_IA64_MODE RT_BIT(9)
902/** In SMM mode after VM-entry. */
903#define VMX_VMCS_CTRL_ENTRY_CONTROLS_ENTRY_SMM RT_BIT(10)
904/** Disable dual treatment of SMI and SMM; must be zero for VM-entry outside of SMM. */
905#define VMX_VMCS_CTRL_ENTRY_CONTROLS_DEACTIVATE_DUALMON RT_BIT(11)
906/** This control determines whether the guest IA32_PERF_GLOBAL_CTRL MSR is loaded on VM entry. */
907#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PERF_MSR RT_BIT(13)
908/** This control determines whether the guest IA32_PAT MSR is loaded on VM entry. */
909#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_PAT_MSR RT_BIT(14)
910/** This control determines whether the guest IA32_EFER MSR is loaded on VM entry. */
911#define VMX_VMCS_CTRL_ENTRY_CONTROLS_LOAD_GUEST_EFER_MSR RT_BIT(15)
912/** @} */
913
914
915/** @name VMX_VMCS_CTRL_EXIT_CONTROLS
916 * @{
917 */
918/** 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) */
919#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_DEBUG RT_BIT(2)
920/** Return to long mode after a VM-exit. */
921#define VMX_VMCS_CTRL_EXIT_CONTROLS_HOST_AMD64 RT_BIT(9)
922/** This control determines whether the IA32_PERF_GLOBAL_CTRL MSR is loaded on VM exit. */
923#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_PERF_MSR RT_BIT(12)
924/** Acknowledge external interrupts with the irq controller if one caused a VM-exit. */
925#define VMX_VMCS_CTRL_EXIT_CONTROLS_ACK_EXTERNAL_IRQ RT_BIT(15)
926/** This control determines whether the guest IA32_PAT MSR is saved on VM exit. */
927#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_PAT_MSR RT_BIT(18)
928/** This control determines whether the host IA32_PAT MSR is loaded on VM exit. */
929#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_PAT_MSR RT_BIT(19)
930/** This control determines whether the guest IA32_EFER MSR is saved on VM exit. */
931#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_GUEST_EFER_MSR RT_BIT(20)
932/** This control determines whether the host IA32_EFER MSR is loaded on VM exit. */
933#define VMX_VMCS_CTRL_EXIT_CONTROLS_LOAD_HOST_EFER_MSR RT_BIT(21)
934/** This control determines whether the value of the VMX preemption timer is saved on VM exit. */
935#define VMX_VMCS_CTRL_EXIT_CONTROLS_SAVE_VMX_PREEMPT_TIMER RT_BIT(22)
936/** @} */
937
938/** @name VMCS field encoding - 32 Bits read-only fields
939 * @{
940 */
941#define VMX_VMCS32_RO_VM_INSTR_ERROR 0x4400
942#define VMX_VMCS32_RO_EXIT_REASON 0x4402
943#define VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO 0x4404
944#define VMX_VMCS32_RO_EXIT_INTERRUPTION_ERRCODE 0x4406
945#define VMX_VMCS32_RO_IDT_INFO 0x4408
946#define VMX_VMCS32_RO_IDT_ERRCODE 0x440A
947#define VMX_VMCS32_RO_EXIT_INSTR_LENGTH 0x440C
948#define VMX_VMCS32_RO_EXIT_INSTR_INFO 0x440E
949/** @} */
950
951/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO
952 * @{
953 */
954#define VMX_EXIT_INTERRUPTION_INFO_VECTOR(a) (a & 0xff)
955#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT 8
956#define VMX_EXIT_INTERRUPTION_INFO_TYPE(a) ((a >> VMX_EXIT_INTERRUPTION_INFO_TYPE_SHIFT) & 7)
957#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID RT_BIT(11)
958#define VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_IS_VALID(a) (a & VMX_EXIT_INTERRUPTION_INFO_ERROR_CODE_VALID)
959#define VMX_EXIT_INTERRUPTION_INFO_NMI_UNBLOCK(a) (a & RT_BIT(12))
960#define VMX_EXIT_INTERRUPTION_INFO_VALID_SHIFT 31
961#define VMX_EXIT_INTERRUPTION_INFO_VALID(a) (a & RT_BIT(31))
962/** Construct an irq event injection value from the exit interruption info value (same except that bit 12 is reserved). */
963#define VMX_VMCS_CTRL_ENTRY_IRQ_INFO_FROM_EXIT_INT_INFO(a) (a & ~RT_BIT(12))
964/** @} */
965
966/** @name VMX_VMCS_RO_EXIT_INTERRUPTION_INFO_TYPE
967 * @{
968 */
969#define VMX_EXIT_INTERRUPTION_INFO_TYPE_EXT 0
970#define VMX_EXIT_INTERRUPTION_INFO_TYPE_NMI 2
971#define VMX_EXIT_INTERRUPTION_INFO_TYPE_HWEXCPT 3
972#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SW 4 /**< int xx */
973#define VMX_EXIT_INTERRUPTION_INFO_TYPE_DBEXCPT 5 /**< Why are we getting this one?? */
974#define VMX_EXIT_INTERRUPTION_INFO_TYPE_SWEXCPT 6
975/** @} */
976
977
978/** @name VMCS field encoding - 32 Bits guest state fields
979 * @{
980 */
981#define VMX_VMCS32_GUEST_ES_LIMIT 0x4800
982#define VMX_VMCS32_GUEST_CS_LIMIT 0x4802
983#define VMX_VMCS32_GUEST_SS_LIMIT 0x4804
984#define VMX_VMCS32_GUEST_DS_LIMIT 0x4806
985#define VMX_VMCS32_GUEST_FS_LIMIT 0x4808
986#define VMX_VMCS32_GUEST_GS_LIMIT 0x480A
987#define VMX_VMCS32_GUEST_LDTR_LIMIT 0x480C
988#define VMX_VMCS32_GUEST_TR_LIMIT 0x480E
989#define VMX_VMCS32_GUEST_GDTR_LIMIT 0x4810
990#define VMX_VMCS32_GUEST_IDTR_LIMIT 0x4812
991#define VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS 0x4814
992#define VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS 0x4816
993#define VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS 0x4818
994#define VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS 0x481A
995#define VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS 0x481C
996#define VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS 0x481E
997#define VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS 0x4820
998#define VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS 0x4822
999#define VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE 0x4824
1000#define VMX_VMCS32_GUEST_ACTIVITY_STATE 0x4826
1001#define VMX_VMCS32_GUEST_SYSENTER_CS 0x482A /**< MSR IA32_SYSENTER_CS */
1002#define VMX_VMCS32_GUEST_PREEMPTION_TIMER_VALUE 0x482E
1003/** @} */
1004
1005
1006/** @name VMX_VMCS_GUEST_ACTIVITY_STATE
1007 * @{
1008 */
1009/** The logical processor is active. */
1010#define VMX_CMS_GUEST_ACTIVITY_ACTIVE 0x0
1011/** The logical processor is inactive, because executed a HLT instruction. */
1012#define VMX_CMS_GUEST_ACTIVITY_HLT 0x1
1013/** The logical processor is inactive, because of a triple fault or other serious error. */
1014#define VMX_CMS_GUEST_ACTIVITY_SHUTDOWN 0x2
1015/** The logical processor is inactive, because it's waiting for a startup-IPI */
1016#define VMX_CMS_GUEST_ACTIVITY_SIPI_WAIT 0x3
1017/** @} */
1018
1019
1020/** @name VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE
1021 * @{
1022 */
1023#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_STI RT_BIT(0)
1024#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_MOVSS RT_BIT(1)
1025#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_SMI RT_BIT(2)
1026#define VMX_VMCS_GUEST_INTERRUPTIBILITY_STATE_BLOCK_NMI RT_BIT(3)
1027/** @} */
1028
1029
1030/** @name VMCS field encoding - 32 Bits host state fields
1031 * @{
1032 */
1033#define VMX_VMCS32_HOST_SYSENTER_CS 0x4C00
1034/** @} */
1035
1036/** @name Natural width control fields
1037 * @{
1038 */
1039#define VMX_VMCS_CTRL_CR0_MASK 0x6000
1040#define VMX_VMCS_CTRL_CR4_MASK 0x6002
1041#define VMX_VMCS_CTRL_CR0_READ_SHADOW 0x6004
1042#define VMX_VMCS_CTRL_CR4_READ_SHADOW 0x6006
1043#define VMX_VMCS_CTRL_CR3_TARGET_VAL0 0x6008
1044#define VMX_VMCS_CTRL_CR3_TARGET_VAL1 0x600A
1045#define VMX_VMCS_CTRL_CR3_TARGET_VAL2 0x600C
1046#define VMX_VMCS_CTRL_CR3_TARGET_VAL31 0x600E
1047/** @} */
1048
1049
1050/** @name Natural width read-only data fields
1051 * @{
1052 */
1053#define VMX_VMCS_RO_EXIT_QUALIFICATION 0x6400
1054#define VMX_VMCS_RO_IO_RCX 0x6402
1055#define VMX_VMCS_RO_IO_RSX 0x6404
1056#define VMX_VMCS_RO_IO_RDI 0x6406
1057#define VMX_VMCS_RO_IO_RIP 0x6408
1058#define VMX_VMCS_EXIT_GUEST_LINEAR_ADDR 0x640A
1059/** @} */
1060
1061
1062/** @name VMX_VMCS_RO_EXIT_QUALIFICATION
1063 * @{
1064 */
1065/** 0-2: Debug register number */
1066#define VMX_EXIT_QUALIFICATION_DRX_REGISTER(a) (a & 7)
1067/** 3: Reserved; cleared to 0. */
1068#define VMX_EXIT_QUALIFICATION_DRX_RES1(a) ((a >> 3) & 1)
1069/** 4: Direction of move (0 = write, 1 = read) */
1070#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION(a) ((a >> 4) & 1)
1071/** 5-7: Reserved; cleared to 0. */
1072#define VMX_EXIT_QUALIFICATION_DRX_RES2(a) ((a >> 5) & 7)
1073/** 8-11: General purpose register number. */
1074#define VMX_EXIT_QUALIFICATION_DRX_GENREG(a) ((a >> 8) & 0xF)
1075/** Rest: reserved. */
1076/** @} */
1077
1078/** @name VMX_EXIT_QUALIFICATION_DRX_DIRECTION values
1079 * @{
1080 */
1081#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_WRITE 0
1082#define VMX_EXIT_QUALIFICATION_DRX_DIRECTION_READ 1
1083/** @} */
1084
1085
1086
1087/** @name CRx accesses
1088 * @{
1089 */
1090/** 0-3: Control register number (0 for CLTS & LMSW) */
1091#define VMX_EXIT_QUALIFICATION_CRX_REGISTER(a) (a & 0xF)
1092/** 4-5: Access type. */
1093#define VMX_EXIT_QUALIFICATION_CRX_ACCESS(a) ((a >> 4) & 3)
1094/** 6: LMSW operand type */
1095#define VMX_EXIT_QUALIFICATION_CRX_LMSW_OP(a) ((a >> 6) & 1)
1096/** 7: Reserved; cleared to 0. */
1097#define VMX_EXIT_QUALIFICATION_CRX_RES1(a) ((a >> 7) & 1)
1098/** 8-11: General purpose register number (0 for CLTS & LMSW). */
1099#define VMX_EXIT_QUALIFICATION_CRX_GENREG(a) ((a >> 8) & 0xF)
1100/** 12-15: Reserved; cleared to 0. */
1101#define VMX_EXIT_QUALIFICATION_CRX_RES2(a) ((a >> 12) & 0xF)
1102/** 16-31: LMSW source data (else 0). */
1103#define VMX_EXIT_QUALIFICATION_CRX_LMSW_DATA(a) ((a >> 16) & 0xFFFF)
1104/** Rest: reserved. */
1105/** @} */
1106
1107/** @name VMX_EXIT_QUALIFICATION_CRX_ACCESS
1108 * @{
1109 */
1110#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_WRITE 0
1111#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_READ 1
1112#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_CLTS 2
1113#define VMX_EXIT_QUALIFICATION_CRX_ACCESS_LMSW 3
1114/** @} */
1115
1116/** @name VMX_EXIT_QUALIFICATION_TASK_SWITCH
1117 * @{
1118 */
1119#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_SELECTOR(a) (a & 0xffff)
1120#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE(a) ((a >> 30)& 0x3)
1121/** Task switch caused by a call instruction. */
1122#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_CALL 0
1123/** Task switch caused by an iret instruction. */
1124#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IRET 1
1125/** Task switch caused by a jmp instruction. */
1126#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_JMP 2
1127/** Task switch caused by an interrupt gate. */
1128#define VMX_EXIT_QUALIFICATION_TASK_SWITCH_TYPE_IDT 3
1129
1130/** @} */
1131
1132
1133/** @name VMX_EXIT_EPT_VIOLATION
1134 * @{
1135 */
1136/** Set if the violation was caused by a data read. */
1137#define VMX_EXIT_QUALIFICATION_EPT_DATA_READ RT_BIT(0)
1138/** Set if the violation was caused by a data write. */
1139#define VMX_EXIT_QUALIFICATION_EPT_DATA_WRITE RT_BIT(1)
1140/** Set if the violation was caused by an insruction fetch. */
1141#define VMX_EXIT_QUALIFICATION_EPT_INSTR_FETCH RT_BIT(2)
1142/** AND of the present bit of all EPT structures. */
1143#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_PRESENT RT_BIT(3)
1144/** AND of the write bit of all EPT structures. */
1145#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_WRITE RT_BIT(4)
1146/** AND of the execute bit of all EPT structures. */
1147#define VMX_EXIT_QUALIFICATION_EPT_ENTRY_EXECUTE RT_BIT(5)
1148/** Set if the guest linear address field contains the faulting address. */
1149#define VMX_EXIT_QUALIFICATION_EPT_GUEST_ADDR_VALID RT_BIT(7)
1150/** If bit 7 is one: (reserved otherwise)
1151 * 1 - violation due to physical address access.
1152 * 0 - violation caused by page walk or access/dirty bit updates
1153 */
1154#define VMX_EXIT_QUALIFICATION_EPT_TRANSLATED_ACCESS RT_BIT(8)
1155/** @} */
1156
1157
1158/** @name VMX_EXIT_PORT_IO
1159 * @{
1160 */
1161/** 0-2: IO operation width. */
1162#define VMX_EXIT_QUALIFICATION_IO_WIDTH(a) (a & 7)
1163/** 3: IO operation direction. */
1164#define VMX_EXIT_QUALIFICATION_IO_DIRECTION(a) ((a >> 3) & 1)
1165/** 4: String IO operation. */
1166#define VMX_EXIT_QUALIFICATION_IO_STRING(a) ((a >> 4) & 1)
1167/** 5: Repeated IO operation. */
1168#define VMX_EXIT_QUALIFICATION_IO_REP(a) ((a >> 5) & 1)
1169/** 6: Operand encoding. */
1170#define VMX_EXIT_QUALIFICATION_IO_ENCODING(a) ((a >> 6) & 1)
1171/** 16-31: IO Port (0-0xffff). */
1172#define VMX_EXIT_QUALIFICATION_IO_PORT(a) ((a >> 16) & 0xffff)
1173/* Rest reserved. */
1174/** @} */
1175
1176/** @name VMX_EXIT_QUALIFICATION_IO_DIRECTION
1177 * @{
1178 */
1179#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_OUT 0
1180#define VMX_EXIT_QUALIFICATION_IO_DIRECTION_IN 1
1181/** @} */
1182
1183
1184/** @name VMX_EXIT_QUALIFICATION_IO_ENCODING
1185 * @{
1186 */
1187#define VMX_EXIT_QUALIFICATION_IO_ENCODING_DX 0
1188#define VMX_EXIT_QUALIFICATION_IO_ENCODING_IMM 1
1189/** @} */
1190
1191/** @name VMX_EXIT_APIC_ACCESS
1192 * @{
1193 */
1194/** 0-11: If the APIC-access VM exit is due to a linear access, the offset of access within the APIC page. */
1195#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_OFFSET(a) (a & 0xfff)
1196/** 12-15: Access type. */
1197#define VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE(a) ((a >> 12) & 0xf)
1198/* Rest reserved. */
1199/** @} */
1200
1201
1202/** @name VMX_EXIT_QUALIFICATION_APIC_ACCESS_TYPE; access types
1203 * @{
1204 */
1205/** Linear read access. */
1206#define VMX_APIC_ACCESS_TYPE_LINEAR_READ 0
1207/** Linear write access. */
1208#define VMX_APIC_ACCESS_TYPE_LINEAR_WRITE 1
1209/** Linear instruction fetch access. */
1210#define VMX_APIC_ACCESS_TYPE_LINEAR_INSTR_FETCH 2
1211/** Linear read/write access during event delivery. */
1212#define VMX_APIC_ACCESS_TYPE_LINEAR_EVENT_DELIVERY 3
1213/** Physical read/write access during event delivery. */
1214#define VMX_APIC_ACCESS_TYPE_PHYSICAL_EVENT_DELIVERY 10
1215/** Physical access for an instruction fetch or during instruction execution. */
1216#define VMX_APIC_ACCESS_TYPE_PHYSICAL_INSTR 15
1217/** @} */
1218
1219/** @} */
1220
1221/** @name VMCS field encoding - Natural width guest state fields
1222 * @{
1223 */
1224#define VMX_VMCS64_GUEST_CR0 0x6800
1225#define VMX_VMCS64_GUEST_CR3 0x6802
1226#define VMX_VMCS64_GUEST_CR4 0x6804
1227#define VMX_VMCS64_GUEST_ES_BASE 0x6806
1228#define VMX_VMCS64_GUEST_CS_BASE 0x6808
1229#define VMX_VMCS64_GUEST_SS_BASE 0x680A
1230#define VMX_VMCS64_GUEST_DS_BASE 0x680C
1231#define VMX_VMCS64_GUEST_FS_BASE 0x680E
1232#define VMX_VMCS64_GUEST_GS_BASE 0x6810
1233#define VMX_VMCS64_GUEST_LDTR_BASE 0x6812
1234#define VMX_VMCS64_GUEST_TR_BASE 0x6814
1235#define VMX_VMCS64_GUEST_GDTR_BASE 0x6816
1236#define VMX_VMCS64_GUEST_IDTR_BASE 0x6818
1237#define VMX_VMCS64_GUEST_DR7 0x681A
1238#define VMX_VMCS64_GUEST_RSP 0x681C
1239#define VMX_VMCS64_GUEST_RIP 0x681E
1240#define VMX_VMCS_GUEST_RFLAGS 0x6820
1241#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS 0x6822
1242#define VMX_VMCS64_GUEST_SYSENTER_ESP 0x6824 /**< MSR IA32_SYSENTER_ESP */
1243#define VMX_VMCS64_GUEST_SYSENTER_EIP 0x6826 /**< MSR IA32_SYSENTER_EIP */
1244/** @} */
1245
1246
1247/** @name VMX_VMCS_GUEST_DEBUG_EXCEPTIONS
1248 * @{
1249 */
1250/** Hardware breakpoint 0 was met. */
1251#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B0 RT_BIT(0)
1252/** Hardware breakpoint 1 was met. */
1253#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B1 RT_BIT(1)
1254/** Hardware breakpoint 2 was met. */
1255#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B2 RT_BIT(2)
1256/** Hardware breakpoint 3 was met. */
1257#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_B3 RT_BIT(3)
1258/** At least one data or IO breakpoint was hit. */
1259#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BREAKPOINT_ENABLED RT_BIT(12)
1260/** A debug exception would have been triggered by single-step execution mode. */
1261#define VMX_VMCS_GUEST_DEBUG_EXCEPTIONS_BS RT_BIT(14)
1262/** Bits 4-11, 13 and 15-63 are reserved. */
1263
1264/** @} */
1265
1266/** @name VMCS field encoding - Natural width host state fields
1267 * @{
1268 */
1269#define VMX_VMCS_HOST_CR0 0x6C00
1270#define VMX_VMCS_HOST_CR3 0x6C02
1271#define VMX_VMCS_HOST_CR4 0x6C04
1272#define VMX_VMCS_HOST_FS_BASE 0x6C06
1273#define VMX_VMCS_HOST_GS_BASE 0x6C08
1274#define VMX_VMCS_HOST_TR_BASE 0x6C0A
1275#define VMX_VMCS_HOST_GDTR_BASE 0x6C0C
1276#define VMX_VMCS_HOST_IDTR_BASE 0x6C0E
1277#define VMX_VMCS_HOST_SYSENTER_ESP 0x6C10
1278#define VMX_VMCS_HOST_SYSENTER_EIP 0x6C12
1279#define VMX_VMCS_HOST_RSP 0x6C14
1280#define VMX_VMCS_HOST_RIP 0x6C16
1281/** @} */
1282
1283/** @} */
1284
1285
1286#if RT_INLINE_ASM_GNU_STYLE
1287# define __STR(x) #x
1288# define STR(x) __STR(x)
1289#endif
1290
1291
1292/** @defgroup grp_vmx_asm vmx assembly helpers
1293 * @ingroup grp_vmx
1294 * @{
1295 */
1296
1297/**
1298 * Executes VMXON
1299 *
1300 * @returns VBox status code
1301 * @param pVMXOn Physical address of VMXON structure
1302 */
1303#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
1304DECLASM(int) VMXEnable(RTHCPHYS pVMXOn);
1305#else
1306DECLINLINE(int) VMXEnable(RTHCPHYS pVMXOn)
1307{
1308 int rc = VINF_SUCCESS;
1309# if RT_INLINE_ASM_GNU_STYLE
1310 __asm__ __volatile__ (
1311 "push %3 \n\t"
1312 "push %2 \n\t"
1313 ".byte 0xF3, 0x0F, 0xC7, 0x34, 0x24 # VMXON [esp] \n\t"
1314 "ja 2f \n\t"
1315 "je 1f \n\t"
1316 "movl $"STR(VERR_VMX_INVALID_VMXON_PTR)", %0 \n\t"
1317 "jmp 2f \n\t"
1318 "1: \n\t"
1319 "movl $"STR(VERR_VMX_GENERIC)", %0 \n\t"
1320 "2: \n\t"
1321 "add $8, %%esp \n\t"
1322 :"=rm"(rc)
1323 :"0"(VINF_SUCCESS),
1324 "ir"((uint32_t)pVMXOn), /* don't allow direct memory reference here, */
1325 "ir"((uint32_t)(pVMXOn >> 32)) /* this would not work with -fomit-frame-pointer */
1326 :"memory"
1327 );
1328# else
1329 __asm
1330 {
1331 push dword ptr [pVMXOn+4]
1332 push dword ptr [pVMXOn]
1333 _emit 0xF3
1334 _emit 0x0F
1335 _emit 0xC7
1336 _emit 0x34
1337 _emit 0x24 /* VMXON [esp] */
1338 jnc vmxon_good
1339 mov dword ptr [rc], VERR_VMX_INVALID_VMXON_PTR
1340 jmp the_end
1341
1342vmxon_good:
1343 jnz the_end
1344 mov dword ptr [rc], VERR_VMX_GENERIC
1345the_end:
1346 add esp, 8
1347 }
1348# endif
1349 return rc;
1350}
1351#endif
1352
1353
1354/**
1355 * Executes VMXOFF
1356 */
1357#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
1358DECLASM(void) VMXDisable(void);
1359#else
1360DECLINLINE(void) VMXDisable(void)
1361{
1362# if RT_INLINE_ASM_GNU_STYLE
1363 __asm__ __volatile__ (
1364 ".byte 0x0F, 0x01, 0xC4 # VMXOFF \n\t"
1365 );
1366# else
1367 __asm
1368 {
1369 _emit 0x0F
1370 _emit 0x01
1371 _emit 0xC4 /* VMXOFF */
1372 }
1373# endif
1374}
1375#endif
1376
1377
1378/**
1379 * Executes VMCLEAR
1380 *
1381 * @returns VBox status code
1382 * @param pVMCS Physical address of VM control structure
1383 */
1384#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
1385DECLASM(int) VMXClearVMCS(RTHCPHYS pVMCS);
1386#else
1387DECLINLINE(int) VMXClearVMCS(RTHCPHYS pVMCS)
1388{
1389 int rc = VINF_SUCCESS;
1390# if RT_INLINE_ASM_GNU_STYLE
1391 __asm__ __volatile__ (
1392 "push %3 \n\t"
1393 "push %2 \n\t"
1394 ".byte 0x66, 0x0F, 0xC7, 0x34, 0x24 # VMCLEAR [esp] \n\t"
1395 "jnc 1f \n\t"
1396 "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
1397 "1: \n\t"
1398 "add $8, %%esp \n\t"
1399 :"=rm"(rc)
1400 :"0"(VINF_SUCCESS),
1401 "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */
1402 "ir"((uint32_t)(pVMCS >> 32)) /* this would not work with -fomit-frame-pointer */
1403 :"memory"
1404 );
1405# else
1406 __asm
1407 {
1408 push dword ptr [pVMCS+4]
1409 push dword ptr [pVMCS]
1410 _emit 0x66
1411 _emit 0x0F
1412 _emit 0xC7
1413 _emit 0x34
1414 _emit 0x24 /* VMCLEAR [esp] */
1415 jnc success
1416 mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
1417success:
1418 add esp, 8
1419 }
1420# endif
1421 return rc;
1422}
1423#endif
1424
1425
1426/**
1427 * Executes VMPTRLD
1428 *
1429 * @returns VBox status code
1430 * @param pVMCS Physical address of VMCS structure
1431 */
1432#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
1433DECLASM(int) VMXActivateVMCS(RTHCPHYS pVMCS);
1434#else
1435DECLINLINE(int) VMXActivateVMCS(RTHCPHYS pVMCS)
1436{
1437 int rc = VINF_SUCCESS;
1438# if RT_INLINE_ASM_GNU_STYLE
1439 __asm__ __volatile__ (
1440 "push %3 \n\t"
1441 "push %2 \n\t"
1442 ".byte 0x0F, 0xC7, 0x34, 0x24 # VMPTRLD [esp] \n\t"
1443 "jnc 1f \n\t"
1444 "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
1445 "1: \n\t"
1446 "add $8, %%esp \n\t"
1447 :"=rm"(rc)
1448 :"0"(VINF_SUCCESS),
1449 "ir"((uint32_t)pVMCS), /* don't allow direct memory reference here, */
1450 "ir"((uint32_t)(pVMCS >> 32)) /* this will not work with -fomit-frame-pointer */
1451 );
1452# else
1453 __asm
1454 {
1455 push dword ptr [pVMCS+4]
1456 push dword ptr [pVMCS]
1457 _emit 0x0F
1458 _emit 0xC7
1459 _emit 0x34
1460 _emit 0x24 /* VMPTRLD [esp] */
1461 jnc success
1462 mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
1463
1464success:
1465 add esp, 8
1466 }
1467# endif
1468 return rc;
1469}
1470#endif
1471
1472/**
1473 * Executes VMPTRST
1474 *
1475 * @returns VBox status code
1476 * @param pVMCS Address that will receive the current pointer
1477 */
1478DECLASM(int) VMXGetActivateVMCS(RTHCPHYS *pVMCS);
1479
1480/**
1481 * Executes VMWRITE
1482 *
1483 * @returns VBox status code
1484 * @param idxField VMCS index
1485 * @param u32Val 32 bits value
1486 */
1487#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
1488DECLASM(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Val);
1489#else
1490DECLINLINE(int) VMXWriteVMCS32(uint32_t idxField, uint32_t u32Val)
1491{
1492 int rc = VINF_SUCCESS;
1493# if RT_INLINE_ASM_GNU_STYLE
1494 __asm__ __volatile__ (
1495 ".byte 0x0F, 0x79, 0xC2 # VMWRITE eax, edx \n\t"
1496 "ja 2f \n\t"
1497 "je 1f \n\t"
1498 "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
1499 "jmp 2f \n\t"
1500 "1: \n\t"
1501 "movl $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t"
1502 "2: \n\t"
1503 :"=rm"(rc)
1504 :"0"(VINF_SUCCESS),
1505 "a"(idxField),
1506 "d"(u32Val)
1507 );
1508# else
1509 __asm
1510 {
1511 push dword ptr [u32Val]
1512 mov eax, [idxField]
1513 _emit 0x0F
1514 _emit 0x79
1515 _emit 0x04
1516 _emit 0x24 /* VMWRITE eax, [esp] */
1517 jnc valid_vmcs
1518 mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
1519 jmp the_end
1520
1521valid_vmcs:
1522 jnz the_end
1523 mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD
1524the_end:
1525 add esp, 4
1526 }
1527# endif
1528 return rc;
1529}
1530#endif
1531
1532/**
1533 * Executes VMWRITE
1534 *
1535 * @returns VBox status code
1536 * @param idxField VMCS index
1537 * @param u64Val 16, 32 or 64 bits value
1538 */
1539#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
1540DECLASM(int) VMXWriteVMCS64(uint32_t idxField, uint64_t u64Val);
1541#else
1542VMMR0DECL(int) VMXWriteVMCS64Ex(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val);
1543
1544#define VMXWriteVMCS64(idxField, u64Val) VMXWriteVMCS64Ex(pVCpu, idxField, u64Val)
1545#endif
1546
1547#if HC_ARCH_BITS == 64
1548#define VMXWriteVMCS VMXWriteVMCS64
1549#else
1550#define VMXWriteVMCS VMXWriteVMCS32
1551#endif /* HC_ARCH_BITS == 64 */
1552
1553
1554/**
1555 * Invalidate a page using invept
1556 * @returns VBox status code
1557 * @param enmFlush Type of flush
1558 * @param pDescriptor Descriptor
1559 */
1560DECLASM(int) VMXR0InvEPT(VMX_FLUSH enmFlush, uint64_t *pDescriptor);
1561
1562/**
1563 * Invalidate a page using invvpid
1564 * @returns VBox status code
1565 * @param enmFlush Type of flush
1566 * @param pDescriptor Descriptor
1567 */
1568DECLASM(int) VMXR0InvVPID(VMX_FLUSH enmFlush, uint64_t *pDescriptor);
1569
1570/**
1571 * Executes VMREAD
1572 *
1573 * @returns VBox status code
1574 * @param idxField VMCS index
1575 * @param pData Ptr to store VM field value
1576 */
1577#if RT_INLINE_ASM_EXTERNAL || HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
1578DECLASM(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pData);
1579#else
1580DECLINLINE(int) VMXReadVMCS32(uint32_t idxField, uint32_t *pData)
1581{
1582 int rc = VINF_SUCCESS;
1583# if RT_INLINE_ASM_GNU_STYLE
1584 __asm__ __volatile__ (
1585 "movl $"STR(VINF_SUCCESS)", %0 \n\t"
1586 ".byte 0x0F, 0x78, 0xc2 # VMREAD eax, edx \n\t"
1587 "ja 2f \n\t"
1588 "je 1f \n\t"
1589 "movl $"STR(VERR_VMX_INVALID_VMCS_PTR)", %0 \n\t"
1590 "jmp 2f \n\t"
1591 "1: \n\t"
1592 "movl $"STR(VERR_VMX_INVALID_VMCS_FIELD)", %0 \n\t"
1593 "2: \n\t"
1594 :"=&r"(rc),
1595 "=d"(*pData)
1596 :"a"(idxField),
1597 "d"(0)
1598 );
1599# else
1600 __asm
1601 {
1602 sub esp, 4
1603 mov dword ptr [esp], 0
1604 mov eax, [idxField]
1605 _emit 0x0F
1606 _emit 0x78
1607 _emit 0x04
1608 _emit 0x24 /* VMREAD eax, [esp] */
1609 mov edx, pData
1610 pop dword ptr [edx]
1611 jnc valid_vmcs
1612 mov dword ptr [rc], VERR_VMX_INVALID_VMCS_PTR
1613 jmp the_end
1614
1615valid_vmcs:
1616 jnz the_end
1617 mov dword ptr [rc], VERR_VMX_INVALID_VMCS_FIELD
1618the_end:
1619 }
1620# endif
1621 return rc;
1622}
1623#endif
1624
1625/**
1626 * Executes VMREAD
1627 *
1628 * @returns VBox status code
1629 * @param idxField VMCS index
1630 * @param pData Ptr to store VM field value
1631 */
1632#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_2X_4GB_ADDR_SPACE_IN_R0)
1633DECLASM(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData);
1634#else
1635DECLINLINE(int) VMXReadVMCS64(uint32_t idxField, uint64_t *pData)
1636{
1637 int rc;
1638
1639 uint32_t val_hi, val;
1640 rc = VMXReadVMCS32(idxField, &val);
1641 rc |= VMXReadVMCS32(idxField + 1, &val_hi);
1642 AssertRC(rc);
1643 *pData = RT_MAKE_U64(val, val_hi);
1644 return rc;
1645}
1646#endif
1647
1648#if HC_ARCH_BITS == 64
1649# define VMXReadVMCS VMXReadVMCS64
1650#else
1651# define VMXReadVMCS VMXReadVMCS32
1652#endif /* HC_ARCH_BITS == 64 */
1653
1654/**
1655 * Gets the last instruction error value from the current VMCS
1656 *
1657 * @returns error value
1658 */
1659DECLINLINE(uint32_t) VMXGetLastError(void)
1660{
1661#if HC_ARCH_BITS == 64
1662 uint64_t uLastError = 0;
1663 int rc = VMXReadVMCS(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError);
1664 AssertRC(rc);
1665 return (uint32_t)uLastError;
1666
1667#else /* 32-bit host: */
1668 uint32_t uLastError = 0;
1669 int rc = VMXReadVMCS32(VMX_VMCS32_RO_VM_INSTR_ERROR, &uLastError);
1670 AssertRC(rc);
1671 return uLastError;
1672#endif
1673}
1674
1675#ifdef IN_RING0
1676VMMR0DECL(int) VMXR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt);
1677VMMR0DECL(int) VMXR0InvalidatePhysPage(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys);
1678#endif /* IN_RING0 */
1679
1680/** @} */
1681
1682#endif
1683
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