summaryrefslogtreecommitdiffstats
path: root/include/VBox/vmm/hm_vmx.h
blob: 95794dca8744f1ee79c977c1f259ff3016af50c3 (plain)
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
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
/** @file
 * HM - VMX Structures and Definitions. (VMM)
 */

/*
 * Copyright (C) 2006-2022 Oracle and/or its affiliates.
 *
 * This file is part of VirtualBox base platform packages, as
 * available from https://www.virtualbox.org.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, in version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses>.
 *
 * The contents of this file may alternatively be used under the terms
 * of the Common Development and Distribution License Version 1.0
 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
 * in the VirtualBox 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.
 *
 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
 */

#ifndef VBOX_INCLUDED_vmm_hm_vmx_h
#define VBOX_INCLUDED_vmm_hm_vmx_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif

#include <VBox/types.h>
#include <iprt/x86.h>
#include <iprt/assertcompile.h>


/** @defgroup grp_hm_vmx    VMX Types and Definitions
 * @ingroup grp_hm
 * @{
 */

/** @name Host-state MSR lazy-restoration flags.
 * @{
 */
/** The host MSRs have been saved. */
#define VMX_LAZY_MSRS_SAVED_HOST                                RT_BIT(0)
/** The guest MSRs are loaded and in effect. */
#define VMX_LAZY_MSRS_LOADED_GUEST                              RT_BIT(1)
/** @} */

/** @name VMX HM-error codes for VERR_HM_UNSUPPORTED_CPU_FEATURE_COMBO.
 *  UFC = Unsupported Feature Combination.
 * @{
 */
/** Unsupported pin-based VM-execution controls combo. */
#define VMX_UFC_CTRL_PIN_EXEC                                   1
/** Unsupported processor-based VM-execution controls combo. */
#define VMX_UFC_CTRL_PROC_EXEC                                  2
/** Unsupported move debug register VM-exit combo. */
#define VMX_UFC_CTRL_PROC_MOV_DRX_EXIT                          3
/** Unsupported VM-entry controls combo. */
#define VMX_UFC_CTRL_ENTRY                                      4
/** Unsupported VM-exit controls combo. */
#define VMX_UFC_CTRL_EXIT                                       5
/** MSR storage capacity of the VMCS autoload/store area is not sufficient
 *  for storing host MSRs. */
#define VMX_UFC_INSUFFICIENT_HOST_MSR_STORAGE                   6
/** MSR storage capacity of the VMCS autoload/store area is not sufficient
 *  for storing guest MSRs. */
#define VMX_UFC_INSUFFICIENT_GUEST_MSR_STORAGE                  7
/** Invalid VMCS size. */
#define VMX_UFC_INVALID_VMCS_SIZE                               8
/** Unsupported secondary processor-based VM-execution controls combo. */
#define VMX_UFC_CTRL_PROC_EXEC2                                 9
/** Invalid unrestricted-guest execution controls combo. */
#define VMX_UFC_INVALID_UX_COMBO                                10
/** EPT flush type not supported. */
#define VMX_UFC_EPT_FLUSH_TYPE_UNSUPPORTED                      11
/** EPT paging structure memory type is not write-back. */
#define VMX_UFC_EPT_MEM_TYPE_NOT_WB                             12
/** EPT requires INVEPT instr. support but it's not available. */
#define VMX_UFC_EPT_INVEPT_UNAVAILABLE                          13
/** EPT requires page-walk length of 4. */
#define VMX_UFC_EPT_PAGE_WALK_LENGTH_UNSUPPORTED                14
/** VMX VMWRITE all feature exposed to the guest but not supported on host. */
#define VMX_UFC_GST_HOST_VMWRITE_ALL                            15
/** LBR stack size cannot be determined for the current CPU. */
#define VMX_UFC_LBR_STACK_SIZE_UNKNOWN                          16
/** LBR stack size of the CPU exceeds our buffer size. */
#define VMX_UFC_LBR_STACK_SIZE_OVERFLOW                         17
/** @} */

/** @name VMX HM-error codes for VERR_VMX_VMCS_FIELD_CACHE_INVALID.
 *  VCI = VMCS-field Cache Invalid.
 * @{
 */
/** Cache of VM-entry controls invalid. */
#define VMX_VCI_CTRL_ENTRY                                      300
/** Cache of VM-exit controls invalid. */
#define VMX_VCI_CTRL_EXIT                                       301
/** Cache of pin-based VM-execution controls invalid. */
#define VMX_VCI_CTRL_PIN_EXEC                                   302
/** Cache of processor-based VM-execution controls invalid. */
#define VMX_VCI_CTRL_PROC_EXEC                                  303
/** Cache of secondary processor-based VM-execution controls invalid. */
#define VMX_VCI_CTRL_PROC_EXEC2                                 304
/** Cache of exception bitmap invalid. */
#define VMX_VCI_CTRL_XCPT_BITMAP                                305
/** Cache of TSC offset invalid. */
#define VMX_VCI_CTRL_TSC_OFFSET                                 306
/** Cache of tertiary processor-based VM-execution controls invalid. */
#define VMX_VCI_CTRL_PROC_EXEC3                                 307
/** @} */

/** @name VMX HM-error codes for VERR_VMX_INVALID_GUEST_STATE.
 *  IGS = Invalid Guest State.
 * @{
 */
/** An error occurred while checking invalid-guest-state. */
#define VMX_IGS_ERROR                                           500
/** The invalid guest-state checks did not find any reason why. */
#define VMX_IGS_REASON_NOT_FOUND                                501
/** CR0 fixed1 bits invalid. */
#define VMX_IGS_CR0_FIXED1                                      502
/** CR0 fixed0 bits invalid. */
#define VMX_IGS_CR0_FIXED0                                      503
/** CR0.PE and CR0.PE invalid VT-x/host combination. */
#define VMX_IGS_CR0_PG_PE_COMBO                                 504
/** CR4 fixed1 bits invalid. */
#define VMX_IGS_CR4_FIXED1                                      505
/** CR4 fixed0 bits invalid. */
#define VMX_IGS_CR4_FIXED0                                      506
/** Reserved bits in VMCS' DEBUGCTL MSR field not set to 0 when
 *  VMX_VMCS_CTRL_ENTRY_LOAD_DEBUG is used. */
#define VMX_IGS_DEBUGCTL_MSR_RESERVED                           507
/** CR0.PG not set for long-mode when not using unrestricted guest. */
#define VMX_IGS_CR0_PG_LONGMODE                                 508
/** CR4.PAE not set for long-mode guest when not using unrestricted guest. */
#define VMX_IGS_CR4_PAE_LONGMODE                                509
/** CR4.PCIDE set for 32-bit guest. */
#define VMX_IGS_CR4_PCIDE                                       510
/** VMCS' DR7 reserved bits not set to 0. */
#define VMX_IGS_DR7_RESERVED                                    511
/** VMCS' PERF_GLOBAL MSR reserved bits not set to 0. */
#define VMX_IGS_PERF_GLOBAL_MSR_RESERVED                        512
/** VMCS' EFER MSR reserved bits not set to 0. */
#define VMX_IGS_EFER_MSR_RESERVED                               513
/** VMCS' EFER MSR.LMA does not match the IA32e mode guest control. */
#define VMX_IGS_EFER_LMA_GUEST_MODE_MISMATCH                    514
/** VMCS' EFER MSR.LMA does not match EFER.LME of the guest when using paging
 *  without unrestricted guest. */
#define VMX_IGS_EFER_LMA_LME_MISMATCH                           515
/** CS.Attr.P bit invalid. */
#define VMX_IGS_CS_ATTR_P_INVALID                               516
/** CS.Attr reserved bits not set to 0. */
#define VMX_IGS_CS_ATTR_RESERVED                                517
/** CS.Attr.G bit invalid. */
#define VMX_IGS_CS_ATTR_G_INVALID                               518
/** CS is unusable. */
#define VMX_IGS_CS_ATTR_UNUSABLE                                519
/** CS and SS DPL unequal. */
#define VMX_IGS_CS_SS_ATTR_DPL_UNEQUAL                          520
/** CS and SS DPL mismatch. */
#define VMX_IGS_CS_SS_ATTR_DPL_MISMATCH                         521
/** CS Attr.Type invalid. */
#define VMX_IGS_CS_ATTR_TYPE_INVALID                            522
/** CS and SS RPL unequal. */
#define VMX_IGS_SS_CS_RPL_UNEQUAL                               523
/** SS.Attr.DPL and SS RPL unequal. */
#define VMX_IGS_SS_ATTR_DPL_RPL_UNEQUAL                         524
/** SS.Attr.DPL invalid for segment type. */
#define VMX_IGS_SS_ATTR_DPL_INVALID                             525
/** SS.Attr.Type invalid. */
#define VMX_IGS_SS_ATTR_TYPE_INVALID                            526
/** SS.Attr.P bit invalid. */
#define VMX_IGS_SS_ATTR_P_INVALID                               527
/** SS.Attr reserved bits not set to 0. */
#define VMX_IGS_SS_ATTR_RESERVED                                528
/** SS.Attr.G bit invalid. */
#define VMX_IGS_SS_ATTR_G_INVALID                               529
/** DS.Attr.A bit invalid. */
#define VMX_IGS_DS_ATTR_A_INVALID                               530
/** DS.Attr.P bit invalid. */
#define VMX_IGS_DS_ATTR_P_INVALID                               531
/** DS.Attr.DPL and DS RPL unequal. */
#define VMX_IGS_DS_ATTR_DPL_RPL_UNEQUAL                         532
/** DS.Attr reserved bits not set to 0. */
#define VMX_IGS_DS_ATTR_RESERVED                                533
/** DS.Attr.G bit invalid. */
#define VMX_IGS_DS_ATTR_G_INVALID                               534
/** DS.Attr.Type invalid. */
#define VMX_IGS_DS_ATTR_TYPE_INVALID                            535
/** ES.Attr.A bit invalid. */
#define VMX_IGS_ES_ATTR_A_INVALID                               536
/** ES.Attr.P bit invalid. */
#define VMX_IGS_ES_ATTR_P_INVALID                               537
/** ES.Attr.DPL and DS RPL unequal. */
#define VMX_IGS_ES_ATTR_DPL_RPL_UNEQUAL                         538
/** ES.Attr reserved bits not set to 0. */
#define VMX_IGS_ES_ATTR_RESERVED                                539
/** ES.Attr.G bit invalid. */
#define VMX_IGS_ES_ATTR_G_INVALID                               540
/** ES.Attr.Type invalid. */
#define VMX_IGS_ES_ATTR_TYPE_INVALID                            541
/** FS.Attr.A bit invalid. */
#define VMX_IGS_FS_ATTR_A_INVALID                               542
/** FS.Attr.P bit invalid. */
#define VMX_IGS_FS_ATTR_P_INVALID                               543
/** FS.Attr.DPL and DS RPL unequal. */
#define VMX_IGS_FS_ATTR_DPL_RPL_UNEQUAL                         544
/** FS.Attr reserved bits not set to 0. */
#define VMX_IGS_FS_ATTR_RESERVED                                545
/** FS.Attr.G bit invalid. */
#define VMX_IGS_FS_ATTR_G_INVALID                               546
/** FS.Attr.Type invalid. */
#define VMX_IGS_FS_ATTR_TYPE_INVALID                            547
/** GS.Attr.A bit invalid. */
#define VMX_IGS_GS_ATTR_A_INVALID                               548
/** GS.Attr.P bit invalid. */
#define VMX_IGS_GS_ATTR_P_INVALID                               549
/** GS.Attr.DPL and DS RPL unequal. */
#define VMX_IGS_GS_ATTR_DPL_RPL_UNEQUAL                         550
/** GS.Attr reserved bits not set to 0. */
#define VMX_IGS_GS_ATTR_RESERVED                                551
/** GS.Attr.G bit invalid. */
#define VMX_IGS_GS_ATTR_G_INVALID                               552
/** GS.Attr.Type invalid. */
#define VMX_IGS_GS_ATTR_TYPE_INVALID                            553
/** V86 mode CS.Base invalid. */
#define VMX_IGS_V86_CS_BASE_INVALID                             554
/** V86 mode CS.Limit invalid. */
#define VMX_IGS_V86_CS_LIMIT_INVALID                            555
/** V86 mode CS.Attr invalid. */
#define VMX_IGS_V86_CS_ATTR_INVALID                             556
/** V86 mode SS.Base invalid. */
#define VMX_IGS_V86_SS_BASE_INVALID                             557
/** V86 mode SS.Limit invalid. */
#define VMX_IGS_V86_SS_LIMIT_INVALID                            558
/** V86 mode SS.Attr invalid. */
#define VMX_IGS_V86_SS_ATTR_INVALID                             559
/** V86 mode DS.Base invalid. */
#define VMX_IGS_V86_DS_BASE_INVALID                             560
/** V86 mode DS.Limit invalid. */
#define VMX_IGS_V86_DS_LIMIT_INVALID                            561
/** V86 mode DS.Attr invalid. */
#define VMX_IGS_V86_DS_ATTR_INVALID                             562
/** V86 mode ES.Base invalid. */
#define VMX_IGS_V86_ES_BASE_INVALID                             563
/** V86 mode ES.Limit invalid. */
#define VMX_IGS_V86_ES_LIMIT_INVALID                            564
/** V86 mode ES.Attr invalid. */
#define VMX_IGS_V86_ES_ATTR_INVALID                             565
/** V86 mode FS.Base invalid. */
#define VMX_IGS_V86_FS_BASE_INVALID                             566
/** V86 mode FS.Limit invalid. */
#define VMX_IGS_V86_FS_LIMIT_INVALID                            567
/** V86 mode FS.Attr invalid. */
#define VMX_IGS_V86_FS_ATTR_INVALID                             568
/** V86 mode GS.Base invalid. */
#define VMX_IGS_V86_GS_BASE_INVALID                             569
/** V86 mode GS.Limit invalid. */
#define VMX_IGS_V86_GS_LIMIT_INVALID                            570
/** V86 mode GS.Attr invalid. */
#define VMX_IGS_V86_GS_ATTR_INVALID                             571
/** Longmode CS.Base invalid. */
#define VMX_IGS_LONGMODE_CS_BASE_INVALID                        572
/** Longmode SS.Base invalid. */
#define VMX_IGS_LONGMODE_SS_BASE_INVALID                        573
/** Longmode DS.Base invalid. */
#define VMX_IGS_LONGMODE_DS_BASE_INVALID                        574
/** Longmode ES.Base invalid. */
#define VMX_IGS_LONGMODE_ES_BASE_INVALID                        575
/** SYSENTER ESP is not canonical. */
#define VMX_IGS_SYSENTER_ESP_NOT_CANONICAL                      576
/** SYSENTER EIP is not canonical. */
#define VMX_IGS_SYSENTER_EIP_NOT_CANONICAL                      577
/** PAT MSR invalid. */
#define VMX_IGS_PAT_MSR_INVALID                                 578
/** PAT MSR reserved bits not set to 0. */
#define VMX_IGS_PAT_MSR_RESERVED                                579
/** GDTR.Base is not canonical. */
#define VMX_IGS_GDTR_BASE_NOT_CANONICAL                         580
/** IDTR.Base is not canonical. */
#define VMX_IGS_IDTR_BASE_NOT_CANONICAL                         581
/** GDTR.Limit invalid. */
#define VMX_IGS_GDTR_LIMIT_INVALID                              582
/** IDTR.Limit invalid. */
#define VMX_IGS_IDTR_LIMIT_INVALID                              583
/** Longmode RIP is invalid. */
#define VMX_IGS_LONGMODE_RIP_INVALID                            584
/** RFLAGS reserved bits not set to 0. */
#define VMX_IGS_RFLAGS_RESERVED                                 585
/** RFLAGS RA1 reserved bits not set to 1. */
#define VMX_IGS_RFLAGS_RESERVED1                                586
/** RFLAGS.VM (V86 mode) invalid. */
#define VMX_IGS_RFLAGS_VM_INVALID                               587
/** RFLAGS.IF invalid. */
#define VMX_IGS_RFLAGS_IF_INVALID                               588
/** Activity state invalid. */
#define VMX_IGS_ACTIVITY_STATE_INVALID                          589
/** Activity state HLT invalid when SS.Attr.DPL is not zero. */
#define VMX_IGS_ACTIVITY_STATE_HLT_INVALID                      590
/** Activity state ACTIVE invalid when block-by-STI or MOV SS. */
#define VMX_IGS_ACTIVITY_STATE_ACTIVE_INVALID                   591
/** Activity state SIPI WAIT invalid. */
#define VMX_IGS_ACTIVITY_STATE_SIPI_WAIT_INVALID                592
/** Interruptibility state reserved bits not set to 0. */
#define VMX_IGS_INTERRUPTIBILITY_STATE_RESERVED                 593
/** Interruptibility state cannot be block-by-STI -and- MOV SS. */
#define VMX_IGS_INTERRUPTIBILITY_STATE_STI_MOVSS_INVALID        594
/** Interruptibility state block-by-STI invalid for EFLAGS. */
#define VMX_IGS_INTERRUPTIBILITY_STATE_STI_EFL_INVALID          595
/** Interruptibility state invalid while trying to deliver external
 *  interrupt. */
#define VMX_IGS_INTERRUPTIBILITY_STATE_EXT_INT_INVALID          596
/** Interruptibility state block-by-MOVSS invalid while trying to deliver an
 *  NMI. */
#define VMX_IGS_INTERRUPTIBILITY_STATE_MOVSS_INVALID            597
/** Interruptibility state block-by-SMI invalid when CPU is not in SMM. */
#define VMX_IGS_INTERRUPTIBILITY_STATE_SMI_INVALID              598
/** Interruptibility state block-by-SMI invalid when trying to enter SMM. */
#define VMX_IGS_INTERRUPTIBILITY_STATE_SMI_SMM_INVALID          599
/** Interruptibility state block-by-STI (maybe) invalid when trying to
 *  deliver an NMI. */
#define VMX_IGS_INTERRUPTIBILITY_STATE_STI_INVALID              600
/** Interruptibility state block-by-NMI invalid when virtual-NMIs control is
 *  active. */
#define VMX_IGS_INTERRUPTIBILITY_STATE_NMI_INVALID              601
/** Pending debug exceptions reserved bits not set to 0. */
#define VMX_IGS_PENDING_DEBUG_RESERVED                          602
/** Longmode pending debug exceptions reserved bits not set to 0. */
#define VMX_IGS_LONGMODE_PENDING_DEBUG_RESERVED                 603
/** Pending debug exceptions.BS bit is not set when it should be. */
#define VMX_IGS_PENDING_DEBUG_XCPT_BS_NOT_SET                   604
/** Pending debug exceptions.BS bit is not clear when it should be. */
#define VMX_IGS_PENDING_DEBUG_XCPT_BS_NOT_CLEAR                 605
/** VMCS link pointer reserved bits not set to 0. */
#define VMX_IGS_VMCS_LINK_PTR_RESERVED                          606
/** TR cannot index into LDT, TI bit MBZ. */
#define VMX_IGS_TR_TI_INVALID                                   607
/** LDTR cannot index into LDT. TI bit MBZ. */
#define VMX_IGS_LDTR_TI_INVALID                                 608
/** TR.Base is not canonical. */
#define VMX_IGS_TR_BASE_NOT_CANONICAL                           609
/** FS.Base is not canonical. */
#define VMX_IGS_FS_BASE_NOT_CANONICAL                           610
/** GS.Base is not canonical. */
#define VMX_IGS_GS_BASE_NOT_CANONICAL                           611
/** LDTR.Base is not canonical. */
#define VMX_IGS_LDTR_BASE_NOT_CANONICAL                         612
/** TR is unusable. */
#define VMX_IGS_TR_ATTR_UNUSABLE                                613
/** TR.Attr.S bit invalid. */
#define VMX_IGS_TR_ATTR_S_INVALID                               614
/** TR is not present. */
#define VMX_IGS_TR_ATTR_P_INVALID                               615
/** TR.Attr reserved bits not set to 0. */
#define VMX_IGS_TR_ATTR_RESERVED                                616
/** TR.Attr.G bit invalid. */
#define VMX_IGS_TR_ATTR_G_INVALID                               617
/** Longmode TR.Attr.Type invalid. */
#define VMX_IGS_LONGMODE_TR_ATTR_TYPE_INVALID                   618
/** TR.Attr.Type invalid. */
#define VMX_IGS_TR_ATTR_TYPE_INVALID                            619
/** CS.Attr.S invalid. */
#define VMX_IGS_CS_ATTR_S_INVALID                               620
/** CS.Attr.DPL invalid. */
#define VMX_IGS_CS_ATTR_DPL_INVALID                             621
/** PAE PDPTE reserved bits not set to 0. */
#define VMX_IGS_PAE_PDPTE_RESERVED                              623
/** VMCS link pointer does not point to a shadow VMCS. */
#define VMX_IGS_VMCS_LINK_PTR_NOT_SHADOW                        624
/** VMCS link pointer to a shadow VMCS with invalid VMCS revision identifer. */
#define VMX_IGS_VMCS_LINK_PTR_SHADOW_VMCS_ID_INVALID            625
/** @} */

/** @name VMX VMCS-Read cache indices.
 * @{
 */
#define VMX_VMCS_GUEST_ES_BASE_CACHE_IDX                        0
#define VMX_VMCS_GUEST_CS_BASE_CACHE_IDX                        1
#define VMX_VMCS_GUEST_SS_BASE_CACHE_IDX                        2
#define VMX_VMCS_GUEST_DS_BASE_CACHE_IDX                        3
#define VMX_VMCS_GUEST_FS_BASE_CACHE_IDX                        4
#define VMX_VMCS_GUEST_GS_BASE_CACHE_IDX                        5
#define VMX_VMCS_GUEST_LDTR_BASE_CACHE_IDX                      6
#define VMX_VMCS_GUEST_TR_BASE_CACHE_IDX                        7
#define VMX_VMCS_GUEST_GDTR_BASE_CACHE_IDX                      8
#define VMX_VMCS_GUEST_IDTR_BASE_CACHE_IDX                      9
#define VMX_VMCS_GUEST_RSP_CACHE_IDX                            10
#define VMX_VMCS_GUEST_RIP_CACHE_IDX                            11
#define VMX_VMCS_GUEST_SYSENTER_ESP_CACHE_IDX                   12
#define VMX_VMCS_GUEST_SYSENTER_EIP_CACHE_IDX                   13
#define VMX_VMCS_RO_EXIT_QUALIFICATION_CACHE_IDX                14
#define VMX_VMCS_RO_GUEST_LINEAR_ADDR_CACHE_IDX                 15
#define VMX_VMCS_MAX_CACHE_IDX                                  (VMX_VMCS_RO_GUEST_LINEAR_ADDR_CACHE_IDX + 1)
#define VMX_VMCS_GUEST_CR3_CACHE_IDX                            16
#define VMX_VMCS_MAX_NESTED_PAGING_CACHE_IDX                    (VMX_VMCS_GUEST_CR3_CACHE_IDX + 1)
/** @} */


/** @name VMX Extended Page Tables (EPT) Common Bits.
 * @{ */
/** Bit 0 - Readable (we often think of it as present). */
#define EPT_E_BIT_READ                      0
#define EPT_E_READ                          RT_BIT_64(EPT_E_BIT_READ)               /**< @see EPT_E_BIT_READ */
/** Bit 1 - Writable. */
#define EPT_E_BIT_WRITE                     1
#define EPT_E_WRITE                         RT_BIT_64(EPT_E_BIT_WRITE)              /**< @see EPT_E_BIT_WRITE */
/** Bit 2 - Executable.
 * @note This controls supervisor instruction fetching if mode-based
 *       execution control is enabled. */
#define EPT_E_BIT_EXECUTE                   2
#define EPT_E_EXECUTE                       RT_BIT_64(EPT_E_BIT_EXECUTE)            /**< @see EPT_E_BIT_EXECUTE */
/** Bits 3-5 - Memory type mask (leaf only, MBZ).
 * The memory type is only applicable for leaf entries and MBZ for
 * non-leaf (causes miconfiguration exit). */
#define EPT_E_MEMTYPE_MASK                  UINT64_C(0x0038)
/** Bits 3-5 - Memory type shifted mask. */
#define EPT_E_MEMTYPE_SMASK                 UINT64_C(0x0007)
/** Bits 3-5 - Memory type shift count. */
#define EPT_E_MEMTYPE_SHIFT                 3
/** Bits 3-5 - Memory type: UC (Uncacheable). */
#define EPT_E_MEMTYPE_UC                    (UINT64_C(0) << EPT_E_MEMTYPE_SHIFT)
/** Bits 3-5 - Memory type: WC (Write Combining). */
#define EPT_E_MEMTYPE_WC                    (UINT64_C(1) << EPT_E_MEMTYPE_SHIFT)
/** Bits 3-5 - Memory type: Invalid (2). */
#define EPT_E_MEMTYPE_INVALID_2             (UINT64_C(2) << EPT_E_MEMTYPE_SHIFT)
/** Bits 3-5 - Memory type: Invalid (3). */
#define EPT_E_MEMTYPE_INVALID_3             (UINT64_C(3) << EPT_E_MEMTYPE_SHIFT)
/** Bits 3-5 - Memory type: WT (Write Through). */
#define EPT_E_MEMTYPE_WT                    (UINT64_C(4) << EPT_E_MEMTYPE_SHIFT)
/** Bits 3-5 - Memory type: WP (Write Protected). */
#define EPT_E_MEMTYPE_WP                    (UINT64_C(5) << EPT_E_MEMTYPE_SHIFT)
/** Bits 3-5 - Memory type: WB (Write Back). */
#define EPT_E_MEMTYPE_WB                    (UINT64_C(6) << EPT_E_MEMTYPE_SHIFT)
/** Bits 3-5 - Memory type: Invalid (7). */
#define EPT_E_MEMTYPE_INVALID_7             (UINT64_C(7) << EPT_E_MEMTYPE_SHIFT)
/** Bit 6 - Ignore page attribute table (leaf, MBZ). */
#define EPT_E_BIT_IGNORE_PAT                6
#define EPT_E_IGNORE_PAT                    RT_BIT_64(EPT_E_BIT_IGNORE_PAT)         /**< @see EPT_E_BIT_IGNORE_PAT */
/** Bit 7 - Leaf entry (MBZ in PML4, ignored in PT). */
#define EPT_E_BIT_LEAF                      7
#define EPT_E_LEAF                          RT_BIT_64(EPT_E_BIT_LEAF)               /**< @see EPT_E_BIT_LEAF */
/** Bit 8 - Accessed (all levels).
 * @note Ignored and not written when EPTP bit 6 is 0. */
#define EPT_E_BIT_ACCESSED                  8
#define EPT_E_ACCESSED                      RT_BIT_64(EPT_E_BIT_ACCESSED)           /**< @see EPT_E_BIT_ACCESSED */
/** Bit 9 - Dirty (leaf only).
 * @note Ignored and not written when EPTP bit 6 is 0. */
#define EPT_E_BIT_DIRTY                     9
#define EPT_E_DIRTY                         RT_BIT_64(EPT_E_BIT_DIRTY)              /**< @see EPT_E_BIT_DIRTY */
/** Bit 10 - Executable for usermode.
 * @note This ignored if mode-based execution control is disabled. */
#define EPT_E_BIT_USER_EXECUTE              10
#define EPT_E_USER_EXECUTE                  RT_BIT_64(EPT_E_BIT_USER_EXECUTE)       /**< @see EPT_E_BIT_USER_EXECUTE */
/* Bit 11 is always ignored. */
/** Bits 12-51 - Physical Page number of the next level. */
#define EPT_E_PG_MASK                       UINT64_C(0x000ffffffffff000)
/** Bit 58 - Page-write access (leaf only, ignored).
 * @note Ignored if EPT page-write control is disabled. */
#define EPT_E_BIT_PAGING_WRITE              58
#define EPT_E_PAGING_WRITE                  RT_BIT_64(EPT_E_BIT_PAGING_WRITE)       /**< @see EPT_E_BIT_PAGING_WRITE*/
/* Bit 59 is always ignored. */
/** Bit 60 - Supervisor shadow stack (leaf only, ignored).
 * @note Ignored if EPT bit 7 is 0. */
#define EPT_E_BIT_SUPER_SHW_STACK           60
#define EPT_E_SUPER_SHW_STACK               RT_BIT_64(EPT_E_BIT_SUPER_SHW_STACK)    /**< @see EPT_E_BIT_SUPER_SHW_STACK */
/** Bit 61 - Sub-page write permission (leaf only, ignored).
 * @note Ignored if sub-page write permission for EPT is disabled. */
#define EPT_E_BIT_SUBPAGE_WRITE_PERM        61
#define EPT_E_SUBPAGE_WRITE_PERM            RT_BIT_64(EPT_E_BIT_SUBPAGE_WRITE_PERM) /**< @see EPT_E_BIT_SUBPAGE_WRITE_PERM*/
/* Bit 62 is always ignored. */
/** Bit 63 - Suppress \#VE (leaf only, ignored).
 * @note Ignored if EPT violation to \#VE conversion is disabled. */
#define EPT_E_BIT_SUPPRESS_VE               63
#define EPT_E_SUPPRESS_VE                   RT_BIT_64(EPT_E_BIT_SUPPRESS_VE)        /**< @see EPT_E_BIT_SUPPRESS_VE */
/** @} */


/**@name Bit fields for common EPT attributes.
 @{ */
/** Read access. */
#define VMX_BF_EPT_PT_READ_SHIFT                        0
#define VMX_BF_EPT_PT_READ_MASK                         UINT64_C(0x0000000000000001)
/** Write access. */
#define VMX_BF_EPT_PT_WRITE_SHIFT                       1
#define VMX_BF_EPT_PT_WRITE_MASK                        UINT64_C(0x0000000000000002)
/** Execute access or execute access for supervisor-mode linear-addresses. */
#define VMX_BF_EPT_PT_EXECUTE_SHIFT                     2
#define VMX_BF_EPT_PT_EXECUTE_MASK                      UINT64_C(0x0000000000000004)
/** EPT memory type. */
#define VMX_BF_EPT_PT_MEMTYPE_SHIFT                     3
#define VMX_BF_EPT_PT_MEMTYPE_MASK                      UINT64_C(0x0000000000000038)
/** Ignore PAT. */
#define VMX_BF_EPT_PT_IGNORE_PAT_SHIFT                  6
#define VMX_BF_EPT_PT_IGNORE_PAT_MASK                   UINT64_C(0x0000000000000040)
/** Ignored (bit 7). */
#define VMX_BF_EPT_PT_IGN_7_SHIFT                       7
#define VMX_BF_EPT_PT_IGN_7_MASK                        UINT64_C(0x0000000000000080)
/** Accessed flag. */
#define VMX_BF_EPT_PT_ACCESSED_SHIFT                    8
#define VMX_BF_EPT_PT_ACCESSED_MASK                     UINT64_C(0x0000000000000100)
/** Dirty flag. */
#define VMX_BF_EPT_PT_DIRTY_SHIFT                       9
#define VMX_BF_EPT_PT_DIRTY_MASK                        UINT64_C(0x0000000000000200)
/** Execute access for user-mode linear addresses. */
#define VMX_BF_EPT_PT_EXECUTE_USER_SHIFT                10
#define VMX_BF_EPT_PT_EXECUTE_USER_MASK                 UINT64_C(0x0000000000000400)
/** Ignored (bit 59:11). */
#define VMX_BF_EPT_PT_IGN_59_11_SHIFT                   11
#define VMX_BF_EPT_PT_IGN_59_11_MASK                    UINT64_C(0x0ffffffffffff800)
/** Supervisor shadow stack. */
#define VMX_BF_EPT_PT_SUPER_SHW_STACK_SHIFT             60
#define VMX_BF_EPT_PT_SUPER_SHW_STACK_MASK              UINT64_C(0x1000000000000000)
/** Ignored (bits 62:61). */
#define VMX_BF_EPT_PT_IGN_62_61_SHIFT                   61
#define VMX_BF_EPT_PT_IGN_62_61_MASK                    UINT64_C(0x6000000000000000)
/** Suppress \#VE. */
#define VMX_BF_EPT_PT_SUPPRESS_VE_SHIFT                 63
#define VMX_BF_EPT_PT_SUPPRESS_VE_MASK                  UINT64_C(0x8000000000000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EPT_PT_, UINT64_C(0), UINT64_MAX,
                            (READ, WRITE, EXECUTE, MEMTYPE, IGNORE_PAT, IGN_7, ACCESSED, DIRTY, EXECUTE_USER, IGN_59_11,
                            SUPER_SHW_STACK, IGN_62_61, SUPPRESS_VE));
/** @} */


/** @name VMX Extended Page Tables (EPT) Structures
 * @{
 */

/**
 * Number of page table entries in the EPT. (PDPTE/PDE/PTE)
 */
#define EPT_PG_ENTRIES          X86_PG_PAE_ENTRIES

/**
 * EPT present mask.
 * These are ONLY the common bits in all EPT page-table entries which does
 * not rely on any CPU feature. It isn't necessarily the complete mask (e.g. when
 * mode-based excute control is active).
 */
#define EPT_PRESENT_MASK       (EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE)

/**
 * EPT Page Directory Pointer Entry. Bit view.
 * In accordance with the VT-x spec.
 *
 * @todo uint64_t isn't safe for bitfields (gcc pedantic warnings, and IIRC,
 *       this did cause trouble with one compiler/version).
 */
typedef struct EPTPML4EBITS
{
    /** Present bit. */
    RT_GCC_EXTENSION uint64_t u1Present       : 1;
    /** Writable bit. */
    RT_GCC_EXTENSION uint64_t u1Write         : 1;
    /** Executable bit. */
    RT_GCC_EXTENSION uint64_t u1Execute       : 1;
    /** Reserved (must be 0). */
    RT_GCC_EXTENSION uint64_t u5Reserved      : 5;
    /** Available for software. */
    RT_GCC_EXTENSION uint64_t u4Available     : 4;
    /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */
    RT_GCC_EXTENSION uint64_t u40PhysAddr     : 40;
    /** Available for software. */
    RT_GCC_EXTENSION uint64_t u12Available    : 12;
} EPTPML4EBITS;
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
/** Bits - - EPT - PML4 MBZ mask. */
#define EPT_PML4E_MBZ_MASK      UINT64_C(0x00000000000000f8)
/** Mask of all possible EPT PML4E attribute bits. */
#define EPT_PML4E_ATTR_MASK     (EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE | EPT_E_ACCESSED | EPT_E_USER_EXECUTE)

/**
 * EPT PML4E.
 * In accordance with the VT-x spec.
 */
typedef union EPTPML4E
{
#ifndef VBOX_WITHOUT_PAGING_BIT_FIELDS
    /** Normal view. */
    EPTPML4EBITS    n;
#endif
    /** Unsigned integer view. */
    X86PGPAEUINT    u;
    /** 64 bit unsigned integer view. */
    uint64_t        au64[1];
    /** 32 bit unsigned integer view. */
    uint32_t        au32[2];
} EPTPML4E;
AssertCompileSize(EPTPML4E, 8);
/** Pointer to a PML4 table entry. */
typedef EPTPML4E *PEPTPML4E;
/** Pointer to a const PML4 table entry. */
typedef const EPTPML4E *PCEPTPML4E;

/**
 * EPT PML4 Table.
 * In accordance with the VT-x spec.
 */
typedef struct EPTPML4
{
    EPTPML4E    a[EPT_PG_ENTRIES];
} EPTPML4;
AssertCompileSize(EPTPML4, 0x1000);
/** 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.
 * In accordance with the VT-x spec.
 */
typedef struct EPTPDPTEBITS
{
    /** Present bit. */
    RT_GCC_EXTENSION uint64_t u1Present       : 1;
    /** Writable bit. */
    RT_GCC_EXTENSION uint64_t u1Write         : 1;
    /** Executable bit. */
    RT_GCC_EXTENSION uint64_t u1Execute       : 1;
    /** Reserved (must be 0). */
    RT_GCC_EXTENSION uint64_t u5Reserved      : 5;
    /** Available for software. */
    RT_GCC_EXTENSION uint64_t u4Available     : 4;
    /** Physical address of the next level (PD). Restricted by maximum physical address width of the cpu. */
    RT_GCC_EXTENSION uint64_t u40PhysAddr     : 40;
    /** Available for software. */
    RT_GCC_EXTENSION uint64_t u12Available    : 12;
} EPTPDPTEBITS;
AssertCompileSize(EPTPDPTEBITS, 8);

/** Bit 7 - - EPT - PDPTE maps a 1GB page. */
#define EPT_PDPTE1G_SIZE_MASK       RT_BIT_64(7)
/** Bits 12-51 - - EPT - Physical Page number of the next level. */
#define EPT_PDPTE_PG_MASK           X86_PDPE_PG_MASK
/** Bits 30-51 - - EPT - Physical Page number of the 1G large page. */
#define EPT_PDPTE1G_PG_MASK         X86_PDPE1G_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
/** Bits 3-7 - - EPT - PDPTE MBZ Mask. */
#define EPT_PDPTE_MBZ_MASK          UINT64_C(0x00000000000000f8)
/** Bits 12-29 - - EPT - 1GB PDPTE MBZ Mask. */
#define EPT_PDPTE1G_MBZ_MASK        UINT64_C(0x000000003ffff000)
/** Mask of all possible EPT PDPTE (1GB) attribute bits. */
#define EPT_PDPTE1G_ATTR_MASK       (  EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE | EPT_E_MEMTYPE_MASK | EPT_E_IGNORE_PAT \
                                     | EPT_E_ACCESSED | EPT_E_DIRTY | EPT_E_USER_EXECUTE)
/** Mask of all possible EPT PDPTE attribute bits. */
#define EPT_PDPTE_ATTR_MASK         (EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE | EPT_E_ACCESSED | EPT_E_USER_EXECUTE)
/** */

/**
 * EPT Page Directory Pointer.
 * In accordance with the VT-x spec.
 */
typedef union EPTPDPTE
{
#ifndef VBOX_WITHOUT_PAGING_BIT_FIELDS
    /** Normal view. */
    EPTPDPTEBITS    n;
#endif
    /** Unsigned integer view. */
    X86PGPAEUINT    u;
    /** 64 bit unsigned integer view. */
    uint64_t        au64[1];
    /** 32 bit unsigned integer view. */
    uint32_t        au32[2];
} EPTPDPTE;
AssertCompileSize(EPTPDPTE, 8);
/** Pointer to an EPT Page Directory Pointer Entry. */
typedef EPTPDPTE *PEPTPDPTE;
/** Pointer to a const EPT Page Directory Pointer Entry. */
typedef const EPTPDPTE *PCEPTPDPTE;

/**
 * EPT Page Directory Pointer Table.
 * In accordance with the VT-x spec.
 */
typedef struct EPTPDPT
{
    EPTPDPTE    a[EPT_PG_ENTRIES];
} EPTPDPT;
AssertCompileSize(EPTPDPT, 0x1000);
/** 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.
 * In accordance with the VT-x spec.
 */
typedef struct EPTPDEBITS
{
    /** Present bit. */
    RT_GCC_EXTENSION uint64_t u1Present       : 1;
    /** Writable bit. */
    RT_GCC_EXTENSION uint64_t u1Write         : 1;
    /** Executable bit. */
    RT_GCC_EXTENSION uint64_t u1Execute       : 1;
    /** Reserved (must be 0). */
    RT_GCC_EXTENSION uint64_t u4Reserved      : 4;
    /** Big page (must be 0 here). */
    RT_GCC_EXTENSION uint64_t u1Size          : 1;
    /** Available for software. */
    RT_GCC_EXTENSION uint64_t u4Available     : 4;
    /** Physical address of page table. Restricted by maximum physical address width of the cpu. */
    RT_GCC_EXTENSION uint64_t u40PhysAddr     : 40;
    /** Available for software. */
    RT_GCC_EXTENSION uint64_t u12Available    : 12;
} EPTPDEBITS;
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
/** Bits 3-7 - EPT - PDE MBZ Mask. */
#define EPT_PDE_MBZ_MASK        UINT64_C(0x00000000000000f8)
/** Mask of all possible EPT PDE (2M) attribute bits. */
#define EPT_PDE2M_ATTR_MASK     (  EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE | EPT_E_MEMTYPE_MASK | EPT_E_IGNORE_PAT \
                                 | EPT_E_ACCESSED | EPT_E_DIRTY | EPT_E_USER_EXECUTE)
/** Mask of all possible EPT PDE attribute bits. */
#define EPT_PDE_ATTR_MASK       (EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE | EPT_E_ACCESSED | EPT_E_USER_EXECUTE)


/**
 * EPT 2MB Page Directory Table Entry. Bit view.
 * In accordance with the VT-x spec.
 */
typedef struct EPTPDE2MBITS
{
    /** Present bit. */
    RT_GCC_EXTENSION uint64_t u1Present       : 1;
    /** Writable bit. */
    RT_GCC_EXTENSION uint64_t u1Write         : 1;
    /** Executable bit. */
    RT_GCC_EXTENSION uint64_t u1Execute       : 1;
    /** EPT Table Memory Type. MBZ for non-leaf nodes. */
    RT_GCC_EXTENSION uint64_t u3EMT           : 3;
    /** Ignore PAT memory type */
    RT_GCC_EXTENSION uint64_t u1IgnorePAT     : 1;
    /** Big page (must be 1 here). */
    RT_GCC_EXTENSION uint64_t u1Size          : 1;
    /** Available for software. */
    RT_GCC_EXTENSION uint64_t u4Available     : 4;
    /** Reserved (must be 0). */
    RT_GCC_EXTENSION uint64_t u9Reserved      : 9;
    /** Physical address of the 2MB page. Restricted by maximum physical address width of the cpu. */
    RT_GCC_EXTENSION uint64_t u31PhysAddr     : 31;
    /** Available for software. */
    RT_GCC_EXTENSION uint64_t u12Available    : 12;
} EPTPDE2MBITS;
AssertCompileSize(EPTPDE2MBITS, 8);

/** Bits 21-51 - - EPT - Physical Page number of the next level. */
#define EPT_PDE2M_PG_MASK       X86_PDE2M_PAE_PG_MASK
/** Bits 20-12 - - EPT - PDE 2M MBZ Mask. */
#define EPT_PDE2M_MBZ_MASK      UINT64_C(0x00000000001ff000)


/**
 * EPT Page Directory Table Entry.
 * In accordance with the VT-x spec.
 */
typedef union EPTPDE
{
#ifndef VBOX_WITHOUT_PAGING_BIT_FIELDS
    /** Normal view. */
    EPTPDEBITS      n;
    /** 2MB view (big). */
    EPTPDE2MBITS    b;
#endif
    /** Unsigned integer view. */
    X86PGPAEUINT    u;
    /** 64 bit unsigned integer view. */
    uint64_t        au64[1];
    /** 32 bit unsigned integer view. */
    uint32_t        au32[2];
} EPTPDE;
AssertCompileSize(EPTPDE, 8);
/** Pointer to an EPT Page Directory Table Entry. */
typedef EPTPDE *PEPTPDE;
/** Pointer to a const EPT Page Directory Table Entry. */
typedef const EPTPDE *PCEPTPDE;

/**
 * EPT Page Directory Table.
 * In accordance with the VT-x spec.
 */
typedef struct EPTPD
{
    EPTPDE      a[EPT_PG_ENTRIES];
} EPTPD;
AssertCompileSize(EPTPD, 0x1000);
/** 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.
 * In accordance with the VT-x spec.
 */
typedef struct EPTPTEBITS
{
    /** 0 - Present bit.
     * @remarks 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. */
    RT_GCC_EXTENSION uint64_t u1Present       : 1;
    /** 1 - Writable bit. */
    RT_GCC_EXTENSION uint64_t u1Write         : 1;
    /** 2 - Executable bit. */
    RT_GCC_EXTENSION uint64_t u1Execute       : 1;
    /** 5:3 - EPT Memory Type. MBZ for non-leaf nodes. */
    RT_GCC_EXTENSION uint64_t u3EMT           : 3;
    /** 6 - Ignore PAT memory type */
    RT_GCC_EXTENSION uint64_t u1IgnorePAT     : 1;
    /** 11:7 - Available for software. */
    RT_GCC_EXTENSION uint64_t u5Available     : 5;
    /** 51:12 - Physical address of page. Restricted by maximum physical
     *  address width of the cpu. */
    RT_GCC_EXTENSION uint64_t u40PhysAddr     : 40;
    /** 63:52 - Available for software. */
    RT_GCC_EXTENSION uint64_t u12Available    : 12;
} EPTPTEBITS;
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
/** No bits - - EPT - PTE MBZ bits. */
#define EPT_PTE_MBZ_MASK        UINT64_C(0x0000000000000000)
/** Mask of all possible EPT PTE attribute bits. */
#define EPT_PTE_ATTR_MASK       (  EPT_E_READ | EPT_E_WRITE | EPT_E_EXECUTE | EPT_E_MEMTYPE_MASK | EPT_E_IGNORE_PAT \
                                 | EPT_E_ACCESSED | EPT_E_USER_EXECUTE)


/**
 * EPT Page Table Entry.
 * In accordance with the VT-x spec.
 */
typedef union EPTPTE
{
#ifndef VBOX_WITHOUT_PAGING_BIT_FIELDS
    /** Normal view. */
    EPTPTEBITS      n;
#endif
    /** Unsigned integer view. */
    X86PGPAEUINT    u;
    /** 64 bit unsigned integer view. */
    uint64_t        au64[1];
    /** 32 bit unsigned integer view. */
    uint32_t        au32[2];
} EPTPTE;
AssertCompileSize(EPTPTE, 8);
/** Pointer to an EPT Page Directory Table Entry. */
typedef EPTPTE *PEPTPTE;
/** Pointer to a const EPT Page Directory Table Entry. */
typedef const EPTPTE *PCEPTPTE;

/**
 * EPT Page Table.
 * In accordance with the VT-x spec.
 */
typedef struct EPTPT
{
    EPTPTE      a[EPT_PG_ENTRIES];
} EPTPT;
AssertCompileSize(EPTPT, 0x1000);
/** Pointer to an extended page table. */
typedef EPTPT *PEPTPT;
/** Pointer to a const extended table. */
typedef const EPTPT *PCEPTPT;

/** EPTP page mask for the EPT PML4 table. */
#define EPT_EPTP_PG_MASK        X86_CR3_AMD64_PAGE_MASK
/** @} */

/**
 * VMX VPID flush types.
 * Valid enum members are in accordance with the VT-x spec.
 */
typedef enum
{
    /** Invalidate a specific page. */
    VMXTLBFLUSHVPID_INDIV_ADDR                    = 0,
    /** Invalidate one context (specific VPID). */
    VMXTLBFLUSHVPID_SINGLE_CONTEXT                = 1,
    /** Invalidate all contexts (all VPIDs). */
    VMXTLBFLUSHVPID_ALL_CONTEXTS                  = 2,
    /** Invalidate a single VPID context retaining global mappings. */
    VMXTLBFLUSHVPID_SINGLE_CONTEXT_RETAIN_GLOBALS = 3,
    /** Unsupported by VirtualBox. */
    VMXTLBFLUSHVPID_NOT_SUPPORTED                 = 0xbad0,
    /** Unsupported by CPU. */
    VMXTLBFLUSHVPID_NONE                          = 0xbad1
} VMXTLBFLUSHVPID;
AssertCompileSize(VMXTLBFLUSHVPID, 4);
/** Mask of all valid INVVPID flush types.  */
#define VMX_INVVPID_VALID_MASK                    (  VMXTLBFLUSHVPID_INDIV_ADDR \
                                                   | VMXTLBFLUSHVPID_SINGLE_CONTEXT \
                                                   | VMXTLBFLUSHVPID_ALL_CONTEXTS \
                                                   | VMXTLBFLUSHVPID_SINGLE_CONTEXT_RETAIN_GLOBALS)

/**
 * VMX EPT flush types.
 * @note Valid enums values are in accordance with the VT-x spec.
 */
typedef enum
{
    /** Invalidate one context (specific EPT). */
    VMXTLBFLUSHEPT_SINGLE_CONTEXT              = 1,
    /* Invalidate all contexts (all EPTs) */
    VMXTLBFLUSHEPT_ALL_CONTEXTS                = 2,
    /** Unsupported by VirtualBox. */
    VMXTLBFLUSHEPT_NOT_SUPPORTED               = 0xbad0,
    /** Unsupported by CPU. */
    VMXTLBFLUSHEPT_NONE                        = 0xbad1
} VMXTLBFLUSHEPT;
AssertCompileSize(VMXTLBFLUSHEPT, 4);
/** Mask of all valid INVEPT flush types.  */
#define VMX_INVEPT_VALID_MASK                     (  VMXTLBFLUSHEPT_SINGLE_CONTEXT \
                                                   | VMXTLBFLUSHEPT_ALL_CONTEXTS)

/**
 * VMX Posted Interrupt Descriptor.
 * In accordance with the VT-x spec.
 */
typedef struct VMXPOSTEDINTRDESC
{
    uint32_t    aVectorBitmap[8];
    uint32_t    fOutstandingNotification : 1;
    uint32_t    uReserved0               : 31;
    uint8_t     au8Reserved0[28];
} VMXPOSTEDINTRDESC;
AssertCompileMemberSize(VMXPOSTEDINTRDESC, aVectorBitmap, 32);
AssertCompileSize(VMXPOSTEDINTRDESC, 64);
/** Pointer to a posted interrupt descriptor. */
typedef VMXPOSTEDINTRDESC *PVMXPOSTEDINTRDESC;
/** Pointer to a const posted interrupt descriptor. */
typedef const VMXPOSTEDINTRDESC *PCVMXPOSTEDINTRDESC;

/**
 * VMX VMCS revision identifier.
 * In accordance with the VT-x spec.
 */
typedef union
{
    struct
    {
        /** Revision identifier. */
        uint32_t    u31RevisionId : 31;
        /** Whether this is a shadow VMCS. */
        uint32_t    fIsShadowVmcs : 1;
    } n;
    /* The unsigned integer view. */
    uint32_t        u;
} VMXVMCSREVID;
AssertCompileSize(VMXVMCSREVID, 4);
/** Pointer to the VMXVMCSREVID union. */
typedef VMXVMCSREVID *PVMXVMCSREVID;
/** Pointer to a const VMXVMCSREVID union. */
typedef const VMXVMCSREVID *PCVMXVMCSREVID;

/**
 * VMX VM-exit instruction information.
 * In accordance with the VT-x spec.
 */
typedef union
{
    /** Plain unsigned int representation. */
    uint32_t    u;

    /** INS and OUTS information. */
    struct
    {
        uint32_t    u7Reserved0 : 7;
        /** The address size; 0=16-bit, 1=32-bit, 2=64-bit, rest undefined. */
        uint32_t    u3AddrSize  : 3;
        uint32_t    u5Reserved1 : 5;
        /** The segment register (X86_SREG_XXX). */
        uint32_t    iSegReg     : 3;
        uint32_t    uReserved2  : 14;
    } StrIo;

    /** INVEPT, INVPCID, INVVPID information. */
    struct
    {
        /** Scaling; 0=no scaling, 1=scale-by-2, 2=scale-by-4, 3=scale-by-8. */
        uint32_t    u2Scaling       : 2;
        uint32_t    u5Undef0        : 5;
        /** The address size; 0=16-bit, 1=32-bit, 2=64-bit, rest undefined. */
        uint32_t    u3AddrSize      : 3;
        /** Cleared to 0. */
        uint32_t    u1Cleared0      : 1;
        uint32_t    u4Undef0        : 4;
        /** The segment register (X86_SREG_XXX). */
        uint32_t    iSegReg         : 3;
        /** The index register (X86_GREG_XXX). */
        uint32_t    iIdxReg         : 4;
        /** Set if index register is invalid. */
        uint32_t    fIdxRegInvalid  : 1;
        /** The base register (X86_GREG_XXX). */
        uint32_t    iBaseReg        : 4;
        /** Set if base register is invalid. */
        uint32_t    fBaseRegInvalid : 1;
        /** Register 2 (X86_GREG_XXX). */
        uint32_t    iReg2           : 4;
    } Inv;

    /** VMCLEAR, VMPTRLD, VMPTRST, VMXON, XRSTORS, XSAVES information. */
    struct
    {
        /** Scaling; 0=no scaling, 1=scale-by-2, 2=scale-by-4, 3=scale-by-8. */
        uint32_t    u2Scaling       : 2;
        uint32_t    u5Reserved0     : 5;
        /** The address size; 0=16-bit, 1=32-bit, 2=64-bit, rest undefined. */
        uint32_t    u3AddrSize      : 3;
        /** Cleared to 0. */
        uint32_t    u1Cleared0      : 1;
        uint32_t    u4Reserved0     : 4;
        /** The segment register (X86_SREG_XXX). */
        uint32_t    iSegReg         : 3;
        /** The index register (X86_GREG_XXX). */
        uint32_t    iIdxReg         : 4;
        /** Set if index register is invalid. */
        uint32_t    fIdxRegInvalid  : 1;
        /** The base register (X86_GREG_XXX). */
        uint32_t    iBaseReg        : 4;
        /** Set if base register is invalid. */
        uint32_t    fBaseRegInvalid : 1;
        /** Register 2 (X86_GREG_XXX). */
        uint32_t    iReg2           : 4;
    } VmxXsave;

    /** LIDT, LGDT, SIDT, SGDT information. */
    struct
    {
        /** Scaling; 0=no scaling, 1=scale-by-2, 2=scale-by-4, 3=scale-by-8. */
        uint32_t    u2Scaling       : 2;
        uint32_t    u5Undef0        : 5;
        /** The address size; 0=16-bit, 1=32-bit, 2=64-bit, rest undefined. */
        uint32_t    u3AddrSize      : 3;
        /** Always cleared to 0. */
        uint32_t    u1Cleared0      : 1;
        /** Operand size; 0=16-bit, 1=32-bit, undefined for 64-bit. */
        uint32_t    uOperandSize    : 1;
        uint32_t    u3Undef0        : 3;
        /** The segment register (X86_SREG_XXX). */
        uint32_t    iSegReg         : 3;
        /** The index register (X86_GREG_XXX). */
        uint32_t    iIdxReg         : 4;
        /** Set if index register is invalid. */
        uint32_t    fIdxRegInvalid  : 1;
        /** The base register (X86_GREG_XXX). */
        uint32_t    iBaseReg        : 4;
        /** Set if base register is invalid. */
        uint32_t    fBaseRegInvalid : 1;
        /** Instruction identity (VMX_INSTR_ID_XXX). */
        uint32_t    u2InstrId       : 2;
        uint32_t    u2Undef0        : 2;
    } GdtIdt;

    /** LLDT, LTR, SLDT, STR information. */
    struct
    {
        /** Scaling; 0=no scaling, 1=scale-by-2, 2=scale-by-4, 3=scale-by-8. */
        uint32_t    u2Scaling       : 2;
        uint32_t    u1Undef0        : 1;
        /** Register 1 (X86_GREG_XXX). */
        uint32_t    iReg1           : 4;
        /** The address size; 0=16-bit, 1=32-bit, 2=64-bit, rest undefined. */
        uint32_t    u3AddrSize      : 3;
        /** Memory/Register - Always cleared to 0 to indicate memory operand. */
        uint32_t    fIsRegOperand   : 1;
        uint32_t    u4Undef0        : 4;
        /** The segment register (X86_SREG_XXX). */
        uint32_t    iSegReg         : 3;
        /** The index register (X86_GREG_XXX). */
        uint32_t    iIdxReg         : 4;
        /** Set if index register is invalid. */
        uint32_t    fIdxRegInvalid  : 1;
        /** The base register (X86_GREG_XXX). */
        uint32_t    iBaseReg        : 4;
        /** Set if base register is invalid. */
        uint32_t    fBaseRegInvalid : 1;
        /** Instruction identity (VMX_INSTR_ID_XXX). */
        uint32_t    u2InstrId       : 2;
        uint32_t    u2Undef0        : 2;
    } LdtTr;

    /** RDRAND, RDSEED information. */
    struct
    {
        /** Scaling; 0=no scaling, 1=scale-by-2, 2=scale-by-4, 3=scale-by-8. */
        uint32_t    u2Undef0        : 2;
        /** Destination register (X86_GREG_XXX). */
        uint32_t    iReg1           : 4;
        uint32_t    u4Undef0        : 4;
        /** Operand size; 0=16-bit, 1=32-bit, 2=64-bit, 3=unused. */
        uint32_t    u2OperandSize   : 2;
        uint32_t    u19Def0         : 20;
    } RdrandRdseed;

    /** VMREAD, VMWRITE information. */
    struct
    {
        /** Scaling; 0=no scaling, 1=scale-by-2, 2=scale-by-4, 3=scale-by-8. */
        uint32_t    u2Scaling       : 2;
        uint32_t    u1Undef0        : 1;
        /** Register 1 (X86_GREG_XXX). */
        uint32_t    iReg1           : 4;
        /** The address size; 0=16-bit, 1=32-bit, 2=64-bit, rest undefined. */
        uint32_t    u3AddrSize      : 3;
        /** Memory or register operand. */
        uint32_t    fIsRegOperand   : 1;
        /** Operand size; 0=16-bit, 1=32-bit, 2=64-bit, 3=unused. */
        uint32_t    u4Undef0        : 4;
        /** The segment register (X86_SREG_XXX). */
        uint32_t    iSegReg         : 3;
        /** The index register (X86_GREG_XXX). */
        uint32_t    iIdxReg         : 4;
        /** Set if index register is invalid. */
        uint32_t    fIdxRegInvalid  : 1;
        /** The base register (X86_GREG_XXX). */
        uint32_t    iBaseReg        : 4;
        /** Set if base register is invalid. */
        uint32_t    fBaseRegInvalid : 1;
        /** Register 2 (X86_GREG_XXX). */
        uint32_t    iReg2           : 4;
    } VmreadVmwrite;

    struct
    {
        uint32_t    u2Undef0        : 3;
        /** First XMM register operand. */
        uint32_t    u4XmmReg1       : 4;
        uint32_t    u23Undef1       : 21;
        /** Second XMM register operand. */
        uint32_t    u4XmmReg2       : 4;
    } LoadIwkey;

    /** This is a combination field of all instruction information. Note! Not all field
     *  combinations are valid (e.g., iReg1 is undefined for memory operands) and
     *  specialized fields are overwritten by their generic counterparts (e.g. no
     *  instruction identity field). */
    struct
    {
        /** Scaling; 0=no scaling, 1=scale-by-2, 2=scale-by-4, 3=scale-by-8. */
        uint32_t    u2Scaling       : 2;
        uint32_t    u1Undef0        : 1;
        /** Register 1 (X86_GREG_XXX). */
        uint32_t    iReg1           : 4;
        /** The address size; 0=16-bit, 1=32-bit, 2=64-bit, rest undefined. */
        uint32_t    u3AddrSize      : 3;
        /** Memory/Register - Always cleared to 0 to indicate memory operand. */
        uint32_t    fIsRegOperand   : 1;
        /** Operand size; 0=16-bit, 1=32-bit, 2=64-bit, 3=unused. */
        uint32_t    uOperandSize    : 2;
        uint32_t    u2Undef0        : 2;
        /** The segment register (X86_SREG_XXX). */
        uint32_t    iSegReg         : 3;
        /** The index register (X86_GREG_XXX). */
        uint32_t    iIdxReg         : 4;
        /** Set if index register is invalid. */
        uint32_t    fIdxRegInvalid  : 1;
        /** The base register (X86_GREG_XXX). */
        uint32_t    iBaseReg        : 4;
        /** Set if base register is invalid. */
        uint32_t    fBaseRegInvalid : 1;
        /** Register 2 (X86_GREG_XXX) or instruction identity. */
        uint32_t    iReg2           : 4;
    } All;
} VMXEXITINSTRINFO;
AssertCompileSize(VMXEXITINSTRINFO, 4);
/** Pointer to a VMX VM-exit instruction info. struct. */
typedef VMXEXITINSTRINFO *PVMXEXITINSTRINFO;
/** Pointer to a const VMX VM-exit instruction info. struct. */
typedef const VMXEXITINSTRINFO *PCVMXEXITINSTRINFO;


/** @name VM-entry failure reported in Exit qualification.
 * See Intel spec. 26.7 "VM-entry failures during or after loading guest-state".
 * @{
 */
/** No errors during VM-entry. */
#define VMX_ENTRY_FAIL_QUAL_NO_ERROR                            (0)
/** Not used. */
#define VMX_ENTRY_FAIL_QUAL_NOT_USED                            (1)
/** Error while loading PDPTEs. */
#define VMX_ENTRY_FAIL_QUAL_PDPTE                               (2)
/** NMI injection when blocking-by-STI is set. */
#define VMX_ENTRY_FAIL_QUAL_NMI_INJECT                          (3)
/** Invalid VMCS link pointer. */
#define VMX_ENTRY_FAIL_QUAL_VMCS_LINK_PTR                       (4)
/** @} */


/** @name VMXMSRPM_XXX - VMX MSR-bitmap permissions.
 * These are -not- specified by Intel but used internally by VirtualBox.
 * @{ */
/** Guest software reads of this MSR must not cause a VM-exit. */
#define VMXMSRPM_ALLOW_RD                                       RT_BIT(0)
/** Guest software reads of this MSR must cause a VM-exit. */
#define VMXMSRPM_EXIT_RD                                        RT_BIT(1)
/** Guest software writes to this MSR must not cause a VM-exit. */
#define VMXMSRPM_ALLOW_WR                                       RT_BIT(2)
/** Guest software writes to this MSR must cause a VM-exit. */
#define VMXMSRPM_EXIT_WR                                        RT_BIT(3)
/** Guest software reads or writes of this MSR must not cause a VM-exit. */
#define VMXMSRPM_ALLOW_RD_WR                                    (VMXMSRPM_ALLOW_RD | VMXMSRPM_ALLOW_WR)
/** Guest software reads or writes of this MSR must cause a VM-exit. */
#define VMXMSRPM_EXIT_RD_WR                                     (VMXMSRPM_EXIT_RD  | VMXMSRPM_EXIT_WR)
/** Mask of valid MSR read permissions. */
#define VMXMSRPM_RD_MASK                                        (VMXMSRPM_ALLOW_RD | VMXMSRPM_EXIT_RD)
/** Mask of valid MSR write permissions. */
#define VMXMSRPM_WR_MASK                                        (VMXMSRPM_ALLOW_WR | VMXMSRPM_EXIT_WR)
/** Mask of valid MSR permissions. */
#define VMXMSRPM_MASK                                           (VMXMSRPM_RD_MASK  | VMXMSRPM_WR_MASK)
/** */
/** Gets whether the MSR permission is valid or not. */
#define VMXMSRPM_IS_FLAG_VALID(a_Msrpm)                         (    (a_Msrpm) != 0 \
                                                                 && ((a_Msrpm) & ~VMXMSRPM_MASK) == 0 \
                                                                 && ((a_Msrpm) & VMXMSRPM_RD_MASK) != VMXMSRPM_RD_MASK \
                                                                 && ((a_Msrpm) & VMXMSRPM_WR_MASK) != VMXMSRPM_WR_MASK)
/** @} */

/**
 * VMX MSR autoload/store slot.
 * In accordance with the VT-x spec.
 */
typedef struct VMXAUTOMSR
{
    /** The MSR Id. */
    uint32_t    u32Msr;
    /** Reserved (MBZ). */
    uint32_t    u32Reserved;
    /** The MSR value. */
    uint64_t    u64Value;
} VMXAUTOMSR;
AssertCompileSize(VMXAUTOMSR, 16);
/** Pointer to an MSR load/store element. */
typedef VMXAUTOMSR *PVMXAUTOMSR;
/** Pointer to a const MSR load/store element. */
typedef const VMXAUTOMSR *PCVMXAUTOMSR;

/** VMX auto load-store MSR (VMXAUTOMSR) offset mask. */
#define VMX_AUTOMSR_OFFSET_MASK         0xf

/**
 * VMX tagged-TLB flush types.
 */
typedef enum
{
    VMXTLBFLUSHTYPE_EPT,
    VMXTLBFLUSHTYPE_VPID,
    VMXTLBFLUSHTYPE_EPT_VPID,
    VMXTLBFLUSHTYPE_NONE
} VMXTLBFLUSHTYPE;
/** Pointer to a VMXTLBFLUSHTYPE enum. */
typedef VMXTLBFLUSHTYPE *PVMXTLBFLUSHTYPE;
/** Pointer to a const VMXTLBFLUSHTYPE enum. */
typedef const VMXTLBFLUSHTYPE *PCVMXTLBFLUSHTYPE;

/**
 * VMX controls MSR.
 * In accordance with the VT-x spec.
 */
typedef union
{
    struct
    {
        /** Bits set here -must- be set in the corresponding VM-execution controls. */
        uint32_t        allowed0;
        /** Bits cleared here -must- be cleared in the corresponding VM-execution
         *  controls. */
        uint32_t        allowed1;
    } n;
    uint64_t            u;
} VMXCTLSMSR;
AssertCompileSize(VMXCTLSMSR, 8);
/** Pointer to a VMXCTLSMSR union. */
typedef VMXCTLSMSR *PVMXCTLSMSR;
/** Pointer to a const VMXCTLSMSR union. */
typedef const VMXCTLSMSR *PCVMXCTLSMSR;

/**
 * VMX MSRs.
 */
typedef struct VMXMSRS
{
    /** Basic information. */
    uint64_t        u64Basic;
    /** Pin-based VM-execution controls. */
    VMXCTLSMSR      PinCtls;
    /** Processor-based VM-execution controls. */
    VMXCTLSMSR      ProcCtls;
    /** Secondary processor-based VM-execution controls. */
    VMXCTLSMSR      ProcCtls2;
    /** VM-exit controls. */
    VMXCTLSMSR      ExitCtls;
    /** VM-entry controls. */
    VMXCTLSMSR      EntryCtls;
    /** True pin-based VM-execution controls. */
    VMXCTLSMSR      TruePinCtls;
    /** True processor-based VM-execution controls. */
    VMXCTLSMSR      TrueProcCtls;
    /** True VM-entry controls. */
    VMXCTLSMSR      TrueEntryCtls;
    /** True VM-exit controls. */
    VMXCTLSMSR      TrueExitCtls;
    /** Miscellaneous data. */
    uint64_t        u64Misc;
    /** CR0 fixed-0 - bits set here must be set in VMX operation. */
    uint64_t        u64Cr0Fixed0;
    /** CR0 fixed-1 - bits clear here must be clear in VMX operation. */
    uint64_t        u64Cr0Fixed1;
    /** CR4 fixed-0 - bits set here must be set in VMX operation. */
    uint64_t        u64Cr4Fixed0;
    /** CR4 fixed-1 - bits clear here must be clear in VMX operation. */
    uint64_t        u64Cr4Fixed1;
    /** VMCS enumeration. */
    uint64_t        u64VmcsEnum;
    /** VM Functions. */
    uint64_t        u64VmFunc;
    /** EPT, VPID capabilities. */
    uint64_t        u64EptVpidCaps;
    /** Tertiary processor-based VM-execution controls. */
    uint64_t        u64ProcCtls3;
    /** Secondary VM-exit controls. */
    uint64_t        u64ExitCtls2;
    /** Reserved for future. */
    uint64_t        a_u64Reserved[8];
} VMXMSRS;
AssertCompileSizeAlignment(VMXMSRS, 8);
AssertCompileSize(VMXMSRS, 224);
/** Pointer to a VMXMSRS struct. */
typedef VMXMSRS *PVMXMSRS;
/** Pointer to a const VMXMSRS struct. */
typedef const VMXMSRS *PCVMXMSRS;


/**
 * LBR MSRs.
 */
typedef struct LBRMSRS
{
    /** List of LastBranch-From-IP MSRs. */
    uint64_t    au64BranchFromIpMsr[32];
    /** List of LastBranch-To-IP MSRs. */
    uint64_t    au64BranchToIpMsr[32];
    /** The MSR containing the index to the most recent branch record.  */
    uint64_t    uBranchTosMsr;
} LBRMSRS;
AssertCompileSizeAlignment(LBRMSRS, 8);
/** Pointer to a VMXMSRS struct. */
typedef LBRMSRS *PLBRMSRS;
/** Pointer to a const VMXMSRS struct. */
typedef const LBRMSRS *PCLBRMSRS;


/** @name VMX Basic Exit Reasons.
 * In accordance with the VT-x spec.
 * Update g_aVMExitHandlers if new VM-exit reasons are added.
 * @{
 */
/** Invalid exit code */
#define VMX_EXIT_INVALID                                        (-1)
/** Exception or non-maskable interrupt (NMI). */
#define VMX_EXIT_XCPT_OR_NMI                                    0
/** External interrupt. */
#define VMX_EXIT_EXT_INT                                        1
/** Triple fault. */
#define VMX_EXIT_TRIPLE_FAULT                                   2
/** INIT signal. */
#define VMX_EXIT_INIT_SIGNAL                                    3
/** Start-up IPI (SIPI). */
#define VMX_EXIT_SIPI                                           4
/** I/O system-management interrupt (SMI). */
#define VMX_EXIT_IO_SMI                                         5
/** Other SMI. */
#define VMX_EXIT_SMI                                            6
/** Interrupt window exiting. */
#define VMX_EXIT_INT_WINDOW                                     7
/** NMI window exiting. */
#define VMX_EXIT_NMI_WINDOW                                     8
/** Task switch. */
#define VMX_EXIT_TASK_SWITCH                                    9
/** CPUID. */
#define VMX_EXIT_CPUID                                          10
/** GETSEC. */
#define VMX_EXIT_GETSEC                                         11
/** HLT. */
#define VMX_EXIT_HLT                                            12
/** INVD. */
#define VMX_EXIT_INVD                                           13
/** INVLPG. */
#define VMX_EXIT_INVLPG                                         14
/** RDPMC. */
#define VMX_EXIT_RDPMC                                          15
/** RDTSC. */
#define VMX_EXIT_RDTSC                                          16
/** RSM in SMM. */
#define VMX_EXIT_RSM                                            17
/** VMCALL. */
#define VMX_EXIT_VMCALL                                         18
/** VMCLEAR. */
#define VMX_EXIT_VMCLEAR                                        19
/** VMLAUNCH. */
#define VMX_EXIT_VMLAUNCH                                       20
/** VMPTRLD. */
#define VMX_EXIT_VMPTRLD                                        21
/** VMPTRST. */
#define VMX_EXIT_VMPTRST                                        22
/** VMREAD. */
#define VMX_EXIT_VMREAD                                         23
/** VMRESUME. */
#define VMX_EXIT_VMRESUME                                       24
/** VMWRITE. */
#define VMX_EXIT_VMWRITE                                        25
/** VMXOFF. */
#define VMX_EXIT_VMXOFF                                         26
/** VMXON. */
#define VMX_EXIT_VMXON                                          27
/** Control-register accesses. */
#define VMX_EXIT_MOV_CRX                                        28
/** Debug-register accesses. */
#define VMX_EXIT_MOV_DRX                                        29
/** I/O instruction. */
#define VMX_EXIT_IO_INSTR                                       30
/** RDMSR. */
#define VMX_EXIT_RDMSR                                          31
/** WRMSR. */
#define VMX_EXIT_WRMSR                                          32
/** VM-entry failure due to invalid guest state. */
#define VMX_EXIT_ERR_INVALID_GUEST_STATE                        33
/** VM-entry failure due to MSR loading. */
#define VMX_EXIT_ERR_MSR_LOAD                                   34
/** MWAIT. */
#define VMX_EXIT_MWAIT                                          36
/** VM-exit due to monitor trap flag. */
#define VMX_EXIT_MTF                                            37
/** MONITOR. */
#define VMX_EXIT_MONITOR                                        39
/** PAUSE. */
#define VMX_EXIT_PAUSE                                          40
/** VM-entry failure due to machine-check. */
#define VMX_EXIT_ERR_MACHINE_CHECK                              41
/** TPR below threshold. Guest software executed MOV to CR8. */
#define VMX_EXIT_TPR_BELOW_THRESHOLD                            43
/** VM-exit due to guest accessing physical address in the APIC-access page. */
#define VMX_EXIT_APIC_ACCESS                                    44
/** VM-exit due to EOI virtualization. */
#define VMX_EXIT_VIRTUALIZED_EOI                                45
/** Access to GDTR/IDTR using LGDT, LIDT, SGDT or SIDT. */
#define VMX_EXIT_GDTR_IDTR_ACCESS                               46
/** Access to LDTR/TR due to LLDT, LTR, SLDT, or STR. */
#define VMX_EXIT_LDTR_TR_ACCESS                                 47
/** EPT violation. */
#define VMX_EXIT_EPT_VIOLATION                                  48
/** EPT misconfiguration. */
#define VMX_EXIT_EPT_MISCONFIG                                  49
/** INVEPT. */
#define VMX_EXIT_INVEPT                                         50
/** RDTSCP. */
#define VMX_EXIT_RDTSCP                                         51
/** VMX-preemption timer expired. */
#define VMX_EXIT_PREEMPT_TIMER                                  52
/** INVVPID. */
#define VMX_EXIT_INVVPID                                        53
/** WBINVD. */
#define VMX_EXIT_WBINVD                                         54
/** XSETBV. */
#define VMX_EXIT_XSETBV                                         55
/** Guest completed write to virtual-APIC. */
#define VMX_EXIT_APIC_WRITE                                     56
/** RDRAND. */
#define VMX_EXIT_RDRAND                                         57
/** INVPCID. */
#define VMX_EXIT_INVPCID                                        58
/** VMFUNC. */
#define VMX_EXIT_VMFUNC                                         59
/** ENCLS. */
#define VMX_EXIT_ENCLS                                          60
/** RDSEED. */
#define VMX_EXIT_RDSEED                                         61
/** Page-modification log full. */
#define VMX_EXIT_PML_FULL                                       62
/** XSAVES. */
#define VMX_EXIT_XSAVES                                         63
/** XRSTORS. */
#define VMX_EXIT_XRSTORS                                        64
/** SPP-related event (SPP miss or misconfiguration). */
#define VMX_EXIT_SPP_EVENT                                      66
/* UMWAIT. */
#define VMX_EXIT_UMWAIT                                         67
/** TPAUSE. */
#define VMX_EXIT_TPAUSE                                         68
/** LOADIWKEY. */
#define VMX_EXIT_LOADIWKEY                                      69
/** The maximum VM-exit value (inclusive). */
#define VMX_EXIT_MAX                                            (VMX_EXIT_LOADIWKEY)
/** @} */


/** @name VM Instruction Errors.
 * In accordance with the VT-x spec.
 * See Intel spec. "30.4 VM Instruction Error Numbers"
 * @{
 */
typedef enum
{
    /** VMCALL executed in VMX root operation. */
    VMXINSTRERR_VMCALL_VMXROOTMODE             = 1,
    /** VMCLEAR with invalid physical address. */
    VMXINSTRERR_VMCLEAR_INVALID_PHYSADDR       = 2,
    /** VMCLEAR with VMXON pointer. */
    VMXINSTRERR_VMCLEAR_VMXON_PTR              = 3,
    /** VMLAUNCH with non-clear VMCS. */
    VMXINSTRERR_VMLAUNCH_NON_CLEAR_VMCS        = 4,
    /** VMRESUME with non-launched VMCS. */
    VMXINSTRERR_VMRESUME_NON_LAUNCHED_VMCS     = 5,
    /** VMRESUME after VMXOFF (VMXOFF and VMXON between VMLAUNCH and VMRESUME). */
    VMXINSTRERR_VMRESUME_AFTER_VMXOFF          = 6,
    /** VM-entry with invalid control field(s). */
    VMXINSTRERR_VMENTRY_INVALID_CTLS           = 7,
    /** VM-entry with invalid host-state field(s). */
    VMXINSTRERR_VMENTRY_INVALID_HOST_STATE     = 8,
    /** VMPTRLD with invalid physical address. */
    VMXINSTRERR_VMPTRLD_INVALID_PHYSADDR       = 9,
    /** VMPTRLD with VMXON pointer. */
    VMXINSTRERR_VMPTRLD_VMXON_PTR              = 10,
    /** VMPTRLD with incorrect VMCS revision identifier. */
    VMXINSTRERR_VMPTRLD_INCORRECT_VMCS_REV     = 11,
    /** VMREAD from unsupported VMCS component. */
    VMXINSTRERR_VMREAD_INVALID_COMPONENT       = 12,
    /** VMWRITE to unsupported VMCS component. */
    VMXINSTRERR_VMWRITE_INVALID_COMPONENT      = 12,
    /** VMWRITE to read-only VMCS component. */
    VMXINSTRERR_VMWRITE_RO_COMPONENT           = 13,
    /** VMXON executed in VMX root operation. */
    VMXINSTRERR_VMXON_IN_VMXROOTMODE           = 15,
    /** VM-entry with invalid executive-VMCS pointer. */
    VMXINSTRERR_VMENTRY_EXEC_VMCS_INVALID_PTR  = 16,
    /** VM-entry with non-launched executive VMCS. */
    VMXINSTRERR_VMENTRY_EXEC_VMCS_NON_LAUNCHED = 17,
    /** VM-entry with executive-VMCS pointer not VMXON pointer. */
    VMXINSTRERR_VMENTRY_EXEC_VMCS_PTR          = 18,
    /** VMCALL with non-clear VMCS. */
    VMXINSTRERR_VMCALL_NON_CLEAR_VMCS          = 19,
    /** VMCALL with invalid VM-exit control fields. */
    VMXINSTRERR_VMCALL_INVALID_EXITCTLS        = 20,
    /** VMCALL with incorrect MSEG revision identifier. */
    VMXINSTRERR_VMCALL_INVALID_MSEG_ID         = 22,
    /** VMXOFF under dual-monitor treatment of SMIs and SMM. */
    VMXINSTRERR_VMXOFF_DUAL_MON                = 23,
    /** VMCALL with invalid SMM-monitor features. */
    VMXINSTRERR_VMCALL_INVALID_SMMCTLS         = 24,
    /** VM-entry with invalid VM-execution control fields in executive VMCS. */
    VMXINSTRERR_VMENTRY_EXEC_VMCS_INVALID_CTLS = 25,
    /** VM-entry with events blocked by MOV SS. */
    VMXINSTRERR_VMENTRY_BLOCK_MOVSS            = 26,
    /** Invalid operand to INVEPT/INVVPID. */
    VMXINSTRERR_INVEPT_INVVPID_INVALID_OPERAND = 28
} VMXINSTRERR;
/** @} */


/** @name VMX abort reasons.
 * In accordance with the VT-x spec.
 * See Intel spec. "27.7 VMX Aborts".
 * Update HMGetVmxAbortDesc() if new reasons are added.
 * @{
 */
typedef enum
{
    /** None - don't use this / uninitialized value. */
    VMXABORT_NONE                  = 0,
    /** VMX abort caused during saving of guest MSRs. */
    VMXABORT_SAVE_GUEST_MSRS       = 1,
    /** VMX abort caused during host PDPTE checks. */
    VMXBOART_HOST_PDPTE            = 2,
    /** VMX abort caused due to current VMCS being corrupted. */
    VMXABORT_CURRENT_VMCS_CORRUPT  = 3,
    /** VMX abort caused during loading of host MSRs. */
    VMXABORT_LOAD_HOST_MSR         = 4,
    /** VMX abort caused due to a machine-check exception during VM-exit. */
    VMXABORT_MACHINE_CHECK_XCPT    = 5,
    /** VMX abort caused due to invalid return from long mode. */
    VMXABORT_HOST_NOT_IN_LONG_MODE = 6,
    /* Type size hack. */
    VMXABORT_32BIT_HACK            = 0x7fffffff
} VMXABORT;
AssertCompileSize(VMXABORT, 4);
/** @} */


/** @name VMX MSR - Basic VMX information.
 * @{
 */
/** VMCS (and related regions) memory type - Uncacheable. */
#define VMX_BASIC_MEM_TYPE_UC                                   0
/** VMCS (and related regions) memory type - Write back. */
#define VMX_BASIC_MEM_TYPE_WB                                   6
/** Width of physical addresses used for VMCS and associated memory regions
 *  (1=32-bit, 0=processor's physical address width). */
#define VMX_BASIC_PHYSADDR_WIDTH_32BIT                          RT_BIT_64(48)

/** Bit fields for MSR_IA32_VMX_BASIC. */
/** VMCS revision identifier used by the processor. */
#define VMX_BF_BASIC_VMCS_ID_SHIFT                              0
#define VMX_BF_BASIC_VMCS_ID_MASK                               UINT64_C(0x000000007fffffff)
/** Bit 31 is reserved and RAZ. */
#define VMX_BF_BASIC_RSVD_32_SHIFT                              31
#define VMX_BF_BASIC_RSVD_32_MASK                               UINT64_C(0x0000000080000000)
/** VMCS size in bytes. */
#define VMX_BF_BASIC_VMCS_SIZE_SHIFT                            32
#define VMX_BF_BASIC_VMCS_SIZE_MASK                             UINT64_C(0x00001fff00000000)
/** Bits 45:47 are reserved. */
#define VMX_BF_BASIC_RSVD_45_47_SHIFT                           45
#define VMX_BF_BASIC_RSVD_45_47_MASK                            UINT64_C(0x0000e00000000000)
/** Width of physical addresses used for the VMCS and associated memory regions
 *  (always 0 on CPUs that support Intel 64 architecture). */
#define VMX_BF_BASIC_PHYSADDR_WIDTH_SHIFT                       48
#define VMX_BF_BASIC_PHYSADDR_WIDTH_MASK                        UINT64_C(0x0001000000000000)
/** Dual-monitor treatment of SMI and SMM supported. */
#define VMX_BF_BASIC_DUAL_MON_SHIFT                             49
#define VMX_BF_BASIC_DUAL_MON_MASK                              UINT64_C(0x0002000000000000)
/** Memory type that must be used for the VMCS and associated memory regions. */
#define VMX_BF_BASIC_VMCS_MEM_TYPE_SHIFT                        50
#define VMX_BF_BASIC_VMCS_MEM_TYPE_MASK                         UINT64_C(0x003c000000000000)
/** VM-exit instruction information for INS/OUTS. */
#define VMX_BF_BASIC_VMCS_INS_OUTS_SHIFT                        54
#define VMX_BF_BASIC_VMCS_INS_OUTS_MASK                         UINT64_C(0x0040000000000000)
/** Whether 'true' VMX controls MSRs are supported for handling of default1 class
 *  bits in VMX control MSRs. */
#define VMX_BF_BASIC_TRUE_CTLS_SHIFT                            55
#define VMX_BF_BASIC_TRUE_CTLS_MASK                             UINT64_C(0x0080000000000000)
/** Whether VM-entry can delivery error code for all hardware exception vectors. */
#define VMX_BF_BASIC_XCPT_ERRCODE_SHIFT                         56
#define VMX_BF_BASIC_XCPT_ERRCODE_MASK                          UINT64_C(0x0100000000000000)
/** Bits 57:63 are reserved and RAZ. */
#define VMX_BF_BASIC_RSVD_56_63_SHIFT                           57
#define VMX_BF_BASIC_RSVD_56_63_MASK                            UINT64_C(0xfe00000000000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_BASIC_, UINT64_C(0), UINT64_MAX,
                            (VMCS_ID, RSVD_32, VMCS_SIZE, RSVD_45_47, PHYSADDR_WIDTH, DUAL_MON, VMCS_MEM_TYPE,
                             VMCS_INS_OUTS, TRUE_CTLS, XCPT_ERRCODE, RSVD_56_63));
/** @} */


/** @name VMX MSR - Miscellaneous data.
 * @{
 */
/** Whether VM-exit stores EFER.LMA into the "IA32e mode guest" field. */
#define VMX_MISC_EXIT_SAVE_EFER_LMA                             RT_BIT(5)
/** Whether Intel PT is supported in VMX operation. */
#define VMX_MISC_INTEL_PT                                       RT_BIT(14)
/** Whether VMWRITE to any valid VMCS field incl. read-only fields, otherwise
 * VMWRITE cannot modify read-only VM-exit information fields. */
#define VMX_MISC_VMWRITE_ALL                                    RT_BIT(29)
/** Whether VM-entry can inject software interrupts, INT1 (ICEBP) with 0-length
 *  instructions. */
#define VMX_MISC_ENTRY_INJECT_SOFT_INT                          RT_BIT(30)
/** Maximum number of MSRs in the auto-load/store MSR areas, (n+1) * 512. */
#define VMX_MISC_MAX_MSRS(a_MiscMsr)                            (512 * (RT_BF_GET((a_MiscMsr), VMX_BF_MISC_MAX_MSRS) + 1))
/** Maximum CR3-target count supported by the CPU. */
#define VMX_MISC_CR3_TARGET_COUNT(a_MiscMsr)                    (((a) >> 16) & 0xff)

/** Bit fields for MSR_IA32_VMX_MISC. */
/** Relationship between the preemption timer and tsc. */
#define VMX_BF_MISC_PREEMPT_TIMER_TSC_SHIFT                     0
#define VMX_BF_MISC_PREEMPT_TIMER_TSC_MASK                      UINT64_C(0x000000000000001f)
/** Whether VM-exit stores EFER.LMA into the "IA32e mode guest" field. */
#define VMX_BF_MISC_EXIT_SAVE_EFER_LMA_SHIFT                    5
#define VMX_BF_MISC_EXIT_SAVE_EFER_LMA_MASK                     UINT64_C(0x0000000000000020)
/** Activity states supported by the implementation. */
#define VMX_BF_MISC_ACTIVITY_STATES_SHIFT                       6
#define VMX_BF_MISC_ACTIVITY_STATES_MASK                        UINT64_C(0x00000000000001c0)
/** Bits 9:13 is reserved and RAZ. */
#define VMX_BF_MISC_RSVD_9_13_SHIFT                             9
#define VMX_BF_MISC_RSVD_9_13_MASK                              UINT64_C(0x0000000000003e00)
/** Whether Intel PT (Processor Trace) can be used in VMX operation. */
#define VMX_BF_MISC_INTEL_PT_SHIFT                              14
#define VMX_BF_MISC_INTEL_PT_MASK                               UINT64_C(0x0000000000004000)
/** Whether RDMSR can be used to read IA32_SMBASE MSR in SMM. */
#define VMX_BF_MISC_SMM_READ_SMBASE_MSR_SHIFT                   15
#define VMX_BF_MISC_SMM_READ_SMBASE_MSR_MASK                    UINT64_C(0x0000000000008000)
/** Number of CR3 target values supported by the processor. (0-256) */
#define VMX_BF_MISC_CR3_TARGET_SHIFT                            16
#define VMX_BF_MISC_CR3_TARGET_MASK                             UINT64_C(0x0000000001ff0000)
/** Maximum number of MSRs in the VMCS. */
#define VMX_BF_MISC_MAX_MSRS_SHIFT                              25
#define VMX_BF_MISC_MAX_MSRS_MASK                               UINT64_C(0x000000000e000000)
/** Whether IA32_SMM_MONITOR_CTL MSR can be modified to allow VMXOFF to block
 *  SMIs. */
#define VMX_BF_MISC_VMXOFF_BLOCK_SMI_SHIFT                      28
#define VMX_BF_MISC_VMXOFF_BLOCK_SMI_MASK                       UINT64_C(0x0000000010000000)
/** Whether VMWRITE to any valid VMCS field incl. read-only fields, otherwise
 * VMWRITE cannot modify read-only VM-exit information fields. */
#define VMX_BF_MISC_VMWRITE_ALL_SHIFT                           29
#define VMX_BF_MISC_VMWRITE_ALL_MASK                            UINT64_C(0x0000000020000000)
/** Whether VM-entry can inject software interrupts, INT1 (ICEBP) with 0-length
 *  instructions. */
#define VMX_BF_MISC_ENTRY_INJECT_SOFT_INT_SHIFT                 30
#define VMX_BF_MISC_ENTRY_INJECT_SOFT_INT_MASK                  UINT64_C(0x0000000040000000)
/** Bit 31 is reserved and RAZ. */
#define VMX_BF_MISC_RSVD_31_SHIFT                               31
#define VMX_BF_MISC_RSVD_31_MASK                                UINT64_C(0x0000000080000000)
/** 32-bit MSEG revision ID used by the processor. */
#define VMX_BF_MISC_MSEG_ID_SHIFT                               32
#define VMX_BF_MISC_MSEG_ID_MASK                                UINT64_C(0xffffffff00000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_MISC_, UINT64_C(0), UINT64_MAX,
                            (PREEMPT_TIMER_TSC, EXIT_SAVE_EFER_LMA, ACTIVITY_STATES, RSVD_9_13, INTEL_PT, SMM_READ_SMBASE_MSR,
                             CR3_TARGET, MAX_MSRS, VMXOFF_BLOCK_SMI, VMWRITE_ALL, ENTRY_INJECT_SOFT_INT, RSVD_31, MSEG_ID));
/** @} */

/** @name VMX MSR - VMCS enumeration.
 * Bit fields for MSR_IA32_VMX_VMCS_ENUM.
 * @{
 */
/** Bit 0 is reserved and RAZ. */
#define VMX_BF_VMCS_ENUM_RSVD_0_SHIFT                           0
#define VMX_BF_VMCS_ENUM_RSVD_0_MASK                            UINT64_C(0x0000000000000001)
/** Highest index value used in VMCS field encoding. */
#define VMX_BF_VMCS_ENUM_HIGHEST_IDX_SHIFT                      1
#define VMX_BF_VMCS_ENUM_HIGHEST_IDX_MASK                       UINT64_C(0x00000000000003fe)
/** Bit 10:63 is reserved and RAZ. */
#define VMX_BF_VMCS_ENUM_RSVD_10_63_SHIFT                       10
#define VMX_BF_VMCS_ENUM_RSVD_10_63_MASK                        UINT64_C(0xfffffffffffffc00)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_VMCS_ENUM_, UINT64_C(0), UINT64_MAX,
                            (RSVD_0, HIGHEST_IDX, RSVD_10_63));
/** @} */


/** @name VMX MSR - VM Functions.
 * Bit fields for MSR_IA32_VMX_VMFUNC.
 * @{
 */
/** EPTP-switching function changes the value of the EPTP to one chosen from the EPTP list. */
#define VMX_BF_VMFUNC_EPTP_SWITCHING_SHIFT                      0
#define VMX_BF_VMFUNC_EPTP_SWITCHING_MASK                       UINT64_C(0x0000000000000001)
/** Bits 1:63 are reserved and RAZ. */
#define VMX_BF_VMFUNC_RSVD_1_63_SHIFT                           1
#define VMX_BF_VMFUNC_RSVD_1_63_MASK                            UINT64_C(0xfffffffffffffffe)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_VMFUNC_, UINT64_C(0), UINT64_MAX,
                            (EPTP_SWITCHING, RSVD_1_63));
/** @} */


/** @name VMX MSR - EPT/VPID capabilities.
 * @{
 */
/** Supports execute-only translations by EPT. */
#define MSR_IA32_VMX_EPT_VPID_CAP_RWX_X_ONLY                    RT_BIT_64(0)
/** Supports page-walk length of 4. */
#define MSR_IA32_VMX_EPT_VPID_CAP_PAGE_WALK_LENGTH_4            RT_BIT_64(6)
/** Supports page-walk length of 5. */
#define MSR_IA32_VMX_EPT_VPID_CAP_PAGE_WALK_LENGTH_5            RT_BIT_64(7)
/** Supports EPT paging-structure memory type to be uncacheable. */
#define MSR_IA32_VMX_EPT_VPID_CAP_MEMTYPE_UC                    RT_BIT_64(8)
/** Supports EPT paging structure memory type to be write-back. */
#define MSR_IA32_VMX_EPT_VPID_CAP_MEMTYPE_WB                    RT_BIT_64(14)
/** Supports EPT PDE to map a 2 MB page. */
#define MSR_IA32_VMX_EPT_VPID_CAP_PDE_2M                        RT_BIT_64(16)
/** Supports EPT PDPTE to map a 1 GB page. */
#define MSR_IA32_VMX_EPT_VPID_CAP_PDPTE_1G                      RT_BIT_64(17)
/** Supports INVEPT instruction. */
#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT                        RT_BIT_64(20)
/** Supports accessed and dirty flags for EPT. */
#define MSR_IA32_VMX_EPT_VPID_CAP_ACCESS_DIRTY                  RT_BIT_64(21)
/** Supports advanced VM-exit info. for EPT violations. */
#define MSR_IA32_VMX_EPT_VPID_CAP_ADVEXITINFO_EPT_VIOLATION     RT_BIT_64(22)
/** Supports supervisor shadow-stack control. */
#define MSR_IA32_VMX_EPT_VPID_CAP_SUPER_SHW_STACK               RT_BIT_64(23)
/** Supports single-context INVEPT type. */
#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_SINGLE_CONTEXT         RT_BIT_64(25)
/** Supports all-context INVEPT type. */
#define MSR_IA32_VMX_EPT_VPID_CAP_INVEPT_ALL_CONTEXTS           RT_BIT_64(26)
/** Supports INVVPID instruction. */
#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID                       RT_BIT_64(32)
/** Supports individual-address INVVPID type. */
#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_INDIV_ADDR            RT_BIT_64(40)
/** Supports single-context INVVPID type. */
#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT        RT_BIT_64(41)
/** Supports all-context INVVPID type. */
#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_ALL_CONTEXTS          RT_BIT_64(42)
/** Supports singe-context-retaining-globals INVVPID type. */
#define MSR_IA32_VMX_EPT_VPID_CAP_INVVPID_SINGLE_CONTEXT_RETAIN_GLOBALS  RT_BIT_64(43)

/** Bit fields for MSR_IA32_VMX_EPT_VPID_CAP. */
#define VMX_BF_EPT_VPID_CAP_EXEC_ONLY_SHIFT                     0
#define VMX_BF_EPT_VPID_CAP_EXEC_ONLY_MASK                      UINT64_C(0x0000000000000001)
#define VMX_BF_EPT_VPID_CAP_RSVD_1_5_SHIFT                      1
#define VMX_BF_EPT_VPID_CAP_RSVD_1_5_MASK                       UINT64_C(0x000000000000003e)
#define VMX_BF_EPT_VPID_CAP_PAGE_WALK_LENGTH_4_SHIFT            6
#define VMX_BF_EPT_VPID_CAP_PAGE_WALK_LENGTH_4_MASK             UINT64_C(0x0000000000000040)
#define VMX_BF_EPT_VPID_CAP_RSVD_7_SHIFT                        7
#define VMX_BF_EPT_VPID_CAP_RSVD_7_MASK                         UINT64_C(0x0000000000000080)
#define VMX_BF_EPT_VPID_CAP_MEMTYPE_UC_SHIFT                    8
#define VMX_BF_EPT_VPID_CAP_MEMTYPE_UC_MASK                     UINT64_C(0x0000000000000100)
#define VMX_BF_EPT_VPID_CAP_RSVD_9_13_SHIFT                     9
#define VMX_BF_EPT_VPID_CAP_RSVD_9_13_MASK                      UINT64_C(0x0000000000003e00)
#define VMX_BF_EPT_VPID_CAP_MEMTYPE_WB_SHIFT                    14
#define VMX_BF_EPT_VPID_CAP_MEMTYPE_WB_MASK                     UINT64_C(0x0000000000004000)
#define VMX_BF_EPT_VPID_CAP_RSVD_15_SHIFT                       15
#define VMX_BF_EPT_VPID_CAP_RSVD_15_MASK                        UINT64_C(0x0000000000008000)
#define VMX_BF_EPT_VPID_CAP_PDE_2M_SHIFT                        16
#define VMX_BF_EPT_VPID_CAP_PDE_2M_MASK                         UINT64_C(0x0000000000010000)
#define VMX_BF_EPT_VPID_CAP_PDPTE_1G_SHIFT                      17
#define VMX_BF_EPT_VPID_CAP_PDPTE_1G_MASK                       UINT64_C(0x0000000000020000)
#define VMX_BF_EPT_VPID_CAP_RSVD_18_19_SHIFT                    18
#define VMX_BF_EPT_VPID_CAP_RSVD_18_19_MASK                     UINT64_C(0x00000000000c0000)
#define VMX_BF_EPT_VPID_CAP_INVEPT_SHIFT                        20
#define VMX_BF_EPT_VPID_CAP_INVEPT_MASK                         UINT64_C(0x0000000000100000)
#define VMX_BF_EPT_VPID_CAP_ACCESS_DIRTY_SHIFT                  21
#define VMX_BF_EPT_VPID_CAP_ACCESS_DIRTY_MASK                   UINT64_C(0x0000000000200000)
#define VMX_BF_EPT_VPID_CAP_ADVEXITINFO_EPT_VIOLATION_SHIFT     22
#define VMX_BF_EPT_VPID_CAP_ADVEXITINFO_EPT_VIOLATION_MASK      UINT64_C(0x0000000000400000)
#define VMX_BF_EPT_VPID_CAP_SUPER_SHW_STACK_SHIFT               23
#define VMX_BF_EPT_VPID_CAP_SUPER_SHW_STACK_MASK                UINT64_C(0x0000000000800000)
#define VMX_BF_EPT_VPID_CAP_RSVD_24_SHIFT                       24
#define VMX_BF_EPT_VPID_CAP_RSVD_24_MASK                        UINT64_C(0x0000000001000000)
#define VMX_BF_EPT_VPID_CAP_INVEPT_SINGLE_CTX_SHIFT             25
#define VMX_BF_EPT_VPID_CAP_INVEPT_SINGLE_CTX_MASK              UINT64_C(0x0000000002000000)
#define VMX_BF_EPT_VPID_CAP_INVEPT_ALL_CTX_SHIFT                26
#define VMX_BF_EPT_VPID_CAP_INVEPT_ALL_CTX_MASK                 UINT64_C(0x0000000004000000)
#define VMX_BF_EPT_VPID_CAP_RSVD_27_31_SHIFT                    27
#define VMX_BF_EPT_VPID_CAP_RSVD_27_31_MASK                     UINT64_C(0x00000000f8000000)
#define VMX_BF_EPT_VPID_CAP_INVVPID_SHIFT                       32
#define VMX_BF_EPT_VPID_CAP_INVVPID_MASK                        UINT64_C(0x0000000100000000)
#define VMX_BF_EPT_VPID_CAP_RSVD_33_39_SHIFT                    33
#define VMX_BF_EPT_VPID_CAP_RSVD_33_39_MASK                     UINT64_C(0x000000fe00000000)
#define VMX_BF_EPT_VPID_CAP_INVVPID_INDIV_ADDR_SHIFT            40
#define VMX_BF_EPT_VPID_CAP_INVVPID_INDIV_ADDR_MASK             UINT64_C(0x0000010000000000)
#define VMX_BF_EPT_VPID_CAP_INVVPID_SINGLE_CTX_SHIFT            41
#define VMX_BF_EPT_VPID_CAP_INVVPID_SINGLE_CTX_MASK             UINT64_C(0x0000020000000000)
#define VMX_BF_EPT_VPID_CAP_INVVPID_ALL_CTX_SHIFT               42
#define VMX_BF_EPT_VPID_CAP_INVVPID_ALL_CTX_MASK                UINT64_C(0x0000040000000000)
#define VMX_BF_EPT_VPID_CAP_INVVPID_SINGLE_CTX_RETAIN_GLOBALS_SHIFT 43
#define VMX_BF_EPT_VPID_CAP_INVVPID_SINGLE_CTX_RETAIN_GLOBALS_MASK  UINT64_C(0x0000080000000000)
#define VMX_BF_EPT_VPID_CAP_RSVD_44_63_SHIFT                    44
#define VMX_BF_EPT_VPID_CAP_RSVD_44_63_MASK                     UINT64_C(0xfffff00000000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EPT_VPID_CAP_, UINT64_C(0), UINT64_MAX,
                            (EXEC_ONLY, RSVD_1_5, PAGE_WALK_LENGTH_4, RSVD_7, MEMTYPE_UC, RSVD_9_13, MEMTYPE_WB, RSVD_15, PDE_2M,
                             PDPTE_1G, RSVD_18_19, INVEPT, ACCESS_DIRTY, ADVEXITINFO_EPT_VIOLATION, SUPER_SHW_STACK, RSVD_24,
                             INVEPT_SINGLE_CTX, INVEPT_ALL_CTX, RSVD_27_31, INVVPID, RSVD_33_39, INVVPID_INDIV_ADDR,
                             INVVPID_SINGLE_CTX, INVVPID_ALL_CTX, INVVPID_SINGLE_CTX_RETAIN_GLOBALS, RSVD_44_63));
/** @} */


/** @name Extended Page Table Pointer (EPTP)
 * In accordance with the VT-x spec.
 * See Intel spec. 23.6.11 "Extended-Page-Table Pointer (EPTP)".
 * @{
 */
/** EPTP memory type: Uncachable. */
#define VMX_EPTP_MEMTYPE_UC                                     0
/** EPTP memory type: Write Back. */
#define VMX_EPTP_MEMTYPE_WB                                     6
/** Page-walk length for PML4 (4-level paging). */
#define VMX_EPTP_PAGE_WALK_LENGTH_4                             3

/** Bit fields for EPTP. */
#define VMX_BF_EPTP_MEMTYPE_SHIFT                               0
#define VMX_BF_EPTP_MEMTYPE_MASK                                UINT64_C(0x0000000000000007)
#define VMX_BF_EPTP_PAGE_WALK_LENGTH_SHIFT                      3
#define VMX_BF_EPTP_PAGE_WALK_LENGTH_MASK                       UINT64_C(0x0000000000000038)
#define VMX_BF_EPTP_ACCESS_DIRTY_SHIFT                          6
#define VMX_BF_EPTP_ACCESS_DIRTY_MASK                           UINT64_C(0x0000000000000040)
#define VMX_BF_EPTP_SUPER_SHW_STACK_SHIFT                       7
#define VMX_BF_EPTP_SUPER_SHW_STACK_MASK                        UINT64_C(0x0000000000000080)
#define VMX_BF_EPTP_RSVD_8_11_SHIFT                             8
#define VMX_BF_EPTP_RSVD_8_11_MASK                              UINT64_C(0x0000000000000f00)
#define VMX_BF_EPTP_PML4_TABLE_ADDR_SHIFT                       12
#define VMX_BF_EPTP_PML4_TABLE_ADDR_MASK                        UINT64_C(0xfffffffffffff000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EPTP_, UINT64_C(0), UINT64_MAX,
                            (MEMTYPE, PAGE_WALK_LENGTH, ACCESS_DIRTY, SUPER_SHW_STACK, RSVD_8_11, PML4_TABLE_ADDR));

/* Mask of valid EPTP bits sans physically non-addressable bits. */
#define VMX_EPTP_VALID_MASK                                     (  VMX_BF_EPTP_MEMTYPE_MASK          \
                                                                 | VMX_BF_EPTP_PAGE_WALK_LENGTH_MASK \
                                                                 | VMX_BF_EPTP_ACCESS_DIRTY_MASK     \
                                                                 | VMX_BF_EPTP_SUPER_SHW_STACK_MASK  \
                                                                 | VMX_BF_EPTP_PML4_TABLE_ADDR_MASK)
/** @} */


/** @name VMCS fields and encoding.
 *
 *  When adding a new field:
 *    - Always add it to g_aVmcsFields.
 *    - Consider if it needs to be added to VMXVVMCS.
 * @{
 */
/** 16-bit control fields.  */
#define VMX_VMCS16_VPID                                         0x0000
#define VMX_VMCS16_POSTED_INT_NOTIFY_VECTOR                     0x0002
#define VMX_VMCS16_EPTP_INDEX                                   0x0004
#define VMX_VMCS16_HLAT_PREFIX_SIZE                             0x0006

/** 16-bit guest-state fields.  */
#define VMX_VMCS16_GUEST_ES_SEL                                 0x0800
#define VMX_VMCS16_GUEST_CS_SEL                                 0x0802
#define VMX_VMCS16_GUEST_SS_SEL                                 0x0804
#define VMX_VMCS16_GUEST_DS_SEL                                 0x0806
#define VMX_VMCS16_GUEST_FS_SEL                                 0x0808
#define VMX_VMCS16_GUEST_GS_SEL                                 0x080a
#define VMX_VMCS16_GUEST_LDTR_SEL                               0x080c
#define VMX_VMCS16_GUEST_TR_SEL                                 0x080e
#define VMX_VMCS16_GUEST_INTR_STATUS                            0x0810
#define VMX_VMCS16_GUEST_PML_INDEX                              0x0812

/** 16-bits host-state fields.  */
#define VMX_VMCS16_HOST_ES_SEL                                  0x0c00
#define VMX_VMCS16_HOST_CS_SEL                                  0x0c02
#define VMX_VMCS16_HOST_SS_SEL                                  0x0c04
#define VMX_VMCS16_HOST_DS_SEL                                  0x0c06
#define VMX_VMCS16_HOST_FS_SEL                                  0x0c08
#define VMX_VMCS16_HOST_GS_SEL                                  0x0c0a
#define VMX_VMCS16_HOST_TR_SEL                                  0x0c0c

/** 64-bit control fields. */
#define VMX_VMCS64_CTRL_IO_BITMAP_A_FULL                        0x2000
#define VMX_VMCS64_CTRL_IO_BITMAP_A_HIGH                        0x2001
#define VMX_VMCS64_CTRL_IO_BITMAP_B_FULL                        0x2002
#define VMX_VMCS64_CTRL_IO_BITMAP_B_HIGH                        0x2003
#define VMX_VMCS64_CTRL_MSR_BITMAP_FULL                         0x2004
#define VMX_VMCS64_CTRL_MSR_BITMAP_HIGH                         0x2005
#define VMX_VMCS64_CTRL_EXIT_MSR_STORE_FULL                     0x2006
#define VMX_VMCS64_CTRL_EXIT_MSR_STORE_HIGH                     0x2007
#define VMX_VMCS64_CTRL_EXIT_MSR_LOAD_FULL                      0x2008
#define VMX_VMCS64_CTRL_EXIT_MSR_LOAD_HIGH                      0x2009
#define VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_FULL                     0x200a
#define VMX_VMCS64_CTRL_ENTRY_MSR_LOAD_HIGH                     0x200b
#define VMX_VMCS64_CTRL_EXEC_VMCS_PTR_FULL                      0x200c
#define VMX_VMCS64_CTRL_EXEC_VMCS_PTR_HIGH                      0x200d
#define VMX_VMCS64_CTRL_EXEC_PML_ADDR_FULL                      0x200e
#define VMX_VMCS64_CTRL_EXEC_PML_ADDR_HIGH                      0x200f
#define VMX_VMCS64_CTRL_TSC_OFFSET_FULL                         0x2010
#define VMX_VMCS64_CTRL_TSC_OFFSET_HIGH                         0x2011
#define VMX_VMCS64_CTRL_VIRT_APIC_PAGEADDR_FULL                 0x2012
#define VMX_VMCS64_CTRL_VIRT_APIC_PAGEADDR_HIGH                 0x2013
#define VMX_VMCS64_CTRL_APIC_ACCESSADDR_FULL                    0x2014
#define VMX_VMCS64_CTRL_APIC_ACCESSADDR_HIGH                    0x2015
#define VMX_VMCS64_CTRL_POSTED_INTR_DESC_FULL                   0x2016
#define VMX_VMCS64_CTRL_POSTED_INTR_DESC_HIGH                   0x2017
#define VMX_VMCS64_CTRL_VMFUNC_CTRLS_FULL                       0x2018
#define VMX_VMCS64_CTRL_VMFUNC_CTRLS_HIGH                       0x2019
#define VMX_VMCS64_CTRL_EPTP_FULL                               0x201a
#define VMX_VMCS64_CTRL_EPTP_HIGH                               0x201b
#define VMX_VMCS64_CTRL_EOI_BITMAP_0_FULL                       0x201c
#define VMX_VMCS64_CTRL_EOI_BITMAP_0_HIGH                       0x201d
#define VMX_VMCS64_CTRL_EOI_BITMAP_1_FULL                       0x201e
#define VMX_VMCS64_CTRL_EOI_BITMAP_1_HIGH                       0x201f
#define VMX_VMCS64_CTRL_EOI_BITMAP_2_FULL                       0x2020
#define VMX_VMCS64_CTRL_EOI_BITMAP_2_HIGH                       0x2021
#define VMX_VMCS64_CTRL_EOI_BITMAP_3_FULL                       0x2022
#define VMX_VMCS64_CTRL_EOI_BITMAP_3_HIGH                       0x2023
#define VMX_VMCS64_CTRL_EPTP_LIST_FULL                          0x2024
#define VMX_VMCS64_CTRL_EPTP_LIST_HIGH                          0x2025
#define VMX_VMCS64_CTRL_VMREAD_BITMAP_FULL                      0x2026
#define VMX_VMCS64_CTRL_VMREAD_BITMAP_HIGH                      0x2027
#define VMX_VMCS64_CTRL_VMWRITE_BITMAP_FULL                     0x2028
#define VMX_VMCS64_CTRL_VMWRITE_BITMAP_HIGH                     0x2029
#define VMX_VMCS64_CTRL_VE_XCPT_INFO_ADDR_FULL                  0x202a
#define VMX_VMCS64_CTRL_VE_XCPT_INFO_ADDR_HIGH                  0x202b
#define VMX_VMCS64_CTRL_XSS_EXITING_BITMAP_FULL                 0x202c
#define VMX_VMCS64_CTRL_XSS_EXITING_BITMAP_HIGH                 0x202d
#define VMX_VMCS64_CTRL_ENCLS_EXITING_BITMAP_FULL               0x202e
#define VMX_VMCS64_CTRL_ENCLS_EXITING_BITMAP_HIGH               0x202f
#define VMX_VMCS64_CTRL_SPPTP_FULL                              0x2030
#define VMX_VMCS64_CTRL_SPPTP_HIGH                              0x2031
#define VMX_VMCS64_CTRL_TSC_MULTIPLIER_FULL                     0x2032
#define VMX_VMCS64_CTRL_TSC_MULTIPLIER_HIGH                     0x2033
#define VMX_VMCS64_CTRL_PROC_EXEC3_FULL                         0x2034
#define VMX_VMCS64_CTRL_PROC_EXEC3_HIGH                         0x2035
#define VMX_VMCS64_CTRL_ENCLV_EXITING_BITMAP_FULL               0x2036
#define VMX_VMCS64_CTRL_ENCLV_EXITING_BITMAP_HIGH               0x2037
#define VMX_VMCS64_CTRL_PCONFIG_EXITING_BITMAP_FULL             0x203e
#define VMX_VMCS64_CTRL_PCONFIG_EXITING_BITMAP_HIGH             0x203f
#define VMX_VMCS64_CTRL_HLAT_PTR_FULL                           0x2040
#define VMX_VMCS64_CTRL_HLAT_PTR_HIGH                           0x2041
#define VMX_VMCS64_CTRL_EXIT2_FULL                              0x2044
#define VMX_VMCS64_CTRL_EXIT2_HIGH                              0x2045

/** 64-bit read-only data fields.  */
#define VMX_VMCS64_RO_GUEST_PHYS_ADDR_FULL                      0x2400
#define VMX_VMCS64_RO_GUEST_PHYS_ADDR_HIGH                      0x2401

/** 64-bit guest-state fields.  */
#define VMX_VMCS64_GUEST_VMCS_LINK_PTR_FULL                     0x2800
#define VMX_VMCS64_GUEST_VMCS_LINK_PTR_HIGH                     0x2801
#define VMX_VMCS64_GUEST_DEBUGCTL_FULL                          0x2802
#define VMX_VMCS64_GUEST_DEBUGCTL_HIGH                          0x2803
#define VMX_VMCS64_GUEST_PAT_FULL                               0x2804
#define VMX_VMCS64_GUEST_PAT_HIGH                               0x2805
#define VMX_VMCS64_GUEST_EFER_FULL                              0x2806
#define VMX_VMCS64_GUEST_EFER_HIGH                              0x2807
#define VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_FULL                  0x2808
#define VMX_VMCS64_GUEST_PERF_GLOBAL_CTRL_HIGH                  0x2809
#define VMX_VMCS64_GUEST_PDPTE0_FULL                            0x280a
#define VMX_VMCS64_GUEST_PDPTE0_HIGH                            0x280b
#define VMX_VMCS64_GUEST_PDPTE1_FULL                            0x280c
#define VMX_VMCS64_GUEST_PDPTE1_HIGH                            0x280d
#define VMX_VMCS64_GUEST_PDPTE2_FULL                            0x280e
#define VMX_VMCS64_GUEST_PDPTE2_HIGH                            0x280f
#define VMX_VMCS64_GUEST_PDPTE3_FULL                            0x2810
#define VMX_VMCS64_GUEST_PDPTE3_HIGH                            0x2811
#define VMX_VMCS64_GUEST_BNDCFGS_FULL                           0x2812
#define VMX_VMCS64_GUEST_BNDCFGS_HIGH                           0x2813
#define VMX_VMCS64_GUEST_RTIT_CTL_FULL                          0x2814
#define VMX_VMCS64_GUEST_RTIT_CTL_HIGH                          0x2815
#define VMX_VMCS64_GUEST_PKRS_FULL                              0x2818
#define VMX_VMCS64_GUEST_PKRS_HIGH                              0x2819

/** 64-bit host-state fields.  */
#define VMX_VMCS64_HOST_PAT_FULL                                0x2c00
#define VMX_VMCS64_HOST_PAT_HIGH                                0x2c01
#define VMX_VMCS64_HOST_EFER_FULL                               0x2c02
#define VMX_VMCS64_HOST_EFER_HIGH                               0x2c03
#define VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_FULL                   0x2c04
#define VMX_VMCS64_HOST_PERF_GLOBAL_CTRL_HIGH                   0x2c05
#define VMX_VMCS64_HOST_PKRS_FULL                               0x2c06
#define VMX_VMCS64_HOST_PKRS_HIGH                               0x2c07

/** 32-bit control fields.  */
#define VMX_VMCS32_CTRL_PIN_EXEC                                0x4000
#define VMX_VMCS32_CTRL_PROC_EXEC                               0x4002
#define VMX_VMCS32_CTRL_EXCEPTION_BITMAP                        0x4004
#define VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MASK                    0x4006
#define VMX_VMCS32_CTRL_PAGEFAULT_ERROR_MATCH                   0x4008
#define VMX_VMCS32_CTRL_CR3_TARGET_COUNT                        0x400a
#define VMX_VMCS32_CTRL_EXIT                                    0x400c
#define VMX_VMCS32_CTRL_EXIT_MSR_STORE_COUNT                    0x400e
#define VMX_VMCS32_CTRL_EXIT_MSR_LOAD_COUNT                     0x4010
#define VMX_VMCS32_CTRL_ENTRY                                   0x4012
#define VMX_VMCS32_CTRL_ENTRY_MSR_LOAD_COUNT                    0x4014
#define VMX_VMCS32_CTRL_ENTRY_INTERRUPTION_INFO                 0x4016
#define VMX_VMCS32_CTRL_ENTRY_EXCEPTION_ERRCODE                 0x4018
#define VMX_VMCS32_CTRL_ENTRY_INSTR_LENGTH                      0x401a
#define VMX_VMCS32_CTRL_TPR_THRESHOLD                           0x401c
#define VMX_VMCS32_CTRL_PROC_EXEC2                              0x401e
#define VMX_VMCS32_CTRL_PLE_GAP                                 0x4020
#define VMX_VMCS32_CTRL_PLE_WINDOW                              0x4022

/** 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_ERROR_CODE              0x4406
#define VMX_VMCS32_RO_IDT_VECTORING_INFO                        0x4408
#define VMX_VMCS32_RO_IDT_VECTORING_ERROR_CODE                  0x440a
#define VMX_VMCS32_RO_EXIT_INSTR_LENGTH                         0x440c
#define VMX_VMCS32_RO_EXIT_INSTR_INFO                           0x440e

/** 32-bit 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_INT_STATE                              0x4824
#define VMX_VMCS32_GUEST_ACTIVITY_STATE                         0x4826
#define VMX_VMCS32_GUEST_SMBASE                                 0x4828
#define VMX_VMCS32_GUEST_SYSENTER_CS                            0x482a
#define VMX_VMCS32_PREEMPT_TIMER_VALUE                          0x482e

/** 32-bit host-state fields. */
#define VMX_VMCS32_HOST_SYSENTER_CS                             0x4C00

/** 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_VAL3                           0x600e

/** 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_RSI                                      0x6404
#define VMX_VMCS_RO_IO_RDI                                      0x6406
#define VMX_VMCS_RO_IO_RIP                                      0x6408
#define VMX_VMCS_RO_GUEST_LINEAR_ADDR                           0x640a

/** Natural-width guest-state fields. */
#define VMX_VMCS_GUEST_CR0                                      0x6800
#define VMX_VMCS_GUEST_CR3                                      0x6802
#define VMX_VMCS_GUEST_CR4                                      0x6804
#define VMX_VMCS_GUEST_ES_BASE                                  0x6806
#define VMX_VMCS_GUEST_CS_BASE                                  0x6808
#define VMX_VMCS_GUEST_SS_BASE                                  0x680a
#define VMX_VMCS_GUEST_DS_BASE                                  0x680c
#define VMX_VMCS_GUEST_FS_BASE                                  0x680e
#define VMX_VMCS_GUEST_GS_BASE                                  0x6810
#define VMX_VMCS_GUEST_LDTR_BASE                                0x6812
#define VMX_VMCS_GUEST_TR_BASE                                  0x6814
#define VMX_VMCS_GUEST_GDTR_BASE                                0x6816
#define VMX_VMCS_GUEST_IDTR_BASE                                0x6818
#define VMX_VMCS_GUEST_DR7                                      0x681a
#define VMX_VMCS_GUEST_RSP                                      0x681c
#define VMX_VMCS_GUEST_RIP                                      0x681e
#define VMX_VMCS_GUEST_RFLAGS                                   0x6820
#define VMX_VMCS_GUEST_PENDING_DEBUG_XCPTS                      0x6822
#define VMX_VMCS_GUEST_SYSENTER_ESP                             0x6824
#define VMX_VMCS_GUEST_SYSENTER_EIP                             0x6826
#define VMX_VMCS_GUEST_S_CET                                    0x6828
#define VMX_VMCS_GUEST_SSP                                      0x682a
#define VMX_VMCS_GUEST_INTR_SSP_TABLE_ADDR                      0x682c

/** 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
#define VMX_VMCS_HOST_S_CET                                     0x6c18
#define VMX_VMCS_HOST_SSP                                       0x6c1a
#define VMX_VMCS_HOST_INTR_SSP_TABLE_ADDR                       0x6c1c

#define VMX_VMCS16_GUEST_SEG_SEL(a_iSegReg)                     (VMX_VMCS16_GUEST_ES_SEL           + (a_iSegReg) * 2)
#define VMX_VMCS_GUEST_SEG_BASE(a_iSegReg)                      (VMX_VMCS_GUEST_ES_BASE            + (a_iSegReg) * 2)
#define VMX_VMCS32_GUEST_SEG_LIMIT(a_iSegReg)                   (VMX_VMCS32_GUEST_ES_LIMIT         + (a_iSegReg) * 2)
#define VMX_VMCS32_GUEST_SEG_ACCESS_RIGHTS(a_iSegReg)           (VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS + (a_iSegReg) * 2)

/**
 * VMCS field.
 * In accordance with the VT-x spec.
 */
typedef union
{
    struct
    {
        /** The access type; 0=full, 1=high of 64-bit fields. */
        uint32_t    fAccessType  : 1;
        /** The index. */
        uint32_t    u8Index      : 8;
        /** The type; 0=control, 1=VM-exit info, 2=guest-state, 3=host-state. */
        uint32_t    u2Type       : 2;
        /** Reserved (MBZ). */
        uint32_t    u1Reserved0  : 1;
        /** The width; 0=16-bit, 1=64-bit, 2=32-bit, 3=natural-width. */
        uint32_t    u2Width      : 2;
        /** Reserved (MBZ). */
        uint32_t    u18Reserved0 : 18;
    } n;

    /* The unsigned integer view. */
    uint32_t    u;
} VMXVMCSFIELD;
AssertCompileSize(VMXVMCSFIELD, 4);
/** Pointer to a VMCS field. */
typedef VMXVMCSFIELD *PVMXVMCSFIELD;
/** Pointer to a const VMCS field. */
typedef const VMXVMCSFIELD *PCVMXVMCSFIELD;

/** VMCS field: Mask of reserved bits (bits 63:15 MBZ), bit 12 is not included! */
#define VMX_VMCSFIELD_RSVD_MASK                                 UINT64_C(0xffffffffffff8000)

/** Bits fields for a VMCS field. */
#define VMX_BF_VMCSFIELD_ACCESS_TYPE_SHIFT                      0
#define VMX_BF_VMCSFIELD_ACCESS_TYPE_MASK                       UINT32_C(0x00000001)
#define VMX_BF_VMCSFIELD_INDEX_SHIFT                            1
#define VMX_BF_VMCSFIELD_INDEX_MASK                             UINT32_C(0x000003fe)
#define VMX_BF_VMCSFIELD_TYPE_SHIFT                             10
#define VMX_BF_VMCSFIELD_TYPE_MASK                              UINT32_C(0x00000c00)
#define VMX_BF_VMCSFIELD_RSVD_12_SHIFT                          12
#define VMX_BF_VMCSFIELD_RSVD_12_MASK                           UINT32_C(0x00001000)
#define VMX_BF_VMCSFIELD_WIDTH_SHIFT                            13
#define VMX_BF_VMCSFIELD_WIDTH_MASK                             UINT32_C(0x00006000)
#define VMX_BF_VMCSFIELD_RSVD_15_31_SHIFT                       15
#define VMX_BF_VMCSFIELD_RSVD_15_31_MASK                        UINT32_C(0xffff8000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_VMCSFIELD_, UINT32_C(0), UINT32_MAX,
                            (ACCESS_TYPE, INDEX, TYPE, RSVD_12, WIDTH, RSVD_15_31));

/**
 * VMCS field encoding: Access type.
 * In accordance with the VT-x spec.
 */
typedef enum
{
    VMXVMCSFIELDACCESS_FULL = 0,
    VMXVMCSFIELDACCESS_HIGH
} VMXVMCSFIELDACCESS;
AssertCompileSize(VMXVMCSFIELDACCESS, 4);
/** VMCS field encoding type: Full. */
#define VMX_VMCSFIELD_ACCESS_FULL                               0
/** VMCS field encoding type: High. */
#define VMX_VMCSFIELD_ACCESS_HIGH                               1

/**
 * VMCS field encoding: Type.
 * In accordance with the VT-x spec.
 */
typedef enum
{
    VMXVMCSFIELDTYPE_CONTROL = 0,
    VMXVMCSFIELDTYPE_VMEXIT_INFO,
    VMXVMCSFIELDTYPE_GUEST_STATE,
    VMXVMCSFIELDTYPE_HOST_STATE
} VMXVMCSFIELDTYPE;
AssertCompileSize(VMXVMCSFIELDTYPE, 4);
/** VMCS field encoding type: Control. */
#define VMX_VMCSFIELD_TYPE_CONTROL                              0
/** VMCS field encoding type: VM-exit information / read-only fields. */
#define VMX_VMCSFIELD_TYPE_VMEXIT_INFO                          1
/** VMCS field encoding type: Guest-state. */
#define VMX_VMCSFIELD_TYPE_GUEST_STATE                          2
/** VMCS field encoding type: Host-state. */
#define VMX_VMCSFIELD_TYPE_HOST_STATE                           3

/**
 * VMCS field encoding: Width.
 * In accordance with the VT-x spec.
 */
typedef enum
{
    VMXVMCSFIELDWIDTH_16BIT = 0,
    VMXVMCSFIELDWIDTH_64BIT,
    VMXVMCSFIELDWIDTH_32BIT,
    VMXVMCSFIELDWIDTH_NATURAL
} VMXVMCSFIELDWIDTH;
AssertCompileSize(VMXVMCSFIELDWIDTH, 4);
/** VMCS field encoding width: 16-bit. */
#define VMX_VMCSFIELD_WIDTH_16BIT                               0
/** VMCS field encoding width: 64-bit. */
#define VMX_VMCSFIELD_WIDTH_64BIT                               1
/** VMCS field encoding width: 32-bit. */
#define VMX_VMCSFIELD_WIDTH_32BIT                               2
/** VMCS field encoding width: Natural width. */
#define VMX_VMCSFIELD_WIDTH_NATURAL                             3
/** @} */


/** @name VM-entry instruction length.
 * @{ */
/** The maximum valid value for VM-entry instruction length while injecting a
 *  software interrupt, software exception or privileged software exception. */
#define VMX_ENTRY_INSTR_LEN_MAX                                 15
/** @} */


/** @name VM-entry register masks.
 * @{ */
/** CR0 bits ignored on VM-entry while loading guest CR0 (ET, CD, NW, bits 6:15,
 *  bit 17 and bits 19:28). */
#define VMX_ENTRY_GUEST_CR0_IGNORE_MASK                         UINT64_C(0x7ffaffd0)
/** DR7 bits set here are always cleared on VM-entry while loading guest DR7 (bit
 *  12, bits 14:15). */
#define VMX_ENTRY_GUEST_DR7_MBZ_MASK                            UINT64_C(0xd000)
/** DR7 bits set here are always set on VM-entry while loading guest DR7 (bit
 *  10). */
#define VMX_ENTRY_GUEST_DR7_MB1_MASK                            UINT64_C(0x400)
/** @} */


/** @name VM-exit register masks.
 * @{ */
/** CR0 bits ignored on VM-exit while loading host CR0 (ET, CD, NW, bits 6:15,
 *  bit 17, bits 19:28 and bits 32:63). */
#define VMX_EXIT_HOST_CR0_IGNORE_MASK                           UINT64_C(0xffffffff7ffaffd0)
/** @} */


/** @name Pin-based VM-execution controls.
 * @{
 */
/** External interrupt exiting. */
#define VMX_PIN_CTLS_EXT_INT_EXIT                               RT_BIT(0)
/** NMI exiting. */
#define VMX_PIN_CTLS_NMI_EXIT                                   RT_BIT(3)
/** Virtual NMIs. */
#define VMX_PIN_CTLS_VIRT_NMI                                   RT_BIT(5)
/** Activate VMX preemption timer. */
#define VMX_PIN_CTLS_PREEMPT_TIMER                              RT_BIT(6)
/** Process interrupts with the posted-interrupt notification vector. */
#define VMX_PIN_CTLS_POSTED_INT                                 RT_BIT(7)
/** Default1 class when true capability MSRs are not supported. */
#define VMX_PIN_CTLS_DEFAULT1                                   UINT32_C(0x00000016)

/** Bit fields for MSR_IA32_VMX_PINBASED_CTLS and Pin-based VM-execution
 *  controls field in the VMCS. */
#define VMX_BF_PIN_CTLS_EXT_INT_EXIT_SHIFT                      0
#define VMX_BF_PIN_CTLS_EXT_INT_EXIT_MASK                       UINT32_C(0x00000001)
#define VMX_BF_PIN_CTLS_RSVD_1_2_SHIFT                          1
#define VMX_BF_PIN_CTLS_RSVD_1_2_MASK                           UINT32_C(0x00000006)
#define VMX_BF_PIN_CTLS_NMI_EXIT_SHIFT                          3
#define VMX_BF_PIN_CTLS_NMI_EXIT_MASK                           UINT32_C(0x00000008)
#define VMX_BF_PIN_CTLS_RSVD_4_SHIFT                            4
#define VMX_BF_PIN_CTLS_RSVD_4_MASK                             UINT32_C(0x00000010)
#define VMX_BF_PIN_CTLS_VIRT_NMI_SHIFT                          5
#define VMX_BF_PIN_CTLS_VIRT_NMI_MASK                           UINT32_C(0x00000020)
#define VMX_BF_PIN_CTLS_PREEMPT_TIMER_SHIFT                     6
#define VMX_BF_PIN_CTLS_PREEMPT_TIMER_MASK                      UINT32_C(0x00000040)
#define VMX_BF_PIN_CTLS_POSTED_INT_SHIFT                        7
#define VMX_BF_PIN_CTLS_POSTED_INT_MASK                         UINT32_C(0x00000080)
#define VMX_BF_PIN_CTLS_RSVD_8_31_SHIFT                         8
#define VMX_BF_PIN_CTLS_RSVD_8_31_MASK                          UINT32_C(0xffffff00)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_PIN_CTLS_, UINT32_C(0), UINT32_MAX,
                            (EXT_INT_EXIT, RSVD_1_2, NMI_EXIT, RSVD_4, VIRT_NMI, PREEMPT_TIMER, POSTED_INT, RSVD_8_31));
/** @} */


/** @name Processor-based VM-execution controls.
 * @{
 */
/** VM-exit as soon as RFLAGS.IF=1 and no blocking is active. */
#define VMX_PROC_CTLS_INT_WINDOW_EXIT                           RT_BIT(2)
/** Use timestamp counter offset. */
#define VMX_PROC_CTLS_USE_TSC_OFFSETTING                        RT_BIT(3)
/** VM-exit when executing the HLT instruction. */
#define VMX_PROC_CTLS_HLT_EXIT                                  RT_BIT(7)
/** VM-exit when executing the INVLPG instruction. */
#define VMX_PROC_CTLS_INVLPG_EXIT                               RT_BIT(9)
/** VM-exit when executing the MWAIT instruction. */
#define VMX_PROC_CTLS_MWAIT_EXIT                                RT_BIT(10)
/** VM-exit when executing the RDPMC instruction. */
#define VMX_PROC_CTLS_RDPMC_EXIT                                RT_BIT(11)
/** VM-exit when executing the RDTSC/RDTSCP instruction. */
#define VMX_PROC_CTLS_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_PROC_CTLS_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_PROC_CTLS_CR3_STORE_EXIT                            RT_BIT(16)
/** Whether the secondary processor based VM-execution controls are used. */
#define VMX_PROC_CTLS_USE_TERTIARY_CTLS                         RT_BIT(17)
/** VM-exit on CR8 loads. */
#define VMX_PROC_CTLS_CR8_LOAD_EXIT                             RT_BIT(19)
/** VM-exit on CR8 stores. */
#define VMX_PROC_CTLS_CR8_STORE_EXIT                            RT_BIT(20)
/** Use TPR shadow. */
#define VMX_PROC_CTLS_USE_TPR_SHADOW                            RT_BIT(21)
/** VM-exit when virtual NMI blocking is disabled. */
#define VMX_PROC_CTLS_NMI_WINDOW_EXIT                           RT_BIT(22)
/** VM-exit when executing a MOV DRx instruction. */
#define VMX_PROC_CTLS_MOV_DR_EXIT                               RT_BIT(23)
/** VM-exit when executing IO instructions. */
#define VMX_PROC_CTLS_UNCOND_IO_EXIT                            RT_BIT(24)
/** Use IO bitmaps. */
#define VMX_PROC_CTLS_USE_IO_BITMAPS                            RT_BIT(25)
/** Monitor trap flag. */
#define VMX_PROC_CTLS_MONITOR_TRAP_FLAG                         RT_BIT(27)
/** Use MSR bitmaps. */
#define VMX_PROC_CTLS_USE_MSR_BITMAPS                           RT_BIT(28)
/** VM-exit when executing the MONITOR instruction. */
#define VMX_PROC_CTLS_MONITOR_EXIT                              RT_BIT(29)
/** VM-exit when executing the PAUSE instruction. */
#define VMX_PROC_CTLS_PAUSE_EXIT                                RT_BIT(30)
/** Whether the secondary processor based VM-execution controls are used. */
#define VMX_PROC_CTLS_USE_SECONDARY_CTLS                        RT_BIT(31)
/** Default1 class when true-capability MSRs are not supported. */
#define VMX_PROC_CTLS_DEFAULT1                                  UINT32_C(0x0401e172)

/** Bit fields for MSR_IA32_VMX_PROCBASED_CTLS and Processor-based VM-execution
 *  controls field in the VMCS. */
#define VMX_BF_PROC_CTLS_RSVD_0_1_SHIFT                         0
#define VMX_BF_PROC_CTLS_RSVD_0_1_MASK                          UINT32_C(0x00000003)
#define VMX_BF_PROC_CTLS_INT_WINDOW_EXIT_SHIFT                  2
#define VMX_BF_PROC_CTLS_INT_WINDOW_EXIT_MASK                   UINT32_C(0x00000004)
#define VMX_BF_PROC_CTLS_USE_TSC_OFFSETTING_SHIFT               3
#define VMX_BF_PROC_CTLS_USE_TSC_OFFSETTING_MASK                UINT32_C(0x00000008)
#define VMX_BF_PROC_CTLS_RSVD_4_6_SHIFT                         4
#define VMX_BF_PROC_CTLS_RSVD_4_6_MASK                          UINT32_C(0x00000070)
#define VMX_BF_PROC_CTLS_HLT_EXIT_SHIFT                         7
#define VMX_BF_PROC_CTLS_HLT_EXIT_MASK                          UINT32_C(0x00000080)
#define VMX_BF_PROC_CTLS_RSVD_8_SHIFT                           8
#define VMX_BF_PROC_CTLS_RSVD_8_MASK                            UINT32_C(0x00000100)
#define VMX_BF_PROC_CTLS_INVLPG_EXIT_SHIFT                      9
#define VMX_BF_PROC_CTLS_INVLPG_EXIT_MASK                       UINT32_C(0x00000200)
#define VMX_BF_PROC_CTLS_MWAIT_EXIT_SHIFT                       10
#define VMX_BF_PROC_CTLS_MWAIT_EXIT_MASK                        UINT32_C(0x00000400)
#define VMX_BF_PROC_CTLS_RDPMC_EXIT_SHIFT                       11
#define VMX_BF_PROC_CTLS_RDPMC_EXIT_MASK                        UINT32_C(0x00000800)
#define VMX_BF_PROC_CTLS_RDTSC_EXIT_SHIFT                       12
#define VMX_BF_PROC_CTLS_RDTSC_EXIT_MASK                        UINT32_C(0x00001000)
#define VMX_BF_PROC_CTLS_RSVD_13_14_SHIFT                       13
#define VMX_BF_PROC_CTLS_RSVD_13_14_MASK                        UINT32_C(0x00006000)
#define VMX_BF_PROC_CTLS_CR3_LOAD_EXIT_SHIFT                    15
#define VMX_BF_PROC_CTLS_CR3_LOAD_EXIT_MASK                     UINT32_C(0x00008000)
#define VMX_BF_PROC_CTLS_CR3_STORE_EXIT_SHIFT                   16
#define VMX_BF_PROC_CTLS_CR3_STORE_EXIT_MASK                    UINT32_C(0x00010000)
#define VMX_BF_PROC_CTLS_USE_TERTIARY_CTLS_SHIFT                17
#define VMX_BF_PROC_CTLS_USE_TERTIARY_CTLS_MASK                 UINT32_C(0x00020000)
#define VMX_BF_PROC_CTLS_RSVD_18_SHIFT                          18
#define VMX_BF_PROC_CTLS_RSVD_18_MASK                           UINT32_C(0x00040000)
#define VMX_BF_PROC_CTLS_CR8_LOAD_EXIT_SHIFT                    19
#define VMX_BF_PROC_CTLS_CR8_LOAD_EXIT_MASK                     UINT32_C(0x00080000)
#define VMX_BF_PROC_CTLS_CR8_STORE_EXIT_SHIFT                   20
#define VMX_BF_PROC_CTLS_CR8_STORE_EXIT_MASK                    UINT32_C(0x00100000)
#define VMX_BF_PROC_CTLS_USE_TPR_SHADOW_SHIFT                   21
#define VMX_BF_PROC_CTLS_USE_TPR_SHADOW_MASK                    UINT32_C(0x00200000)
#define VMX_BF_PROC_CTLS_NMI_WINDOW_EXIT_SHIFT                  22
#define VMX_BF_PROC_CTLS_NMI_WINDOW_EXIT_MASK                   UINT32_C(0x00400000)
#define VMX_BF_PROC_CTLS_MOV_DR_EXIT_SHIFT                      23
#define VMX_BF_PROC_CTLS_MOV_DR_EXIT_MASK                       UINT32_C(0x00800000)
#define VMX_BF_PROC_CTLS_UNCOND_IO_EXIT_SHIFT                   24
#define VMX_BF_PROC_CTLS_UNCOND_IO_EXIT_MASK                    UINT32_C(0x01000000)
#define VMX_BF_PROC_CTLS_USE_IO_BITMAPS_SHIFT                   25
#define VMX_BF_PROC_CTLS_USE_IO_BITMAPS_MASK                    UINT32_C(0x02000000)
#define VMX_BF_PROC_CTLS_RSVD_26_SHIFT                          26
#define VMX_BF_PROC_CTLS_RSVD_26_MASK                           UINT32_C(0x4000000)
#define VMX_BF_PROC_CTLS_MONITOR_TRAP_FLAG_SHIFT                27
#define VMX_BF_PROC_CTLS_MONITOR_TRAP_FLAG_MASK                 UINT32_C(0x08000000)
#define VMX_BF_PROC_CTLS_USE_MSR_BITMAPS_SHIFT                  28
#define VMX_BF_PROC_CTLS_USE_MSR_BITMAPS_MASK                   UINT32_C(0x10000000)
#define VMX_BF_PROC_CTLS_MONITOR_EXIT_SHIFT                     29
#define VMX_BF_PROC_CTLS_MONITOR_EXIT_MASK                      UINT32_C(0x20000000)
#define VMX_BF_PROC_CTLS_PAUSE_EXIT_SHIFT                       30
#define VMX_BF_PROC_CTLS_PAUSE_EXIT_MASK                        UINT32_C(0x40000000)
#define VMX_BF_PROC_CTLS_USE_SECONDARY_CTLS_SHIFT               31
#define VMX_BF_PROC_CTLS_USE_SECONDARY_CTLS_MASK                UINT32_C(0x80000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_PROC_CTLS_, UINT32_C(0), UINT32_MAX,
                            (RSVD_0_1, INT_WINDOW_EXIT, USE_TSC_OFFSETTING, RSVD_4_6, HLT_EXIT, RSVD_8, INVLPG_EXIT,
                             MWAIT_EXIT, RDPMC_EXIT, RDTSC_EXIT, RSVD_13_14, CR3_LOAD_EXIT, CR3_STORE_EXIT, USE_TERTIARY_CTLS,
                             RSVD_18, CR8_LOAD_EXIT, CR8_STORE_EXIT, USE_TPR_SHADOW, NMI_WINDOW_EXIT, MOV_DR_EXIT, UNCOND_IO_EXIT,
                             USE_IO_BITMAPS, RSVD_26, MONITOR_TRAP_FLAG, USE_MSR_BITMAPS, MONITOR_EXIT, PAUSE_EXIT,
                             USE_SECONDARY_CTLS));
/** @} */


/** @name Secondary Processor-based VM-execution controls.
 * @{
 */
/** Virtualize APIC accesses. */
#define VMX_PROC_CTLS2_VIRT_APIC_ACCESS                         RT_BIT(0)
/** EPT supported/enabled. */
#define VMX_PROC_CTLS2_EPT                                      RT_BIT(1)
/** Descriptor table instructions cause VM-exits. */
#define VMX_PROC_CTLS2_DESC_TABLE_EXIT                          RT_BIT(2)
/** RDTSCP supported/enabled. */
#define VMX_PROC_CTLS2_RDTSCP                                   RT_BIT(3)
/** Virtualize x2APIC mode. */
#define VMX_PROC_CTLS2_VIRT_X2APIC_MODE                         RT_BIT(4)
/** VPID supported/enabled. */
#define VMX_PROC_CTLS2_VPID                                     RT_BIT(5)
/** VM-exit when executing the WBINVD instruction. */
#define VMX_PROC_CTLS2_WBINVD_EXIT                              RT_BIT(6)
/** Unrestricted guest execution. */
#define VMX_PROC_CTLS2_UNRESTRICTED_GUEST                       RT_BIT(7)
/** APIC register virtualization. */
#define VMX_PROC_CTLS2_APIC_REG_VIRT                            RT_BIT(8)
/** Virtual-interrupt delivery. */
#define VMX_PROC_CTLS2_VIRT_INT_DELIVERY                        RT_BIT(9)
/** A specified number of pause loops cause a VM-exit. */
#define VMX_PROC_CTLS2_PAUSE_LOOP_EXIT                          RT_BIT(10)
/** VM-exit when executing RDRAND instructions. */
#define VMX_PROC_CTLS2_RDRAND_EXIT                              RT_BIT(11)
/** Enables INVPCID instructions. */
#define VMX_PROC_CTLS2_INVPCID                                  RT_BIT(12)
/** Enables VMFUNC instructions. */
#define VMX_PROC_CTLS2_VMFUNC                                   RT_BIT(13)
/** Enables VMCS shadowing. */
#define VMX_PROC_CTLS2_VMCS_SHADOWING                           RT_BIT(14)
/** Enables ENCLS VM-exits. */
#define VMX_PROC_CTLS2_ENCLS_EXIT                               RT_BIT(15)
/** VM-exit when executing RDSEED. */
#define VMX_PROC_CTLS2_RDSEED_EXIT                              RT_BIT(16)
/** Enables page-modification logging. */
#define VMX_PROC_CTLS2_PML                                      RT_BIT(17)
/** Controls whether EPT-violations may cause \#VE instead of exits. */
#define VMX_PROC_CTLS2_EPT_XCPT_VE                              RT_BIT(18)
/** Conceal VMX non-root operation from Intel processor trace (PT). */
#define VMX_PROC_CTLS2_CONCEAL_VMX_FROM_PT                      RT_BIT(19)
/** Enables XSAVES/XRSTORS instructions. */
#define VMX_PROC_CTLS2_XSAVES_XRSTORS                           RT_BIT(20)
/** Enables supervisor/user mode based EPT execute permission for linear
 *  addresses. */
#define VMX_PROC_CTLS2_MODE_BASED_EPT_PERM                      RT_BIT(22)
/** Enables EPT write permissions to be specified at granularity of 128 bytes. */
#define VMX_PROC_CTLS2_SPP_EPT                                  RT_BIT(23)
/** Intel PT output addresses are treated as guest-physical addresses and
 *  translated using EPT. */
#define VMX_PROC_CTLS2_PT_EPT                                   RT_BIT(24)
/** Use TSC scaling. */
#define VMX_PROC_CTLS2_TSC_SCALING                              RT_BIT(25)
/** Enables TPAUSE, UMONITOR and UMWAIT instructions. */
#define VMX_PROC_CTLS2_USER_WAIT_PAUSE                          RT_BIT(26)
/** Enables consulting ENCLV-exiting bitmap when executing ENCLV. */
#define VMX_PROC_CTLS2_ENCLV_EXIT                               RT_BIT(28)

/** Bit fields for MSR_IA32_VMX_PROCBASED_CTLS2 and Secondary processor-based
 *  VM-execution controls field in the VMCS. */
#define VMX_BF_PROC_CTLS2_VIRT_APIC_ACCESS_SHIFT                0
#define VMX_BF_PROC_CTLS2_VIRT_APIC_ACCESS_MASK                 UINT32_C(0x00000001)
#define VMX_BF_PROC_CTLS2_EPT_SHIFT                             1
#define VMX_BF_PROC_CTLS2_EPT_MASK                              UINT32_C(0x00000002)
#define VMX_BF_PROC_CTLS2_DESC_TABLE_EXIT_SHIFT                 2
#define VMX_BF_PROC_CTLS2_DESC_TABLE_EXIT_MASK                  UINT32_C(0x00000004)
#define VMX_BF_PROC_CTLS2_RDTSCP_SHIFT                          3
#define VMX_BF_PROC_CTLS2_RDTSCP_MASK                           UINT32_C(0x00000008)
#define VMX_BF_PROC_CTLS2_VIRT_X2APIC_MODE_SHIFT                4
#define VMX_BF_PROC_CTLS2_VIRT_X2APIC_MODE_MASK                 UINT32_C(0x00000010)
#define VMX_BF_PROC_CTLS2_VPID_SHIFT                            5
#define VMX_BF_PROC_CTLS2_VPID_MASK                             UINT32_C(0x00000020)
#define VMX_BF_PROC_CTLS2_WBINVD_EXIT_SHIFT                     6
#define VMX_BF_PROC_CTLS2_WBINVD_EXIT_MASK                      UINT32_C(0x00000040)
#define VMX_BF_PROC_CTLS2_UNRESTRICTED_GUEST_SHIFT              7
#define VMX_BF_PROC_CTLS2_UNRESTRICTED_GUEST_MASK               UINT32_C(0x00000080)
#define VMX_BF_PROC_CTLS2_APIC_REG_VIRT_SHIFT                   8
#define VMX_BF_PROC_CTLS2_APIC_REG_VIRT_MASK                    UINT32_C(0x00000100)
#define VMX_BF_PROC_CTLS2_VIRT_INT_DELIVERY_SHIFT               9
#define VMX_BF_PROC_CTLS2_VIRT_INT_DELIVERY_MASK                UINT32_C(0x00000200)
#define VMX_BF_PROC_CTLS2_PAUSE_LOOP_EXIT_SHIFT                 10
#define VMX_BF_PROC_CTLS2_PAUSE_LOOP_EXIT_MASK                  UINT32_C(0x00000400)
#define VMX_BF_PROC_CTLS2_RDRAND_EXIT_SHIFT                     11
#define VMX_BF_PROC_CTLS2_RDRAND_EXIT_MASK                      UINT32_C(0x00000800)
#define VMX_BF_PROC_CTLS2_INVPCID_SHIFT                         12
#define VMX_BF_PROC_CTLS2_INVPCID_MASK                          UINT32_C(0x00001000)
#define VMX_BF_PROC_CTLS2_VMFUNC_SHIFT                          13
#define VMX_BF_PROC_CTLS2_VMFUNC_MASK                           UINT32_C(0x00002000)
#define VMX_BF_PROC_CTLS2_VMCS_SHADOWING_SHIFT                  14
#define VMX_BF_PROC_CTLS2_VMCS_SHADOWING_MASK                   UINT32_C(0x00004000)
#define VMX_BF_PROC_CTLS2_ENCLS_EXIT_SHIFT                      15
#define VMX_BF_PROC_CTLS2_ENCLS_EXIT_MASK                       UINT32_C(0x00008000)
#define VMX_BF_PROC_CTLS2_RDSEED_EXIT_SHIFT                     16
#define VMX_BF_PROC_CTLS2_RDSEED_EXIT_MASK                      UINT32_C(0x00010000)
#define VMX_BF_PROC_CTLS2_PML_SHIFT                             17
#define VMX_BF_PROC_CTLS2_PML_MASK                              UINT32_C(0x00020000)
#define VMX_BF_PROC_CTLS2_EPT_VE_SHIFT                          18
#define VMX_BF_PROC_CTLS2_EPT_VE_MASK                           UINT32_C(0x00040000)
#define VMX_BF_PROC_CTLS2_CONCEAL_VMX_FROM_PT_SHIFT             19
#define VMX_BF_PROC_CTLS2_CONCEAL_VMX_FROM_PT_MASK              UINT32_C(0x00080000)
#define VMX_BF_PROC_CTLS2_XSAVES_XRSTORS_SHIFT                  20
#define VMX_BF_PROC_CTLS2_XSAVES_XRSTORS_MASK                   UINT32_C(0x00100000)
#define VMX_BF_PROC_CTLS2_RSVD_21_SHIFT                         21
#define VMX_BF_PROC_CTLS2_RSVD_21_MASK                          UINT32_C(0x00200000)
#define VMX_BF_PROC_CTLS2_MODE_BASED_EPT_PERM_SHIFT             22
#define VMX_BF_PROC_CTLS2_MODE_BASED_EPT_PERM_MASK              UINT32_C(0x00400000)
#define VMX_BF_PROC_CTLS2_SPP_EPT_SHIFT                         23
#define VMX_BF_PROC_CTLS2_SPP_EPT_MASK                          UINT32_C(0x00800000)
#define VMX_BF_PROC_CTLS2_PT_EPT_SHIFT                          24
#define VMX_BF_PROC_CTLS2_PT_EPT_MASK                           UINT32_C(0x01000000)
#define VMX_BF_PROC_CTLS2_TSC_SCALING_SHIFT                     25
#define VMX_BF_PROC_CTLS2_TSC_SCALING_MASK                      UINT32_C(0x02000000)
#define VMX_BF_PROC_CTLS2_USER_WAIT_PAUSE_SHIFT                 26
#define VMX_BF_PROC_CTLS2_USER_WAIT_PAUSE_MASK                  UINT32_C(0x04000000)
#define VMX_BF_PROC_CTLS2_RSVD_27_SHIFT                         27
#define VMX_BF_PROC_CTLS2_RSVD_27_MASK                          UINT32_C(0x08000000)
#define VMX_BF_PROC_CTLS2_ENCLV_EXIT_SHIFT                      28
#define VMX_BF_PROC_CTLS2_ENCLV_EXIT_MASK                       UINT32_C(0x10000000)
#define VMX_BF_PROC_CTLS2_RSVD_29_31_SHIFT                      29
#define VMX_BF_PROC_CTLS2_RSVD_29_31_MASK                       UINT32_C(0xe0000000)

RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_PROC_CTLS2_, UINT32_C(0), UINT32_MAX,
                            (VIRT_APIC_ACCESS, EPT, DESC_TABLE_EXIT, RDTSCP, VIRT_X2APIC_MODE, VPID, WBINVD_EXIT,
                             UNRESTRICTED_GUEST, APIC_REG_VIRT, VIRT_INT_DELIVERY, PAUSE_LOOP_EXIT, RDRAND_EXIT, INVPCID, VMFUNC,
                             VMCS_SHADOWING, ENCLS_EXIT, RDSEED_EXIT, PML, EPT_VE, CONCEAL_VMX_FROM_PT, XSAVES_XRSTORS, RSVD_21,
                             MODE_BASED_EPT_PERM, SPP_EPT, PT_EPT, TSC_SCALING, USER_WAIT_PAUSE, RSVD_27, ENCLV_EXIT,
                             RSVD_29_31));
/** @} */


/** @name Tertiary Processor-based VM-execution controls.
 * @{
 */
/** VM-exit when executing LOADIWKEY. */
#define VMX_PROC_CTLS3_LOADIWKEY_EXIT                           RT_BIT_64(0)

/** Bit fields for Tertiary processor-based VM-execution controls field in the VMCS. */
#define VMX_BF_PROC_CTLS3_LOADIWKEY_EXIT_SHIFT                  0
#define VMX_BF_PROC_CTLS3_LOADIWKEY_EXIT_MASK                   UINT64_C(0x0000000000000001)
#define VMX_BF_PROC_CTLS3_RSVD_1_63_SHIFT                       1
#define VMX_BF_PROC_CTLS3_RSVD_1_63_MASK                        UINT64_C(0xfffffffffffffffe)

RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_PROC_CTLS3_, UINT64_C(0), UINT64_MAX,
                            (LOADIWKEY_EXIT, RSVD_1_63));
/** @} */


/** @name VM-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_ENTRY_CTLS_LOAD_DEBUG                               RT_BIT(2)
/** 64-bit guest mode. Must be 0 for CPUs that don't support AMD64. */
#define VMX_ENTRY_CTLS_IA32E_MODE_GUEST                         RT_BIT(9)
/** In SMM mode after VM-entry. */
#define VMX_ENTRY_CTLS_ENTRY_TO_SMM                             RT_BIT(10)
/** Disable dual treatment of SMI and SMM; must be zero for VM-entry outside of SMM. */
#define VMX_ENTRY_CTLS_DEACTIVATE_DUAL_MON                      RT_BIT(11)
/** Whether the guest IA32_PERF_GLOBAL_CTRL MSR is loaded on VM-entry. */
#define VMX_ENTRY_CTLS_LOAD_PERF_MSR                            RT_BIT(13)
/** Whether the guest IA32_PAT MSR is loaded on VM-entry. */
#define VMX_ENTRY_CTLS_LOAD_PAT_MSR                             RT_BIT(14)
/** Whether the guest IA32_EFER MSR is loaded on VM-entry. */
#define VMX_ENTRY_CTLS_LOAD_EFER_MSR                            RT_BIT(15)
/** Whether the guest IA32_BNDCFGS MSR is loaded on VM-entry. */
#define VMX_ENTRY_CTLS_LOAD_BNDCFGS_MSR                         RT_BIT(16)
/** Whether to conceal VMX from Intel PT (Processor Trace). */
#define VMX_ENTRY_CTLS_CONCEAL_VMX_FROM_PT                      RT_BIT(17)
/** Whether the guest IA32_RTIT MSR is loaded on VM-entry. */
#define VMX_ENTRY_CTLS_LOAD_RTIT_CTL_MSR                        RT_BIT(18)
/** Whether the guest CET-related MSRs and SPP are loaded on VM-entry. */
#define VMX_ENTRY_CTLS_LOAD_CET_STATE                           RT_BIT(20)
/** Whether the guest IA32_PKRS MSR is loaded on VM-entry. */
#define VMX_ENTRY_CTLS_LOAD_PKRS_MSR                            RT_BIT(22)
/** Default1 class when true-capability MSRs are not supported. */
#define VMX_ENTRY_CTLS_DEFAULT1                                 UINT32_C(0x000011ff)

/** Bit fields for MSR_IA32_VMX_ENTRY_CTLS and VM-entry controls field in the
 *  VMCS. */
#define VMX_BF_ENTRY_CTLS_RSVD_0_1_SHIFT                        0
#define VMX_BF_ENTRY_CTLS_RSVD_0_1_MASK                         UINT32_C(0x00000003)
#define VMX_BF_ENTRY_CTLS_LOAD_DEBUG_SHIFT                      2
#define VMX_BF_ENTRY_CTLS_LOAD_DEBUG_MASK                       UINT32_C(0x00000004)
#define VMX_BF_ENTRY_CTLS_RSVD_3_8_SHIFT                        3
#define VMX_BF_ENTRY_CTLS_RSVD_3_8_MASK                         UINT32_C(0x000001f8)
#define VMX_BF_ENTRY_CTLS_IA32E_MODE_GUEST_SHIFT                9
#define VMX_BF_ENTRY_CTLS_IA32E_MODE_GUEST_MASK                 UINT32_C(0x00000200)
#define VMX_BF_ENTRY_CTLS_ENTRY_SMM_SHIFT                       10
#define VMX_BF_ENTRY_CTLS_ENTRY_SMM_MASK                        UINT32_C(0x00000400)
#define VMX_BF_ENTRY_CTLS_DEACTIVATE_DUAL_MON_SHIFT             11
#define VMX_BF_ENTRY_CTLS_DEACTIVATE_DUAL_MON_MASK              UINT32_C(0x00000800)
#define VMX_BF_ENTRY_CTLS_RSVD_12_SHIFT                         12
#define VMX_BF_ENTRY_CTLS_RSVD_12_MASK                          UINT32_C(0x00001000)
#define VMX_BF_ENTRY_CTLS_LOAD_PERF_MSR_SHIFT                   13
#define VMX_BF_ENTRY_CTLS_LOAD_PERF_MSR_MASK                    UINT32_C(0x00002000)
#define VMX_BF_ENTRY_CTLS_LOAD_PAT_MSR_SHIFT                    14
#define VMX_BF_ENTRY_CTLS_LOAD_PAT_MSR_MASK                     UINT32_C(0x00004000)
#define VMX_BF_ENTRY_CTLS_LOAD_EFER_MSR_SHIFT                   15
#define VMX_BF_ENTRY_CTLS_LOAD_EFER_MSR_MASK                    UINT32_C(0x00008000)
#define VMX_BF_ENTRY_CTLS_LOAD_BNDCFGS_MSR_SHIFT                16
#define VMX_BF_ENTRY_CTLS_LOAD_BNDCFGS_MSR_MASK                 UINT32_C(0x00010000)
#define VMX_BF_ENTRY_CTLS_CONCEAL_VMX_FROM_PT_SHIFT             17
#define VMX_BF_ENTRY_CTLS_CONCEAL_VMX_FROM_PT_MASK              UINT32_C(0x00020000)
#define VMX_BF_ENTRY_CTLS_LOAD_RTIT_CTL_MSR_SHIFT               18
#define VMX_BF_ENTRY_CTLS_LOAD_RTIT_CTL_MSR_MASK                UINT32_C(0x00040000)
#define VMX_BF_ENTRY_CTLS_RSVD_19_SHIFT                         19
#define VMX_BF_ENTRY_CTLS_RSVD_19_MASK                          UINT32_C(0x00080000)
#define VMX_BF_ENTRY_CTLS_LOAD_CET_SHIFT                        20
#define VMX_BF_ENTRY_CTLS_LOAD_CET_MASK                         UINT32_C(0x00100000)
#define VMX_BF_ENTRY_CTLS_RSVD_21_SHIFT                         21
#define VMX_BF_ENTRY_CTLS_RSVD_21_MASK                          UINT32_C(0x00200000)
#define VMX_BF_ENTRY_CTLS_LOAD_PKRS_MSR_SHIFT                   22
#define VMX_BF_ENTRY_CTLS_LOAD_PKRS_MSR_MASK                    UINT32_C(0x00400000)
#define VMX_BF_ENTRY_CTLS_RSVD_23_31_SHIFT                      23
#define VMX_BF_ENTRY_CTLS_RSVD_23_31_MASK                       UINT32_C(0xff800000)

RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_ENTRY_CTLS_, UINT32_C(0), UINT32_MAX,
                            (RSVD_0_1, LOAD_DEBUG, RSVD_3_8, IA32E_MODE_GUEST, ENTRY_SMM, DEACTIVATE_DUAL_MON, RSVD_12,
                             LOAD_PERF_MSR, LOAD_PAT_MSR, LOAD_EFER_MSR, LOAD_BNDCFGS_MSR, CONCEAL_VMX_FROM_PT,
                             LOAD_RTIT_CTL_MSR, RSVD_19, LOAD_CET, RSVD_21, LOAD_PKRS_MSR, RSVD_23_31));
/** @} */


/** @name VM-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_EXIT_CTLS_SAVE_DEBUG                                RT_BIT(2)
/** Return to long mode after a VM-exit. */
#define VMX_EXIT_CTLS_HOST_ADDR_SPACE_SIZE                      RT_BIT(9)
/** Whether the host IA32_PERF_GLOBAL_CTRL MSR is loaded on VM-exit. */
#define VMX_EXIT_CTLS_LOAD_PERF_MSR                             RT_BIT(12)
/** Acknowledge external interrupts with the irq controller if one caused a VM-exit. */
#define VMX_EXIT_CTLS_ACK_EXT_INT                               RT_BIT(15)
/** Whether the guest IA32_PAT MSR is saved on VM-exit. */
#define VMX_EXIT_CTLS_SAVE_PAT_MSR                              RT_BIT(18)
/** Whether the host IA32_PAT MSR is loaded on VM-exit. */
#define VMX_EXIT_CTLS_LOAD_PAT_MSR                              RT_BIT(19)
/** Whether the guest IA32_EFER MSR is saved on VM-exit. */
#define VMX_EXIT_CTLS_SAVE_EFER_MSR                             RT_BIT(20)
/** Whether the host IA32_EFER MSR is loaded on VM-exit. */
#define VMX_EXIT_CTLS_LOAD_EFER_MSR                             RT_BIT(21)
/** Whether the value of the VMX preemption timer is saved on every VM-exit. */
#define VMX_EXIT_CTLS_SAVE_PREEMPT_TIMER                        RT_BIT(22)
/** Whether IA32_BNDCFGS MSR is cleared on VM-exit. */
#define VMX_EXIT_CTLS_CLEAR_BNDCFGS_MSR                         RT_BIT(23)
/** Whether to conceal VMX from Intel PT. */
#define VMX_EXIT_CTLS_CONCEAL_VMX_FROM_PT                       RT_BIT(24)
/** Whether IA32_RTIT_CTL MSR is cleared on VM-exit. */
#define VMX_EXIT_CTLS_CLEAR_RTIT_CTL_MSR                        RT_BIT(25)
/** Whether CET-related MSRs and SPP are loaded on VM-exit. */
#define VMX_EXIT_CTLS_LOAD_CET_STATE                            RT_BIT(28)
/** Whether the host IA32_PKRS MSR is loaded on VM-exit. */
#define VMX_EXIT_CTLS_LOAD_PKRS_MSR                             RT_BIT(29)
/** Whether the host IA32_PERF_GLOBAL_CTRL MSR is saved on VM-exit. */
#define VMX_EXIT_CTLS_SAVE_PERF_MSR                             RT_BIT(30)
/** Whether secondary VM-exit controls are used. */
#define VMX_EXIT_CTLS_USE_SECONDARY_CTLS                        RT_BIT(31)
/** Default1 class when true-capability MSRs are not supported. */
#define VMX_EXIT_CTLS_DEFAULT1                                  UINT32_C(0x00036dff)

/** Bit fields for MSR_IA32_VMX_EXIT_CTLS and VM-exit controls field in the
 *  VMCS. */
#define VMX_BF_EXIT_CTLS_RSVD_0_1_SHIFT                         0
#define VMX_BF_EXIT_CTLS_RSVD_0_1_MASK                          UINT32_C(0x00000003)
#define VMX_BF_EXIT_CTLS_SAVE_DEBUG_SHIFT                       2
#define VMX_BF_EXIT_CTLS_SAVE_DEBUG_MASK                        UINT32_C(0x00000004)
#define VMX_BF_EXIT_CTLS_RSVD_3_8_SHIFT                         3
#define VMX_BF_EXIT_CTLS_RSVD_3_8_MASK                          UINT32_C(0x000001f8)
#define VMX_BF_EXIT_CTLS_HOST_ADDR_SPACE_SIZE_SHIFT             9
#define VMX_BF_EXIT_CTLS_HOST_ADDR_SPACE_SIZE_MASK              UINT32_C(0x00000200)
#define VMX_BF_EXIT_CTLS_RSVD_10_11_SHIFT                       10
#define VMX_BF_EXIT_CTLS_RSVD_10_11_MASK                        UINT32_C(0x00000c00)
#define VMX_BF_EXIT_CTLS_LOAD_PERF_MSR_SHIFT                    12
#define VMX_BF_EXIT_CTLS_LOAD_PERF_MSR_MASK                     UINT32_C(0x00001000)
#define VMX_BF_EXIT_CTLS_RSVD_13_14_SHIFT                       13
#define VMX_BF_EXIT_CTLS_RSVD_13_14_MASK                        UINT32_C(0x00006000)
#define VMX_BF_EXIT_CTLS_ACK_EXT_INT_SHIFT                      15
#define VMX_BF_EXIT_CTLS_ACK_EXT_INT_MASK                       UINT32_C(0x00008000)
#define VMX_BF_EXIT_CTLS_RSVD_16_17_SHIFT                       16
#define VMX_BF_EXIT_CTLS_RSVD_16_17_MASK                        UINT32_C(0x00030000)
#define VMX_BF_EXIT_CTLS_SAVE_PAT_MSR_SHIFT                     18
#define VMX_BF_EXIT_CTLS_SAVE_PAT_MSR_MASK                      UINT32_C(0x00040000)
#define VMX_BF_EXIT_CTLS_LOAD_PAT_MSR_SHIFT                     19
#define VMX_BF_EXIT_CTLS_LOAD_PAT_MSR_MASK                      UINT32_C(0x00080000)
#define VMX_BF_EXIT_CTLS_SAVE_EFER_MSR_SHIFT                    20
#define VMX_BF_EXIT_CTLS_SAVE_EFER_MSR_MASK                     UINT32_C(0x00100000)
#define VMX_BF_EXIT_CTLS_LOAD_EFER_MSR_SHIFT                    21
#define VMX_BF_EXIT_CTLS_LOAD_EFER_MSR_MASK                     UINT32_C(0x00200000)
#define VMX_BF_EXIT_CTLS_SAVE_PREEMPT_TIMER_SHIFT               22
#define VMX_BF_EXIT_CTLS_SAVE_PREEMPT_TIMER_MASK                UINT32_C(0x00400000)
#define VMX_BF_EXIT_CTLS_CLEAR_BNDCFGS_MSR_SHIFT                23
#define VMX_BF_EXIT_CTLS_CLEAR_BNDCFGS_MSR_MASK                 UINT32_C(0x00800000)
#define VMX_BF_EXIT_CTLS_CONCEAL_VMX_FROM_PT_SHIFT              24
#define VMX_BF_EXIT_CTLS_CONCEAL_VMX_FROM_PT_MASK               UINT32_C(0x01000000)
#define VMX_BF_EXIT_CTLS_CLEAR_RTIT_CTL_MSR_SHIFT               25
#define VMX_BF_EXIT_CTLS_CLEAR_RTIT_CTL_MSR_MASK                UINT32_C(0x02000000)
#define VMX_BF_EXIT_CTLS_RSVD_26_27_SHIFT                       26
#define VMX_BF_EXIT_CTLS_RSVD_26_27_MASK                        UINT32_C(0x0c000000)
#define VMX_BF_EXIT_CTLS_LOAD_CET_SHIFT                         28
#define VMX_BF_EXIT_CTLS_LOAD_CET_MASK                          UINT32_C(0x10000000)
#define VMX_BF_EXIT_CTLS_LOAD_PKRS_MSR_SHIFT                    29
#define VMX_BF_EXIT_CTLS_LOAD_PKRS_MSR_MASK                     UINT32_C(0x20000000)
#define VMX_BF_EXIT_CTLS_SAVE_PERF_MSR_SHIFT                    30
#define VMX_BF_EXIT_CTLS_SAVE_PERF_MSR_MASK                     UINT32_C(0x40000000)
#define VMX_BF_EXIT_CTLS_USE_SECONDARY_CTLS_SHIFT               31
#define VMX_BF_EXIT_CTLS_USE_SECONDARY_CTLS_MASK                UINT32_C(0x80000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_CTLS_, UINT32_C(0), UINT32_MAX,
                            (RSVD_0_1, SAVE_DEBUG, RSVD_3_8, HOST_ADDR_SPACE_SIZE, RSVD_10_11, LOAD_PERF_MSR, RSVD_13_14,
                             ACK_EXT_INT, RSVD_16_17, SAVE_PAT_MSR, LOAD_PAT_MSR, SAVE_EFER_MSR, LOAD_EFER_MSR,
                             SAVE_PREEMPT_TIMER, CLEAR_BNDCFGS_MSR, CONCEAL_VMX_FROM_PT, CLEAR_RTIT_CTL_MSR, RSVD_26_27,
                             LOAD_CET, LOAD_PKRS_MSR, SAVE_PERF_MSR, USE_SECONDARY_CTLS));
/** @} */


/** @name VM-exit reason.
 * @{
 */
#define VMX_EXIT_REASON_BASIC(a)                                ((a) & 0xffff)
#define VMX_EXIT_REASON_HAS_ENTRY_FAILED(a)                     (((a) >> 31) & 1)
#define VMX_EXIT_REASON_ENTRY_FAILED                            RT_BIT(31)

/** Bit fields for VM-exit reason. */
/** The exit reason. */
#define VMX_BF_EXIT_REASON_BASIC_SHIFT                          0
#define VMX_BF_EXIT_REASON_BASIC_MASK                           UINT32_C(0x0000ffff)
/** Bits 16:26 are reseved and MBZ. */
#define VMX_BF_EXIT_REASON_RSVD_16_26_SHIFT                     16
#define VMX_BF_EXIT_REASON_RSVD_16_26_MASK                      UINT32_C(0x07ff0000)
/** Whether the VM-exit was incident to enclave mode. */
#define VMX_BF_EXIT_REASON_ENCLAVE_MODE_SHIFT                   27
#define VMX_BF_EXIT_REASON_ENCLAVE_MODE_MASK                    UINT32_C(0x08000000)
/** Pending MTF (Monitor Trap Flag) during VM-exit (only applicable in SMM mode). */
#define VMX_BF_EXIT_REASON_SMM_PENDING_MTF_SHIFT                28
#define VMX_BF_EXIT_REASON_SMM_PENDING_MTF_MASK                 UINT32_C(0x10000000)
/** VM-exit from VMX root operation (only possible with SMM). */
#define VMX_BF_EXIT_REASON_VMX_ROOT_MODE_SHIFT                  29
#define VMX_BF_EXIT_REASON_VMX_ROOT_MODE_MASK                   UINT32_C(0x20000000)
/** Bit 30 is reserved and MBZ. */
#define VMX_BF_EXIT_REASON_RSVD_30_SHIFT                        30
#define VMX_BF_EXIT_REASON_RSVD_30_MASK                         UINT32_C(0x40000000)
/** Whether VM-entry failed (currently only happens during loading guest-state
 *  or MSRs or machine check exceptions). */
#define VMX_BF_EXIT_REASON_ENTRY_FAILED_SHIFT                   31
#define VMX_BF_EXIT_REASON_ENTRY_FAILED_MASK                    UINT32_C(0x80000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_REASON_, UINT32_C(0), UINT32_MAX,
                            (BASIC, RSVD_16_26, ENCLAVE_MODE, SMM_PENDING_MTF, VMX_ROOT_MODE, RSVD_30, ENTRY_FAILED));
/** @} */


/** @name VM-entry interruption information.
 * @{
 */
#define VMX_ENTRY_INT_INFO_IS_VALID(a)                          (((a) >> 31) & 1)
#define VMX_ENTRY_INT_INFO_VECTOR(a)                            ((a) & 0xff)
#define VMX_ENTRY_INT_INFO_TYPE_SHIFT                           8
#define VMX_ENTRY_INT_INFO_TYPE(a)                              (((a) >> 8) & 7)
#define VMX_ENTRY_INT_INFO_ERROR_CODE_VALID                     RT_BIT(11)
#define VMX_ENTRY_INT_INFO_IS_ERROR_CODE_VALID(a)               (((a) >> 11) & 1)
#define VMX_ENTRY_INT_INFO_NMI_UNBLOCK_IRET                     12
#define VMX_ENTRY_INT_INFO_IS_NMI_UNBLOCK_IRET(a)               (((a) >> 12) & 1)
#define VMX_ENTRY_INT_INFO_VALID                                RT_BIT(31)
#define VMX_ENTRY_INT_INFO_IS_VALID(a)                          (((a) >> 31) & 1)
/** Construct an VM-entry interruption information field from a VM-exit interruption
 *  info value (same except that bit 12 is reserved). */
#define VMX_ENTRY_INT_INFO_FROM_EXIT_INT_INFO(a)                ((a) & ~RT_BIT(12))
/** Construct a VM-entry interruption information field from an IDT-vectoring
 *  information field (same except that bit 12 is reserved). */
#define VMX_ENTRY_INT_INFO_FROM_EXIT_IDT_INFO(a)                ((a) & ~RT_BIT(12))
/** If the VM-entry interruption information field indicates a page-fault. */
#define VMX_ENTRY_INT_INFO_IS_XCPT_PF(a)                        (((a) & (  VMX_BF_ENTRY_INT_INFO_VALID_MASK \
                                                                         | VMX_BF_ENTRY_INT_INFO_TYPE_MASK \
                                                                         | VMX_BF_ENTRY_INT_INFO_VECTOR_MASK)) \
                                                                     == (  RT_BF_MAKE(VMX_BF_ENTRY_INT_INFO_VALID,  1) \
                                                                         | RT_BF_MAKE(VMX_BF_ENTRY_INT_INFO_TYPE,   VMX_ENTRY_INT_INFO_TYPE_HW_XCPT) \
                                                                         | RT_BF_MAKE(VMX_BF_ENTRY_INT_INFO_VECTOR, X86_XCPT_PF)))
/** If the VM-entry interruption information field indicates an external
 *  interrupt. */
#define VMX_ENTRY_INT_INFO_IS_EXT_INT(a)                        (((a) & (  VMX_BF_ENTRY_INT_INFO_VALID_MASK \
                                                                         | VMX_BF_ENTRY_INT_INFO_TYPE_MASK)) \
                                                                     == (  RT_BF_MAKE(VMX_BF_ENTRY_INT_INFO_VALID, 1) \
                                                                         | RT_BF_MAKE(VMX_BF_ENTRY_INT_INFO_TYPE,  VMX_ENTRY_INT_INFO_TYPE_EXT_INT)))
/** If the VM-entry interruption information field indicates an NMI. */
#define VMX_ENTRY_INT_INFO_IS_XCPT_NMI(a)                       (((a) & (  VMX_BF_ENTRY_INT_INFO_VALID_MASK \
                                                                         | VMX_BF_ENTRY_INT_INFO_TYPE_MASK \
                                                                         | VMX_BF_ENTRY_INT_INFO_VECTOR_MASK)) \
                                                                     == (  RT_BF_MAKE(VMX_BF_ENTRY_INT_INFO_VALID,  1) \
                                                                         | RT_BF_MAKE(VMX_BF_ENTRY_INT_INFO_TYPE,   VMX_ENTRY_INT_INFO_TYPE_NMI) \
                                                                         | RT_BF_MAKE(VMX_BF_ENTRY_INT_INFO_VECTOR, X86_XCPT_NMI)))

/** Bit fields for VM-entry interruption information. */
/** The VM-entry interruption vector. */
#define VMX_BF_ENTRY_INT_INFO_VECTOR_SHIFT                      0
#define VMX_BF_ENTRY_INT_INFO_VECTOR_MASK                       UINT32_C(0x000000ff)
/** The VM-entry interruption type (see VMX_ENTRY_INT_INFO_TYPE_XXX). */
#define VMX_BF_ENTRY_INT_INFO_TYPE_SHIFT                        8
#define VMX_BF_ENTRY_INT_INFO_TYPE_MASK                         UINT32_C(0x00000700)
/** Whether this event has an error code. */
#define VMX_BF_ENTRY_INT_INFO_ERR_CODE_VALID_SHIFT              11
#define VMX_BF_ENTRY_INT_INFO_ERR_CODE_VALID_MASK               UINT32_C(0x00000800)
/** Bits 12:30 are reserved and MBZ. */
#define VMX_BF_ENTRY_INT_INFO_RSVD_12_30_SHIFT                  12
#define VMX_BF_ENTRY_INT_INFO_RSVD_12_30_MASK                   UINT32_C(0x7ffff000)
/** Whether this VM-entry interruption info is valid. */
#define VMX_BF_ENTRY_INT_INFO_VALID_SHIFT                       31
#define VMX_BF_ENTRY_INT_INFO_VALID_MASK                        UINT32_C(0x80000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_ENTRY_INT_INFO_, UINT32_C(0), UINT32_MAX,
                            (VECTOR, TYPE, ERR_CODE_VALID, RSVD_12_30, VALID));
/** @} */


/** @name VM-entry exception error code.
 * @{ */
/** Error code valid mask. */
/** @todo r=ramshankar: Intel spec. 26.2.1.3 "VM-Entry Control Fields" states that
 *        bits 31:15 MBZ. However, Intel spec. 6.13 "Error Code" states "To keep the
 *        stack aligned for doubleword pushes, the upper half of the error code is
 *        reserved" which implies bits 31:16 MBZ (and not 31:15) which is what we
 *        use below. */
#define VMX_ENTRY_INT_XCPT_ERR_CODE_VALID_MASK                  UINT32_C(0xffff)
/** @} */

/** @name VM-entry interruption information types.
 * @{
 */
#define VMX_ENTRY_INT_INFO_TYPE_EXT_INT                         0
#define VMX_ENTRY_INT_INFO_TYPE_RSVD                            1
#define VMX_ENTRY_INT_INFO_TYPE_NMI                             2
#define VMX_ENTRY_INT_INFO_TYPE_HW_XCPT                         3
#define VMX_ENTRY_INT_INFO_TYPE_SW_INT                          4
#define VMX_ENTRY_INT_INFO_TYPE_PRIV_SW_XCPT                    5
#define VMX_ENTRY_INT_INFO_TYPE_SW_XCPT                         6
#define VMX_ENTRY_INT_INFO_TYPE_OTHER_EVENT                     7
/** @} */


/** @name VM-entry interruption information vector types for
 *        VMX_ENTRY_INT_INFO_TYPE_OTHER_EVENT.
 * @{ */
#define VMX_ENTRY_INT_INFO_VECTOR_MTF                           0
/** @} */


/** @name VM-exit interruption information.
 * @{
 */
#define VMX_EXIT_INT_INFO_VECTOR(a)                             ((a) & 0xff)
#define VMX_EXIT_INT_INFO_TYPE_SHIFT                            8
#define VMX_EXIT_INT_INFO_TYPE(a)                               (((a) >> 8) & 7)
#define VMX_EXIT_INT_INFO_ERROR_CODE_VALID                      RT_BIT(11)
#define VMX_EXIT_INT_INFO_IS_ERROR_CODE_VALID(a)                (((a) >> 11) & 1)
#define VMX_EXIT_INT_INFO_NMI_UNBLOCK_IRET                      12
#define VMX_EXIT_INT_INFO_IS_NMI_UNBLOCK_IRET(a)                (((a) >> 12) & 1)
#define VMX_EXIT_INT_INFO_VALID                                 RT_BIT(31)
#define VMX_EXIT_INT_INFO_IS_VALID(a)                           (((a) >> 31) & 1)

/** If the VM-exit interruption information field indicates an page-fault. */
#define VMX_EXIT_INT_INFO_IS_XCPT_PF(a)                         (((a) & (  VMX_BF_EXIT_INT_INFO_VALID_MASK \
                                                                         | VMX_BF_EXIT_INT_INFO_TYPE_MASK \
                                                                         | VMX_BF_EXIT_INT_INFO_VECTOR_MASK)) \
                                                                     == (  RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VALID,  1) \
                                                                         | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_TYPE,   VMX_EXIT_INT_INFO_TYPE_HW_XCPT) \
                                                                         | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VECTOR, X86_XCPT_PF)))
/** If the VM-exit interruption information field indicates an double-fault. */
#define VMX_EXIT_INT_INFO_IS_XCPT_DF(a)                         (((a) & (  VMX_BF_EXIT_INT_INFO_VALID_MASK \
                                                                         | VMX_BF_EXIT_INT_INFO_TYPE_MASK \
                                                                         | VMX_BF_EXIT_INT_INFO_VECTOR_MASK)) \
                                                                     == (  RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VALID,  1) \
                                                                         | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_TYPE,   VMX_EXIT_INT_INFO_TYPE_HW_XCPT) \
                                                                         | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VECTOR, X86_XCPT_DF)))
/** If the VM-exit interruption information field indicates an NMI. */
#define VMX_EXIT_INT_INFO_IS_XCPT_NMI(a)                        (((a) & (  VMX_BF_EXIT_INT_INFO_VALID_MASK \
                                                                         | VMX_BF_EXIT_INT_INFO_TYPE_MASK \
                                                                         | VMX_BF_EXIT_INT_INFO_VECTOR_MASK)) \
                                                                     == (  RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VALID,  1) \
                                                                         | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_TYPE,   VMX_EXIT_INT_INFO_TYPE_NMI) \
                                                                         | RT_BF_MAKE(VMX_BF_EXIT_INT_INFO_VECTOR, X86_XCPT_NMI)))


/** Bit fields for VM-exit interruption infomration. */
/** The VM-exit interruption vector. */
#define VMX_BF_EXIT_INT_INFO_VECTOR_SHIFT                       0
#define VMX_BF_EXIT_INT_INFO_VECTOR_MASK                        UINT32_C(0x000000ff)
/** The VM-exit interruption type (see VMX_EXIT_INT_INFO_TYPE_XXX). */
#define VMX_BF_EXIT_INT_INFO_TYPE_SHIFT                         8
#define VMX_BF_EXIT_INT_INFO_TYPE_MASK                          UINT32_C(0x00000700)
/** Whether this event has an error code. */
#define VMX_BF_EXIT_INT_INFO_ERR_CODE_VALID_SHIFT               11
#define VMX_BF_EXIT_INT_INFO_ERR_CODE_VALID_MASK                UINT32_C(0x00000800)
/** Whether NMI-unblocking due to IRET is active. */
#define VMX_BF_EXIT_INT_INFO_NMI_UNBLOCK_IRET_SHIFT             12
#define VMX_BF_EXIT_INT_INFO_NMI_UNBLOCK_IRET_MASK              UINT32_C(0x00001000)
/** Bits 13:30 is reserved (MBZ). */
#define VMX_BF_EXIT_INT_INFO_RSVD_13_30_SHIFT                   13
#define VMX_BF_EXIT_INT_INFO_RSVD_13_30_MASK                    UINT32_C(0x7fffe000)
/** Whether this VM-exit interruption info is valid. */
#define VMX_BF_EXIT_INT_INFO_VALID_SHIFT                        31
#define VMX_BF_EXIT_INT_INFO_VALID_MASK                         UINT32_C(0x80000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_INT_INFO_, UINT32_C(0), UINT32_MAX,
                            (VECTOR, TYPE, ERR_CODE_VALID, NMI_UNBLOCK_IRET, RSVD_13_30, VALID));
/** @} */


/** @name VM-exit interruption information types.
 * @{
 */
#define VMX_EXIT_INT_INFO_TYPE_EXT_INT                          0
#define VMX_EXIT_INT_INFO_TYPE_NMI                              2
#define VMX_EXIT_INT_INFO_TYPE_HW_XCPT                          3
#define VMX_EXIT_INT_INFO_TYPE_SW_INT                           4
#define VMX_EXIT_INT_INFO_TYPE_PRIV_SW_XCPT                     5
#define VMX_EXIT_INT_INFO_TYPE_SW_XCPT                          6
#define VMX_EXIT_INT_INFO_TYPE_UNUSED                           7
/** @} */


/** @name VM-exit instruction identity.
 *
 * These are found in VM-exit instruction information fields for certain
 * instructions.
 * @{ */
typedef uint32_t VMXINSTRID;
/** Whether the instruction ID field is valid. */
#define VMXINSTRID_VALID                                        RT_BIT_32(31)
/** Whether the instruction's primary operand in the Mod R/M byte (bits 0:3) is a
 *  read or write. */
#define VMXINSTRID_MODRM_PRIMARY_OP_W                           RT_BIT_32(30)
/** Gets whether the instruction ID is valid or not. */
#define VMXINSTRID_IS_VALID(a)                                  (((a) >> 31) & 1)
#define VMXINSTRID_IS_MODRM_PRIMARY_OP_W(a)                     (((a) >> 30) & 1)
/** Gets the instruction ID. */
#define VMXINSTRID_GET_ID(a)                                    ((a) & ~(VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W))
/** No instruction ID info. */
#define VMXINSTRID_NONE                                         0

/** The OR'd rvalues are from the VT-x spec (valid bit is VBox specific): */
#define VMXINSTRID_SGDT                                         (0x0 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W)
#define VMXINSTRID_SIDT                                         (0x1 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W)
#define VMXINSTRID_LGDT                                         (0x2 | VMXINSTRID_VALID)
#define VMXINSTRID_LIDT                                         (0x3 | VMXINSTRID_VALID)

#define VMXINSTRID_SLDT                                         (0x0 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W)
#define VMXINSTRID_STR                                          (0x1 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W)
#define VMXINSTRID_LLDT                                         (0x2 | VMXINSTRID_VALID)
#define VMXINSTRID_LTR                                          (0x3 | VMXINSTRID_VALID)

/** The following IDs are used internally (some for logging, others for conveying
 *  the ModR/M primary operand write bit): */
#define VMXINSTRID_VMLAUNCH                                     (0x10 | VMXINSTRID_VALID)
#define VMXINSTRID_VMRESUME                                     (0x11 | VMXINSTRID_VALID)
#define VMXINSTRID_VMREAD                                       (0x12 | VMXINSTRID_VALID)
#define VMXINSTRID_VMWRITE                                      (0x13 | VMXINSTRID_VALID | VMXINSTRID_MODRM_PRIMARY_OP_W)
#define VMXINSTRID_IO_IN                                        (0x14 | VMXINSTRID_VALID)
#define VMXINSTRID_IO_INS                                       (0x15 | VMXINSTRID_VALID)
#define VMXINSTRID_IO_OUT                                       (0x16 | VMXINSTRID_VALID)
#define VMXINSTRID_IO_OUTS                                      (0x17 | VMXINSTRID_VALID)
#define VMXINSTRID_MOV_TO_DRX                                   (0x18 | VMXINSTRID_VALID)
#define VMXINSTRID_MOV_FROM_DRX                                 (0x19 | VMXINSTRID_VALID)
/** @} */


/** @name IDT-vectoring information.
 * @{
 */
#define VMX_IDT_VECTORING_INFO_VECTOR(a)                        ((a) & 0xff)
#define VMX_IDT_VECTORING_INFO_TYPE_SHIFT                       8
#define VMX_IDT_VECTORING_INFO_TYPE(a)                          (((a) >> 8) & 7)
#define VMX_IDT_VECTORING_INFO_ERROR_CODE_VALID                 RT_BIT(11)
#define VMX_IDT_VECTORING_INFO_IS_ERROR_CODE_VALID(a)           (((a) >> 11) & 1)
#define VMX_IDT_VECTORING_INFO_IS_VALID(a)                      (((a) >> 31) & 1)
#define VMX_IDT_VECTORING_INFO_VALID                            RT_BIT(31)

/** Construct an IDT-vectoring information field from an VM-entry interruption
 *  information field (same except that bit 12 is reserved). */
#define VMX_IDT_VECTORING_INFO_FROM_ENTRY_INT_INFO(a)           ((a) & ~RT_BIT(12))
/** If the IDT-vectoring information field indicates a page-fault. */
#define VMX_IDT_VECTORING_INFO_IS_XCPT_PF(a)                    (((a) & (  VMX_BF_IDT_VECTORING_INFO_VALID_MASK \
                                                                         | VMX_BF_IDT_VECTORING_INFO_TYPE_MASK \
                                                                         | VMX_BF_IDT_VECTORING_INFO_VECTOR_MASK)) \
                                                                     == (  RT_BF_MAKE(VMX_BF_IDT_VECTORING_INFO_VALID,  1) \
                                                                         | RT_BF_MAKE(VMX_BF_IDT_VECTORING_INFO_TYPE,   VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT) \
                                                                         | RT_BF_MAKE(VMX_BF_IDT_VECTORING_INFO_VECTOR, X86_XCPT_PF)))
/** If the IDT-vectoring information field indicates an NMI. */
#define VMX_IDT_VECTORING_INFO_IS_XCPT_NMI(a)                   (((a) & (  VMX_BF_IDT_VECTORING_INFO_VALID_MASK \
                                                                         | VMX_BF_IDT_VECTORING_INFO_TYPE_MASK \
                                                                         | VMX_BF_IDT_VECTORING_INFO_VECTOR_MASK)) \
                                                                     == (  RT_BF_MAKE(VMX_BF_IDT_VECTORING_INFO_VALID,  1) \
                                                                         | RT_BF_MAKE(VMX_BF_IDT_VECTORING_INFO_TYPE,   VMX_IDT_VECTORING_INFO_TYPE_NMI) \
                                                                         | RT_BF_MAKE(VMX_BF_IDT_VECTORING_INFO_VECTOR, X86_XCPT_NMI)))


/** Bit fields for IDT-vectoring information. */
/** The IDT-vectoring info vector. */
#define VMX_BF_IDT_VECTORING_INFO_VECTOR_SHIFT                  0
#define VMX_BF_IDT_VECTORING_INFO_VECTOR_MASK                   UINT32_C(0x000000ff)
/** The IDT-vectoring info type (see VMX_IDT_VECTORING_INFO_TYPE_XXX). */
#define VMX_BF_IDT_VECTORING_INFO_TYPE_SHIFT                    8
#define VMX_BF_IDT_VECTORING_INFO_TYPE_MASK                     UINT32_C(0x00000700)
/** Whether the event has an error code. */
#define VMX_BF_IDT_VECTORING_INFO_ERR_CODE_VALID_SHIFT          11
#define VMX_BF_IDT_VECTORING_INFO_ERR_CODE_VALID_MASK           UINT32_C(0x00000800)
/** Bit 12 is undefined. */
#define VMX_BF_IDT_VECTORING_INFO_UNDEF_12_SHIFT                12
#define VMX_BF_IDT_VECTORING_INFO_UNDEF_12_MASK                 UINT32_C(0x00001000)
/** Bits 13:30 is reserved (MBZ). */
#define VMX_BF_IDT_VECTORING_INFO_RSVD_13_30_SHIFT              13
#define VMX_BF_IDT_VECTORING_INFO_RSVD_13_30_MASK               UINT32_C(0x7fffe000)
/** Whether this IDT-vectoring info is valid. */
#define VMX_BF_IDT_VECTORING_INFO_VALID_SHIFT                   31
#define VMX_BF_IDT_VECTORING_INFO_VALID_MASK                    UINT32_C(0x80000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_IDT_VECTORING_INFO_, UINT32_C(0), UINT32_MAX,
                            (VECTOR, TYPE, ERR_CODE_VALID, UNDEF_12, RSVD_13_30, VALID));
/** @} */


/** @name IDT-vectoring information vector types.
 * @{
 */
#define VMX_IDT_VECTORING_INFO_TYPE_EXT_INT                     0
#define VMX_IDT_VECTORING_INFO_TYPE_NMI                         2
#define VMX_IDT_VECTORING_INFO_TYPE_HW_XCPT                     3
#define VMX_IDT_VECTORING_INFO_TYPE_SW_INT                      4
#define VMX_IDT_VECTORING_INFO_TYPE_PRIV_SW_XCPT                5
#define VMX_IDT_VECTORING_INFO_TYPE_SW_XCPT                     6
#define VMX_IDT_VECTORING_INFO_TYPE_UNUSED                      7
/** @} */


/** @name TPR threshold.
 * @{ */
/** Mask of the TPR threshold field (bits 31:4 MBZ). */
#define VMX_TPR_THRESHOLD_MASK                                   UINT32_C(0xf)

/** Bit fields for TPR threshold. */
#define VMX_BF_TPR_THRESHOLD_TPR_SHIFT                           0
#define VMX_BF_TPR_THRESHOLD_TPR_MASK                            UINT32_C(0x0000000f)
#define VMX_BF_TPR_THRESHOLD_RSVD_4_31_SHIFT                     4
#define VMX_BF_TPR_THRESHOLD_RSVD_4_31_MASK                      UINT32_C(0xfffffff0)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_TPR_THRESHOLD_, UINT32_C(0), UINT32_MAX,
                            (TPR, RSVD_4_31));
/** @} */


/** @name Guest-activity states.
 * @{
 */
/** The logical processor is active. */
#define VMX_VMCS_GUEST_ACTIVITY_ACTIVE                          0x0
/** The logical processor is inactive, because it executed a HLT instruction. */
#define VMX_VMCS_GUEST_ACTIVITY_HLT                             0x1
/** The logical processor is inactive, because of a triple fault or other serious error. */
#define VMX_VMCS_GUEST_ACTIVITY_SHUTDOWN                        0x2
/** The logical processor is inactive, because it's waiting for a startup-IPI */
#define VMX_VMCS_GUEST_ACTIVITY_SIPI_WAIT                       0x3
/** @} */


/** @name Guest-interruptibility states.
 * @{
 */
#define VMX_VMCS_GUEST_INT_STATE_BLOCK_STI                      RT_BIT(0)
#define VMX_VMCS_GUEST_INT_STATE_BLOCK_MOVSS                    RT_BIT(1)
#define VMX_VMCS_GUEST_INT_STATE_BLOCK_SMI                      RT_BIT(2)
#define VMX_VMCS_GUEST_INT_STATE_BLOCK_NMI                      RT_BIT(3)
#define VMX_VMCS_GUEST_INT_STATE_ENCLAVE                        RT_BIT(4)

/** Mask of the guest-interruptibility state field (bits 31:5 MBZ). */
#define VMX_VMCS_GUEST_INT_STATE_MASK                           UINT32_C(0x1f)
/** @} */


/** @name Exit qualification for debug exceptions.
 * @{
 */
/** Hardware breakpoint 0 was met. */
#define VMX_VMCS_EXIT_QUAL_DEBUG_XCPT_BP0                       RT_BIT_64(0)
/** Hardware breakpoint 1 was met. */
#define VMX_VMCS_EXIT_QUAL_DEBUG_XCPT_BP1                       RT_BIT_64(1)
/** Hardware breakpoint 2 was met. */
#define VMX_VMCS_EXIT_QUAL_DEBUG_XCPT_BP2                       RT_BIT_64(2)
/** Hardware breakpoint 3 was met. */
#define VMX_VMCS_EXIT_QUAL_DEBUG_XCPT_BP3                       RT_BIT_64(3)
/** Debug register access detected. */
#define VMX_VMCS_EXIT_QUAL_DEBUG_XCPT_BD                        RT_BIT_64(13)
/** A debug exception would have been triggered by single-step execution mode. */
#define VMX_VMCS_EXIT_QUAL_DEBUG_XCPT_BS                        RT_BIT_64(14)
/** Mask of all valid bits. */
#define VMX_VMCS_EXIT_QUAL_VALID_MASK                           (  VMX_VMCS_EXIT_QUAL_DEBUG_XCPT_BP0 \
                                                                 | VMX_VMCS_EXIT_QUAL_DEBUG_XCPT_BP1 \
                                                                 | VMX_VMCS_EXIT_QUAL_DEBUG_XCPT_BP2 \
                                                                 | VMX_VMCS_EXIT_QUAL_DEBUG_XCPT_BP3 \
                                                                 | VMX_VMCS_EXIT_QUAL_DEBUG_XCPT_BD  \
                                                                 | VMX_VMCS_EXIT_QUAL_DEBUG_XCPT_BS)

/** Bit fields for Exit qualifications due to debug exceptions. */
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_BP0_SHIFT                   0
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_BP0_MASK                    UINT64_C(0x0000000000000001)
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_BP1_SHIFT                   1
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_BP1_MASK                    UINT64_C(0x0000000000000002)
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_BP2_SHIFT                   2
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_BP2_MASK                    UINT64_C(0x0000000000000004)
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_BP3_SHIFT                   3
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_BP3_MASK                    UINT64_C(0x0000000000000008)
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_RSVD_4_12_SHIFT             4
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_RSVD_4_12_MASK              UINT64_C(0x0000000000001ff0)
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_BD_SHIFT                    13
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_BD_MASK                     UINT64_C(0x0000000000002000)
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_BS_SHIFT                    14
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_BS_MASK                     UINT64_C(0x0000000000004000)
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_RSVD_15_63_SHIFT            15
#define VMX_BF_EXIT_QUAL_DEBUG_XCPT_RSVD_15_63_MASK             UINT64_C(0xffffffffffff8000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_QUAL_DEBUG_XCPT_, UINT64_C(0), UINT64_MAX,
                            (BP0, BP1, BP2, BP3, RSVD_4_12, BD, BS, RSVD_15_63));
/** @} */

/** @name Exit qualification for Mov DRx.
 * @{
 */
/** 0-2:  Debug register number */
#define VMX_EXIT_QUAL_DRX_REGISTER(a)                           ((a) & 7)
/** 3:    Reserved; cleared to 0. */
#define VMX_EXIT_QUAL_DRX_RES1(a)                               (((a) >> 3) & 1)
/** 4:    Direction of move (0 = write, 1 = read) */
#define VMX_EXIT_QUAL_DRX_DIRECTION(a)                          (((a) >> 4) & 1)
/** 5-7:  Reserved; cleared to 0. */
#define VMX_EXIT_QUAL_DRX_RES2(a)                               (((a) >> 5) & 7)
/** 8-11: General purpose register number. */
#define VMX_EXIT_QUAL_DRX_GENREG(a)                             (((a) >> 8) & 0xf)

/** Bit fields for Exit qualification due to Mov DRx. */
#define VMX_BF_EXIT_QUAL_DRX_REGISTER_SHIFT                     0
#define VMX_BF_EXIT_QUAL_DRX_REGISTER_MASK                      UINT64_C(0x0000000000000007)
#define VMX_BF_EXIT_QUAL_DRX_RSVD_1_SHIFT                       3
#define VMX_BF_EXIT_QUAL_DRX_RSVD_1_MASK                        UINT64_C(0x0000000000000008)
#define VMX_BF_EXIT_QUAL_DRX_DIRECTION_SHIFT                    4
#define VMX_BF_EXIT_QUAL_DRX_DIRECTION_MASK                     UINT64_C(0x0000000000000010)
#define VMX_BF_EXIT_QUAL_DRX_RSVD_5_7_SHIFT                     5
#define VMX_BF_EXIT_QUAL_DRX_RSVD_5_7_MASK                      UINT64_C(0x00000000000000e0)
#define VMX_BF_EXIT_QUAL_DRX_GENREG_SHIFT                       8
#define VMX_BF_EXIT_QUAL_DRX_GENREG_MASK                        UINT64_C(0x0000000000000f00)
#define VMX_BF_EXIT_QUAL_DRX_RSVD_12_63_SHIFT                   12
#define VMX_BF_EXIT_QUAL_DRX_RSVD_12_63_MASK                    UINT64_C(0xfffffffffffff000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_QUAL_DRX_, UINT64_C(0), UINT64_MAX,
                            (REGISTER, RSVD_1, DIRECTION, RSVD_5_7, GENREG, RSVD_12_63));
/** @} */


/** @name Exit qualification for debug exceptions types.
 * @{
 */
#define VMX_EXIT_QUAL_DRX_DIRECTION_WRITE                       0
#define VMX_EXIT_QUAL_DRX_DIRECTION_READ                        1
/** @} */


/** @name Exit qualification for control-register accesses.
 * @{
 */
/** 0-3:   Control register number (0 for CLTS & LMSW) */
#define VMX_EXIT_QUAL_CRX_REGISTER(a)                           ((a) & 0xf)
/** 4-5:   Access type. */
#define VMX_EXIT_QUAL_CRX_ACCESS(a)                             (((a) >> 4) & 3)
/** 6:     LMSW operand type memory (1 for memory, 0 for register). */
#define VMX_EXIT_QUAL_CRX_LMSW_OP_MEM(a)                        (((a) >> 6) & 1)
/** 7:     Reserved; cleared to 0. */
#define VMX_EXIT_QUAL_CRX_RES1(a)                               (((a) >> 7) & 1)
/** 8-11:  General purpose register number (0 for CLTS & LMSW). */
#define VMX_EXIT_QUAL_CRX_GENREG(a)                             (((a) >> 8) & 0xf)
/** 12-15: Reserved; cleared to 0. */
#define VMX_EXIT_QUAL_CRX_RES2(a)                               (((a) >> 12) & 0xf)
/** 16-31: LMSW source data (else 0). */
#define VMX_EXIT_QUAL_CRX_LMSW_DATA(a)                          (((a) >> 16) & 0xffff)

/** Bit fields for Exit qualification for control-register accesses. */
#define VMX_BF_EXIT_QUAL_CRX_REGISTER_SHIFT                     0
#define VMX_BF_EXIT_QUAL_CRX_REGISTER_MASK                      UINT64_C(0x000000000000000f)
#define VMX_BF_EXIT_QUAL_CRX_ACCESS_SHIFT                       4
#define VMX_BF_EXIT_QUAL_CRX_ACCESS_MASK                        UINT64_C(0x0000000000000030)
#define VMX_BF_EXIT_QUAL_CRX_LMSW_OP_SHIFT                      6
#define VMX_BF_EXIT_QUAL_CRX_LMSW_OP_MASK                       UINT64_C(0x0000000000000040)
#define VMX_BF_EXIT_QUAL_CRX_RSVD_7_SHIFT                       7
#define VMX_BF_EXIT_QUAL_CRX_RSVD_7_MASK                        UINT64_C(0x0000000000000080)
#define VMX_BF_EXIT_QUAL_CRX_GENREG_SHIFT                       8
#define VMX_BF_EXIT_QUAL_CRX_GENREG_MASK                        UINT64_C(0x0000000000000f00)
#define VMX_BF_EXIT_QUAL_CRX_RSVD_12_15_SHIFT                   12
#define VMX_BF_EXIT_QUAL_CRX_RSVD_12_15_MASK                    UINT64_C(0x000000000000f000)
#define VMX_BF_EXIT_QUAL_CRX_LMSW_DATA_SHIFT                    16
#define VMX_BF_EXIT_QUAL_CRX_LMSW_DATA_MASK                     UINT64_C(0x00000000ffff0000)
#define VMX_BF_EXIT_QUAL_CRX_RSVD_32_63_SHIFT                   32
#define VMX_BF_EXIT_QUAL_CRX_RSVD_32_63_MASK                    UINT64_C(0xffffffff00000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_QUAL_CRX_, UINT64_C(0), UINT64_MAX,
                            (REGISTER, ACCESS, LMSW_OP, RSVD_7, GENREG, RSVD_12_15, LMSW_DATA, RSVD_32_63));
/** @} */


/** @name Exit qualification for control-register access types.
 * @{
 */
#define VMX_EXIT_QUAL_CRX_ACCESS_WRITE                          0
#define VMX_EXIT_QUAL_CRX_ACCESS_READ                           1
#define VMX_EXIT_QUAL_CRX_ACCESS_CLTS                           2
#define VMX_EXIT_QUAL_CRX_ACCESS_LMSW                           3
/** @} */


/** @name Exit qualification for task switch.
 * @{
 */
#define VMX_EXIT_QUAL_TASK_SWITCH_SELECTOR(a)                   ((a) & 0xffff)
#define VMX_EXIT_QUAL_TASK_SWITCH_TYPE(a)                       (((a) >> 30) & 0x3)
/** Task switch caused by a call instruction. */
#define VMX_EXIT_QUAL_TASK_SWITCH_TYPE_CALL                     0
/** Task switch caused by an iret instruction. */
#define VMX_EXIT_QUAL_TASK_SWITCH_TYPE_IRET                     1
/** Task switch caused by a jmp instruction. */
#define VMX_EXIT_QUAL_TASK_SWITCH_TYPE_JMP                      2
/** Task switch caused by an interrupt gate. */
#define VMX_EXIT_QUAL_TASK_SWITCH_TYPE_IDT                      3

/** Bit fields for Exit qualification for task switches. */
#define VMX_BF_EXIT_QUAL_TASK_SWITCH_NEW_TSS_SHIFT              0
#define VMX_BF_EXIT_QUAL_TASK_SWITCH_NEW_TSS_MASK               UINT64_C(0x000000000000ffff)
#define VMX_BF_EXIT_QUAL_TASK_SWITCH_RSVD_16_29_SHIFT           16
#define VMX_BF_EXIT_QUAL_TASK_SWITCH_RSVD_16_29_MASK            UINT64_C(0x000000003fff0000)
#define VMX_BF_EXIT_QUAL_TASK_SWITCH_SOURCE_SHIFT               30
#define VMX_BF_EXIT_QUAL_TASK_SWITCH_SOURCE_MASK                UINT64_C(0x00000000c0000000)
#define VMX_BF_EXIT_QUAL_TASK_SWITCH_RSVD_32_63_SHIFT           32
#define VMX_BF_EXIT_QUAL_TASK_SWITCH_RSVD_32_63_MASK            UINT64_C(0xffffffff00000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_QUAL_TASK_SWITCH_, UINT64_C(0), UINT64_MAX,
                            (NEW_TSS, RSVD_16_29, SOURCE, RSVD_32_63));
/** @} */


/** @name Exit qualification for EPT violations.
 * @{
 */
/** Set if acess causing the violation was a data read. */
#define VMX_EXIT_QUAL_EPT_ACCESS_READ                           RT_BIT_64(0)
/** Set if acess causing the violation was a data write. */
#define VMX_EXIT_QUAL_EPT_ACCESS_WRITE                          RT_BIT_64(1)
/** Set if the violation was caused by an instruction fetch. */
#define VMX_EXIT_QUAL_EPT_ACCESS_INSTR_FETCH                    RT_BIT_64(2)
/** AND of the read bit of all EPT structures. */
#define VMX_EXIT_QUAL_EPT_ENTRY_READ                            RT_BIT_64(3)
/** AND of the write bit of all EPT structures. */
#define VMX_EXIT_QUAL_EPT_ENTRY_WRITE                           RT_BIT_64(4)
/** AND of the execute bit of all EPT structures. */
#define VMX_EXIT_QUAL_EPT_ENTRY_EXECUTE                         RT_BIT_64(5)
/** And of the execute bit of all EPT structures for user-mode addresses
 *  (requires mode-based execute control). */
#define VMX_EXIT_QUAL_EPT_ENTRY_EXECUTE_USER                    RT_BIT_64(6)
/** Set if the guest linear address field is valid. */
#define VMX_EXIT_QUAL_EPT_LINEAR_ADDR_VALID                     RT_BIT_64(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_QUAL_EPT_LINEAR_TO_PHYS_ADDR                   RT_BIT_64(8)
/** If bit 7, 8 and advanced VM-exit info. for EPT is one: (reserved otherwise)
 *  1 - linear address is user-mode address.
 *  0 - linear address is supervisor-mode address.
 */
#define VMX_EXIT_QUAL_EPT_LINEAR_ADDR_USER                      RT_BIT_64(9)
/** If bit 7, 8 and advanced VM-exit info. for EPT is one: (reserved otherwise)
 *  1 - linear address translates to read-only page.
 *  0 - linear address translates to read-write page.
 */
#define VMX_EXIT_QUAL_EPT_LINEAR_ADDR_RO                        RT_BIT_64(10)
/** If bit 7, 8 and advanced VM-exit info. for EPT is one: (reserved otherwise)
 *  1 - linear address translates to executable-disabled page.
 *  0 - linear address translates to executable page.
 */
#define VMX_EXIT_QUAL_EPT_LINEAR_ADDR_XD                        RT_BIT_64(11)
/** NMI unblocking due to IRET. */
#define VMX_EXIT_QUAL_EPT_NMI_UNBLOCK_IRET                      RT_BIT_64(12)
/** Set if acess causing the violation was a shadow-stack access. */
#define VMX_EXIT_QUAL_EPT_ACCESS_SHW_STACK                      RT_BIT_64(13)
/** If supervisor-shadow stack is enabled: (reserved otherwise)
 *  1 - supervisor shadow-stack access allowed.
 *  0 - supervisor shadow-stack access disallowed.
 */
#define VMX_EXIT_QUAL_EPT_ENTRY_SHW_STACK_SUPER                 RT_BIT_64(14)
/** Set if access is related to trace output by Intel PT (reserved otherwise). */
#define VMX_EXIT_QUAL_EPT_ACCESS_PT_TRACE                       RT_BIT_64(16)

/** Checks whether NMI unblocking due to IRET. */
#define VMX_EXIT_QUAL_EPT_IS_NMI_UNBLOCK_IRET(a)                (((a) >> 12) & 1)

/** Bit fields for Exit qualification for EPT violations. */
#define VMX_BF_EXIT_QUAL_EPT_ACCESS_READ_SHIFT                  0
#define VMX_BF_EXIT_QUAL_EPT_ACCESS_READ_MASK                   UINT64_C(0x0000000000000001)
#define VMX_BF_EXIT_QUAL_EPT_ACCESS_WRITE_SHIFT                 1
#define VMX_BF_EXIT_QUAL_EPT_ACCESS_WRITE_MASK                  UINT64_C(0x0000000000000002)
#define VMX_BF_EXIT_QUAL_EPT_ACCESS_INSTR_FETCH_SHIFT           2
#define VMX_BF_EXIT_QUAL_EPT_ACCESS_INSTR_FETCH_MASK            UINT64_C(0x0000000000000004)
#define VMX_BF_EXIT_QUAL_EPT_ENTRY_READ_SHIFT                   3
#define VMX_BF_EXIT_QUAL_EPT_ENTRY_READ_MASK                    UINT64_C(0x0000000000000008)
#define VMX_BF_EXIT_QUAL_EPT_ENTRY_WRITE_SHIFT                  4
#define VMX_BF_EXIT_QUAL_EPT_ENTRY_WRITE_MASK                   UINT64_C(0x0000000000000010)
#define VMX_BF_EXIT_QUAL_EPT_ENTRY_EXECUTE_SHIFT                5
#define VMX_BF_EXIT_QUAL_EPT_ENTRY_EXECUTE_MASK                 UINT64_C(0x0000000000000020)
#define VMX_BF_EXIT_QUAL_EPT_ENTRY_EXECUTE_USER_SHIFT           6
#define VMX_BF_EXIT_QUAL_EPT_ENTRY_EXECUTE_USER_MASK            UINT64_C(0x0000000000000040)
#define VMX_BF_EXIT_QUAL_EPT_LINEAR_ADDR_VALID_SHIFT            7
#define VMX_BF_EXIT_QUAL_EPT_LINEAR_ADDR_VALID_MASK             UINT64_C(0x0000000000000080)
#define VMX_BF_EXIT_QUAL_EPT_LINEAR_TO_PHYS_ADDR_SHIFT          8
#define VMX_BF_EXIT_QUAL_EPT_LINEAR_TO_PHYS_ADDR_MASK           UINT64_C(0x0000000000000100)
#define VMX_BF_EXIT_QUAL_EPT_LINEAR_ADDR_USER_SHIFT             9
#define VMX_BF_EXIT_QUAL_EPT_LINEAR_ADDR_USER_MASK              UINT64_C(0x0000000000000200)
#define VMX_BF_EXIT_QUAL_EPT_LINEAR_ADDR_RO_SHIFT               10
#define VMX_BF_EXIT_QUAL_EPT_LINEAR_ADDR_RO_MASK                UINT64_C(0x0000000000000400)
#define VMX_BF_EXIT_QUAL_EPT_LINEAR_ADDR_XD_SHIFT               11
#define VMX_BF_EXIT_QUAL_EPT_LINEAR_ADDR_XD_MASK                UINT64_C(0x0000000000000800)
#define VMX_BF_EXIT_QUAL_EPT_NMI_UNBLOCK_IRET_SHIFT             12
#define VMX_BF_EXIT_QUAL_EPT_NMI_UNBLOCK_IRET_MASK              UINT64_C(0x0000000000001000)
#define VMX_BF_EXIT_QUAL_EPT_ACCESS_SHW_STACK_SHIFT             13
#define VMX_BF_EXIT_QUAL_EPT_ACCESS_SHW_STACK_MASK              UINT64_C(0x0000000000002000)
#define VMX_BF_EXIT_QUAL_EPT_ENTRY_SHW_STACK_SUPER_SHIFT         14
#define VMX_BF_EXIT_QUAL_EPT_ENTRY_SHW_STACK_SUPER_MASK          UINT64_C(0x0000000000004000)
#define VMX_BF_EXIT_QUAL_EPT_RSVD_15_SHIFT                      15
#define VMX_BF_EXIT_QUAL_EPT_RSVD_15_MASK                       UINT64_C(0x0000000000008000)
#define VMX_BF_EXIT_QUAL_EPT_ACCESS_PT_TRACE_SHIFT              16
#define VMX_BF_EXIT_QUAL_EPT_ACCESS_PT_TRACE_MASK               UINT64_C(0x0000000000010000)
#define VMX_BF_EXIT_QUAL_EPT_RSVD_17_63_SHIFT                   17
#define VMX_BF_EXIT_QUAL_EPT_RSVD_17_63_MASK                    UINT64_C(0xfffffffffffe0000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_QUAL_EPT_, UINT64_C(0), UINT64_MAX,
                            (ACCESS_READ, ACCESS_WRITE, ACCESS_INSTR_FETCH, ENTRY_READ, ENTRY_WRITE, ENTRY_EXECUTE,
                             ENTRY_EXECUTE_USER, LINEAR_ADDR_VALID, LINEAR_TO_PHYS_ADDR, LINEAR_ADDR_USER, LINEAR_ADDR_RO,
                             LINEAR_ADDR_XD, NMI_UNBLOCK_IRET, ACCESS_SHW_STACK, ENTRY_SHW_STACK_SUPER, RSVD_15,
                             ACCESS_PT_TRACE, RSVD_17_63));
/** @} */


/** @name Exit qualification for I/O instructions.
 * @{
 */
/** 0-2:   IO operation size 0(=1 byte), 1(=2 bytes) and 3(=4 bytes). */
#define VMX_EXIT_QUAL_IO_SIZE(a)                                ((a) & 7)
/** 3:     IO operation direction. */
#define VMX_EXIT_QUAL_IO_DIRECTION(a)                           (((a) >> 3) & 1)
/** 4:     String IO operation (INS / OUTS). */
#define VMX_EXIT_QUAL_IO_IS_STRING(a)                           (((a) >> 4) & 1)
/** 5:     Repeated IO operation. */
#define VMX_EXIT_QUAL_IO_IS_REP(a)                              (((a) >> 5) & 1)
/** 6:     Operand encoding. */
#define VMX_EXIT_QUAL_IO_ENCODING(a)                            (((a) >> 6) & 1)
/** 16-31: IO Port (0-0xffff). */
#define VMX_EXIT_QUAL_IO_PORT(a)                                (((a) >> 16) & 0xffff)

/** Bit fields for Exit qualification for I/O instructions. */
#define VMX_BF_EXIT_QUAL_IO_WIDTH_SHIFT                         0
#define VMX_BF_EXIT_QUAL_IO_WIDTH_MASK                          UINT64_C(0x0000000000000007)
#define VMX_BF_EXIT_QUAL_IO_DIRECTION_SHIFT                     3
#define VMX_BF_EXIT_QUAL_IO_DIRECTION_MASK                      UINT64_C(0x0000000000000008)
#define VMX_BF_EXIT_QUAL_IO_IS_STRING_SHIFT                     4
#define VMX_BF_EXIT_QUAL_IO_IS_STRING_MASK                      UINT64_C(0x0000000000000010)
#define VMX_BF_EXIT_QUAL_IO_IS_REP_SHIFT                        5
#define VMX_BF_EXIT_QUAL_IO_IS_REP_MASK                         UINT64_C(0x0000000000000020)
#define VMX_BF_EXIT_QUAL_IO_ENCODING_SHIFT                      6
#define VMX_BF_EXIT_QUAL_IO_ENCODING_MASK                       UINT64_C(0x0000000000000040)
#define VMX_BF_EXIT_QUAL_IO_RSVD_7_15_SHIFT                     7
#define VMX_BF_EXIT_QUAL_IO_RSVD_7_15_MASK                      UINT64_C(0x000000000000ff80)
#define VMX_BF_EXIT_QUAL_IO_PORT_SHIFT                          16
#define VMX_BF_EXIT_QUAL_IO_PORT_MASK                           UINT64_C(0x00000000ffff0000)
#define VMX_BF_EXIT_QUAL_IO_RSVD_32_63_SHIFT                    32
#define VMX_BF_EXIT_QUAL_IO_RSVD_32_63_MASK                     UINT64_C(0xffffffff00000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_QUAL_IO_, UINT64_C(0), UINT64_MAX,
                            (WIDTH, DIRECTION, IS_STRING, IS_REP, ENCODING, RSVD_7_15, PORT, RSVD_32_63));
/** @} */


/** @name Exit qualification for I/O instruction types.
 * @{
 */
#define VMX_EXIT_QUAL_IO_DIRECTION_OUT                          0
#define VMX_EXIT_QUAL_IO_DIRECTION_IN                           1
/** @} */


/** @name Exit qualification for I/O instruction encoding.
 * @{
 */
#define VMX_EXIT_QUAL_IO_ENCODING_DX                            0
#define VMX_EXIT_QUAL_IO_ENCODING_IMM                           1
/** @} */


/** @name Exit qualification for APIC-access VM-exits from linear and
 *        guest-physical accesses.
 * @{
 */
/** 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_QUAL_APIC_ACCESS_OFFSET(a)                     ((a) & 0xfff)
/** 12-15: Access type. */
#define VMX_EXIT_QUAL_APIC_ACCESS_TYPE(a)                       (((a) & 0xf000) >> 12)
/* Rest reserved. */

/** Bit fields for Exit qualification for APIC-access VM-exits. */
#define VMX_BF_EXIT_QUAL_APIC_ACCESS_OFFSET_SHIFT               0
#define VMX_BF_EXIT_QUAL_APIC_ACCESS_OFFSET_MASK                UINT64_C(0x0000000000000fff)
#define VMX_BF_EXIT_QUAL_APIC_ACCESS_TYPE_SHIFT                 12
#define VMX_BF_EXIT_QUAL_APIC_ACCESS_TYPE_MASK                  UINT64_C(0x000000000000f000)
#define VMX_BF_EXIT_QUAL_APIC_ACCESS_RSVD_16_63_SHIFT           16
#define VMX_BF_EXIT_QUAL_APIC_ACCESS_RSVD_16_63_MASK            UINT64_C(0xffffffffffff0000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_EXIT_QUAL_APIC_ACCESS_, UINT64_C(0), UINT64_MAX,
                            (OFFSET, TYPE, RSVD_16_63));
/** @} */


/** @name Exit qualification for linear address APIC-access types.
 * @{
 */
/** Linear access for a data read during instruction execution. */
#define VMX_APIC_ACCESS_TYPE_LINEAR_READ                        0
/** Linear access for a data write during instruction execution. */
#define VMX_APIC_ACCESS_TYPE_LINEAR_WRITE                       1
/** Linear access for an instruction fetch. */
#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

/**
 * APIC-access type.
 * In accordance with the VT-x spec.
 */
typedef enum
{
    VMXAPICACCESS_LINEAR_READ             = VMX_APIC_ACCESS_TYPE_LINEAR_READ,
    VMXAPICACCESS_LINEAR_WRITE            = VMX_APIC_ACCESS_TYPE_LINEAR_WRITE,
    VMXAPICACCESS_LINEAR_INSTR_FETCH      = VMX_APIC_ACCESS_TYPE_LINEAR_INSTR_FETCH,
    VMXAPICACCESS_LINEAR_EVENT_DELIVERY   = VMX_APIC_ACCESS_TYPE_LINEAR_EVENT_DELIVERY,
    VMXAPICACCESS_PHYSICAL_EVENT_DELIVERY = VMX_APIC_ACCESS_TYPE_PHYSICAL_EVENT_DELIVERY,
    VMXAPICACCESS_PHYSICAL_INSTR          = VMX_APIC_ACCESS_TYPE_PHYSICAL_INSTR
} VMXAPICACCESS;
AssertCompileSize(VMXAPICACCESS, 4);
/** @} */


/** @name VMX_BF_XXTR_INSINFO_XXX - VMX_EXIT_XDTR_ACCESS instruction information.
 * Found in VMX_VMCS32_RO_EXIT_INSTR_INFO.
 * @{
 */
/** Address calculation scaling field (powers of two). */
#define VMX_BF_XDTR_INSINFO_SCALE_SHIFT                         0
#define VMX_BF_XDTR_INSINFO_SCALE_MASK                          UINT32_C(0x00000003)
/** Bits 2 thru 6 are undefined. */
#define VMX_BF_XDTR_INSINFO_UNDEF_2_6_SHIFT                     2
#define VMX_BF_XDTR_INSINFO_UNDEF_2_6_MASK                      UINT32_C(0x0000007c)
/** Address size, only 0(=16), 1(=32) and 2(=64) are defined.
 * @remarks anyone's guess why this is a 3 bit field... */
#define VMX_BF_XDTR_INSINFO_ADDR_SIZE_SHIFT                     7
#define VMX_BF_XDTR_INSINFO_ADDR_SIZE_MASK                      UINT32_C(0x00000380)
/** Bit 10 is defined as zero. */
#define VMX_BF_XDTR_INSINFO_ZERO_10_SHIFT                       10
#define VMX_BF_XDTR_INSINFO_ZERO_10_MASK                        UINT32_C(0x00000400)
/** Operand size, either (1=)32-bit or (0=)16-bit, but get this, it's undefined
 * for exits from 64-bit code as the operand size there is fixed. */
#define VMX_BF_XDTR_INSINFO_OP_SIZE_SHIFT                       11
#define VMX_BF_XDTR_INSINFO_OP_SIZE_MASK                        UINT32_C(0x00000800)
/** Bits 12 thru 14 are undefined. */
#define VMX_BF_XDTR_INSINFO_UNDEF_12_14_SHIFT                   12
#define VMX_BF_XDTR_INSINFO_UNDEF_12_14_MASK                    UINT32_C(0x00007000)
/** Applicable segment register (X86_SREG_XXX values). */
#define VMX_BF_XDTR_INSINFO_SREG_SHIFT                          15
#define VMX_BF_XDTR_INSINFO_SREG_MASK                           UINT32_C(0x00038000)
/** Index register (X86_GREG_XXX values). Undefined if HAS_INDEX_REG is clear. */
#define VMX_BF_XDTR_INSINFO_INDEX_REG_SHIFT                     18
#define VMX_BF_XDTR_INSINFO_INDEX_REG_MASK                      UINT32_C(0x003c0000)
/** Is VMX_BF_XDTR_INSINFO_INDEX_REG_XXX valid (=1) or not (=0). */
#define VMX_BF_XDTR_INSINFO_HAS_INDEX_REG_SHIFT                 22
#define VMX_BF_XDTR_INSINFO_HAS_INDEX_REG_MASK                  UINT32_C(0x00400000)
/** Base register (X86_GREG_XXX values). Undefined if HAS_BASE_REG is clear. */
#define VMX_BF_XDTR_INSINFO_BASE_REG_SHIFT                      23
#define VMX_BF_XDTR_INSINFO_BASE_REG_MASK                       UINT32_C(0x07800000)
/** Is VMX_XDTR_INSINFO_BASE_REG_XXX valid (=1) or not (=0). */
#define VMX_BF_XDTR_INSINFO_HAS_BASE_REG_SHIFT                  27
#define VMX_BF_XDTR_INSINFO_HAS_BASE_REG_MASK                   UINT32_C(0x08000000)
/** The instruction identity (VMX_XDTR_INSINFO_II_XXX values). */
#define VMX_BF_XDTR_INSINFO_INSTR_ID_SHIFT                      28
#define VMX_BF_XDTR_INSINFO_INSTR_ID_MASK                       UINT32_C(0x30000000)
#define VMX_XDTR_INSINFO_II_SGDT                                0 /**< Instruction ID: SGDT */
#define VMX_XDTR_INSINFO_II_SIDT                                1 /**< Instruction ID: SIDT */
#define VMX_XDTR_INSINFO_II_LGDT                                2 /**< Instruction ID: LGDT */
#define VMX_XDTR_INSINFO_II_LIDT                                3 /**< Instruction ID: LIDT */
/** Bits 30 & 31 are undefined. */
#define VMX_BF_XDTR_INSINFO_UNDEF_30_31_SHIFT                   30
#define VMX_BF_XDTR_INSINFO_UNDEF_30_31_MASK                    UINT32_C(0xc0000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_XDTR_INSINFO_, UINT32_C(0), UINT32_MAX,
                            (SCALE, UNDEF_2_6, ADDR_SIZE, ZERO_10, OP_SIZE, UNDEF_12_14, SREG, INDEX_REG, HAS_INDEX_REG,
                             BASE_REG, HAS_BASE_REG, INSTR_ID, UNDEF_30_31));
/** @} */


/** @name VMX_BF_YYTR_INSINFO_XXX - VMX_EXIT_TR_ACCESS instruction information.
 * Found in VMX_VMCS32_RO_EXIT_INSTR_INFO.
 * This is similar to VMX_BF_XDTR_INSINFO_XXX.
 * @{
 */
/** Address calculation scaling field (powers of two). */
#define VMX_BF_YYTR_INSINFO_SCALE_SHIFT                         0
#define VMX_BF_YYTR_INSINFO_SCALE_MASK                          UINT32_C(0x00000003)
/** Bit 2 is undefined. */
#define VMX_BF_YYTR_INSINFO_UNDEF_2_SHIFT                       2
#define VMX_BF_YYTR_INSINFO_UNDEF_2_MASK                        UINT32_C(0x00000004)
/** Register operand 1. Undefined if VMX_YYTR_INSINFO_HAS_REG1 is clear. */
#define VMX_BF_YYTR_INSINFO_REG1_SHIFT                          3
#define VMX_BF_YYTR_INSINFO_REG1_MASK                           UINT32_C(0x00000078)
/** Address size, only 0(=16), 1(=32) and 2(=64) are defined.
 * @remarks anyone's guess why this is a 3 bit field... */
#define VMX_BF_YYTR_INSINFO_ADDR_SIZE_SHIFT                     7
#define VMX_BF_YYTR_INSINFO_ADDR_SIZE_MASK                      UINT32_C(0x00000380)
/** Is VMX_YYTR_INSINFO_REG1_XXX valid (=1) or not (=0). */
#define VMX_BF_YYTR_INSINFO_HAS_REG1_SHIFT                      10
#define VMX_BF_YYTR_INSINFO_HAS_REG1_MASK                       UINT32_C(0x00000400)
/** Bits 11 thru 14 are undefined. */
#define VMX_BF_YYTR_INSINFO_UNDEF_11_14_SHIFT                   11
#define VMX_BF_YYTR_INSINFO_UNDEF_11_14_MASK                    UINT32_C(0x00007800)
/** Applicable segment register (X86_SREG_XXX values). */
#define VMX_BF_YYTR_INSINFO_SREG_SHIFT                          15
#define VMX_BF_YYTR_INSINFO_SREG_MASK                           UINT32_C(0x00038000)
/** Index register (X86_GREG_XXX values). Undefined if HAS_INDEX_REG is clear. */
#define VMX_BF_YYTR_INSINFO_INDEX_REG_SHIFT                     18
#define VMX_BF_YYTR_INSINFO_INDEX_REG_MASK                      UINT32_C(0x003c0000)
/** Is VMX_YYTR_INSINFO_INDEX_REG_XXX valid (=1) or not (=0). */
#define VMX_BF_YYTR_INSINFO_HAS_INDEX_REG_SHIFT                 22
#define VMX_BF_YYTR_INSINFO_HAS_INDEX_REG_MASK                  UINT32_C(0x00400000)
/** Base register (X86_GREG_XXX values). Undefined if HAS_BASE_REG is clear. */
#define VMX_BF_YYTR_INSINFO_BASE_REG_SHIFT                      23
#define VMX_BF_YYTR_INSINFO_BASE_REG_MASK                       UINT32_C(0x07800000)
/** Is VMX_YYTR_INSINFO_BASE_REG_XXX valid (=1) or not (=0). */
#define VMX_BF_YYTR_INSINFO_HAS_BASE_REG_SHIFT                  27
#define VMX_BF_YYTR_INSINFO_HAS_BASE_REG_MASK                   UINT32_C(0x08000000)
/** The instruction identity (VMX_YYTR_INSINFO_II_XXX values) */
#define VMX_BF_YYTR_INSINFO_INSTR_ID_SHIFT                      28
#define VMX_BF_YYTR_INSINFO_INSTR_ID_MASK                       UINT32_C(0x30000000)
#define VMX_YYTR_INSINFO_II_SLDT                                0 /**< Instruction ID: SLDT */
#define VMX_YYTR_INSINFO_II_STR                                 1 /**< Instruction ID: STR */
#define VMX_YYTR_INSINFO_II_LLDT                                2 /**< Instruction ID: LLDT */
#define VMX_YYTR_INSINFO_II_LTR                                 3 /**< Instruction ID: LTR */
/** Bits 30 & 31 are undefined. */
#define VMX_BF_YYTR_INSINFO_UNDEF_30_31_SHIFT                   30
#define VMX_BF_YYTR_INSINFO_UNDEF_30_31_MASK                    UINT32_C(0xc0000000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_YYTR_INSINFO_, UINT32_C(0), UINT32_MAX,
                            (SCALE, UNDEF_2, REG1, ADDR_SIZE, HAS_REG1, UNDEF_11_14, SREG, INDEX_REG, HAS_INDEX_REG,
                             BASE_REG, HAS_BASE_REG, INSTR_ID, UNDEF_30_31));
/** @} */


/** @name Format of Pending-Debug-Exceptions.
 * Bits 4-11, 13, 15 and 17-63 are reserved.
 * Similar to DR6 except bit 12 (breakpoint enabled) and bit 16 (RTM) are both
 * possibly valid here but not in DR6.
 * @{
 */
/** Hardware breakpoint 0 was met. */
#define VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BP0                   RT_BIT_64(0)
/** Hardware breakpoint 1 was met. */
#define VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BP1                   RT_BIT_64(1)
/** Hardware breakpoint 2 was met. */
#define VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BP2                   RT_BIT_64(2)
/** Hardware breakpoint 3 was met. */
#define VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BP3                   RT_BIT_64(3)
/** At least one data or IO breakpoint was hit. */
#define VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_EN_BP                 RT_BIT_64(12)
/** A debug exception would have been triggered by single-step execution mode. */
#define VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BS                    RT_BIT_64(14)
/** A debug exception occurred inside an RTM region. */
#define VMX_VMCS_GUEST_PENDING_DEBUG_RTM                        RT_BIT_64(16)
/** Mask of valid bits. */
#define VMX_VMCS_GUEST_PENDING_DEBUG_VALID_MASK                 (  VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BP0 \
                                                                 | VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BP1 \
                                                                 | VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BP2 \
                                                                 | VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BP3 \
                                                                 | VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_EN_BP \
                                                                 | VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BS \
                                                                 | VMX_VMCS_GUEST_PENDING_DEBUG_RTM)
#define VMX_VMCS_GUEST_PENDING_DEBUG_RTM_MASK                   (  VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_EN_BP \
                                                                 | VMX_VMCS_GUEST_PENDING_DEBUG_XCPT_BS \
                                                                 | VMX_VMCS_GUEST_PENDING_DEBUG_RTM)
/** Bit fields for Pending debug exceptions. */
#define VMX_BF_VMCS_PENDING_DBG_XCPT_BP0_SHIFT                  0
#define VMX_BF_VMCS_PENDING_DBG_XCPT_BP0_MASK                   UINT64_C(0x0000000000000001)
#define VMX_BF_VMCS_PENDING_DBG_XCPT_BP1_SHIFT                  1
#define VMX_BF_VMCS_PENDING_DBG_XCPT_BP1_MASK                   UINT64_C(0x0000000000000002)
#define VMX_BF_VMCS_PENDING_DBG_XCPT_BP2_SHIFT                  2
#define VMX_BF_VMCS_PENDING_DBG_XCPT_BP2_MASK                   UINT64_C(0x0000000000000004)
#define VMX_BF_VMCS_PENDING_DBG_XCPT_BP3_SHIFT                  3
#define VMX_BF_VMCS_PENDING_DBG_XCPT_BP3_MASK                   UINT64_C(0x0000000000000008)
#define VMX_BF_VMCS_PENDING_DBG_XCPT_RSVD_4_11_SHIFT            4
#define VMX_BF_VMCS_PENDING_DBG_XCPT_RSVD_4_11_MASK             UINT64_C(0x0000000000000ff0)
#define VMX_BF_VMCS_PENDING_DBG_XCPT_EN_BP_SHIFT                12
#define VMX_BF_VMCS_PENDING_DBG_XCPT_EN_BP_MASK                 UINT64_C(0x0000000000001000)
#define VMX_BF_VMCS_PENDING_DBG_XCPT_RSVD_13_SHIFT              13
#define VMX_BF_VMCS_PENDING_DBG_XCPT_RSVD_13_MASK               UINT64_C(0x0000000000002000)
#define VMX_BF_VMCS_PENDING_DBG_XCPT_BS_SHIFT                   14
#define VMX_BF_VMCS_PENDING_DBG_XCPT_BS_MASK                    UINT64_C(0x0000000000004000)
#define VMX_BF_VMCS_PENDING_DBG_XCPT_RSVD_15_SHIFT              15
#define VMX_BF_VMCS_PENDING_DBG_XCPT_RSVD_15_MASK               UINT64_C(0x0000000000008000)
#define VMX_BF_VMCS_PENDING_DBG_XCPT_RTM_SHIFT                  16
#define VMX_BF_VMCS_PENDING_DBG_XCPT_RTM_MASK                   UINT64_C(0x0000000000010000)
#define VMX_BF_VMCS_PENDING_DBG_XCPT_RSVD_17_63_SHIFT           17
#define VMX_BF_VMCS_PENDING_DBG_XCPT_RSVD_17_63_MASK            UINT64_C(0xfffffffffffe0000)
RT_BF_ASSERT_COMPILE_CHECKS(VMX_BF_VMCS_PENDING_DBG_XCPT_, UINT64_C(0), UINT64_MAX,
                            (BP0, BP1, BP2, BP3, RSVD_4_11, EN_BP, RSVD_13, BS, RSVD_15, RTM, RSVD_17_63));
/** @} */


/**
 * VM-exit auxiliary information.
 *
 * This includes information that isn't necessarily stored in the guest-CPU
 * context but provided as part of VM-exits.
 */
typedef struct
{
    /** The VM-exit reason. */
    uint32_t                uReason;
    /** The Exit qualification field. */
    uint64_t                u64Qual;
    /** The Guest-linear address field. */
    uint64_t                u64GuestLinearAddr;
    /** The Guest-physical address field. */
    uint64_t                u64GuestPhysAddr;
    /** The guest pending-debug exceptions. */
    uint64_t                u64GuestPendingDbgXcpts;
    /** The VM-exit instruction length. */
    uint32_t                cbInstr;
    /** The VM-exit instruction information. */
    VMXEXITINSTRINFO        InstrInfo;
    /** VM-exit interruption information. */
    uint32_t                uExitIntInfo;
    /** VM-exit interruption error code. */
    uint32_t                uExitIntErrCode;
    /** IDT-vectoring information. */
    uint32_t                uIdtVectoringInfo;
    /** IDT-vectoring error code. */
    uint32_t                uIdtVectoringErrCode;
} VMXEXITAUX;
/** Pointer to a VMXEXITAUX struct. */
typedef VMXEXITAUX *PVMXEXITAUX;
/** Pointer to a const VMXEXITAUX struct. */
typedef const VMXEXITAUX *PCVMXEXITAUX;


/** @defgroup grp_hm_vmx_virt    VMX virtualization.
 * @{
 */

/** @name Virtual VMX MSR - Miscellaneous data.
 * @{ */
/** Number of CR3-target values supported. */
#define VMX_V_CR3_TARGET_COUNT                                  4
/** Activity states supported. */
#define VMX_V_GUEST_ACTIVITY_STATE_MASK                         (VMX_VMCS_GUEST_ACTIVITY_HLT | VMX_VMCS_GUEST_ACTIVITY_SHUTDOWN)
/** VMX preemption-timer shift (Core i7-2600 taken as reference). */
#define VMX_V_PREEMPT_TIMER_SHIFT                               5
/** Maximum number of MSRs in the auto-load/store MSR areas, (n+1) * 512. */
#define VMX_V_AUTOMSR_COUNT_MAX                                 0
/** SMM MSEG revision ID. */
#define VMX_V_MSEG_REV_ID                                       0
/** @} */

/** @name VMX_V_VMCS_STATE_XXX - Virtual VMCS launch state.
 * @{ */
/** VMCS launch state clear. */
#define VMX_V_VMCS_LAUNCH_STATE_CLEAR                           RT_BIT(0)
/** VMCS launch state active. */
#define VMX_V_VMCS_LAUNCH_STATE_ACTIVE                          RT_BIT(1)
/** VMCS launch state current. */
#define VMX_V_VMCS_LAUNCH_STATE_CURRENT                         RT_BIT(2)
/** VMCS launch state launched. */
#define VMX_V_VMCS_LAUNCH_STATE_LAUNCHED                        RT_BIT(3)
/** The mask of valid VMCS launch states. */
#define VMX_V_VMCS_LAUNCH_STATE_MASK                            (  VMX_V_VMCS_LAUNCH_STATE_CLEAR \
                                                                 | VMX_V_VMCS_LAUNCH_STATE_ACTIVE \
                                                                 | VMX_V_VMCS_LAUNCH_STATE_CURRENT \
                                                                 | VMX_V_VMCS_LAUNCH_STATE_LAUNCHED)
/** @} */

/** CR0 bits set here must always be set when in VMX operation. */
#define VMX_V_CR0_FIXED0                                        (X86_CR0_PE | X86_CR0_NE | X86_CR0_PG)
/** CR0 bits set here must always be set when in VMX non-root operation with
 *  unrestricted-guest control enabled. */
#define VMX_V_CR0_FIXED0_UX                                     (X86_CR0_NE)
/** CR0 bits cleared here must always be cleared when in VMX operation. */
#define VMX_V_CR0_FIXED1                                        UINT32_C(0xffffffff)
/** CR4 bits set here must always be set when in VMX operation. */
#define VMX_V_CR4_FIXED0                                        (X86_CR4_VMXE)

/** Virtual VMCS revision ID. Bump this arbitarily chosen identifier if incompatible
 *  changes to the layout of VMXVVMCS is done. Bit 31 MBZ. */
#define VMX_V_VMCS_REVISION_ID                                  UINT32_C(0x40000001)
AssertCompile(!(VMX_V_VMCS_REVISION_ID & RT_BIT(31)));

/** The size of the virtual VMCS region (we use the maximum allowed size to avoid
 *  complications when teleporation may be implemented). */
#define VMX_V_VMCS_SIZE                                         X86_PAGE_4K_SIZE
/** The size of the virtual VMCS region (in pages). */
#define VMX_V_VMCS_PAGES                                        1

/** The size of the virtual shadow VMCS region. */
#define VMX_V_SHADOW_VMCS_SIZE                                  VMX_V_VMCS_SIZE
/** The size of the virtual shadow VMCS region (in pages). */
#define VMX_V_SHADOW_VMCS_PAGES                                 VMX_V_VMCS_PAGES

/** The size of the Virtual-APIC page (in bytes). */
#define VMX_V_VIRT_APIC_SIZE                                    X86_PAGE_4K_SIZE
/** The size of the Virtual-APIC page (in pages). */
#define VMX_V_VIRT_APIC_PAGES                                   1

/** The size of the VMREAD/VMWRITE bitmap (in bytes). */
#define VMX_V_VMREAD_VMWRITE_BITMAP_SIZE                        X86_PAGE_4K_SIZE
/** The size of the VMREAD/VMWRITE-bitmap (in pages). */
#define VMX_V_VMREAD_VMWRITE_BITMAP_PAGES                       1

/** The size of the MSR bitmap (in bytes). */
#define VMX_V_MSR_BITMAP_SIZE                                   X86_PAGE_4K_SIZE
/** The size of the MSR bitmap (in pages). */
#define VMX_V_MSR_BITMAP_PAGES                                  1

/** The size of I/O bitmap A (in bytes). */
#define VMX_V_IO_BITMAP_A_SIZE                                  X86_PAGE_4K_SIZE
/** The size of I/O bitmap A (in pages). */
#define VMX_V_IO_BITMAP_A_PAGES                                 1

/** The size of I/O bitmap B (in bytes). */
#define VMX_V_IO_BITMAP_B_SIZE                                  X86_PAGE_4K_SIZE
/** The size of I/O bitmap B (in pages). */
#define VMX_V_IO_BITMAP_B_PAGES                                 1

/** The size of the auto-load/store MSR area (in bytes). */
#define VMX_V_AUTOMSR_AREA_SIZE                                 ((512 * (VMX_V_AUTOMSR_COUNT_MAX + 1)) * sizeof(VMXAUTOMSR))
/* Assert that the size is page aligned or adjust the VMX_V_AUTOMSR_AREA_PAGES macro below. */
AssertCompile(RT_ALIGN_Z(VMX_V_AUTOMSR_AREA_SIZE, X86_PAGE_4K_SIZE) == VMX_V_AUTOMSR_AREA_SIZE);
/** The size of the auto-load/store MSR area (in pages). */
#define VMX_V_AUTOMSR_AREA_PAGES                                ((VMX_V_AUTOMSR_AREA_SIZE) >> X86_PAGE_4K_SHIFT)

/** The highest index value used for supported virtual VMCS field encoding. */
#define VMX_V_VMCS_MAX_INDEX                                    RT_BF_GET(VMX_VMCS64_CTRL_EXIT2_HIGH, VMX_BF_VMCSFIELD_INDEX)

/**
 * Virtual VM-exit information.
 *
 * This is a convenience structure that bundles some VM-exit information related
 * fields together.
 */
typedef struct
{
    /** The VM-exit reason. */
    uint32_t                uReason;
    /** The VM-exit instruction length. */
    uint32_t                cbInstr;
    /** The VM-exit instruction information. */
    VMXEXITINSTRINFO        InstrInfo;
    /** The VM-exit instruction ID. */
    VMXINSTRID              uInstrId;

    /** The Exit qualification field. */
    uint64_t                u64Qual;
    /** The Guest-linear address field. */
    uint64_t                u64GuestLinearAddr;
    /** The Guest-physical address field. */
    uint64_t                u64GuestPhysAddr;
    /** The guest pending-debug exceptions. */
    uint64_t                u64GuestPendingDbgXcpts;
    /** The effective guest-linear address if @a InstrInfo indicates a memory-based
     *  instruction VM-exit. */
    RTGCPTR                 GCPtrEffAddr;
} VMXVEXITINFO;
/** Pointer to the VMXVEXITINFO struct. */
typedef VMXVEXITINFO *PVMXVEXITINFO;
/** Pointer to a const VMXVEXITINFO struct. */
typedef const VMXVEXITINFO *PCVMXVEXITINFO;
AssertCompileMemberAlignment(VMXVEXITINFO, u64Qual, 8);

/** Initialize a VMXVEXITINFO structure from only an exit reason. */
#define VMXVEXITINFO_INIT_ONLY_REASON(a_uReason) \
    { (a_uReason), 0, { 0 }, VMXINSTRID_NONE, 0, 0, 0, 0, 0 }

/** Initialize a VMXVEXITINFO structure from exit reason and instruction length (no info). */
#define VMXVEXITINFO_INIT_WITH_INSTR_LEN(a_uReason, a_cbInstr) \
    { (a_uReason), (a_cbInstr), { 0 }, VMXINSTRID_NONE, 0, 0, 0, 0, 0 }

/** Initialize a VMXVEXITINFO structure from exit reason and exit qualification. */
#define VMXVEXITINFO_INIT_WITH_QUAL(a_uReason, a_uQual) \
    { (a_uReason), 0, { 0 }, VMXINSTRID_NONE, (a_uQual), 0, 0, 0, 0 }

/** Initialize a VMXVEXITINFO structure from exit reason, exit qualification,
 *  instruction info and length. */
#define VMXVEXITINFO_INIT_WITH_QUAL_AND_INSTR_INFO(a_uReason, a_uQual, a_uInstrInfo, a_cbInstr) \
    { (a_uReason), (a_cbInstr), { a_uInstrInfo }, VMXINSTRID_NONE, (a_uQual), 0, 0, 0, 0 }

/** Initialize a VMXVEXITINFO structure from exit reason, exit qualification,
 *  instruction info and length all copied from a VMXTRANSIENT structure. */
#define VMXVEXITINFO_INIT_WITH_QUAL_AND_INSTR_INFO_FROM_TRANSIENT(a_pVmxTransient) \
    VMXVEXITINFO_INIT_WITH_QUAL_AND_INSTR_INFO((a_pVmxTransient)->uExitReason, \
                                               (a_pVmxTransient)->uExitQual, \
                                               (a_pVmxTransient)->ExitInstrInfo.u, \
                                               (a_pVmxTransient)->cbExitInstr)

/** Initialize a VMXVEXITINFO structure from exit reason, exit qualification,
 *  instruction length (no info). */
#define VMXVEXITINFO_INIT_WITH_QUAL_AND_INSTR_LEN(a_uReason, a_uQual, a_cbInstr) \
    { (a_uReason), (a_cbInstr), { 0 }, VMXINSTRID_NONE, (a_uQual), 0, 0, 0, 0 }

/** Initialize a VMXVEXITINFO structure from exit reason, exit qualification and
 *  instruction length (no info) all copied from a VMXTRANSIENT structure. */
#define VMXVEXITINFO_INIT_WITH_QUAL_AND_INSTR_LEN_FROM_TRANSIENT(a_pVmxTransient) \
    VMXVEXITINFO_INIT_WITH_QUAL_AND_INSTR_LEN((a_pVmxTransient)->uExitReason, \
                                              (a_pVmxTransient)->uExitQual, \
                                              (a_pVmxTransient)->cbExitInstr)

/** Initialize a VMXVEXITINFO structure from exit reason, exit qualification,
 *  instruction info, instruction length and guest linear address. */
#define VMXVEXITINFO_INIT_WITH_QUAL_AND_INSTR_INFO_AND_LIN_ADDR(a_uReason, a_uQual, a_uInstrInfo, \
                                                                a_cbInstr, a_uGstLinAddr) \
    { (a_uReason), (a_cbInstr), { (a_uInstrInfo) }, VMXINSTRID_NONE, (a_uQual), (a_uGstLinAddr), 0, 0, 0 }

/** Initialize a VMXVEXITINFO structure from exit reason, exit qualification,
 *  instruction info, instruction length and guest linear address all copied
 *  from a VMXTRANSIENT structure. */
#define VMXVEXITINFO_INIT_WITH_QUAL_AND_INSTR_INFO_AND_LIN_ADDR_FROM_TRANSIENT(a_pVmxTransient) \
    VMXVEXITINFO_INIT_WITH_QUAL_AND_INSTR_INFO_AND_LIN_ADDR((a_pVmxTransient)->uExitReason, \
                                                            (a_pVmxTransient)->uExitQual, \
                                                            (a_pVmxTransient)->ExitInstrInfo.u, \
                                                            (a_pVmxTransient)->cbExitInstr, \
                                                            (a_pVmxTransient)->uGuestLinearAddr)

/** Initialize a VMXVEXITINFO structure from exit reason and pending debug
 *  exceptions. */
#define VMXVEXITINFO_INIT_WITH_DBG_XCPTS(a_uReason, a_uPendingDbgXcpts) \
    { (a_uReason), 0, { 0 }, VMXINSTRID_NONE, 0, 0, 0, (a_uPendingDbgXcpts), 0 }

/** Initialize a VMXVEXITINFO structure from exit reason and pending debug
 *  exceptions both copied from a VMXTRANSIENT structure. */
#define VMXVEXITINFO_INIT_WITH_DBG_XCPTS_FROM_TRANSIENT(a_pVmxTransient) \
    VMXVEXITINFO_INIT_WITH_DBG_XCPTS((a_pVmxTransient)->uExitReason, (a_pVmxTransient)->uGuestPendingDbgXcpts)


/** Initialize a VMXVEXITINFO structure from exit reason, exit qualification,
 *  instruction length, guest linear address and guest physical address. */
#define VMXVEXITINFO_INIT_WITH_QUAL_AND_INSTR_LEN_AND_GST_ADDRESSES(a_uReason, a_uQual, a_cbInstr, \
                                                                    a_uGstLinAddr, a_uGstPhysAddr) \
    { (a_uReason), (a_cbInstr), { 0 }, VMXINSTRID_NONE, (a_uQual), (a_uGstLinAddr), (a_uGstPhysAddr), 0, 0 }


/**
 * Virtual VM-exit information for events.
 *
 * This is a convenience structure that bundles some event-based VM-exit information
 * related fields together that are not included in VMXVEXITINFO.
 *
 * This is kept as a separate structure and not included in VMXVEXITINFO, to make it
 * easier to distinguish that IEM VM-exit handlers will set one or more of the
 * following fields in the virtual VMCS. Including it in the VMXVEXITINFO will not
 * make it ovbious which fields may get set (or cleared).
 */
typedef struct
{
    /** VM-exit interruption information. */
    uint32_t                uExitIntInfo;
    /** VM-exit interruption error code. */
    uint32_t                uExitIntErrCode;
    /** IDT-vectoring information. */
    uint32_t                uIdtVectoringInfo;
    /** IDT-vectoring error code. */
    uint32_t                uIdtVectoringErrCode;
} VMXVEXITEVENTINFO;
/** Pointer to the VMXVEXITEVENTINFO struct. */
typedef VMXVEXITEVENTINFO *PVMXVEXITEVENTINFO;
/** Pointer to a const VMXVEXITEVENTINFO struct. */
typedef const VMXVEXITEVENTINFO *PCVMXVEXITEVENTINFO;

/** Initialize a VMXVEXITEVENTINFO. */
#define VMXVEXITEVENTINFO_INIT(a_uExitIntInfo, a_uExitIntErrCode, a_uIdtVectoringInfo, a_uIdtVectoringErrCode) \
    { (a_uExitIntInfo), (a_uExitIntErrCode), (a_uIdtVectoringInfo), (a_uIdtVectoringErrCode) }

/** Initialize a VMXVEXITEVENTINFO with VM-exit interruption info and VM-exit
 *  interruption error code. */
#define VMXVEXITEVENTINFO_INIT_ONLY_INT(a_uExitIntInfo, a_uExitIntErrCode) \
    VMXVEXITEVENTINFO_INIT(a_uExitIntInfo, a_uExitIntErrCode, 0, 0)

/** Initialize a VMXVEXITEVENTINFO with IDT vectoring info and IDT
 *  vectoring error code. */
#define VMXVEXITEVENTINFO_INIT_ONLY_IDT(a_uIdtVectoringInfo, a_uIdtVectoringErrCode) \
    VMXVEXITEVENTINFO_INIT(0, 0, a_uIdtVectoringInfo, a_uIdtVectoringErrCode)

/**
 * Virtual VMCS.
 *
 * This is our custom format. Relevant fields from this VMCS will be merged into the
 * actual/shadow VMCS when we execute nested-guest code using hardware-assisted
 * VMX.
 *
 * The first 8 bytes must be in accordance with the Intel VT-x spec.
 * See Intel spec. 24.2 "Format of the VMCS Region".
 *
 * The offset and size of the VMCS state field (@a fVmcsState) is also fixed (not by
 * the Intel spec. but for our own requirements) as we use it to offset into guest
 * memory.
 *
 * Although the guest is supposed to access the VMCS only through the execution of
 * VMX instructions (VMREAD, VMWRITE etc.), since the VMCS may reside in guest
 * memory (e.g, active but not current VMCS), for saved-states compatibility, and
 * for teleportation purposes, any newly added fields should be added to the
 * appropriate reserved sections or at the end of the structure.
 *
 * We always treat natural-width fields as 64-bit in our implementation since
 * it's easier, allows for teleporation in the future and does not affect guest
 * software.
 *
 * @note Any fields that are added or modified here, make sure to update the
 *       corresponding fields in IEM (g_aoffVmcsMap), the corresponding saved
 *       state structure in CPUM (g_aVmxHwvirtVmcs) and bump the SSM version.
 *       Also consider updating CPUMIsGuestVmxVmcsFieldValid and cpumR3InfoVmxVmcs.
 */
#pragma pack(1)
typedef struct
{
    /** @name Header.
     * @{
     */
    VMXVMCSREVID    u32VmcsRevId;                /**< 0x000 - VMX VMCS revision identifier. */
    VMXABORT        enmVmxAbort;                 /**< 0x004 - VMX-abort indicator. */
    uint8_t         fVmcsState;                  /**< 0x008 - VMCS launch state, see VMX_V_VMCS_LAUNCH_STATE_XXX. */
    uint8_t         au8Padding0[3];              /**< 0x009 - Reserved for future. */
    uint32_t        au32Reserved0[12];           /**< 0x00c - Reserved for future. */
    /** @} */

    /** @name Read-only fields.
     * @{ */
    /** 16-bit fields. */
    uint16_t        u16Reserved0[14];            /**< 0x03c - Reserved for future. */

    /** 32-bit fields. */
    uint32_t        u32RoVmInstrError;           /**< 0x058 - VM-instruction error. */
    uint32_t        u32RoExitReason;             /**< 0x05c - VM-exit reason. */
    uint32_t        u32RoExitIntInfo;            /**< 0x060 - VM-exit interruption information. */
    uint32_t        u32RoExitIntErrCode;         /**< 0x064 - VM-exit interruption error code. */
    uint32_t        u32RoIdtVectoringInfo;       /**< 0x068 - IDT-vectoring information. */
    uint32_t        u32RoIdtVectoringErrCode;    /**< 0x06c - IDT-vectoring error code. */
    uint32_t        u32RoExitInstrLen;           /**< 0x070 - VM-exit instruction length. */
    uint32_t        u32RoExitInstrInfo;          /**< 0x074 - VM-exit instruction information. */
    uint32_t        au32RoReserved2[16];         /**< 0x078 - Reserved for future. */

    /** 64-bit fields. */
    RTUINT64U       u64RoGuestPhysAddr;          /**< 0x0b8 - Guest-physical address. */
    RTUINT64U       au64Reserved1[8];            /**< 0x0c0 - Reserved for future. */

    /** Natural-width fields. */
    RTUINT64U       u64RoExitQual;               /**< 0x100 - Exit qualification. */
    RTUINT64U       u64RoIoRcx;                  /**< 0x108 - I/O RCX. */
    RTUINT64U       u64RoIoRsi;                  /**< 0x110 - I/O RSI. */
    RTUINT64U       u64RoIoRdi;                  /**< 0x118 - I/O RDI. */
    RTUINT64U       u64RoIoRip;                  /**< 0x120 - I/O RIP. */
    RTUINT64U       u64RoGuestLinearAddr;        /**< 0x128 - Guest-linear address. */
    RTUINT64U       au64Reserved5[16];           /**< 0x130 - Reserved for future. */
    /** @} */

    /** @name Control fields.
     * @{ */
    /** 16-bit fields. */
    uint16_t        u16Vpid;                     /**< 0x1b0 - Virtual processor ID. */
    uint16_t        u16PostIntNotifyVector;      /**< 0x1b2 - Posted interrupt notify vector. */
    uint16_t        u16EptpIndex;                /**< 0x1b4 - EPTP index. */
    uint16_t        u16HlatPrefixSize;           /**< 0x1b6 - HLAT prefix size. */
    uint16_t        au16Reserved0[12];           /**< 0x1b8 - Reserved for future. */

    /** 32-bit fields. */
    uint32_t        u32PinCtls;                  /**< 0x1d0 - Pin-based VM-execution controls. */
    uint32_t        u32ProcCtls;                 /**< 0x1d4 - Processor-based VM-execution controls. */
    uint32_t        u32XcptBitmap;               /**< 0x1d8 - Exception bitmap. */
    uint32_t        u32XcptPFMask;               /**< 0x1dc - Page-fault exception error mask. */
    uint32_t        u32XcptPFMatch;              /**< 0x1e0 - Page-fault exception error match. */
    uint32_t        u32Cr3TargetCount;           /**< 0x1e4 - CR3-target count. */
    uint32_t        u32ExitCtls;                 /**< 0x1e8 - VM-exit controls. */
    uint32_t        u32ExitMsrStoreCount;        /**< 0x1ec - VM-exit MSR store count. */
    uint32_t        u32ExitMsrLoadCount;         /**< 0x1f0 - VM-exit MSR load count. */
    uint32_t        u32EntryCtls;                /**< 0x1f4 - VM-entry controls. */
    uint32_t        u32EntryMsrLoadCount;        /**< 0x1f8 - VM-entry MSR load count. */
    uint32_t        u32EntryIntInfo;             /**< 0x1fc - VM-entry interruption information. */
    uint32_t        u32EntryXcptErrCode;         /**< 0x200 - VM-entry exception error code. */
    uint32_t        u32EntryInstrLen;            /**< 0x204 - VM-entry instruction length. */
    uint32_t        u32TprThreshold;             /**< 0x208 - TPR-threshold. */
    uint32_t        u32ProcCtls2;                /**< 0x20c - Secondary-processor based VM-execution controls. */
    uint32_t        u32PleGap;                   /**< 0x210 - Pause-loop exiting Gap. */
    uint32_t        u32PleWindow;                /**< 0x214 - Pause-loop exiting Window. */
    uint32_t        au32Reserved1[16];           /**< 0x218 - Reserved for future. */

    /** 64-bit fields. */
    RTUINT64U       u64AddrIoBitmapA;            /**< 0x258 - I/O bitmap A address. */
    RTUINT64U       u64AddrIoBitmapB;            /**< 0x260 - I/O bitmap B address. */
    RTUINT64U       u64AddrMsrBitmap;            /**< 0x268 - MSR bitmap address. */
    RTUINT64U       u64AddrExitMsrStore;         /**< 0x270 - VM-exit MSR-store area address. */
    RTUINT64U       u64AddrExitMsrLoad;          /**< 0x278 - VM-exit MSR-load area address. */
    RTUINT64U       u64AddrEntryMsrLoad;         /**< 0x280 - VM-entry MSR-load area address. */
    RTUINT64U       u64ExecVmcsPtr;              /**< 0x288 - Executive-VMCS pointer. */
    RTUINT64U       u64AddrPml;                  /**< 0x290 - Page-modification log address (PML). */
    RTUINT64U       u64TscOffset;                /**< 0x298 - TSC offset. */
    RTUINT64U       u64AddrVirtApic;             /**< 0x2a0 - Virtual-APIC address. */
    RTUINT64U       u64AddrApicAccess;           /**< 0x2a8 - APIC-access address. */
    RTUINT64U       u64AddrPostedIntDesc;        /**< 0x2b0 - Posted-interrupt descriptor address. */
    RTUINT64U       u64VmFuncCtls;               /**< 0x2b8 - VM-functions control. */
    RTUINT64U       u64EptPtr;                   /**< 0x2c0 - EPT pointer. */
    RTUINT64U       u64EoiExitBitmap0;           /**< 0x2c8 - EOI-exit bitmap 0. */
    RTUINT64U       u64EoiExitBitmap1;           /**< 0x2d0 - EOI-exit bitmap 1. */
    RTUINT64U       u64EoiExitBitmap2;           /**< 0x2d8 - EOI-exit bitmap 2. */
    RTUINT64U       u64EoiExitBitmap3;           /**< 0x2e0 - EOI-exit bitmap 3. */
    RTUINT64U       u64AddrEptpList;             /**< 0x2e8 - EPTP-list address. */
    RTUINT64U       u64AddrVmreadBitmap;         /**< 0x2f0 - VMREAD-bitmap address. */
    RTUINT64U       u64AddrVmwriteBitmap;        /**< 0x2f8 - VMWRITE-bitmap address. */
    RTUINT64U       u64AddrXcptVeInfo;           /**< 0x300 - Virtualization-exception information address. */
    RTUINT64U       u64XssExitBitmap;            /**< 0x308 - XSS-exiting bitmap. */
    RTUINT64U       u64EnclsExitBitmap;          /**< 0x310 - ENCLS-exiting bitmap address. */
    RTUINT64U       u64SppTablePtr;              /**< 0x318 - Sub-page-permission-table pointer (SPPTP). */
    RTUINT64U       u64TscMultiplier;            /**< 0x320 - TSC multiplier. */
    RTUINT64U       u64ProcCtls3;                /**< 0x328 - Tertiary-Processor based VM-execution controls. */
    RTUINT64U       u64EnclvExitBitmap;          /**< 0x330 - ENCLV-exiting bitmap. */
    RTUINT64U       u64PconfigExitBitmap;        /**< 0x338 - PCONFIG-exiting bitmap. */
    RTUINT64U       u64HlatPtr;                  /**< 0x340 - HLAT pointer. */
    RTUINT64U       u64ExitCtls2;                /**< 0x348 - Secondary VM-exit controls. */
    RTUINT64U       au64Reserved0[10];           /**< 0x350 - Reserved for future. */

    /** Natural-width fields. */
    RTUINT64U       u64Cr0Mask;                  /**< 0x3a0 - CR0 guest/host Mask. */
    RTUINT64U       u64Cr4Mask;                  /**< 0x3a8 - CR4 guest/host Mask. */
    RTUINT64U       u64Cr0ReadShadow;            /**< 0x3b0 - CR0 read shadow. */
    RTUINT64U       u64Cr4ReadShadow;            /**< 0x3b8 - CR4 read shadow. */
    RTUINT64U       u64Cr3Target0;               /**< 0x3c0 - CR3-target value 0. */
    RTUINT64U       u64Cr3Target1;               /**< 0x3c8 - CR3-target value 1. */
    RTUINT64U       u64Cr3Target2;               /**< 0x3d0 - CR3-target value 2. */
    RTUINT64U       u64Cr3Target3;               /**< 0x3d8 - CR3-target value 3. */
    RTUINT64U       au64Reserved4[32];           /**< 0x3e0 - Reserved for future. */
    /** @} */

    /** @name Host-state fields.
     * @{ */
    /** 16-bit fields. */
    /* Order of [Es..Gs] fields below must match [X86_SREG_ES..X86_SREG_GS]. */
    RTSEL           HostEs;                      /**< 0x4e0 - Host ES selector. */
    RTSEL           HostCs;                      /**< 0x4e2 - Host CS selector. */
    RTSEL           HostSs;                      /**< 0x4e4 - Host SS selector. */
    RTSEL           HostDs;                      /**< 0x4e6 - Host DS selector. */
    RTSEL           HostFs;                      /**< 0x4e8 - Host FS selector. */
    RTSEL           HostGs;                      /**< 0x4ea - Host GS selector. */
    RTSEL           HostTr;                      /**< 0x4ec - Host TR selector. */
    uint16_t        au16Reserved2[13];           /**< 0x4ee - Reserved for future. */

    /** 32-bit fields. */
    uint32_t        u32HostSysenterCs;           /**< 0x508 - Host SYSENTER CS. */
    uint32_t        au32Reserved4[11];           /**< 0x50c - Reserved for future. */

    /** 64-bit fields. */
    RTUINT64U       u64HostPatMsr;               /**< 0x538 - Host PAT MSR. */
    RTUINT64U       u64HostEferMsr;              /**< 0x540 - Host EFER MSR. */
    RTUINT64U       u64HostPerfGlobalCtlMsr;     /**< 0x548 - Host global performance-control MSR. */
    RTUINT64U       u64HostPkrsMsr;              /**< 0x550 - Host PKRS MSR. */
    RTUINT64U       au64Reserved3[15];           /**< 0x558 - Reserved for future. */

    /** Natural-width fields. */
    RTUINT64U       u64HostCr0;                  /**< 0x5d0 - Host CR0. */
    RTUINT64U       u64HostCr3;                  /**< 0x5d8 - Host CR3. */
    RTUINT64U       u64HostCr4;                  /**< 0x5e0 - Host CR4. */
    RTUINT64U       u64HostFsBase;               /**< 0x5e8 - Host FS base. */
    RTUINT64U       u64HostGsBase;               /**< 0x5f0 - Host GS base. */
    RTUINT64U       u64HostTrBase;               /**< 0x5f8 - Host TR base. */
    RTUINT64U       u64HostGdtrBase;             /**< 0x600 - Host GDTR base. */
    RTUINT64U       u64HostIdtrBase;             /**< 0x608 - Host IDTR base. */
    RTUINT64U       u64HostSysenterEsp;          /**< 0x610 - Host SYSENTER ESP base. */
    RTUINT64U       u64HostSysenterEip;          /**< 0x618 - Host SYSENTER ESP base. */
    RTUINT64U       u64HostRsp;                  /**< 0x620 - Host RSP. */
    RTUINT64U       u64HostRip;                  /**< 0x628 - Host RIP. */
    RTUINT64U       u64HostSCetMsr;              /**< 0x630 - Host S_CET MSR. */
    RTUINT64U       u64HostSsp;                  /**< 0x638 - Host SSP. */
    RTUINT64U       u64HostIntrSspTableAddrMsr;  /**< 0x640 - Host Interrupt SSP table address MSR. */
    RTUINT64U       au64Reserved7[29];           /**< 0x648 - Reserved for future. */
    /** @} */

    /** @name Guest-state fields.
     * @{ */
    /** 16-bit fields. */
    /* Order of [Es..Gs] fields below must match [X86_SREG_ES..X86_SREG_GS]. */
    RTSEL           GuestEs;                     /**< 0x730 - Guest ES selector. */
    RTSEL           GuestCs;                     /**< 0x732 - Guest ES selector. */
    RTSEL           GuestSs;                     /**< 0x734 - Guest ES selector. */
    RTSEL           GuestDs;                     /**< 0x736 - Guest ES selector. */
    RTSEL           GuestFs;                     /**< 0x738 - Guest ES selector. */
    RTSEL           GuestGs;                     /**< 0x73a - Guest ES selector. */
    RTSEL           GuestLdtr;                   /**< 0x73c - Guest LDTR selector. */
    RTSEL           GuestTr;                     /**< 0x73e - Guest TR selector. */
    uint16_t        u16GuestIntStatus;           /**< 0x740 - Guest interrupt status (virtual-interrupt delivery). */
    uint16_t        u16PmlIndex;                 /**< 0x742 - PML index. */
    uint16_t        au16Reserved1[14];           /**< 0x744 - Reserved for future. */

    /** 32-bit fields. */
    /* Order of [Es..Gs] fields below must match [X86_SREG_ES..X86_SREG_GS]. */
    uint32_t        u32GuestEsLimit;             /**< 0x760 - Guest ES limit. */
    uint32_t        u32GuestCsLimit;             /**< 0x764 - Guest CS limit. */
    uint32_t        u32GuestSsLimit;             /**< 0x768 - Guest SS limit. */
    uint32_t        u32GuestDsLimit;             /**< 0x76c - Guest DS limit. */
    uint32_t        u32GuestFsLimit;             /**< 0x770 - Guest FS limit. */
    uint32_t        u32GuestGsLimit;             /**< 0x774 - Guest GS limit. */
    uint32_t        u32GuestLdtrLimit;           /**< 0x778 - Guest LDTR limit. */
    uint32_t        u32GuestTrLimit;             /**< 0x77c - Guest TR limit. */
    uint32_t        u32GuestGdtrLimit;           /**< 0x780 - Guest GDTR limit. */
    uint32_t        u32GuestIdtrLimit;           /**< 0x784 - Guest IDTR limit. */
    uint32_t        u32GuestEsAttr;              /**< 0x788 - Guest ES attributes. */
    uint32_t        u32GuestCsAttr;              /**< 0x78c - Guest CS attributes. */
    uint32_t        u32GuestSsAttr;              /**< 0x790 - Guest SS attributes. */
    uint32_t        u32GuestDsAttr;              /**< 0x794 - Guest DS attributes. */
    uint32_t        u32GuestFsAttr;              /**< 0x798 - Guest FS attributes. */
    uint32_t        u32GuestGsAttr;              /**< 0x79c - Guest GS attributes. */
    uint32_t        u32GuestLdtrAttr;            /**< 0x7a0 - Guest LDTR attributes. */
    uint32_t        u32GuestTrAttr;              /**< 0x7a4 - Guest TR attributes. */
    uint32_t        u32GuestIntrState;           /**< 0x7a8 - Guest interruptibility state. */
    uint32_t        u32GuestActivityState;       /**< 0x7ac - Guest activity state. */
    uint32_t        u32GuestSmBase;              /**< 0x7b0 - Guest SMBASE. */
    uint32_t        u32GuestSysenterCS;          /**< 0x7b4 - Guest SYSENTER CS. */
    uint32_t        u32PreemptTimer;             /**< 0x7b8 - Preemption timer value. */
    uint32_t        au32Reserved3[11];           /**< 0x7bc - Reserved for future. */

    /** 64-bit fields. */
    RTUINT64U       u64VmcsLinkPtr;              /**< 0x7e8 - VMCS link pointer. */
    RTUINT64U       u64GuestDebugCtlMsr;         /**< 0x7f0 - Guest debug-control MSR. */
    RTUINT64U       u64GuestPatMsr;              /**< 0x7f8 - Guest PAT MSR. */
    RTUINT64U       u64GuestEferMsr;             /**< 0x800 - Guest EFER MSR. */
    RTUINT64U       u64GuestPerfGlobalCtlMsr;    /**< 0x808 - Guest global performance-control MSR. */
    RTUINT64U       u64GuestPdpte0;              /**< 0x810 - Guest PDPTE 0. */
    RTUINT64U       u64GuestPdpte1;              /**< 0x818 - Guest PDPTE 0. */
    RTUINT64U       u64GuestPdpte2;              /**< 0x820 - Guest PDPTE 1. */
    RTUINT64U       u64GuestPdpte3;              /**< 0x828 - Guest PDPTE 2. */
    RTUINT64U       u64GuestBndcfgsMsr;          /**< 0x830 - Guest Bounds config MPX MSR (Intel Memory Protection Extensions). */
    RTUINT64U       u64GuestRtitCtlMsr;          /**< 0x838 - Guest RTIT control MSR (Intel Real Time Instruction Trace). */
    RTUINT64U       u64GuestPkrsMsr;             /**< 0x840 - Guest PKRS MSR. */
    RTUINT64U       au64Reserved2[31];           /**< 0x848 - Reserved for future. */

    /** Natural-width fields. */
    RTUINT64U       u64GuestCr0;                 /**< 0x940 - Guest CR0. */
    RTUINT64U       u64GuestCr3;                 /**< 0x948 - Guest CR3. */
    RTUINT64U       u64GuestCr4;                 /**< 0x950 - Guest CR4. */
    RTUINT64U       u64GuestEsBase;              /**< 0x958 - Guest ES base. */
    RTUINT64U       u64GuestCsBase;              /**< 0x960 - Guest CS base. */
    RTUINT64U       u64GuestSsBase;              /**< 0x968 - Guest SS base. */
    RTUINT64U       u64GuestDsBase;              /**< 0x970 - Guest DS base. */
    RTUINT64U       u64GuestFsBase;              /**< 0x978 - Guest FS base. */
    RTUINT64U       u64GuestGsBase;              /**< 0x980 - Guest GS base. */
    RTUINT64U       u64GuestLdtrBase;            /**< 0x988 - Guest LDTR base. */
    RTUINT64U       u64GuestTrBase;              /**< 0x990 - Guest TR base. */
    RTUINT64U       u64GuestGdtrBase;            /**< 0x998 - Guest GDTR base. */
    RTUINT64U       u64GuestIdtrBase;            /**< 0x9a0 - Guest IDTR base. */
    RTUINT64U       u64GuestDr7;                 /**< 0x9a8 - Guest DR7. */
    RTUINT64U       u64GuestRsp;                 /**< 0x9b0 - Guest RSP. */
    RTUINT64U       u64GuestRip;                 /**< 0x9b8 - Guest RIP. */
    RTUINT64U       u64GuestRFlags;              /**< 0x9c0 - Guest RFLAGS. */
    RTUINT64U       u64GuestPendingDbgXcpts;     /**< 0x9c8 - Guest pending debug exceptions. */
    RTUINT64U       u64GuestSysenterEsp;         /**< 0x9d0 - Guest SYSENTER ESP. */
    RTUINT64U       u64GuestSysenterEip;         /**< 0x9d8 - Guest SYSENTER EIP. */
    RTUINT64U       u64GuestSCetMsr;             /**< 0x9e0 - Guest S_CET MSR. */
    RTUINT64U       u64GuestSsp;                 /**< 0x9e8 - Guest SSP. */
    RTUINT64U       u64GuestIntrSspTableAddrMsr; /**< 0x9f0 - Guest Interrupt SSP table address MSR. */
    RTUINT64U       au64Reserved6[29];           /**< 0x9f8 - Reserved for future. */
    /** @} */

    /** 0xae0 - Padding / reserved for future use. */
    uint8_t         abPadding[X86_PAGE_4K_SIZE - 0xae0];
} VMXVVMCS;
#pragma pack()
/** Pointer to the VMXVVMCS struct. */
typedef VMXVVMCS *PVMXVVMCS;
/** Pointer to a const VMXVVMCS struct. */
typedef const VMXVVMCS *PCVMXVVMCS;
AssertCompileSize(VMXVVMCS, X86_PAGE_4K_SIZE);
AssertCompileMemberSize(VMXVVMCS, fVmcsState, sizeof(uint8_t));
AssertCompileMemberOffset(VMXVVMCS, enmVmxAbort,        0x004);
AssertCompileMemberOffset(VMXVVMCS, fVmcsState,         0x008);
AssertCompileMemberOffset(VMXVVMCS, u32RoVmInstrError,  0x058);
AssertCompileMemberOffset(VMXVVMCS, u64RoGuestPhysAddr, 0x0b8);
AssertCompileMemberOffset(VMXVVMCS, u64RoExitQual,      0x100);
AssertCompileMemberOffset(VMXVVMCS, u16Vpid,            0x1b0);
AssertCompileMemberOffset(VMXVVMCS, u32PinCtls,         0x1d0);
AssertCompileMemberOffset(VMXVVMCS, u64AddrIoBitmapA,   0x258);
AssertCompileMemberOffset(VMXVVMCS, u64Cr0Mask,         0x3a0);
AssertCompileMemberOffset(VMXVVMCS, HostEs,             0x4e0);
AssertCompileMemberOffset(VMXVVMCS, u32HostSysenterCs,  0x508);
AssertCompileMemberOffset(VMXVVMCS, u64HostPatMsr,      0x538);
AssertCompileMemberOffset(VMXVVMCS, u64HostCr0,         0x5d0);
AssertCompileMemberOffset(VMXVVMCS, GuestEs,            0x730);
AssertCompileMemberOffset(VMXVVMCS, u32GuestEsLimit,    0x760);
AssertCompileMemberOffset(VMXVVMCS, u64VmcsLinkPtr,     0x7e8);
AssertCompileMemberOffset(VMXVVMCS, u64GuestCr0,        0x940);

/**
 * Virtual VMX-instruction and VM-exit diagnostics.
 *
 * These are not the same as VM instruction errors that are enumerated in the Intel
 * spec. These are purely internal, fine-grained definitions used for diagnostic
 * purposes and are not reported to guest software under the VM-instruction error
 * field in its VMCS.
 *
 * @note Members of this enum are used as array indices, so no gaps are allowed.
 *       Please update g_apszVmxVDiagDesc when you add new fields to this enum.
 */
typedef enum
{
    /* Internal processing errors. */
    kVmxVDiag_None = 0,
    kVmxVDiag_Ipe_1,
    kVmxVDiag_Ipe_2,
    kVmxVDiag_Ipe_3,
    kVmxVDiag_Ipe_4,
    kVmxVDiag_Ipe_5,
    kVmxVDiag_Ipe_6,
    kVmxVDiag_Ipe_7,
    kVmxVDiag_Ipe_8,
    kVmxVDiag_Ipe_9,
    kVmxVDiag_Ipe_10,
    kVmxVDiag_Ipe_11,
    kVmxVDiag_Ipe_12,
    kVmxVDiag_Ipe_13,
    kVmxVDiag_Ipe_14,
    kVmxVDiag_Ipe_15,
    kVmxVDiag_Ipe_16,
    /* VMXON. */
    kVmxVDiag_Vmxon_A20M,
    kVmxVDiag_Vmxon_Cpl,
    kVmxVDiag_Vmxon_Cr0Fixed0,
    kVmxVDiag_Vmxon_Cr0Fixed1,
    kVmxVDiag_Vmxon_Cr4Fixed0,
    kVmxVDiag_Vmxon_Cr4Fixed1,
    kVmxVDiag_Vmxon_Intercept,
    kVmxVDiag_Vmxon_LongModeCS,
    kVmxVDiag_Vmxon_MsrFeatCtl,
    kVmxVDiag_Vmxon_PtrAbnormal,
    kVmxVDiag_Vmxon_PtrAlign,
    kVmxVDiag_Vmxon_PtrMap,
    kVmxVDiag_Vmxon_PtrReadPhys,
    kVmxVDiag_Vmxon_PtrWidth,
    kVmxVDiag_Vmxon_RealOrV86Mode,
    kVmxVDiag_Vmxon_ShadowVmcs,
    kVmxVDiag_Vmxon_VmxAlreadyRoot,
    kVmxVDiag_Vmxon_Vmxe,
    kVmxVDiag_Vmxon_VmcsRevId,
    kVmxVDiag_Vmxon_VmxRootCpl,
    /* VMXOFF. */
    kVmxVDiag_Vmxoff_Cpl,
    kVmxVDiag_Vmxoff_Intercept,
    kVmxVDiag_Vmxoff_LongModeCS,
    kVmxVDiag_Vmxoff_RealOrV86Mode,
    kVmxVDiag_Vmxoff_Vmxe,
    kVmxVDiag_Vmxoff_VmxRoot,
    /* VMPTRLD. */
    kVmxVDiag_Vmptrld_Cpl,
    kVmxVDiag_Vmptrld_LongModeCS,
    kVmxVDiag_Vmptrld_PtrAbnormal,
    kVmxVDiag_Vmptrld_PtrAlign,
    kVmxVDiag_Vmptrld_PtrMap,
    kVmxVDiag_Vmptrld_PtrReadPhys,
    kVmxVDiag_Vmptrld_PtrVmxon,
    kVmxVDiag_Vmptrld_PtrWidth,
    kVmxVDiag_Vmptrld_RealOrV86Mode,
    kVmxVDiag_Vmptrld_RevPtrReadPhys,
    kVmxVDiag_Vmptrld_ShadowVmcs,
    kVmxVDiag_Vmptrld_VmcsRevId,
    kVmxVDiag_Vmptrld_VmxRoot,
    /* VMPTRST. */
    kVmxVDiag_Vmptrst_Cpl,
    kVmxVDiag_Vmptrst_LongModeCS,
    kVmxVDiag_Vmptrst_PtrMap,
    kVmxVDiag_Vmptrst_RealOrV86Mode,
    kVmxVDiag_Vmptrst_VmxRoot,
    /* VMCLEAR. */
    kVmxVDiag_Vmclear_Cpl,
    kVmxVDiag_Vmclear_LongModeCS,
    kVmxVDiag_Vmclear_PtrAbnormal,
    kVmxVDiag_Vmclear_PtrAlign,
    kVmxVDiag_Vmclear_PtrMap,
    kVmxVDiag_Vmclear_PtrReadPhys,
    kVmxVDiag_Vmclear_PtrVmxon,
    kVmxVDiag_Vmclear_PtrWidth,
    kVmxVDiag_Vmclear_RealOrV86Mode,
    kVmxVDiag_Vmclear_VmxRoot,
    /* VMWRITE. */
    kVmxVDiag_Vmwrite_Cpl,
    kVmxVDiag_Vmwrite_FieldInvalid,
    kVmxVDiag_Vmwrite_FieldRo,
    kVmxVDiag_Vmwrite_LinkPtrInvalid,
    kVmxVDiag_Vmwrite_LongModeCS,
    kVmxVDiag_Vmwrite_PtrInvalid,
    kVmxVDiag_Vmwrite_PtrMap,
    kVmxVDiag_Vmwrite_RealOrV86Mode,
    kVmxVDiag_Vmwrite_VmxRoot,
    /* VMREAD. */
    kVmxVDiag_Vmread_Cpl,
    kVmxVDiag_Vmread_FieldInvalid,
    kVmxVDiag_Vmread_LinkPtrInvalid,
    kVmxVDiag_Vmread_LongModeCS,
    kVmxVDiag_Vmread_PtrInvalid,
    kVmxVDiag_Vmread_PtrMap,
    kVmxVDiag_Vmread_RealOrV86Mode,
    kVmxVDiag_Vmread_VmxRoot,
    /* INVVPID. */
    kVmxVDiag_Invvpid_Cpl,
    kVmxVDiag_Invvpid_DescRsvd,
    kVmxVDiag_Invvpid_LongModeCS,
    kVmxVDiag_Invvpid_RealOrV86Mode,
    kVmxVDiag_Invvpid_TypeInvalid,
    kVmxVDiag_Invvpid_Type0InvalidAddr,
    kVmxVDiag_Invvpid_Type0InvalidVpid,
    kVmxVDiag_Invvpid_Type1InvalidVpid,
    kVmxVDiag_Invvpid_Type3InvalidVpid,
    kVmxVDiag_Invvpid_VmxRoot,
    /* INVEPT. */
    kVmxVDiag_Invept_Cpl,
    kVmxVDiag_Invept_DescRsvd,
    kVmxVDiag_Invept_EptpInvalid,
    kVmxVDiag_Invept_LongModeCS,
    kVmxVDiag_Invept_RealOrV86Mode,
    kVmxVDiag_Invept_TypeInvalid,
    kVmxVDiag_Invept_VmxRoot,
    /* VMLAUNCH/VMRESUME. */
    kVmxVDiag_Vmentry_AddrApicAccess,
    kVmxVDiag_Vmentry_AddrApicAccessEqVirtApic,
    kVmxVDiag_Vmentry_AddrApicAccessHandlerReg,
    kVmxVDiag_Vmentry_AddrEntryMsrLoad,
    kVmxVDiag_Vmentry_AddrExitMsrLoad,
    kVmxVDiag_Vmentry_AddrExitMsrStore,
    kVmxVDiag_Vmentry_AddrIoBitmapA,
    kVmxVDiag_Vmentry_AddrIoBitmapB,
    kVmxVDiag_Vmentry_AddrMsrBitmap,
    kVmxVDiag_Vmentry_AddrVirtApicPage,
    kVmxVDiag_Vmentry_AddrVmcsLinkPtr,
    kVmxVDiag_Vmentry_AddrVmreadBitmap,
    kVmxVDiag_Vmentry_AddrVmwriteBitmap,
    kVmxVDiag_Vmentry_ApicRegVirt,
    kVmxVDiag_Vmentry_BlocKMovSS,
    kVmxVDiag_Vmentry_Cpl,
    kVmxVDiag_Vmentry_Cr3TargetCount,
    kVmxVDiag_Vmentry_EntryCtlsAllowed1,
    kVmxVDiag_Vmentry_EntryCtlsDisallowed0,
    kVmxVDiag_Vmentry_EntryInstrLen,
    kVmxVDiag_Vmentry_EntryInstrLenZero,
    kVmxVDiag_Vmentry_EntryIntInfoErrCodePe,
    kVmxVDiag_Vmentry_EntryIntInfoErrCodeVec,
    kVmxVDiag_Vmentry_EntryIntInfoTypeVecRsvd,
    kVmxVDiag_Vmentry_EntryXcptErrCodeRsvd,
    kVmxVDiag_Vmentry_EptpAccessDirty,
    kVmxVDiag_Vmentry_EptpPageWalkLength,
    kVmxVDiag_Vmentry_EptpMemType,
    kVmxVDiag_Vmentry_EptpRsvd,
    kVmxVDiag_Vmentry_ExitCtlsAllowed1,
    kVmxVDiag_Vmentry_ExitCtlsDisallowed0,
    kVmxVDiag_Vmentry_GuestActStateHlt,
    kVmxVDiag_Vmentry_GuestActStateRsvd,
    kVmxVDiag_Vmentry_GuestActStateShutdown,
    kVmxVDiag_Vmentry_GuestActStateSsDpl,
    kVmxVDiag_Vmentry_GuestActStateStiMovSs,
    kVmxVDiag_Vmentry_GuestCr0Fixed0,
    kVmxVDiag_Vmentry_GuestCr0Fixed1,
    kVmxVDiag_Vmentry_GuestCr0PgPe,
    kVmxVDiag_Vmentry_GuestCr3,
    kVmxVDiag_Vmentry_GuestCr4Fixed0,
    kVmxVDiag_Vmentry_GuestCr4Fixed1,
    kVmxVDiag_Vmentry_GuestDebugCtl,
    kVmxVDiag_Vmentry_GuestDr7,
    kVmxVDiag_Vmentry_GuestEferMsr,
    kVmxVDiag_Vmentry_GuestEferMsrRsvd,
    kVmxVDiag_Vmentry_GuestGdtrBase,
    kVmxVDiag_Vmentry_GuestGdtrLimit,
    kVmxVDiag_Vmentry_GuestIdtrBase,
    kVmxVDiag_Vmentry_GuestIdtrLimit,
    kVmxVDiag_Vmentry_GuestIntStateEnclave,
    kVmxVDiag_Vmentry_GuestIntStateExtInt,
    kVmxVDiag_Vmentry_GuestIntStateNmi,
    kVmxVDiag_Vmentry_GuestIntStateRFlagsSti,
    kVmxVDiag_Vmentry_GuestIntStateRsvd,
    kVmxVDiag_Vmentry_GuestIntStateSmi,
    kVmxVDiag_Vmentry_GuestIntStateStiMovSs,
    kVmxVDiag_Vmentry_GuestIntStateVirtNmi,
    kVmxVDiag_Vmentry_GuestPae,
    kVmxVDiag_Vmentry_GuestPatMsr,
    kVmxVDiag_Vmentry_GuestPcide,
    kVmxVDiag_Vmentry_GuestPdpte,
    kVmxVDiag_Vmentry_GuestPndDbgXcptBsNoTf,
    kVmxVDiag_Vmentry_GuestPndDbgXcptBsTf,
    kVmxVDiag_Vmentry_GuestPndDbgXcptRsvd,
    kVmxVDiag_Vmentry_GuestPndDbgXcptRtm,
    kVmxVDiag_Vmentry_GuestRip,
    kVmxVDiag_Vmentry_GuestRipRsvd,
    kVmxVDiag_Vmentry_GuestRFlagsIf,
    kVmxVDiag_Vmentry_GuestRFlagsRsvd,
    kVmxVDiag_Vmentry_GuestRFlagsVm,
    kVmxVDiag_Vmentry_GuestSegAttrCsDefBig,
    kVmxVDiag_Vmentry_GuestSegAttrCsDplEqSs,
    kVmxVDiag_Vmentry_GuestSegAttrCsDplLtSs,
    kVmxVDiag_Vmentry_GuestSegAttrCsDplZero,
    kVmxVDiag_Vmentry_GuestSegAttrCsType,
    kVmxVDiag_Vmentry_GuestSegAttrCsTypeRead,
    kVmxVDiag_Vmentry_GuestSegAttrDescTypeCs,
    kVmxVDiag_Vmentry_GuestSegAttrDescTypeDs,
    kVmxVDiag_Vmentry_GuestSegAttrDescTypeEs,
    kVmxVDiag_Vmentry_GuestSegAttrDescTypeFs,
    kVmxVDiag_Vmentry_GuestSegAttrDescTypeGs,
    kVmxVDiag_Vmentry_GuestSegAttrDescTypeSs,
    kVmxVDiag_Vmentry_GuestSegAttrDplRplCs,
    kVmxVDiag_Vmentry_GuestSegAttrDplRplDs,
    kVmxVDiag_Vmentry_GuestSegAttrDplRplEs,
    kVmxVDiag_Vmentry_GuestSegAttrDplRplFs,
    kVmxVDiag_Vmentry_GuestSegAttrDplRplGs,
    kVmxVDiag_Vmentry_GuestSegAttrDplRplSs,
    kVmxVDiag_Vmentry_GuestSegAttrGranCs,
    kVmxVDiag_Vmentry_GuestSegAttrGranDs,
    kVmxVDiag_Vmentry_GuestSegAttrGranEs,
    kVmxVDiag_Vmentry_GuestSegAttrGranFs,
    kVmxVDiag_Vmentry_GuestSegAttrGranGs,
    kVmxVDiag_Vmentry_GuestSegAttrGranSs,
    kVmxVDiag_Vmentry_GuestSegAttrLdtrDescType,
    kVmxVDiag_Vmentry_GuestSegAttrLdtrGran,
    kVmxVDiag_Vmentry_GuestSegAttrLdtrPresent,
    kVmxVDiag_Vmentry_GuestSegAttrLdtrRsvd,
    kVmxVDiag_Vmentry_GuestSegAttrLdtrType,
    kVmxVDiag_Vmentry_GuestSegAttrPresentCs,
    kVmxVDiag_Vmentry_GuestSegAttrPresentDs,
    kVmxVDiag_Vmentry_GuestSegAttrPresentEs,
    kVmxVDiag_Vmentry_GuestSegAttrPresentFs,
    kVmxVDiag_Vmentry_GuestSegAttrPresentGs,
    kVmxVDiag_Vmentry_GuestSegAttrPresentSs,
    kVmxVDiag_Vmentry_GuestSegAttrRsvdCs,
    kVmxVDiag_Vmentry_GuestSegAttrRsvdDs,
    kVmxVDiag_Vmentry_GuestSegAttrRsvdEs,
    kVmxVDiag_Vmentry_GuestSegAttrRsvdFs,
    kVmxVDiag_Vmentry_GuestSegAttrRsvdGs,
    kVmxVDiag_Vmentry_GuestSegAttrRsvdSs,
    kVmxVDiag_Vmentry_GuestSegAttrSsDplEqRpl,
    kVmxVDiag_Vmentry_GuestSegAttrSsDplZero,
    kVmxVDiag_Vmentry_GuestSegAttrSsType,
    kVmxVDiag_Vmentry_GuestSegAttrTrDescType,
    kVmxVDiag_Vmentry_GuestSegAttrTrGran,
    kVmxVDiag_Vmentry_GuestSegAttrTrPresent,
    kVmxVDiag_Vmentry_GuestSegAttrTrRsvd,
    kVmxVDiag_Vmentry_GuestSegAttrTrType,
    kVmxVDiag_Vmentry_GuestSegAttrTrUnusable,
    kVmxVDiag_Vmentry_GuestSegAttrTypeAccCs,
    kVmxVDiag_Vmentry_GuestSegAttrTypeAccDs,
    kVmxVDiag_Vmentry_GuestSegAttrTypeAccEs,
    kVmxVDiag_Vmentry_GuestSegAttrTypeAccFs,
    kVmxVDiag_Vmentry_GuestSegAttrTypeAccGs,
    kVmxVDiag_Vmentry_GuestSegAttrTypeAccSs,
    kVmxVDiag_Vmentry_GuestSegAttrV86Cs,
    kVmxVDiag_Vmentry_GuestSegAttrV86Ds,
    kVmxVDiag_Vmentry_GuestSegAttrV86Es,
    kVmxVDiag_Vmentry_GuestSegAttrV86Fs,
    kVmxVDiag_Vmentry_GuestSegAttrV86Gs,
    kVmxVDiag_Vmentry_GuestSegAttrV86Ss,
    kVmxVDiag_Vmentry_GuestSegBaseCs,
    kVmxVDiag_Vmentry_GuestSegBaseDs,
    kVmxVDiag_Vmentry_GuestSegBaseEs,
    kVmxVDiag_Vmentry_GuestSegBaseFs,
    kVmxVDiag_Vmentry_GuestSegBaseGs,
    kVmxVDiag_Vmentry_GuestSegBaseLdtr,
    kVmxVDiag_Vmentry_GuestSegBaseSs,
    kVmxVDiag_Vmentry_GuestSegBaseTr,
    kVmxVDiag_Vmentry_GuestSegBaseV86Cs,
    kVmxVDiag_Vmentry_GuestSegBaseV86Ds,
    kVmxVDiag_Vmentry_GuestSegBaseV86Es,
    kVmxVDiag_Vmentry_GuestSegBaseV86Fs,
    kVmxVDiag_Vmentry_GuestSegBaseV86Gs,
    kVmxVDiag_Vmentry_GuestSegBaseV86Ss,
    kVmxVDiag_Vmentry_GuestSegLimitV86Cs,
    kVmxVDiag_Vmentry_GuestSegLimitV86Ds,
    kVmxVDiag_Vmentry_GuestSegLimitV86Es,
    kVmxVDiag_Vmentry_GuestSegLimitV86Fs,
    kVmxVDiag_Vmentry_GuestSegLimitV86Gs,
    kVmxVDiag_Vmentry_GuestSegLimitV86Ss,
    kVmxVDiag_Vmentry_GuestSegSelCsSsRpl,
    kVmxVDiag_Vmentry_GuestSegSelLdtr,
    kVmxVDiag_Vmentry_GuestSegSelTr,
    kVmxVDiag_Vmentry_GuestSysenterEspEip,
    kVmxVDiag_Vmentry_VmcsLinkPtrCurVmcs,
    kVmxVDiag_Vmentry_VmcsLinkPtrReadPhys,
    kVmxVDiag_Vmentry_VmcsLinkPtrRevId,
    kVmxVDiag_Vmentry_VmcsLinkPtrShadow,
    kVmxVDiag_Vmentry_HostCr0Fixed0,
    kVmxVDiag_Vmentry_HostCr0Fixed1,
    kVmxVDiag_Vmentry_HostCr3,
    kVmxVDiag_Vmentry_HostCr4Fixed0,
    kVmxVDiag_Vmentry_HostCr4Fixed1,
    kVmxVDiag_Vmentry_HostCr4Pae,
    kVmxVDiag_Vmentry_HostCr4Pcide,
    kVmxVDiag_Vmentry_HostCsTr,
    kVmxVDiag_Vmentry_HostEferMsr,
    kVmxVDiag_Vmentry_HostEferMsrRsvd,
    kVmxVDiag_Vmentry_HostGuestLongMode,
    kVmxVDiag_Vmentry_HostGuestLongModeNoCpu,
    kVmxVDiag_Vmentry_HostLongMode,
    kVmxVDiag_Vmentry_HostPatMsr,
    kVmxVDiag_Vmentry_HostRip,
    kVmxVDiag_Vmentry_HostRipRsvd,
    kVmxVDiag_Vmentry_HostSel,
    kVmxVDiag_Vmentry_HostSegBase,
    kVmxVDiag_Vmentry_HostSs,
    kVmxVDiag_Vmentry_HostSysenterEspEip,
    kVmxVDiag_Vmentry_IoBitmapAPtrReadPhys,
    kVmxVDiag_Vmentry_IoBitmapBPtrReadPhys,
    kVmxVDiag_Vmentry_LongModeCS,
    kVmxVDiag_Vmentry_MsrBitmapPtrReadPhys,
    kVmxVDiag_Vmentry_MsrLoad,
    kVmxVDiag_Vmentry_MsrLoadCount,
    kVmxVDiag_Vmentry_MsrLoadPtrReadPhys,
    kVmxVDiag_Vmentry_MsrLoadRing3,
    kVmxVDiag_Vmentry_MsrLoadRsvd,
    kVmxVDiag_Vmentry_NmiWindowExit,
    kVmxVDiag_Vmentry_PinCtlsAllowed1,
    kVmxVDiag_Vmentry_PinCtlsDisallowed0,
    kVmxVDiag_Vmentry_ProcCtlsAllowed1,
    kVmxVDiag_Vmentry_ProcCtlsDisallowed0,
    kVmxVDiag_Vmentry_ProcCtls2Allowed1,
    kVmxVDiag_Vmentry_ProcCtls2Disallowed0,
    kVmxVDiag_Vmentry_PtrInvalid,
    kVmxVDiag_Vmentry_PtrShadowVmcs,
    kVmxVDiag_Vmentry_RealOrV86Mode,
    kVmxVDiag_Vmentry_SavePreemptTimer,
    kVmxVDiag_Vmentry_TprThresholdRsvd,
    kVmxVDiag_Vmentry_TprThresholdVTpr,
    kVmxVDiag_Vmentry_VirtApicPagePtrReadPhys,
    kVmxVDiag_Vmentry_VirtIntDelivery,
    kVmxVDiag_Vmentry_VirtNmi,
    kVmxVDiag_Vmentry_VirtX2ApicTprShadow,
    kVmxVDiag_Vmentry_VirtX2ApicVirtApic,
    kVmxVDiag_Vmentry_VmcsClear,
    kVmxVDiag_Vmentry_VmcsLaunch,
    kVmxVDiag_Vmentry_VmreadBitmapPtrReadPhys,
    kVmxVDiag_Vmentry_VmwriteBitmapPtrReadPhys,
    kVmxVDiag_Vmentry_VmxRoot,
    kVmxVDiag_Vmentry_Vpid,
    kVmxVDiag_Vmexit_HostPdpte,
    kVmxVDiag_Vmexit_MsrLoad,
    kVmxVDiag_Vmexit_MsrLoadCount,
    kVmxVDiag_Vmexit_MsrLoadPtrReadPhys,
    kVmxVDiag_Vmexit_MsrLoadRing3,
    kVmxVDiag_Vmexit_MsrLoadRsvd,
    kVmxVDiag_Vmexit_MsrStore,
    kVmxVDiag_Vmexit_MsrStoreCount,
    kVmxVDiag_Vmexit_MsrStorePtrReadPhys,
    kVmxVDiag_Vmexit_MsrStorePtrWritePhys,
    kVmxVDiag_Vmexit_MsrStoreRing3,
    kVmxVDiag_Vmexit_MsrStoreRsvd,
    kVmxVDiag_Vmexit_VirtApicPagePtrWritePhys,
    /* Last member for determining array index limit. */
    kVmxVDiag_End
} VMXVDIAG;
AssertCompileSize(VMXVDIAG, 4);

/** @} */

/** @} */

#endif /* !VBOX_INCLUDED_vmm_hm_vmx_h */