summaryrefslogtreecommitdiff
path: root/include/VBox/vmm/hm_svm.h
blob: 7a67c387c8022ee5a07314aca6a93012978078c4 (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
/** @file
 * HM - SVM Structures and Definitions. (VMM)
 */

/*
 * Copyright (C) 2006-2013 Oracle Corporation
 *
 * This file is part of VirtualBox Open Source Edition (OSE), as
 * available from http://www.virtualbox.org. This file is free software;
 * you can redistribute it and/or modify it under the terms of the GNU
 * General Public License (GPL) as published by the Free Software
 * Foundation, in version 2 as it comes in the "COPYING" file of the
 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
 *
 * The contents of this file may alternatively be used under the terms
 * of the Common Development and Distribution License Version 1.0
 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
 * VirtualBox OSE distribution, in which case the provisions of the
 * CDDL are applicable instead of those of the GPL.
 *
 * You may elect to license modified versions of this file under the
 * terms and conditions of either the GPL or the CDDL or both.
 */

#ifndef ___VBox_vmm_svm_h
#define ___VBox_vmm_svm_h

#include <VBox/types.h>
#include <VBox/err.h>
#include <iprt/assert.h>
#include <iprt/asm.h>

/** @defgroup grp_svm   svm Types and Definitions
 * @ingroup grp_hm
 * @{
 */

/** @name SVM features for cpuid 0x8000000a
 * @{
 */
/** Bit 0 - NP - Nested Paging supported. */
#define AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING             RT_BIT(0)
/** Bit 1 - LbrVirt - Support for saving five debug MSRs. */
#define AMD_CPUID_SVM_FEATURE_EDX_LBR_VIRT                  RT_BIT(1)
/** Bit 2 - SVML - SVM locking bit supported. */
#define AMD_CPUID_SVM_FEATURE_EDX_SVM_LOCK                  RT_BIT(2)
/** Bit 3 - NRIPS - Saving the next instruction pointer is supported. */
#define AMD_CPUID_SVM_FEATURE_EDX_NRIP_SAVE                 RT_BIT(3)
/** Bit 4 - TscRateMsr - Support for MSR TSC ratio. */
#define AMD_CPUID_SVM_FEATURE_EDX_TSC_RATE_MSR              RT_BIT(4)
/** Bit 5 - VmcbClean - Support VMCB clean bits. */
#define AMD_CPUID_SVM_FEATURE_EDX_VMCB_CLEAN                RT_BIT(5)
/** Bit 6 - FlushByAsid - Indicate TLB flushing for current ASID only, and that
 *  VMCB.TLB_Control is supported. */
#define AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID             RT_BIT(6)
/** Bit 7 - DecodeAssist - Indicate decode assist is supported. */
#define AMD_CPUID_SVM_FEATURE_EDX_DECODE_ASSIST             RT_BIT(7)
/** Bit 10 - PauseFilter - Indicates support for the PAUSE intercept filter. */
#define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER              RT_BIT(10)
/** Bit 12 - PauseFilterThreshold - Indicates support for the PAUSE
 *  intercept filter cycle count threshold. */
#define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER_THRESHOLD    RT_BIT(12)
/** Bit 13 - AVIC - Advanced Virtual Interrupt Controller. */
#define AMD_CPUID_SVM_FEATURE_EDX_AVIC                      RT_BIT(13)
/** @} */


/** @name SVM Basic Exit Reasons.
 * @{
 */
/** Invalid guest state in VMCB. */
#define SVM_EXIT_INVALID                (-1)
/** Read from CR0-CR15. */
#define SVM_EXIT_READ_CR0               0x0
#define SVM_EXIT_READ_CR1               0x1
#define SVM_EXIT_READ_CR2               0x2
#define SVM_EXIT_READ_CR3               0x3
#define SVM_EXIT_READ_CR4               0x4
#define SVM_EXIT_READ_CR5               0x5
#define SVM_EXIT_READ_CR6               0x6
#define SVM_EXIT_READ_CR7               0x7
#define SVM_EXIT_READ_CR8               0x8
#define SVM_EXIT_READ_CR9               0x9
#define SVM_EXIT_READ_CR10              0xA
#define SVM_EXIT_READ_CR11              0xB
#define SVM_EXIT_READ_CR12              0xC
#define SVM_EXIT_READ_CR13              0xD
#define SVM_EXIT_READ_CR14              0xE
#define SVM_EXIT_READ_CR15              0xF
/** Writes to CR0-CR15. */
#define SVM_EXIT_WRITE_CR0              0x10
#define SVM_EXIT_WRITE_CR1              0x11
#define SVM_EXIT_WRITE_CR2              0x12
#define SVM_EXIT_WRITE_CR3              0x13
#define SVM_EXIT_WRITE_CR4              0x14
#define SVM_EXIT_WRITE_CR5              0x15
#define SVM_EXIT_WRITE_CR6              0x16
#define SVM_EXIT_WRITE_CR7              0x17
#define SVM_EXIT_WRITE_CR8              0x18
#define SVM_EXIT_WRITE_CR9              0x19
#define SVM_EXIT_WRITE_CR10             0x1A
#define SVM_EXIT_WRITE_CR11             0x1B
#define SVM_EXIT_WRITE_CR12             0x1C
#define SVM_EXIT_WRITE_CR13             0x1D
#define SVM_EXIT_WRITE_CR14             0x1E
#define SVM_EXIT_WRITE_CR15             0x1F
/** Read from DR0-DR15. */
#define SVM_EXIT_READ_DR0               0x20
#define SVM_EXIT_READ_DR1               0x21
#define SVM_EXIT_READ_DR2               0x22
#define SVM_EXIT_READ_DR3               0x23
#define SVM_EXIT_READ_DR4               0x24
#define SVM_EXIT_READ_DR5               0x25
#define SVM_EXIT_READ_DR6               0x26
#define SVM_EXIT_READ_DR7               0x27
#define SVM_EXIT_READ_DR8               0x28
#define SVM_EXIT_READ_DR9               0x29
#define SVM_EXIT_READ_DR10              0x2A
#define SVM_EXIT_READ_DR11              0x2B
#define SVM_EXIT_READ_DR12              0x2C
#define SVM_EXIT_READ_DR13              0x2D
#define SVM_EXIT_READ_DR14              0x2E
#define SVM_EXIT_READ_DR15              0x2F
/** Writes to DR0-DR15. */
#define SVM_EXIT_WRITE_DR0              0x30
#define SVM_EXIT_WRITE_DR1              0x31
#define SVM_EXIT_WRITE_DR2              0x32
#define SVM_EXIT_WRITE_DR3              0x33
#define SVM_EXIT_WRITE_DR4              0x34
#define SVM_EXIT_WRITE_DR5              0x35
#define SVM_EXIT_WRITE_DR6              0x36
#define SVM_EXIT_WRITE_DR7              0x37
#define SVM_EXIT_WRITE_DR8              0x38
#define SVM_EXIT_WRITE_DR9              0x39
#define SVM_EXIT_WRITE_DR10             0x3A
#define SVM_EXIT_WRITE_DR11             0x3B
#define SVM_EXIT_WRITE_DR12             0x3C
#define SVM_EXIT_WRITE_DR13             0x3D
#define SVM_EXIT_WRITE_DR14             0x3E
#define SVM_EXIT_WRITE_DR15             0x3F
/* Exception 0-31. */
#define SVM_EXIT_EXCEPTION_0            0x40
#define SVM_EXIT_EXCEPTION_1            0x41
#define SVM_EXIT_EXCEPTION_2            0x42
#define SVM_EXIT_EXCEPTION_3            0x43
#define SVM_EXIT_EXCEPTION_4            0x44
#define SVM_EXIT_EXCEPTION_5            0x45
#define SVM_EXIT_EXCEPTION_6            0x46
#define SVM_EXIT_EXCEPTION_7            0x47
#define SVM_EXIT_EXCEPTION_8            0x48
#define SVM_EXIT_EXCEPTION_9            0x49
#define SVM_EXIT_EXCEPTION_A            0x4A
#define SVM_EXIT_EXCEPTION_B            0x4B
#define SVM_EXIT_EXCEPTION_C            0x4C
#define SVM_EXIT_EXCEPTION_D            0x4D
#define SVM_EXIT_EXCEPTION_E            0x4E
#define SVM_EXIT_EXCEPTION_F            0x4F
#define SVM_EXIT_EXCEPTION_10           0x50
#define SVM_EXIT_EXCEPTION_11           0x51
#define SVM_EXIT_EXCEPTION_12           0x52
#define SVM_EXIT_EXCEPTION_13           0x53
#define SVM_EXIT_EXCEPTION_14           0x54
#define SVM_EXIT_EXCEPTION_15           0x55
#define SVM_EXIT_EXCEPTION_16           0x56
#define SVM_EXIT_EXCEPTION_17           0x57
#define SVM_EXIT_EXCEPTION_18           0x58
#define SVM_EXIT_EXCEPTION_19           0x59
#define SVM_EXIT_EXCEPTION_1A           0x5A
#define SVM_EXIT_EXCEPTION_1B           0x5B
#define SVM_EXIT_EXCEPTION_1C           0x5C
#define SVM_EXIT_EXCEPTION_1D           0x5D
#define SVM_EXIT_EXCEPTION_1E           0x5E
#define SVM_EXIT_EXCEPTION_1F           0x5F
/** Physical maskable interrupt. */
#define SVM_EXIT_INTR                   0x60
/** Non-maskable interrupt. */
#define SVM_EXIT_NMI                    0x61
/** System Management interrupt. */
#define SVM_EXIT_SMI                    0x62
/** Physical INIT signal. */
#define SVM_EXIT_INIT                   0x63
/** Virtual interrupt. */
#define SVM_EXIT_VINTR                  0x64
/** Write to CR0 that changed any bits other than CR0.TS or CR0.MP. */
#define SVM_EXIT_CR0_SEL_WRITE          0x65
/** IDTR read. */
#define SVM_EXIT_IDTR_READ              0x66
/** GDTR read. */
#define SVM_EXIT_GDTR_READ              0x67
/** LDTR read. */
#define SVM_EXIT_LDTR_READ              0x68
/** TR read. */
#define SVM_EXIT_TR_READ                0x69
/** IDTR write. */
#define SVM_EXIT_IDTR_WRITE             0x6A
/** GDTR write. */
#define SVM_EXIT_GDTR_WRITE             0x6B
/** LDTR write. */
#define SVM_EXIT_LDTR_WRITE             0x6C
/** TR write. */
#define SVM_EXIT_TR_WRITE               0x6D
/** RDTSC instruction. */
#define SVM_EXIT_RDTSC                  0x6E
/** RDPMC instruction. */
#define SVM_EXIT_RDPMC                  0x6F
/** PUSHF instruction. */
#define SVM_EXIT_PUSHF                  0x70
/** POPF instruction. */
#define SVM_EXIT_POPF                   0x71
/** CPUID instruction. */
#define SVM_EXIT_CPUID                  0x72
/** RSM instruction. */
#define SVM_EXIT_RSM                    0x73
/** IRET instruction. */
#define SVM_EXIT_IRET                   0x74
/** software interrupt (INTn instructions). */
#define SVM_EXIT_SWINT                  0x75
/** INVD instruction. */
#define SVM_EXIT_INVD                   0x76
/** PAUSE instruction. */
#define SVM_EXIT_PAUSE                  0x77
/** HLT instruction. */
#define SVM_EXIT_HLT                    0x78
/** INVLPG instructions. */
#define SVM_EXIT_INVLPG                 0x79
/** INVLPGA instruction. */
#define SVM_EXIT_INVLPGA                0x7A
/** IN or OUT accessing protected port (the EXITINFO1 field provides more information). */
#define SVM_EXIT_IOIO                   0x7B
/** RDMSR or WRMSR access to protected MSR. */
#define SVM_EXIT_MSR                    0x7C
/** task switch. */
#define SVM_EXIT_TASK_SWITCH            0x7D
/** FP legacy handling enabled, and processor is frozen in an x87/mmx instruction waiting for an interrupt. */
#define SVM_EXIT_FERR_FREEZE            0x7E
/** Shutdown. */
#define SVM_EXIT_SHUTDOWN               0x7F
/** VMRUN instruction. */
#define SVM_EXIT_VMRUN                  0x80
/** VMMCALL instruction. */
#define SVM_EXIT_VMMCALL                0x81
/** VMLOAD instruction. */
#define SVM_EXIT_VMLOAD                 0x82
/** VMSAVE instruction. */
#define SVM_EXIT_VMSAVE                 0x83
/** STGI instruction. */
#define SVM_EXIT_STGI                   0x84
/** CLGI instruction. */
#define SVM_EXIT_CLGI                   0x85
/** SKINIT instruction. */
#define SVM_EXIT_SKINIT                 0x86
/** RDTSCP instruction. */
#define SVM_EXIT_RDTSCP                 0x87
/** ICEBP instruction. */
#define SVM_EXIT_ICEBP                  0x88
/** WBINVD instruction. */
#define SVM_EXIT_WBINVD                 0x89
/** MONITOR instruction. */
#define SVM_EXIT_MONITOR                0x8A
/** MWAIT instruction. */
#define SVM_EXIT_MWAIT                  0x8B
/** MWAIT instruction, when armed. */
#define SVM_EXIT_MWAIT_ARMED            0x8C
/** Nested paging: host-level page fault occurred (EXITINFO1 contains fault errorcode; EXITINFO2 contains the guest physical address causing the fault). */
#define SVM_EXIT_NPF                    0x400
/** AVIC: Virtual IPI delivery not completed. */
#define SVM_EXIT_AVIC_INCOMPLETE_IPI    0x401
/** AVIC: Attempted access by guest to a vAPIC register not handled by AVIC
 *  hardware. */
#define SVM_EXIT_AVIC_NOACCEL           0x402

/** The maximum possible exit value. */
#define SVM_EXIT_MAX                    (SVM_EXIT_AVIC_NOACCEL)
/** @} */


/** @name SVMVMCB.u64ExitInfo2 for task switches
 * @{
 */
/** Set to 1 if the task switch was caused by an IRET; else cleared to 0. */
#define SVM_EXIT2_TASK_SWITCH_IRET                  RT_BIT_64(36)
/** Set to 1 if the task switch was caused by a far jump; else cleared to 0. */
#define SVM_EXIT2_TASK_SWITCH_JMP                   RT_BIT_64(38)
/** Set to 1 if the task switch has an error code; else cleared to 0. */
#define SVM_EXIT2_TASK_SWITCH_HAS_ERROR_CODE        RT_BIT_64(44)
/** The value of EFLAGS.RF that would be saved in the outgoing TSS if the task switch were not intercepted. */
#define SVM_EXIT2_TASK_SWITCH_EFLAGS_RF             RT_BIT_64(48)
/** @} */

/** @name SVMVMCB.u64ExitInfo1 for MSR accesses
 * @{
 */
/** The access was a read MSR. */
#define SVM_EXIT1_MSR_READ                      0x0
/** The access was a write MSR. */
#define SVM_EXIT1_MSR_WRITE                     0x1
/** @} */

/** @name SVMVMCB.ctrl.u32InterceptCtrl1
 * @{
 */
/** 0 Intercept INTR (physical maskable interrupt). */
#define SVM_CTRL1_INTERCEPT_INTR              RT_BIT(0)
/** 1 Intercept NMI. */
#define SVM_CTRL1_INTERCEPT_NMI               RT_BIT(1)
/** 2 Intercept SMI. */
#define SVM_CTRL1_INTERCEPT_SMI               RT_BIT(2)
/** 3 Intercept INIT. */
#define SVM_CTRL1_INTERCEPT_INIT              RT_BIT(3)
/** 4 Intercept VINTR (virtual maskable interrupt). */
#define SVM_CTRL1_INTERCEPT_VINTR             RT_BIT(4)
/** 5 Intercept CR0 writes that change bits other than CR0.TS or CR0.MP */
#define SVM_CTRL1_INTERCEPT_CR0               RT_BIT(5)
/** 6 Intercept reads of IDTR. */
#define SVM_CTRL1_INTERCEPT_IDTR_READS        RT_BIT(6)
/** 7 Intercept reads of GDTR. */
#define SVM_CTRL1_INTERCEPT_GDTR_READS        RT_BIT(7)
/** 8 Intercept reads of LDTR. */
#define SVM_CTRL1_INTERCEPT_LDTR_READS        RT_BIT(8)
/** 9 Intercept reads of TR. */
#define SVM_CTRL1_INTERCEPT_TR_READS          RT_BIT(9)
/** 10 Intercept writes of IDTR. */
#define SVM_CTRL1_INTERCEPT_IDTR_WRITES       RT_BIT(10)
/** 11 Intercept writes of GDTR. */
#define SVM_CTRL1_INTERCEPT_GDTR_WRITES       RT_BIT(11)
/** 12 Intercept writes of LDTR. */
#define SVM_CTRL1_INTERCEPT_LDTR_WRITES       RT_BIT(12)
/** 13 Intercept writes of TR. */
#define SVM_CTRL1_INTERCEPT_TR_WRITES         RT_BIT(13)
/** 14 Intercept RDTSC instruction. */
#define SVM_CTRL1_INTERCEPT_RDTSC             RT_BIT(14)
/** 15 Intercept RDPMC instruction. */
#define SVM_CTRL1_INTERCEPT_RDPMC             RT_BIT(15)
/** 16 Intercept PUSHF instruction. */
#define SVM_CTRL1_INTERCEPT_PUSHF             RT_BIT(16)
/** 17 Intercept POPF instruction. */
#define SVM_CTRL1_INTERCEPT_POPF              RT_BIT(17)
/** 18 Intercept CPUID instruction. */
#define SVM_CTRL1_INTERCEPT_CPUID             RT_BIT(18)
/** 19 Intercept RSM instruction. */
#define SVM_CTRL1_INTERCEPT_RSM               RT_BIT(19)
/** 20 Intercept IRET instruction. */
#define SVM_CTRL1_INTERCEPT_IRET              RT_BIT(20)
/** 21 Intercept INTn instruction. */
#define SVM_CTRL1_INTERCEPT_INTN              RT_BIT(21)
/** 22 Intercept INVD instruction. */
#define SVM_CTRL1_INTERCEPT_INVD              RT_BIT(22)
/** 23 Intercept PAUSE instruction. */
#define SVM_CTRL1_INTERCEPT_PAUSE             RT_BIT(23)
/** 24 Intercept HLT instruction. */
#define SVM_CTRL1_INTERCEPT_HLT               RT_BIT(24)
/** 25 Intercept INVLPG instruction. */
#define SVM_CTRL1_INTERCEPT_INVLPG            RT_BIT(25)
/** 26 Intercept INVLPGA instruction. */
#define SVM_CTRL1_INTERCEPT_INVLPGA           RT_BIT(26)
/** 27 IOIO_PROT Intercept IN/OUT accesses to selected ports. */
#define SVM_CTRL1_INTERCEPT_INOUT_BITMAP      RT_BIT(27)
/** 28 MSR_PROT Intercept RDMSR or WRMSR accesses to selected MSRs. */
#define SVM_CTRL1_INTERCEPT_MSR_SHADOW        RT_BIT(28)
/** 29 Intercept task switches. */
#define SVM_CTRL1_INTERCEPT_TASK_SWITCH       RT_BIT(29)
/** 30 FERR_FREEZE: intercept processor "freezing" during legacy FERR handling. */
#define SVM_CTRL1_INTERCEPT_FERR_FREEZE       RT_BIT(30)
/** 31 Intercept shutdown events. */
#define SVM_CTRL1_INTERCEPT_SHUTDOWN          RT_BIT(31)
/** @} */


/** @name SVMVMCB.ctrl.u32InterceptCtrl2
 * @{
 */
/** 0 Intercept VMRUN instruction. */
#define SVM_CTRL2_INTERCEPT_VMRUN             RT_BIT(0)
/** 1 Intercept VMMCALL instruction. */
#define SVM_CTRL2_INTERCEPT_VMMCALL           RT_BIT(1)
/** 2 Intercept VMLOAD instruction. */
#define SVM_CTRL2_INTERCEPT_VMLOAD            RT_BIT(2)
/** 3 Intercept VMSAVE instruction. */
#define SVM_CTRL2_INTERCEPT_VMSAVE            RT_BIT(3)
/** 4 Intercept STGI instruction. */
#define SVM_CTRL2_INTERCEPT_STGI              RT_BIT(4)
/** 5 Intercept CLGI instruction. */
#define SVM_CTRL2_INTERCEPT_CLGI              RT_BIT(5)
/** 6 Intercept SKINIT instruction. */
#define SVM_CTRL2_INTERCEPT_SKINIT            RT_BIT(6)
/** 7 Intercept RDTSCP instruction. */
#define SVM_CTRL2_INTERCEPT_RDTSCP            RT_BIT(7)
/** 8 Intercept ICEBP instruction. */
#define SVM_CTRL2_INTERCEPT_ICEBP             RT_BIT(8)
/** 9 Intercept WBINVD instruction. */
#define SVM_CTRL2_INTERCEPT_WBINVD            RT_BIT(9)
/** 10 Intercept MONITOR instruction. */
#define SVM_CTRL2_INTERCEPT_MONITOR           RT_BIT(10)
/** 11 Intercept MWAIT instruction unconditionally. */
#define SVM_CTRL2_INTERCEPT_MWAIT             RT_BIT(11)
/** 12 Intercept MWAIT instruction when armed. */
#define SVM_CTRL2_INTERCEPT_MWAIT_ARMED       RT_BIT(12)
/** 13 Intercept XSETBV instruction. */
#define SVM_CTRL2_INTERCEPT_XSETBV            RT_BIT(13)
/** @} */

/** @name SVMVMCB.ctrl.u64NestedPaging
 * @{
 */
#define SVM_NESTED_PAGING_ENABLE                RT_BIT(0)
/** @} */

/** @name SVMVMCB.ctrl.u64IntShadow
 * @{
 */
#define SVM_INTERRUPT_SHADOW_ACTIVE             RT_BIT(0)
/** @} */


/** @name SVMINTCTRL.u3Type
 * @{
 */
/** External or virtual interrupt. */
#define SVM_EVENT_EXTERNAL_IRQ                  0
/** Non-maskable interrupt. */
#define SVM_EVENT_NMI                           2
/** Exception; fault or trap. */
#define SVM_EVENT_EXCEPTION                     3
/** Software interrupt. */
#define SVM_EVENT_SOFTWARE_INT                  4
/** @} */


/** @name SVMVMCB.ctrl.TLBCtrl.n.u8TLBFlush
 * @{
 */
/** Flush nothing. */
#define SVM_TLB_FLUSH_NOTHING                           0
/** Flush entire TLB (host+guest entries) */
#define SVM_TLB_FLUSH_ENTIRE                            1
/** Flush this guest's TLB entries (by ASID) */
#define SVM_TLB_FLUSH_SINGLE_CONTEXT                    3
/** Flush this guest's non-global TLB entries (by ASID) */
#define SVM_TLB_FLUSH_SINGLE_CONTEXT_RETAIN_GLOBALS     7
/** @} */


/**
 * SVM Selector type; includes hidden parts.
 */
#pragma pack(1)
typedef struct
{
    uint16_t    u16Sel;
    uint16_t    u16Attr;
    uint32_t    u32Limit;
    uint64_t    u64Base;        /**< Only lower 32 bits are implemented for CS, DS, ES & SS. */
} SVMSEL;
#pragma pack()

/**
 * SVM GDTR/IDTR type.
 */
#pragma pack(1)
typedef struct
{
    uint16_t    u16Reserved1;
    uint16_t    u16Reserved2;
    uint32_t    u32Limit;       /**< Only lower 16 bits are implemented. */
    uint64_t    u64Base;
} SVMGDTR;
#pragma pack()
typedef SVMGDTR SVMIDTR;

/**
 * SVM Event injection structure (EVENTINJ and EXITINTINFO).
 */
typedef union
{
    struct
    {
        uint32_t    u8Vector            : 8;
        uint32_t    u3Type              : 3;
        uint32_t    u1ErrorCodeValid    : 1;
        uint32_t    u19Reserved         : 19;
        uint32_t    u1Valid             : 1;
        uint32_t    u32ErrorCode        : 32;
    } n;
    uint64_t    u;
} SVMEVENT;
/** Pointer to the SVMEVENT union. */
typedef SVMEVENT *PSVMEVENT;

/**
 * SVM Interrupt control structure (Virtual Interrupt Control).
 */
typedef union
{
    struct
    {
        uint32_t    u8VTPR              : 8;
        uint32_t    u1VIrqValid         : 1;
        uint32_t    u7Reserved          : 7;
        uint32_t    u4VIrqPriority      : 4;
        uint32_t    u1IgnoreTPR         : 1;
        uint32_t    u3Reserved          : 3;
        uint32_t    u1VIrqMasking       : 1;
        uint32_t    u6Reserved          : 6;
        uint32_t    u1AvicEnable        : 1;
        uint32_t    u8VIrqVector        : 8;
        uint32_t    u24Reserved         : 24;
    } n;
    uint64_t    u;
} SVMINTCTRL;

/**
 * SVM TLB control structure.
 */
typedef union
{
    struct
    {
        uint32_t    u32ASID             : 32;
        uint32_t    u8TLBFlush          : 8;
        uint32_t    u24Reserved         : 24;
    } n;
    uint64_t    u;
} SVMTLBCTRL;

/**
 * SVM IOIO exit structure (EXITINFO1 for IOIO intercepts).
 */
typedef union
{
    struct
    {
        uint32_t    u1Type              : 1;        /**< 0 = out, 1 = in */
        uint32_t    u1Reserved          : 1;
        uint32_t    u1STR               : 1;
        uint32_t    u1REP               : 1;
        uint32_t    u1OP8               : 1;
        uint32_t    u1OP16              : 1;
        uint32_t    u1OP32              : 1;
        uint32_t    u1ADDR16            : 1;
        uint32_t    u1ADDR32            : 1;
        uint32_t    u1ADDR64            : 1;
        uint32_t    u6Reserved          : 6;
        uint32_t    u16Port             : 16;
    } n;
    uint32_t    u;
} SVMIOIOEXIT;

/** @name SVMIOIOEXIT.u1Type
 *  @{ */
/** IO write. */
#define SVM_IOIO_WRITE                  0
/** IO read. */
#define SVM_IOIO_READ                   1
/** @}*/

/**
 * SVM nested paging structure.
 */
typedef union
{
    struct
    {
        uint32_t    u1NestedPaging      : 1;             /**< enabled/disabled */
    } n;
    uint64_t    u;
} SVMNPCTRL;

/**
 * SVM AVIC.
 */
typedef union
{
    struct
    {
        uint64_t    u12Reserved1        : 12;
        uint64_t    u40Addr             : 40;
        uint64_t    u12Reserved2        : 12;
    } n;
    uint64_t    u;
} SVMAVIC;
AssertCompileSize(SVMAVIC, 8);

/**
 * SVM AVIC PHYSICAL_TABLE pointer.
 */
typedef union
{
    struct
    {
        uint64_t    u8LastGuestCoreId   : 8;
        uint64_t    u4Reserved          : 4;
        uint64_t    u40Addr             : 40;
        uint64_t    u12Reserved         : 12;
    } n;
    uint64_t    u;
} SVMAVICPHYS;
AssertCompileSize(SVMAVICPHYS, 8);

/**
 * SVM VM Control Block. (VMCB)
 */
#pragma pack(1)
typedef struct SVMVMCB
{
    /** Control Area. */
    struct
    {
        /** Offset 0x00 - Intercept reads of CR0-15. */
        uint16_t    u16InterceptRdCRx;
        /** Offset 0x02 - Intercept writes to CR0-15. */
        uint16_t    u16InterceptWrCRx;
        /** Offset 0x04 - Intercept reads of DR0-15. */
        uint16_t    u16InterceptRdDRx;
        /** Offset 0x06 - Intercept writes to DR0-15. */
        uint16_t    u16InterceptWrDRx;
        /** Offset 0x08 - Intercept exception vectors 0-31. */
        uint32_t    u32InterceptException;
        /** Offset 0x0C - Intercept control field 1. */
        uint32_t    u32InterceptCtrl1;
        /** Offset 0x0C - Intercept control field 2. */
        uint32_t    u32InterceptCtrl2;
        /** Offset 0x14-0x3F - Reserved. */
        uint8_t     u8Reserved[0x3c - 0x14];
        /** Offset 0x3c - PAUSE filter threshold.  */
        uint16_t    u16PauseFilterThreshold;
        /** Offset 0x3e - PAUSE intercept filter count. */
        uint16_t    u16PauseFilterCount;
        /** Offset 0x40 - Physical address of IOPM. */
        uint64_t    u64IOPMPhysAddr;
        /** Offset 0x48 - Physical address of MSRPM. */
        uint64_t    u64MSRPMPhysAddr;
        /** Offset 0x50 - TSC Offset. */
        uint64_t    u64TSCOffset;
        /** Offset 0x58 - TLB control field. */
        SVMTLBCTRL  TLBCtrl;
        /** Offset 0x60 - Interrupt control field. */
        SVMINTCTRL  IntCtrl;
        /** Offset 0x68 - Interrupt shadow. */
        uint64_t    u64IntShadow;
        /** Offset 0x70 - Exit code. */
        uint64_t    u64ExitCode;
        /** Offset 0x78 - Exit info 1. */
        uint64_t    u64ExitInfo1;
        /** Offset 0x80 - Exit info 2. */
        uint64_t    u64ExitInfo2;
        /** Offset 0x88 - Exit Interrupt info. */
        SVMEVENT    ExitIntInfo;
        /** Offset 0x90 - Nested Paging. */
        SVMNPCTRL   NestedPaging;
        /** Offset 0x98 - AVIC APIC BAR.  */
        SVMAVIC     AvicBar;
        /** Offset 0xA0-0xA7 - Reserved. */
        uint8_t     u8Reserved2[0xA8-0xA0];
        /** Offset 0xA8 - Event injection. */
        SVMEVENT    EventInject;
        /** Offset 0xB0 - Host CR3 for nested paging. */
        uint64_t    u64NestedPagingCR3;
        /** Offset 0xB8 - LBR Virtualization. */
        uint64_t    u64LBRVirt;
        /** Offset 0xC0 - VMCB Clean Bits. */
        uint64_t    u64VmcbCleanBits;
        /** Offset 0xC8 - Next sequential instruction pointer. */
        uint64_t    u64NextRIP;
        /** Offset 0xD0 - Number of bytes fetched. */
        uint8_t     cbInstrFetched;
        /** Offset 0xD1 - Number of bytes fetched. */
        uint8_t     abInstr[15];
        /** Offset 0xE0 - AVIC APIC_BACKING_PAGE pointer. */
        SVMAVIC     AvicBackingPagePtr;
        /** Offset 0xE8-0xEF - Reserved. */
        uint8_t     u8Reserved3[0xF0 - 0xE8];
        /** Offset 0xF0 - AVIC LOGICAL_TABLE pointer. */
        SVMAVIC     AvicLogicalTablePtr;
        /** Offset 0xF8 - AVIC PHYSICAL_TABLE pointer. */
        SVMAVICPHYS AvicPhysicalTablePtr;
    } ctrl;

    /** Offset 0x100-0x3FF - Reserved. */
    uint8_t     u8Reserved3[0x400-0x100];

    /** State Save Area. Starts at offset 0x400. */
    struct
    {
        /** Offset 0x400 - Guest ES register + hidden parts. */
        SVMSEL      ES;
        /** Offset 0x410 - Guest CS register + hidden parts. */
        SVMSEL      CS;
        /** Offset 0x420 - Guest SS register + hidden parts. */
        SVMSEL      SS;
        /** Offset 0x430 - Guest DS register + hidden parts. */
        SVMSEL      DS;
        /** Offset 0x440 - Guest FS register + hidden parts. */
        SVMSEL      FS;
        /** Offset 0x450 - Guest GS register + hidden parts. */
        SVMSEL      GS;
        /** Offset 0x460 - Guest GDTR register. */
        SVMGDTR     GDTR;
        /** Offset 0x470 - Guest LDTR register + hidden parts. */
        SVMSEL      LDTR;
        /** Offset 0x480 - Guest IDTR register. */
        SVMIDTR     IDTR;
        /** Offset 0x490 - Guest TR register + hidden parts. */
        SVMSEL      TR;
        /** Offset 0x4A0-0x4CA - Reserved. */
        uint8_t     u8Reserved4[0x4CB-0x4A0];
        /** Offset 0x4CB - CPL. */
        uint8_t     u8CPL;
        /** Offset 0x4CC-0x4CF - Reserved. */
        uint8_t     u8Reserved5[0x4D0-0x4CC];
        /** Offset 0x4D0 - EFER. */
        uint64_t    u64EFER;
        /** Offset 0x4D8-0x547 - Reserved. */
        uint8_t     u8Reserved6[0x548-0x4D8];
        /** Offset 0x548 - CR4. */
        uint64_t    u64CR4;
        /** Offset 0x550 - CR3. */
        uint64_t    u64CR3;
        /** Offset 0x558 - CR0. */
        uint64_t    u64CR0;
        /** Offset 0x560 - DR7. */
        uint64_t    u64DR7;
        /** Offset 0x568 - DR6. */
        uint64_t    u64DR6;
        /** Offset 0x570 - RFLAGS. */
        uint64_t    u64RFlags;
        /** Offset 0x578 - RIP. */
        uint64_t    u64RIP;
        /** Offset 0x580-0x5D7 - Reserved. */
        uint8_t     u8Reserved7[0x5D8-0x580];
        /** Offset 0x5D8 - RSP. */
        uint64_t    u64RSP;
        /** Offset 0x5E0-0x5F7 - Reserved. */
        uint8_t     u8Reserved8[0x5F8-0x5E0];
        /** Offset 0x5F8 - RAX. */
        uint64_t    u64RAX;
        /** Offset 0x600 - STAR. */
        uint64_t    u64STAR;
        /** Offset 0x608 - LSTAR. */
        uint64_t    u64LSTAR;
        /** Offset 0x610 - CSTAR. */
        uint64_t    u64CSTAR;
        /** Offset 0x618 - SFMASK. */
        uint64_t    u64SFMASK;
        /** Offset 0x620 - KernelGSBase. */
        uint64_t    u64KernelGSBase;
        /** Offset 0x628 - SYSENTER_CS. */
        uint64_t    u64SysEnterCS;
        /** Offset 0x630 - SYSENTER_ESP. */
        uint64_t    u64SysEnterESP;
        /** Offset 0x638 - SYSENTER_EIP. */
        uint64_t    u64SysEnterEIP;
        /** Offset 0x640 - CR2. */
        uint64_t    u64CR2;
        /** Offset 0x648-0x667 - Reserved. */
        uint8_t     u8Reserved9[0x668-0x648];
        /** Offset 0x668 - G_PAT. */
        uint64_t    u64GPAT;
        /** Offset 0x670 - DBGCTL. */
        uint64_t    u64DBGCTL;
        /** Offset 0x678 - BR_FROM. */
        uint64_t    u64BR_FROM;
        /** Offset 0x680 - BR_TO. */
        uint64_t    u64BR_TO;
        /** Offset 0x688 - LASTEXCPFROM. */
        uint64_t    u64LASTEXCPFROM;
        /** Offset 0x690 - LASTEXCPTO. */
        uint64_t    u64LASTEXCPTO;
    } guest;

    /** Offset 0x698-0xFFF- Reserved. */
    uint8_t     u8Reserved10[0x1000-0x698];
} SVMVMCB;
#pragma pack()
/** Pointer to the SVMVMCB structure. */
typedef SVMVMCB *PSVMVMCB;
AssertCompileMemberOffset(SVMVMCB, ctrl.u16InterceptRdCRx,    0x000);
AssertCompileMemberOffset(SVMVMCB, ctrl.u16PauseFilterCount,  0x03e);
AssertCompileMemberOffset(SVMVMCB, ctrl.TLBCtrl,              0x058);
AssertCompileMemberOffset(SVMVMCB, ctrl.ExitIntInfo,          0x088);
AssertCompileMemberOffset(SVMVMCB, ctrl.EventInject,          0x0A8);
AssertCompileMemberOffset(SVMVMCB, ctrl.abInstr,              0x0D1);
AssertCompileMemberOffset(SVMVMCB, ctrl.AvicBackingPagePtr,   0x0E0);
AssertCompileMemberOffset(SVMVMCB, ctrl.AvicLogicalTablePtr,  0x0F0);
AssertCompileMemberOffset(SVMVMCB, ctrl.AvicPhysicalTablePtr, 0x0F8);
AssertCompileMemberOffset(SVMVMCB, guest,                     0x400);
AssertCompileMemberOffset(SVMVMCB, guest.ES,                  0x400);
AssertCompileMemberOffset(SVMVMCB, guest.TR,                  0x490);
AssertCompileMemberOffset(SVMVMCB, guest.u64EFER,             0x4D0);
AssertCompileMemberOffset(SVMVMCB, guest.u64CR4,              0x548);
AssertCompileMemberOffset(SVMVMCB, guest.u64RIP,              0x578);
AssertCompileMemberOffset(SVMVMCB, guest.u64RSP,              0x5D8);
AssertCompileMemberOffset(SVMVMCB, guest.u64CR2,              0x640);
AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved4,         0x4A0);
AssertCompileMemberOffset(SVMVMCB, guest.u8CPL,               0x4CB);
AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved6,         0x4D8);
AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved7,         0x580);
AssertCompileMemberOffset(SVMVMCB, guest.u8Reserved9,         0x648);
AssertCompileMemberOffset(SVMVMCB, guest.u64GPAT,             0x668);
AssertCompileMemberOffset(SVMVMCB, guest.u64LASTEXCPTO,       0x690);
AssertCompileMemberOffset(SVMVMCB, u8Reserved10,              0x698);
AssertCompileSize(SVMVMCB, 0x1000);

#ifdef IN_RING0
VMMR0DECL(int) SVMR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt);
#endif /* IN_RING0 */

/** @} */

#endif