VirtualBox

source: vbox/trunk/include/VBox/vmm/hm_svm.h@ 66301

Last change on this file since 66301 was 66301, checked in by vboxsync, 8 years ago

VMM: Nested Hw.virt: SVM bits.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 40.1 KB
Line 
1/** @file
2 * HM - SVM (AMD-V) Structures and Definitions. (VMM)
3 */
4
5/*
6 * Copyright (C) 2006-2016 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 *
16 * The contents of this file may alternatively be used under the terms
17 * of the Common Development and Distribution License Version 1.0
18 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
19 * VirtualBox OSE distribution, in which case the provisions of the
20 * CDDL are applicable instead of those of the GPL.
21 *
22 * You may elect to license modified versions of this file under the
23 * terms and conditions of either the GPL or the CDDL or both.
24 */
25
26#ifndef ___VBox_vmm_svm_h
27#define ___VBox_vmm_svm_h
28
29#include <VBox/types.h>
30#include <VBox/err.h>
31#include <iprt/assert.h>
32#include <iprt/asm.h>
33
34#ifdef RT_OS_SOLARIS
35# undef ES
36# undef CS
37# undef DS
38# undef SS
39# undef FS
40# undef GS
41#endif
42
43/** @defgroup grp_hm_svm SVM (AMD-V) Types and Definitions
44 * @ingroup grp_hm
45 * @{
46 */
47
48/** @name SVM features for cpuid 0x8000000a
49 * @{
50 */
51/** Bit 0 - NP - Nested Paging supported. */
52#define AMD_CPUID_SVM_FEATURE_EDX_NESTED_PAGING RT_BIT(0)
53/** Bit 1 - LbrVirt - Support for saving five debug MSRs. */
54#define AMD_CPUID_SVM_FEATURE_EDX_LBR_VIRT RT_BIT(1)
55/** Bit 2 - SVML - SVM locking bit supported. */
56#define AMD_CPUID_SVM_FEATURE_EDX_SVM_LOCK RT_BIT(2)
57/** Bit 3 - NRIPS - Saving the next instruction pointer is supported. */
58#define AMD_CPUID_SVM_FEATURE_EDX_NRIP_SAVE RT_BIT(3)
59/** Bit 4 - TscRateMsr - Support for MSR TSC ratio. */
60#define AMD_CPUID_SVM_FEATURE_EDX_TSC_RATE_MSR RT_BIT(4)
61/** Bit 5 - VmcbClean - Support VMCB clean bits. */
62#define AMD_CPUID_SVM_FEATURE_EDX_VMCB_CLEAN RT_BIT(5)
63/** Bit 6 - FlushByAsid - Indicate TLB flushing for current ASID only, and that
64 * VMCB.TLB_Control is supported. */
65#define AMD_CPUID_SVM_FEATURE_EDX_FLUSH_BY_ASID RT_BIT(6)
66/** Bit 7 - DecodeAssist - Indicate decode assist is supported. */
67#define AMD_CPUID_SVM_FEATURE_EDX_DECODE_ASSIST RT_BIT(7)
68/** Bit 10 - PauseFilter - Indicates support for the PAUSE intercept filter. */
69#define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER RT_BIT(10)
70/** Bit 12 - PauseFilterThreshold - Indicates support for the PAUSE
71 * intercept filter cycle count threshold. */
72#define AMD_CPUID_SVM_FEATURE_EDX_PAUSE_FILTER_THRESHOLD RT_BIT(12)
73/** Bit 13 - AVIC - Advanced Virtual Interrupt Controller. */
74#define AMD_CPUID_SVM_FEATURE_EDX_AVIC RT_BIT(13)
75/** @} */
76
77/** @name SVM generic / convenient defines.
78 * @{
79 */
80/** Number of pages required for the VMCB. */
81#define SVM_VMCB_PAGES 1
82/** Number of pages required for the MSR permission bitmap. */
83#define SVM_MSRPM_PAGES 2
84/** Number of pages required for the IO permission bitmap. */
85#define SVM_IOPM_PAGES 3
86/** @} */
87
88/*
89 * Ugly!
90 * When compiling the recompiler, its own svm.h defines clash with
91 * the following defines. Avoid just the duplicates here as we still
92 * require other definitions and structures in this header.
93 */
94#ifndef IN_REM_R3
95/** @name SVM Basic Exit Reasons.
96 * @{
97 */
98/** Invalid guest state in VMCB. */
99# define SVM_EXIT_INVALID (uint64_t)(-1)
100/** Read from CR0-CR15. */
101# define SVM_EXIT_READ_CR0 0x0
102# define SVM_EXIT_READ_CR1 0x1
103# define SVM_EXIT_READ_CR2 0x2
104# define SVM_EXIT_READ_CR3 0x3
105# define SVM_EXIT_READ_CR4 0x4
106# define SVM_EXIT_READ_CR5 0x5
107# define SVM_EXIT_READ_CR6 0x6
108# define SVM_EXIT_READ_CR7 0x7
109# define SVM_EXIT_READ_CR8 0x8
110# define SVM_EXIT_READ_CR9 0x9
111# define SVM_EXIT_READ_CR10 0xA
112# define SVM_EXIT_READ_CR11 0xB
113# define SVM_EXIT_READ_CR12 0xC
114# define SVM_EXIT_READ_CR13 0xD
115# define SVM_EXIT_READ_CR14 0xE
116# define SVM_EXIT_READ_CR15 0xF
117/** Writes to CR0-CR15. */
118# define SVM_EXIT_WRITE_CR0 0x10
119# define SVM_EXIT_WRITE_CR1 0x11
120# define SVM_EXIT_WRITE_CR2 0x12
121# define SVM_EXIT_WRITE_CR3 0x13
122# define SVM_EXIT_WRITE_CR4 0x14
123# define SVM_EXIT_WRITE_CR5 0x15
124# define SVM_EXIT_WRITE_CR6 0x16
125# define SVM_EXIT_WRITE_CR7 0x17
126# define SVM_EXIT_WRITE_CR8 0x18
127# define SVM_EXIT_WRITE_CR9 0x19
128# define SVM_EXIT_WRITE_CR10 0x1A
129# define SVM_EXIT_WRITE_CR11 0x1B
130# define SVM_EXIT_WRITE_CR12 0x1C
131# define SVM_EXIT_WRITE_CR13 0x1D
132# define SVM_EXIT_WRITE_CR14 0x1E
133# define SVM_EXIT_WRITE_CR15 0x1F
134/** Read from DR0-DR15. */
135# define SVM_EXIT_READ_DR0 0x20
136# define SVM_EXIT_READ_DR1 0x21
137# define SVM_EXIT_READ_DR2 0x22
138# define SVM_EXIT_READ_DR3 0x23
139# define SVM_EXIT_READ_DR4 0x24
140# define SVM_EXIT_READ_DR5 0x25
141# define SVM_EXIT_READ_DR6 0x26
142# define SVM_EXIT_READ_DR7 0x27
143# define SVM_EXIT_READ_DR8 0x28
144# define SVM_EXIT_READ_DR9 0x29
145# define SVM_EXIT_READ_DR10 0x2A
146# define SVM_EXIT_READ_DR11 0x2B
147# define SVM_EXIT_READ_DR12 0x2C
148# define SVM_EXIT_READ_DR13 0x2D
149# define SVM_EXIT_READ_DR14 0x2E
150# define SVM_EXIT_READ_DR15 0x2F
151/** Writes to DR0-DR15. */
152# define SVM_EXIT_WRITE_DR0 0x30
153# define SVM_EXIT_WRITE_DR1 0x31
154# define SVM_EXIT_WRITE_DR2 0x32
155# define SVM_EXIT_WRITE_DR3 0x33
156# define SVM_EXIT_WRITE_DR4 0x34
157# define SVM_EXIT_WRITE_DR5 0x35
158# define SVM_EXIT_WRITE_DR6 0x36
159# define SVM_EXIT_WRITE_DR7 0x37
160# define SVM_EXIT_WRITE_DR8 0x38
161# define SVM_EXIT_WRITE_DR9 0x39
162# define SVM_EXIT_WRITE_DR10 0x3A
163# define SVM_EXIT_WRITE_DR11 0x3B
164# define SVM_EXIT_WRITE_DR12 0x3C
165# define SVM_EXIT_WRITE_DR13 0x3D
166# define SVM_EXIT_WRITE_DR14 0x3E
167# define SVM_EXIT_WRITE_DR15 0x3F
168/* Exception 0-31. */
169# define SVM_EXIT_EXCEPTION_0 0x40
170# define SVM_EXIT_EXCEPTION_1 0x41
171# define SVM_EXIT_EXCEPTION_2 0x42
172# define SVM_EXIT_EXCEPTION_3 0x43
173# define SVM_EXIT_EXCEPTION_4 0x44
174# define SVM_EXIT_EXCEPTION_5 0x45
175# define SVM_EXIT_EXCEPTION_6 0x46
176# define SVM_EXIT_EXCEPTION_7 0x47
177# define SVM_EXIT_EXCEPTION_8 0x48
178# define SVM_EXIT_EXCEPTION_9 0x49
179# define SVM_EXIT_EXCEPTION_A 0x4A
180# define SVM_EXIT_EXCEPTION_B 0x4B
181# define SVM_EXIT_EXCEPTION_C 0x4C
182# define SVM_EXIT_EXCEPTION_D 0x4D
183# define SVM_EXIT_EXCEPTION_E 0x4E
184# define SVM_EXIT_EXCEPTION_F 0x4F
185# define SVM_EXIT_EXCEPTION_10 0x50
186# define SVM_EXIT_EXCEPTION_11 0x51
187# define SVM_EXIT_EXCEPTION_12 0x52
188# define SVM_EXIT_EXCEPTION_13 0x53
189# define SVM_EXIT_EXCEPTION_14 0x54
190# define SVM_EXIT_EXCEPTION_15 0x55
191# define SVM_EXIT_EXCEPTION_16 0x56
192# define SVM_EXIT_EXCEPTION_17 0x57
193# define SVM_EXIT_EXCEPTION_18 0x58
194# define SVM_EXIT_EXCEPTION_19 0x59
195# define SVM_EXIT_EXCEPTION_1A 0x5A
196# define SVM_EXIT_EXCEPTION_1B 0x5B
197# define SVM_EXIT_EXCEPTION_1C 0x5C
198# define SVM_EXIT_EXCEPTION_1D 0x5D
199# define SVM_EXIT_EXCEPTION_1E 0x5E
200# define SVM_EXIT_EXCEPTION_1F 0x5F
201/** Physical maskable interrupt. */
202# define SVM_EXIT_INTR 0x60
203/** Non-maskable interrupt. */
204# define SVM_EXIT_NMI 0x61
205/** System Management interrupt. */
206# define SVM_EXIT_SMI 0x62
207/** Physical INIT signal. */
208# define SVM_EXIT_INIT 0x63
209/** Virtual interrupt. */
210# define SVM_EXIT_VINTR 0x64
211/** Write to CR0 that changed any bits other than CR0.TS or CR0.MP. */
212# define SVM_EXIT_CR0_SEL_WRITE 0x65
213/** IDTR read. */
214# define SVM_EXIT_IDTR_READ 0x66
215/** GDTR read. */
216# define SVM_EXIT_GDTR_READ 0x67
217/** LDTR read. */
218# define SVM_EXIT_LDTR_READ 0x68
219/** TR read. */
220# define SVM_EXIT_TR_READ 0x69
221/** IDTR write. */
222# define SVM_EXIT_IDTR_WRITE 0x6A
223/** GDTR write. */
224# define SVM_EXIT_GDTR_WRITE 0x6B
225/** LDTR write. */
226# define SVM_EXIT_LDTR_WRITE 0x6C
227/** TR write. */
228# define SVM_EXIT_TR_WRITE 0x6D
229/** RDTSC instruction. */
230# define SVM_EXIT_RDTSC 0x6E
231/** RDPMC instruction. */
232# define SVM_EXIT_RDPMC 0x6F
233/** PUSHF instruction. */
234# define SVM_EXIT_PUSHF 0x70
235/** POPF instruction. */
236# define SVM_EXIT_POPF 0x71
237/** CPUID instruction. */
238# define SVM_EXIT_CPUID 0x72
239/** RSM instruction. */
240# define SVM_EXIT_RSM 0x73
241/** IRET instruction. */
242# define SVM_EXIT_IRET 0x74
243/** software interrupt (INTn instructions). */
244# define SVM_EXIT_SWINT 0x75
245/** INVD instruction. */
246# define SVM_EXIT_INVD 0x76
247/** PAUSE instruction. */
248# define SVM_EXIT_PAUSE 0x77
249/** HLT instruction. */
250# define SVM_EXIT_HLT 0x78
251/** INVLPG instructions. */
252# define SVM_EXIT_INVLPG 0x79
253/** INVLPGA instruction. */
254# define SVM_EXIT_INVLPGA 0x7A
255/** IN or OUT accessing protected port (the EXITINFO1 field provides more information). */
256# define SVM_EXIT_IOIO 0x7B
257/** RDMSR or WRMSR access to protected MSR. */
258# define SVM_EXIT_MSR 0x7C
259/** task switch. */
260# define SVM_EXIT_TASK_SWITCH 0x7D
261/** FP legacy handling enabled, and processor is frozen in an x87/mmx instruction waiting for an interrupt. */
262# define SVM_EXIT_FERR_FREEZE 0x7E
263/** Shutdown. */
264# define SVM_EXIT_SHUTDOWN 0x7F
265/** VMRUN instruction. */
266# define SVM_EXIT_VMRUN 0x80
267/** VMMCALL instruction. */
268# define SVM_EXIT_VMMCALL 0x81
269/** VMLOAD instruction. */
270# define SVM_EXIT_VMLOAD 0x82
271/** VMSAVE instruction. */
272# define SVM_EXIT_VMSAVE 0x83
273/** STGI instruction. */
274# define SVM_EXIT_STGI 0x84
275/** CLGI instruction. */
276# define SVM_EXIT_CLGI 0x85
277/** SKINIT instruction. */
278# define SVM_EXIT_SKINIT 0x86
279/** RDTSCP instruction. */
280# define SVM_EXIT_RDTSCP 0x87
281/** ICEBP instruction. */
282# define SVM_EXIT_ICEBP 0x88
283/** WBINVD instruction. */
284# define SVM_EXIT_WBINVD 0x89
285/** MONITOR instruction. */
286# define SVM_EXIT_MONITOR 0x8A
287/** MWAIT instruction. */
288# define SVM_EXIT_MWAIT 0x8B
289/** MWAIT instruction, when armed. */
290# define SVM_EXIT_MWAIT_ARMED 0x8C
291/** XSETBV instruction. */
292# define SVM_EXIT_XSETBV 0x8D
293/** Nested paging: host-level page fault occurred (EXITINFO1 contains fault errorcode; EXITINFO2 contains the guest physical address causing the fault). */
294# define SVM_EXIT_NPF 0x400
295/** AVIC: Virtual IPI delivery not completed. */
296# define SVM_EXIT_AVIC_INCOMPLETE_IPI 0x401
297/** AVIC: Attempted access by guest to a vAPIC register not handled by AVIC
298 * hardware. */
299# define SVM_EXIT_AVIC_NOACCEL 0x402
300/** The maximum possible exit value. */
301# define SVM_EXIT_MAX (SVM_EXIT_AVIC_NOACCEL)
302/** @} */
303#endif /* !IN_REM_R3*/
304
305
306/** @name SVMVMCB.u64ExitInfo2 for task switches
307 * @{
308 */
309/** Set to 1 if the task switch was caused by an IRET; else cleared to 0. */
310#define SVM_EXIT2_TASK_SWITCH_IRET RT_BIT_64(36)
311/** Set to 1 if the task switch was caused by a far jump; else cleared to 0. */
312#define SVM_EXIT2_TASK_SWITCH_JMP RT_BIT_64(38)
313/** Set to 1 if the task switch has an error code; else cleared to 0. */
314#define SVM_EXIT2_TASK_SWITCH_HAS_ERROR_CODE RT_BIT_64(44)
315/** The value of EFLAGS.RF that would be saved in the outgoing TSS if the task switch were not intercepted. */
316#define SVM_EXIT2_TASK_SWITCH_EFLAGS_RF RT_BIT_64(48)
317/** @} */
318
319/** @name SVMVMCB.u64ExitInfo1 for MSR accesses
320 * @{
321 */
322/** The access was a read MSR. */
323#define SVM_EXIT1_MSR_READ 0x0
324/** The access was a write MSR. */
325#define SVM_EXIT1_MSR_WRITE 0x1
326/** @} */
327
328
329/** @name SVMVMCB.ctrl.u64InterceptCtrl
330 * @{
331 */
332/** Intercept INTR (physical maskable interrupt). */
333#define SVM_CTRL_INTERCEPT_INTR RT_BIT_64(0)
334/** Intercept NMI. */
335#define SVM_CTRL_INTERCEPT_NMI RT_BIT_64(1)
336/** Intercept SMI. */
337#define SVM_CTRL_INTERCEPT_SMI RT_BIT_64(2)
338/** Intercept INIT. */
339#define SVM_CTRL_INTERCEPT_INIT RT_BIT_64(3)
340/** Intercept VINTR (virtual maskable interrupt). */
341#define SVM_CTRL_INTERCEPT_VINTR RT_BIT_64(4)
342/** Intercept CR0 writes that change bits other than CR0.TS or CR0.MP */
343#define SVM_CTRL_INTERCEPT_CR0 RT_BIT_64(5)
344/** Intercept reads of IDTR. */
345#define SVM_CTRL_INTERCEPT_IDTR_READS RT_BIT_64(6)
346/** Intercept reads of GDTR. */
347#define SVM_CTRL_INTERCEPT_GDTR_READS RT_BIT_64(7)
348/** Intercept reads of LDTR. */
349#define SVM_CTRL_INTERCEPT_LDTR_READS RT_BIT_64(8)
350/** Intercept reads of TR. */
351#define SVM_CTRL_INTERCEPT_TR_READS RT_BIT_64(9)
352/** Intercept writes of IDTR. */
353#define SVM_CTRL_INTERCEPT_IDTR_WRITES RT_BIT_64(10)
354/** Intercept writes of GDTR. */
355#define SVM_CTRL_INTERCEPT_GDTR_WRITES RT_BIT_64(11)
356/** Intercept writes of LDTR. */
357#define SVM_CTRL_INTERCEPT_LDTR_WRITES RT_BIT_64(12)
358/** Intercept writes of TR. */
359#define SVM_CTRL_INTERCEPT_TR_WRITES RT_BIT_64(13)
360/** Intercept RDTSC instruction. */
361#define SVM_CTRL_INTERCEPT_RDTSC RT_BIT_64(14)
362/** Intercept RDPMC instruction. */
363#define SVM_CTRL_INTERCEPT_RDPMC RT_BIT_64(15)
364/** Intercept PUSHF instruction. */
365#define SVM_CTRL_INTERCEPT_PUSHF RT_BIT_64(16)
366/** Intercept POPF instruction. */
367#define SVM_CTRL_INTERCEPT_POPF RT_BIT_64(17)
368/** Intercept CPUID instruction. */
369#define SVM_CTRL_INTERCEPT_CPUID RT_BIT_64(18)
370/** Intercept RSM instruction. */
371#define SVM_CTRL_INTERCEPT_RSM RT_BIT_64(19)
372/** Intercept IRET instruction. */
373#define SVM_CTRL_INTERCEPT_IRET RT_BIT_64(20)
374/** Intercept INTn instruction. */
375#define SVM_CTRL_INTERCEPT_INTN RT_BIT_64(21)
376/** Intercept INVD instruction. */
377#define SVM_CTRL_INTERCEPT_INVD RT_BIT_64(22)
378/** Intercept PAUSE instruction. */
379#define SVM_CTRL_INTERCEPT_PAUSE RT_BIT_64(23)
380/** Intercept HLT instruction. */
381#define SVM_CTRL_INTERCEPT_HLT RT_BIT_64(24)
382/** Intercept INVLPG instruction. */
383#define SVM_CTRL_INTERCEPT_INVLPG RT_BIT_64(25)
384/** Intercept INVLPGA instruction. */
385#define SVM_CTRL_INTERCEPT_INVLPGA RT_BIT_64(26)
386/** IOIO_PROT Intercept IN/OUT accesses to selected ports. */
387#define SVM_CTRL_INTERCEPT_INOUT_BITMAP RT_BIT_64(27)
388/** MSR_PROT Intercept RDMSR or WRMSR accesses to selected MSRs. */
389#define SVM_CTRL_INTERCEPT_MSR_SHADOW RT_BIT_64(28)
390/** Intercept task switches. */
391#define SVM_CTRL_INTERCEPT_TASK_SWITCH RT_BIT_64(29)
392/** FERR_FREEZE: intercept processor "freezing" during legacy FERR handling. */
393#define SVM_CTRL_INTERCEPT_FERR_FREEZE RT_BIT_64(30)
394/** Intercept shutdown events. */
395#define SVM_CTRL_INTERCEPT_SHUTDOWN RT_BIT_64(31)
396/** Intercept VMRUN instruction. */
397#define SVM_CTRL_INTERCEPT_VMRUN RT_BIT_64(32 + 0)
398/** Intercept VMMCALL instruction. */
399#define SVM_CTRL_INTERCEPT_VMMCALL RT_BIT_64(32 + 1)
400/** Intercept VMLOAD instruction. */
401#define SVM_CTRL_INTERCEPT_VMLOAD RT_BIT_64(32 + 2)
402/** Intercept VMSAVE instruction. */
403#define SVM_CTRL_INTERCEPT_VMSAVE RT_BIT_64(32 + 3)
404/** Intercept STGI instruction. */
405#define SVM_CTRL_INTERCEPT_STGI RT_BIT_64(32 + 4)
406/** Intercept CLGI instruction. */
407#define SVM_CTRL_INTERCEPT_CLGI RT_BIT_64(32 + 5)
408/** Intercept SKINIT instruction. */
409#define SVM_CTRL_INTERCEPT_SKINIT RT_BIT_64(32 + 6)
410/** Intercept RDTSCP instruction. */
411#define SVM_CTRL_INTERCEPT_RDTSCP RT_BIT_64(32 + 7)
412/** Intercept ICEBP instruction. */
413#define SVM_CTRL_INTERCEPT_ICEBP RT_BIT_64(32 + 8)
414/** Intercept WBINVD instruction. */
415#define SVM_CTRL_INTERCEPT_WBINVD RT_BIT_64(32 + 9)
416/** Intercept MONITOR instruction. */
417#define SVM_CTRL_INTERCEPT_MONITOR RT_BIT_64(32 + 10)
418/** Intercept MWAIT instruction unconditionally. */
419#define SVM_CTRL_INTERCEPT_MWAIT RT_BIT_64(32 + 11)
420/** Intercept MWAIT instruction when armed. */
421#define SVM_CTRL_INTERCEPT_MWAIT_ARMED RT_BIT_64(32 + 12)
422/** Intercept XSETBV instruction. */
423#define SVM_CTRL_INTERCEPT_XSETBV RT_BIT_64(32 + 13)
424/* Bit 14 - Reserved, SBZ. */
425/** Intercept EFER writes after guest instruction finishes. */
426#define SVM_CTRL_INTERCEPT_EFER_WRITES_TRAP RT_BIT_64(32 + 15)
427/** Intercept CR0 writes after guest instruction finishes. */
428#define SVM_CTRL_INTERCEPT_CR0_WRITES_TRAP RT_BIT_64(32 + 16)
429/** Intercept CR0 writes after guest instruction finishes. */
430#define SVM_CTRL_INTERCEPT_CR1_WRITES_TRAP RT_BIT_64(32 + 17)
431/** Intercept CR0 writes after guest instruction finishes. */
432#define SVM_CTRL_INTERCEPT_CR2_WRITES_TRAP RT_BIT_64(32 + 18)
433/** Intercept CR0 writes after guest instruction finishes. */
434#define SVM_CTRL_INTERCEPT_CR3_WRITES_TRAP RT_BIT_64(32 + 19)
435/** Intercept CR0 writes after guest instruction finishes. */
436#define SVM_CTRL_INTERCEPT_CR4_WRITES_TRAP RT_BIT_64(32 + 20)
437/** Intercept CR0 writes after guest instruction finishes. */
438#define SVM_CTRL_INTERCEPT_CR5_WRITES_TRAP RT_BIT_64(32 + 21)
439/** Intercept CR0 writes after guest instruction finishes. */
440#define SVM_CTRL_INTERCEPT_CR6_WRITES_TRAP RT_BIT_64(32 + 22)
441/** Intercept CR0 writes after guest instruction finishes. */
442#define SVM_CTRL_INTERCEPT_CR7_WRITES_TRAP RT_BIT_64(32 + 23)
443/** Intercept CR0 writes after guest instruction finishes. */
444#define SVM_CTRL_INTERCEPT_CR8_WRITES_TRAP RT_BIT_64(32 + 24)
445/** Intercept CR0 writes after guest instruction finishes. */
446#define SVM_CTRL_INTERCEPT_CR9_WRITES_TRAP RT_BIT_64(32 + 25)
447/** Intercept CR0 writes after guest instruction finishes. */
448#define SVM_CTRL_INTERCEPT_CR10_WRITES_TRAP RT_BIT_64(32 + 26)
449/** Intercept CR0 writes after guest instruction finishes. */
450#define SVM_CTRL_INTERCEPT_CR11_WRITES_TRAP RT_BIT_64(32 + 27)
451/** Intercept CR0 writes after guest instruction finishes. */
452#define SVM_CTRL_INTERCEPT_CR12_WRITES_TRAP RT_BIT_64(32 + 28)
453/** Intercept CR0 writes after guest instruction finishes. */
454#define SVM_CTRL_INTERCEPT_CR13_WRITES_TRAP RT_BIT_64(32 + 29)
455/** Intercept CR0 writes after guest instruction finishes. */
456#define SVM_CTRL_INTERCEPT_CR14_WRITES_TRAP RT_BIT_64(32 + 30)
457/** Intercept CR0 writes after guest instruction finishes. */
458#define SVM_CTRL_INTERCEPT_CR15_WRITES_TRAP RT_BIT_64(32 + 31)
459/** @} */
460
461/** @name SVMVMCB.ctrl.u64NestedPaging
462 * @{
463 */
464#define SVM_NESTED_PAGING_ENABLE RT_BIT_64(0)
465/** @} */
466
467/** @name SVMVMCB.ctrl.u64IntShadow
468 * @{
469 */
470#define SVM_INTERRUPT_SHADOW_ACTIVE RT_BIT_64(0)
471/** @} */
472
473/** @name SVMVMCB.u64LbrVirt
474 * @{
475 */
476#define SVM_LBR_VIRT_ENABLE RT_BIT_64(0)
477/** @} */
478
479/** @name SVMINTCTRL.u3Type
480 * @{
481 */
482/** External or virtual interrupt. */
483#define SVM_EVENT_EXTERNAL_IRQ 0
484/** Non-maskable interrupt. */
485#define SVM_EVENT_NMI 2
486/** Exception; fault or trap. */
487#define SVM_EVENT_EXCEPTION 3
488/** Software interrupt. */
489#define SVM_EVENT_SOFTWARE_INT 4
490/** @} */
491
492
493/** @name SVMVMCB.ctrl.TLBCtrl.n.u8TLBFlush
494 * @{
495 */
496/** Flush nothing. */
497#define SVM_TLB_FLUSH_NOTHING 0
498/** Flush entire TLB (host+guest entries) */
499#define SVM_TLB_FLUSH_ENTIRE 1
500/** Flush this guest's TLB entries (by ASID) */
501#define SVM_TLB_FLUSH_SINGLE_CONTEXT 3
502/** Flush this guest's non-global TLB entries (by ASID) */
503#define SVM_TLB_FLUSH_SINGLE_CONTEXT_RETAIN_GLOBALS 7
504/** @} */
505
506
507/**
508 * SVM Selector type; includes hidden parts.
509 */
510typedef struct
511{
512 uint16_t u16Sel;
513 uint16_t u16Attr;
514 uint32_t u32Limit;
515 uint64_t u64Base; /**< Only lower 32 bits are implemented for CS, DS, ES & SS. */
516} SVMSEL;
517AssertCompileSize(SVMSEL, 16);
518
519/**
520 * SVM GDTR/IDTR type.
521 */
522typedef struct
523{
524 uint16_t u16Reserved1;
525 uint16_t u16Reserved2;
526 uint32_t u32Limit; /**< Only lower 16 bits are implemented. */
527 uint64_t u64Base;
528} SVMGDTR;
529AssertCompileSize(SVMGDTR, 16);
530typedef SVMGDTR SVMIDTR;
531
532/**
533 * SVM Event injection structure (EVENTINJ and EXITINTINFO).
534 */
535typedef union
536{
537 struct
538 {
539 uint32_t u8Vector : 8;
540 uint32_t u3Type : 3;
541 uint32_t u1ErrorCodeValid : 1;
542 uint32_t u19Reserved : 19;
543 uint32_t u1Valid : 1;
544 uint32_t u32ErrorCode : 32;
545 } n;
546 uint64_t u;
547} SVMEVENT;
548/** Pointer to the SVMEVENT union. */
549typedef SVMEVENT *PSVMEVENT;
550/** Pointer to a const SVMEVENT union. */
551typedef const SVMEVENT *PCSVMEVENT;
552
553/**
554 * SVM Interrupt control structure (Virtual Interrupt Control).
555 */
556typedef union
557{
558 struct
559 {
560 uint32_t u8VTPR : 8; /* V_TPR */
561 uint32_t u1VIrqPending : 1; /* V_IRQ */
562 uint32_t u7Reserved : 7;
563 uint32_t u4VIntrPrio : 4; /* V_INTR_PRIO */
564 uint32_t u1IgnoreTPR : 1; /* V_IGN_TPR */
565 uint32_t u3Reserved : 3;
566 uint32_t u1VIntrMasking : 1; /* V_INTR_MASKING */
567 uint32_t u6Reserved : 6;
568 uint32_t u1AvicEnable : 1;
569 uint32_t u8VIntrVector : 8; /* V_INTR_VECTOR */
570 uint32_t u24Reserved : 24;
571 } n;
572 uint64_t u;
573} SVMINTCTRL;
574
575/**
576 * SVM TLB control structure.
577 */
578typedef union
579{
580 struct
581 {
582 uint32_t u32ASID : 32;
583 uint32_t u8TLBFlush : 8;
584 uint32_t u24Reserved : 24;
585 } n;
586 uint64_t u;
587} SVMTLBCTRL;
588
589/**
590 * SVM IOIO exit structure (EXITINFO1 for IOIO intercepts).
591 */
592typedef union
593{
594 struct
595 {
596 uint32_t u1Type : 1; /**< Bit 0: 0 = out, 1 = in */
597 uint32_t u1Reserved : 1; /**< Bit 1: Reserved */
598 uint32_t u1STR : 1; /**< Bit 2: String I/O (1) or not (0). */
599 uint32_t u1REP : 1; /**< Bit 3: Repeat prefixed string I/O. */
600 uint32_t u1OP8 : 1; /**< Bit 4: 8-bit operand. */
601 uint32_t u1OP16 : 1; /**< Bit 5: 16-bit operand. */
602 uint32_t u1OP32 : 1; /**< Bit 6: 32-bit operand. */
603 uint32_t u1ADDR16 : 1; /**< Bit 7: 16-bit operand. */
604 uint32_t u1ADDR32 : 1; /**< Bit 8: 32-bit operand. */
605 uint32_t u1ADDR64 : 1; /**< Bit 9: 64-bit operand. */
606 uint32_t u3SEG : 3; /**< BITS 12:10: Effective segment number. Added with decode assist in APM v3.17. */
607 uint32_t u3Reserved : 3;
608 uint32_t u16Port : 16; /**< Bits 31:16: Port number. */
609 } n;
610 uint32_t u;
611} SVMIOIOEXIT;
612
613/** @name SVMIOIOEXIT.u1Type
614 * @{ */
615/** IO write. */
616#define SVM_IOIO_WRITE 0
617/** IO read. */
618#define SVM_IOIO_READ 1
619/** @}*/
620
621/**
622 * SVM nested paging structure.
623 */
624typedef union
625{
626 struct
627 {
628 uint32_t u1NestedPaging : 1; /**< enabled/disabled */
629 } n;
630 uint64_t u;
631} SVMNPCTRL;
632
633/**
634 * SVM AVIC.
635 */
636typedef union
637{
638 struct
639 {
640 uint64_t u12Reserved1 : 12;
641 uint64_t u40Addr : 40;
642 uint64_t u12Reserved2 : 12;
643 } n;
644 uint64_t u;
645} SVMAVIC;
646AssertCompileSize(SVMAVIC, 8);
647
648/**
649 * SVM AVIC PHYSICAL_TABLE pointer.
650 */
651typedef union
652{
653 struct
654 {
655 uint64_t u8LastGuestCoreId : 8;
656 uint64_t u4Reserved : 4;
657 uint64_t u40Addr : 40;
658 uint64_t u12Reserved : 12;
659 } n;
660 uint64_t u;
661} SVMAVICPHYS;
662AssertCompileSize(SVMAVICPHYS, 8);
663
664
665/**
666 * SVM VMCB control area.
667 */
668#pragma pack(1)
669typedef struct
670{
671 /** Offset 0x00 - Intercept reads of CR0-CR15. */
672 uint16_t u16InterceptRdCRx;
673 /** Offset 0x02 - Intercept writes to CR0-CR15. */
674 uint16_t u16InterceptWrCRx;
675 /** Offset 0x04 - Intercept reads of DR0-DR15. */
676 uint16_t u16InterceptRdDRx;
677 /** Offset 0x06 - Intercept writes to DR0-DR15. */
678 uint16_t u16InterceptWrDRx;
679 /** Offset 0x08 - Intercept exception vectors 0-31. */
680 uint32_t u32InterceptXcpt;
681 /** Offset 0x0c - Intercept control. */
682 uint64_t u64InterceptCtrl;
683 /** Offset 0x14-0x3f - Reserved. */
684 uint8_t u8Reserved[0x3c - 0x14];
685 /** Offset 0x3c - PAUSE filter threshold. */
686 uint16_t u16PauseFilterThreshold;
687 /** Offset 0x3e - PAUSE intercept filter count. */
688 uint16_t u16PauseFilterCount;
689 /** Offset 0x40 - Physical address of IOPM. */
690 uint64_t u64IOPMPhysAddr;
691 /** Offset 0x48 - Physical address of MSRPM. */
692 uint64_t u64MSRPMPhysAddr;
693 /** Offset 0x50 - TSC Offset. */
694 uint64_t u64TSCOffset;
695 /** Offset 0x58 - TLB control field. */
696 SVMTLBCTRL TLBCtrl;
697 /** Offset 0x60 - Interrupt control field. */
698 SVMINTCTRL IntCtrl;
699 /** Offset 0x68 - Interrupt shadow. */
700 uint64_t u64IntShadow;
701 /** Offset 0x70 - Exit code. */
702 uint64_t u64ExitCode;
703 /** Offset 0x78 - Exit info 1. */
704 uint64_t u64ExitInfo1;
705 /** Offset 0x80 - Exit info 2. */
706 uint64_t u64ExitInfo2;
707 /** Offset 0x88 - Exit Interrupt info. */
708 SVMEVENT ExitIntInfo;
709 /** Offset 0x90 - Nested Paging. */
710 SVMNPCTRL NestedPaging;
711 /** Offset 0x98 - AVIC APIC BAR. */
712 SVMAVIC AvicBar;
713 /** Offset 0xa0-0xa7 - Reserved. */
714 uint8_t u8Reserved2[0xA8-0xA0];
715 /** Offset 0xa8 - Event injection. */
716 SVMEVENT EventInject;
717 /** Offset 0xb0 - Host CR3 for nested paging. */
718 uint64_t u64NestedPagingCR3;
719 /** Offset 0xb8 - LBR Virtualization. */
720 uint64_t u64LBRVirt;
721 /** Offset 0xc0 - VMCB Clean Bits. */
722 uint64_t u64VmcbCleanBits;
723 /** Offset 0xc8 - Next sequential instruction pointer. */
724 uint64_t u64NextRIP;
725 /** Offset 0xd0 - Number of bytes fetched. */
726 uint8_t cbInstrFetched;
727 /** Offset 0xd1 - Fetched bytes. */
728 uint8_t abInstr[15];
729 /** Offset 0xe0 - AVIC APIC_BACKING_PAGE pointer. */
730 SVMAVIC AvicBackingPagePtr;
731 /** Offset 0xe8-0xef - Reserved. */
732 uint8_t u8Reserved3[0xF0 - 0xE8];
733 /** Offset 0xf0 - AVIC LOGICAL_TABLE pointer. */
734 SVMAVIC AvicLogicalTablePtr;
735 /** Offset 0xf8 - AVIC PHYSICAL_TABLE pointer. */
736 SVMAVICPHYS AvicPhysicalTablePtr;
737} SVMVMCBCTRL;
738#pragma pack()
739/** Pointer to the SVMVMCBSTATESAVE structure. */
740typedef SVMVMCBCTRL *PSVMVMCBCTRL;
741/** Pointer to a const SVMVMCBSTATESAVE structure. */
742typedef const SVMVMCBCTRL *PCSVMVMCBCTRL;
743AssertCompileSize(SVMVMCBCTRL, 0x100);
744AssertCompileMemberOffset(SVMVMCBCTRL, u16InterceptRdCRx, 0x00);
745AssertCompileMemberOffset(SVMVMCBCTRL, u16InterceptWrCRx, 0x02);
746AssertCompileMemberOffset(SVMVMCBCTRL, u16InterceptRdDRx, 0x04);
747AssertCompileMemberOffset(SVMVMCBCTRL, u16InterceptWrDRx, 0x06);
748AssertCompileMemberOffset(SVMVMCBCTRL, u32InterceptXcpt, 0x08);
749AssertCompileMemberOffset(SVMVMCBCTRL, u64InterceptCtrl, 0x0c);
750AssertCompileMemberOffset(SVMVMCBCTRL, u8Reserved, 0x14);
751AssertCompileMemberOffset(SVMVMCBCTRL, u16PauseFilterThreshold, 0x3c);
752AssertCompileMemberOffset(SVMVMCBCTRL, u16PauseFilterCount, 0x3e);
753AssertCompileMemberOffset(SVMVMCBCTRL, u64IOPMPhysAddr, 0x40);
754AssertCompileMemberOffset(SVMVMCBCTRL, u64MSRPMPhysAddr, 0x48);
755AssertCompileMemberOffset(SVMVMCBCTRL, u64TSCOffset, 0x50);
756AssertCompileMemberOffset(SVMVMCBCTRL, TLBCtrl, 0x58);
757AssertCompileMemberOffset(SVMVMCBCTRL, IntCtrl, 0x60);
758AssertCompileMemberOffset(SVMVMCBCTRL, u64IntShadow, 0x68);
759AssertCompileMemberOffset(SVMVMCBCTRL, u64ExitCode, 0x70);
760AssertCompileMemberOffset(SVMVMCBCTRL, u64ExitInfo1, 0x78);
761AssertCompileMemberOffset(SVMVMCBCTRL, u64ExitInfo2, 0x80);
762AssertCompileMemberOffset(SVMVMCBCTRL, ExitIntInfo, 0x88);
763AssertCompileMemberOffset(SVMVMCBCTRL, NestedPaging, 0x90);
764AssertCompileMemberOffset(SVMVMCBCTRL, AvicBar, 0x98);
765AssertCompileMemberOffset(SVMVMCBCTRL, u8Reserved2, 0xa0);
766AssertCompileMemberOffset(SVMVMCBCTRL, EventInject, 0xa8);
767AssertCompileMemberOffset(SVMVMCBCTRL, u64NestedPagingCR3, 0xb0);
768AssertCompileMemberOffset(SVMVMCBCTRL, u64LBRVirt, 0xb8);
769AssertCompileMemberOffset(SVMVMCBCTRL, u64VmcbCleanBits, 0xc0);
770AssertCompileMemberOffset(SVMVMCBCTRL, u64NextRIP, 0xc8);
771AssertCompileMemberOffset(SVMVMCBCTRL, cbInstrFetched, 0xd0);
772AssertCompileMemberOffset(SVMVMCBCTRL, abInstr, 0xd1);
773AssertCompileMemberOffset(SVMVMCBCTRL, AvicBackingPagePtr, 0xe0);
774AssertCompileMemberOffset(SVMVMCBCTRL, u8Reserved3, 0xe8);
775AssertCompileMemberOffset(SVMVMCBCTRL, AvicLogicalTablePtr, 0xf0);
776AssertCompileMemberOffset(SVMVMCBCTRL, AvicPhysicalTablePtr, 0xf8);
777
778/**
779 * SVM VMCB state save area.
780 */
781#pragma pack(1)
782typedef struct
783{
784 /** Offset 0x400 - Guest ES register + hidden parts. */
785 SVMSEL ES;
786 /** Offset 0x410 - Guest CS register + hidden parts. */
787 SVMSEL CS;
788 /** Offset 0x420 - Guest SS register + hidden parts. */
789 SVMSEL SS;
790 /** Offset 0x430 - Guest DS register + hidden parts. */
791 SVMSEL DS;
792 /** Offset 0x440 - Guest FS register + hidden parts. */
793 SVMSEL FS;
794 /** Offset 0x450 - Guest GS register + hidden parts. */
795 SVMSEL GS;
796 /** Offset 0x460 - Guest GDTR register. */
797 SVMGDTR GDTR;
798 /** Offset 0x470 - Guest LDTR register + hidden parts. */
799 SVMSEL LDTR;
800 /** Offset 0x480 - Guest IDTR register. */
801 SVMIDTR IDTR;
802 /** Offset 0x490 - Guest TR register + hidden parts. */
803 SVMSEL TR;
804 /** Offset 0x4A0-0x4CA - Reserved. */
805 uint8_t u8Reserved4[0x4CB-0x4A0];
806 /** Offset 0x4CB - CPL. */
807 uint8_t u8CPL;
808 /** Offset 0x4CC-0x4CF - Reserved. */
809 uint8_t u8Reserved5[0x4D0-0x4CC];
810 /** Offset 0x4D0 - EFER. */
811 uint64_t u64EFER;
812 /** Offset 0x4D8-0x547 - Reserved. */
813 uint8_t u8Reserved6[0x548-0x4D8];
814 /** Offset 0x548 - CR4. */
815 uint64_t u64CR4;
816 /** Offset 0x550 - CR3. */
817 uint64_t u64CR3;
818 /** Offset 0x558 - CR0. */
819 uint64_t u64CR0;
820 /** Offset 0x560 - DR7. */
821 uint64_t u64DR7;
822 /** Offset 0x568 - DR6. */
823 uint64_t u64DR6;
824 /** Offset 0x570 - RFLAGS. */
825 uint64_t u64RFlags;
826 /** Offset 0x578 - RIP. */
827 uint64_t u64RIP;
828 /** Offset 0x580-0x5D7 - Reserved. */
829 uint8_t u8Reserved7[0x5D8-0x580];
830 /** Offset 0x5D8 - RSP. */
831 uint64_t u64RSP;
832 /** Offset 0x5E0-0x5F7 - Reserved. */
833 uint8_t u8Reserved8[0x5F8-0x5E0];
834 /** Offset 0x5F8 - RAX. */
835 uint64_t u64RAX;
836 /** Offset 0x600 - STAR. */
837 uint64_t u64STAR;
838 /** Offset 0x608 - LSTAR. */
839 uint64_t u64LSTAR;
840 /** Offset 0x610 - CSTAR. */
841 uint64_t u64CSTAR;
842 /** Offset 0x618 - SFMASK. */
843 uint64_t u64SFMASK;
844 /** Offset 0x620 - KernelGSBase. */
845 uint64_t u64KernelGSBase;
846 /** Offset 0x628 - SYSENTER_CS. */
847 uint64_t u64SysEnterCS;
848 /** Offset 0x630 - SYSENTER_ESP. */
849 uint64_t u64SysEnterESP;
850 /** Offset 0x638 - SYSENTER_EIP. */
851 uint64_t u64SysEnterEIP;
852 /** Offset 0x640 - CR2. */
853 uint64_t u64CR2;
854 /** Offset 0x648-0x667 - Reserved. */
855 uint8_t u8Reserved9[0x668-0x648];
856 /** Offset 0x668 - G_PAT. */
857 uint64_t u64GPAT;
858 /** Offset 0x670 - DBGCTL. */
859 uint64_t u64DBGCTL;
860 /** Offset 0x678 - BR_FROM. */
861 uint64_t u64BR_FROM;
862 /** Offset 0x680 - BR_TO. */
863 uint64_t u64BR_TO;
864 /** Offset 0x688 - LASTEXCPFROM. */
865 uint64_t u64LASTEXCPFROM;
866 /** Offset 0x690 - LASTEXCPTO. */
867 uint64_t u64LASTEXCPTO;
868} SVMVMCBSTATESAVE;
869#pragma pack()
870/** Pointer to the SVMVMCBSTATESAVE structure. */
871typedef SVMVMCBSTATESAVE *PSVMVMCBSTATESAVE;
872/** Pointer to a const SVMVMCBSTATESAVE structure. */
873typedef const SVMVMCBSTATESAVE *PCSVMVMCBSTATESAVE;
874AssertCompileSize(SVMVMCBSTATESAVE, 0x298);
875AssertCompileMemberOffset(SVMVMCBSTATESAVE, ES, 0x400 - 0x400);
876AssertCompileMemberOffset(SVMVMCBSTATESAVE, CS, 0x410 - 0x400);
877AssertCompileMemberOffset(SVMVMCBSTATESAVE, SS, 0x420 - 0x400);
878AssertCompileMemberOffset(SVMVMCBSTATESAVE, DS, 0x430 - 0x400);
879AssertCompileMemberOffset(SVMVMCBSTATESAVE, FS, 0x440 - 0x400);
880AssertCompileMemberOffset(SVMVMCBSTATESAVE, GS, 0x450 - 0x400);
881AssertCompileMemberOffset(SVMVMCBSTATESAVE, GDTR, 0x460 - 0x400);
882AssertCompileMemberOffset(SVMVMCBSTATESAVE, LDTR, 0x470 - 0x400);
883AssertCompileMemberOffset(SVMVMCBSTATESAVE, IDTR, 0x480 - 0x400);
884AssertCompileMemberOffset(SVMVMCBSTATESAVE, TR, 0x490 - 0x400);
885AssertCompileMemberOffset(SVMVMCBSTATESAVE, u8Reserved4, 0x4a0 - 0x400);
886AssertCompileMemberOffset(SVMVMCBSTATESAVE, u8CPL, 0x4cb - 0x400);
887AssertCompileMemberOffset(SVMVMCBSTATESAVE, u8Reserved5, 0x4cc - 0x400);
888AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64EFER, 0x4d0 - 0x400);
889AssertCompileMemberOffset(SVMVMCBSTATESAVE, u8Reserved6, 0x4d8 - 0x400);
890AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64CR4, 0x548 - 0x400);
891AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64CR3, 0x550 - 0x400);
892AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64CR0, 0x558 - 0x400);
893AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64DR7, 0x560 - 0x400);
894AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64DR6, 0x568 - 0x400);
895AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64RFlags, 0x570 - 0x400);
896AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64RIP, 0x578 - 0x400);
897AssertCompileMemberOffset(SVMVMCBSTATESAVE, u8Reserved7, 0x580 - 0x400);
898AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64RSP, 0x5d8 - 0x400);
899AssertCompileMemberOffset(SVMVMCBSTATESAVE, u8Reserved8, 0x5e0 - 0x400);
900AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64RAX, 0x5f8 - 0x400);
901AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64STAR, 0x600 - 0x400);
902AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64LSTAR, 0x608 - 0x400);
903AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64CSTAR, 0x610 - 0x400);
904AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64SFMASK, 0x618 - 0x400);
905AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64KernelGSBase, 0x620 - 0x400);
906AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64SysEnterCS, 0x628 - 0x400);
907AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64SysEnterESP, 0x630 - 0x400);
908AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64SysEnterEIP, 0x638 - 0x400);
909AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64CR2, 0x640 - 0x400);
910AssertCompileMemberOffset(SVMVMCBSTATESAVE, u8Reserved9, 0x648 - 0x400);
911AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64GPAT, 0x668 - 0x400);
912AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64DBGCTL, 0x670 - 0x400);
913AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64BR_FROM, 0x678 - 0x400);
914AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64BR_TO, 0x680 - 0x400);
915AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64LASTEXCPFROM, 0x688 - 0x400);
916AssertCompileMemberOffset(SVMVMCBSTATESAVE, u64LASTEXCPTO, 0x690 - 0x400);
917
918/**
919 * SVM VM Control Block. (VMCB)
920 */
921#pragma pack(1)
922typedef struct SVMVMCB
923{
924 /** Offset 0x00 - Control area. */
925 SVMVMCBCTRL ctrl;
926 /** Offset 0x100-0x3FF - Reserved. */
927 uint8_t u8Reserved3[0x400-0x100];
928 /** Offset 0x400 - State save area. */
929 SVMVMCBSTATESAVE guest;
930 /** Offset 0x698-0xFFF- Reserved. */
931 uint8_t u8Reserved10[0x1000-0x698];
932} SVMVMCB;
933#pragma pack()
934/** Pointer to the SVMVMCB structure. */
935typedef SVMVMCB *PSVMVMCB;
936/** Pointer to a const SVMVMCB structure. */
937typedef const SVMVMCB *PCSVMVMCB;
938AssertCompileMemberOffset(SVMVMCB, ctrl, 0x00);
939AssertCompileMemberOffset(SVMVMCB, u8Reserved3, 0x100);
940AssertCompileMemberOffset(SVMVMCB, guest, 0x400);
941AssertCompileMemberOffset(SVMVMCB, u8Reserved10, 0x698);
942AssertCompileSize(SVMVMCB, 0x1000);
943
944#ifdef IN_RING0
945VMMR0DECL(int) SVMR0InvalidatePage(PVM pVM, PVMCPU pVCpu, RTGCPTR GCVirt);
946#endif /* IN_RING0 */
947
948/**
949 * Segment attribute conversion between CPU and AMD-V VMCB format.
950 *
951 * The CPU format of the segment attribute is described in X86DESCATTRBITS
952 * which is 16-bits (i.e. includes 4 bits of the segment limit).
953 *
954 * The AMD-V VMCB format the segment attribute is compact 12-bits (strictly
955 * only the attribute bits and nothing else). Upper 4-bits are unused.
956 */
957#define HMSVM_CPU_2_VMCB_SEG_ATTR(a) ( ((a) & 0xff) | (((a) & 0xf000) >> 4) )
958#define HMSVM_VMCB_2_CPU_SEG_ATTR(a) ( ((a) & 0xff) | (((a) & 0x0f00) << 4) )
959
960/** @def HMSVM_SEG_REG_COPY_TO_VMCB
961 * Copies the specified segment register to a VMCB from a virtual CPU context.
962 *
963 * @param a_pCtx The virtual-CPU context.
964 * @param a_pVmcbStateSave Pointer to the VMCB state-save area.
965 * @param a_REG The segment register in the VMCB state-save
966 * struct (ES/CS/SS/DS).
967 * @param a_reg The segment register in the virtual CPU struct
968 * (es/cs/ss/ds).
969 */
970#define HMSVM_SEG_REG_COPY_TO_VMCB(a_pCtx, a_pVmcbStateSave, a_REG, a_reg) \
971 do \
972 { \
973 Assert((a_pCtx)->a_reg.fFlags & CPUMSELREG_FLAGS_VALID); \
974 Assert((a_pCtx)->a_reg.ValidSel == (a_pCtx)->a_reg.Sel); \
975 (a_pVmcbStateSave)->a_REG.u16Sel = (a_pCtx)->a_reg.Sel; \
976 (a_pVmcbStateSave)->a_REG.u32Limit = (a_pCtx)->a_reg.u32Limit; \
977 (a_pVmcbStateSave)->a_REG.u64Base = (a_pCtx)->a_reg.u64Base; \
978 (a_pVmcbStateSave)->a_REG.u16Attr = HMSVM_CPU_2_VMCB_SEG_ATTR((a_pCtx)->a_reg.Attr.u); \
979 } while (0)
980
981/** @def HMSVM_SEG_REG_COPY_TO_VMCB
982 * Copies the specified segment register from the VMCB to a virtual CPU
983 * context.
984 *
985 * @param a_pCtx The virtual-CPU context.
986 * @param a_pVmcbStateSave Pointer to the VMCB state-save area.
987 * @param a_REG The segment register in the VMCB state-save
988 * struct (ES/CS/SS/DS).
989 * @param a_reg The segment register in the virtual CPU struct
990 * (es/ds/ss/ds).
991 */
992#define HMSVM_SEG_REG_COPY_FROM_VMCB(a_pCtx, a_pVmcbStateSave, a_REG, a_reg) \
993 do \
994 { \
995 (a_pCtx)->a_reg.Sel = (a_pVmcbStateSave)->a_REG.u16Sel; \
996 (a_pCtx)->a_reg.ValidSel = (a_pVmcbStateSave)->a_REG.u16Sel; \
997 (a_pCtx)->a_reg.fFlags = CPUMSELREG_FLAGS_VALID; \
998 (a_pCtx)->a_reg.u32Limit = (a_pVmcbStateSave)->a_REG.u32Limit; \
999 (a_pCtx)->a_reg.u64Base = (a_pVmcbStateSave)->a_REG.u64Base; \
1000 (a_pCtx)->a_reg.Attr.u = HMSVM_VMCB_2_CPU_SEG_ATTR((a_pVmcbStateSave)->a_REG.u16Attr); \
1001 } while (0)
1002/** @} */
1003
1004
1005/** @} */
1006
1007#endif
1008
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette