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