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
|