1 /////////////////////////////////////////////////////////////////////////
2 // $Id: vmx.h 14086 2021-01-30 08:35:35Z sshwarts $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //   Copyright (c) 2009-2019 Stanislav Shwartsman
6 //          Written by Stanislav Shwartsman [sshwarts at sourceforge net]
7 //
8 //  This library is free software; you can redistribute it and/or
9 //  modify it under the terms of the GNU Lesser General Public
10 //  License as published by the Free Software Foundation; either
11 //  version 2 of the License, or (at your option) any later version.
12 //
13 //  This library is distributed in the hope that it will be useful,
14 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 //  Lesser General Public License for more details.
17 //
18 //  You should have received a copy of the GNU Lesser General Public
19 //  License along with this library; if not, write to the Free Software
20 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
21 //
22 /////////////////////////////////////////////////////////////////////////
23 
24 #ifndef _BX_VMX_INTEL_H_
25 #define _BX_VMX_INTEL_H_
26 
27 #define VMX_VMCS_AREA_SIZE   4096
28 
29 // VMCS pointer is always 64-bit variable
30 const Bit64u BX_INVALID_VMCSPTR = BX_CONST64(0xFFFFFFFFFFFFFFFF);
31 
32 // bits supported in IA32_FEATURE_CONTROL MSR
33 const Bit32u BX_IA32_FEATURE_CONTROL_LOCK_BIT = 0x1;
34 const Bit32u BX_IA32_FEATURE_CONTROL_VMX_ENABLE_BIT = 0x4;
35 
36 const Bit32u BX_IA32_FEATURE_CONTROL_BITS = (BX_IA32_FEATURE_CONTROL_LOCK_BIT | BX_IA32_FEATURE_CONTROL_VMX_ENABLE_BIT);
37 
38 // VMX error codes
39 enum VMX_error_code {
40     VMXERR_NO_ERROR = 0,
41     VMXERR_VMCALL_IN_VMX_ROOT_OPERATION = 1,
42     VMXERR_VMCLEAR_WITH_INVALID_ADDR = 2,
43     VMXERR_VMCLEAR_WITH_VMXON_VMCS_PTR = 3,
44     VMXERR_VMLAUNCH_NON_CLEAR_VMCS = 4,
45     VMXERR_VMRESUME_NON_LAUNCHED_VMCS = 5,
46     VMXERR_VMRESUME_VMCS_CORRUPTED = 6,
47     VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD = 7,
48     VMXERR_VMENTRY_INVALID_VM_HOST_STATE_FIELD = 8,
49     VMXERR_VMPTRLD_INVALID_PHYSICAL_ADDRESS = 9,
50     VMXERR_VMPTRLD_WITH_VMXON_PTR = 10,
51     VMXERR_VMPTRLD_INCORRECT_VMCS_REVISION_ID = 11,
52     VMXERR_UNSUPPORTED_VMCS_COMPONENT_ACCESS = 12,
53     VMXERR_VMWRITE_READ_ONLY_VMCS_COMPONENT = 13,
54     VMXERR_RESERVED14 = 14,
55     VMXERR_VMXON_IN_VMX_ROOT_OPERATION = 15,
56     VMXERR_VMENTRY_INVALID_EXECUTIVE_VMCS = 16,
57     VMXERR_VMENTRY_NON_LAUNCHED_EXECUTIVE_VMCS = 17,
58     VMXERR_VMENTRY_NOT_VMXON_EXECUTIVE_VMCS = 18,
59     VMXERR_VMCALL_NON_CLEAR_VMCS = 19,
60     VMXERR_VMCALL_INVALID_VMEXIT_FIELD = 20,
61     VMXERR_RESERVED21 = 21,
62     VMXERR_VMCALL_INVALID_MSEG_REVISION_ID = 22,
63     VMXERR_VMXOFF_WITH_CONFIGURED_SMM_MONITOR = 23,
64     VMXERR_VMCALL_WITH_INVALID_SMM_MONITOR_FEATURES = 24,
65     VMXERR_VMENTRY_INVALID_VM_CONTROL_FIELD_IN_EXECUTIVE_VMCS = 25,
66     VMXERR_VMENTRY_MOV_SS_BLOCKING = 26,
67     VMXERR_RESERVED27 = 27,
68     VMXERR_INVALID_INVEPT_INVVPID = 28
69 };
70 
71 enum VMX_vmexit_reason {
72    VMX_VMEXIT_EXCEPTION_NMI = 0,
73    VMX_VMEXIT_EXTERNAL_INTERRUPT = 1,
74    VMX_VMEXIT_TRIPLE_FAULT = 2,
75    VMX_VMEXIT_INIT = 3,
76    VMX_VMEXIT_SIPI = 4,
77    VMX_VMEXIT_IO_SMI = 5,
78    VMX_VMEXIT_SMI = 6,
79    VMX_VMEXIT_INTERRUPT_WINDOW = 7,
80    VMX_VMEXIT_NMI_WINDOW = 8,
81    VMX_VMEXIT_TASK_SWITCH = 9,
82    VMX_VMEXIT_CPUID = 10,
83    VMX_VMEXIT_GETSEC = 11,
84    VMX_VMEXIT_HLT = 12,
85    VMX_VMEXIT_INVD = 13,
86    VMX_VMEXIT_INVLPG = 14,
87    VMX_VMEXIT_RDPMC = 15,
88    VMX_VMEXIT_RDTSC = 16,
89    VMX_VMEXIT_RSM = 17,
90    VMX_VMEXIT_VMCALL = 18,
91    VMX_VMEXIT_VMCLEAR = 19,
92    VMX_VMEXIT_VMLAUNCH = 20,
93    VMX_VMEXIT_VMPTRLD = 21,
94    VMX_VMEXIT_VMPTRST = 22,
95    VMX_VMEXIT_VMREAD = 23,
96    VMX_VMEXIT_VMRESUME = 24,
97    VMX_VMEXIT_VMWRITE = 25,
98    VMX_VMEXIT_VMXOFF = 26,
99    VMX_VMEXIT_VMXON = 27,
100    VMX_VMEXIT_CR_ACCESS = 28,
101    VMX_VMEXIT_DR_ACCESS = 29,
102    VMX_VMEXIT_IO_INSTRUCTION = 30,
103    VMX_VMEXIT_RDMSR = 31,
104    VMX_VMEXIT_WRMSR = 32,
105    VMX_VMEXIT_VMENTRY_FAILURE_GUEST_STATE = 33,
106    VMX_VMEXIT_VMENTRY_FAILURE_MSR = 34,
107    VMX_VMEXIT_RESERVED35 = 35,
108    VMX_VMEXIT_MWAIT = 36,
109    VMX_VMEXIT_MONITOR_TRAP_FLAG = 37,
110    VMX_VMEXIT_RESERVED38 = 38,
111    VMX_VMEXIT_MONITOR = 39,
112    VMX_VMEXIT_PAUSE = 40,
113    VMX_VMEXIT_VMENTRY_FAILURE_MCA = 41, // will never happen in Bochs
114    VMX_VMEXIT_RESERVED42 = 42,
115    VMX_VMEXIT_TPR_THRESHOLD = 43,
116    VMX_VMEXIT_APIC_ACCESS = 44,
117    VMX_VMEXIT_VIRTUALIZED_EOI = 45,
118    VMX_VMEXIT_GDTR_IDTR_ACCESS = 46,
119    VMX_VMEXIT_LDTR_TR_ACCESS = 47,
120    VMX_VMEXIT_EPT_VIOLATION = 48,
121    VMX_VMEXIT_EPT_MISCONFIGURATION = 49,
122    VMX_VMEXIT_INVEPT = 50,
123    VMX_VMEXIT_RDTSCP = 51,
124    VMX_VMEXIT_VMX_PREEMPTION_TIMER_EXPIRED = 52,
125    VMX_VMEXIT_INVVPID = 53,
126    VMX_VMEXIT_WBINVD = 54,
127    VMX_VMEXIT_XSETBV = 55,
128    VMX_VMEXIT_APIC_WRITE = 56,
129    VMX_VMEXIT_RDRAND = 57,
130    VMX_VMEXIT_INVPCID = 58,
131    VMX_VMEXIT_VMFUNC = 59,
132    VMX_VMEXIT_ENCLS = 60,
133    VMX_VMEXIT_RDSEED = 61,
134    VMX_VMEXIT_PML_LOGFULL = 62,
135    VMX_VMEXIT_XSAVES = 63,
136    VMX_VMEXIT_XRSTORS = 64,
137    VMX_VMEXIT_RESERVED65 = 65,
138    VMX_VMEXIT_SPP = 66,
139    VMX_VMEXIT_UMWAIT = 67,
140    VMX_VMEXIT_TPAUSE = 68,
141    VMX_VMEXIT_RESERVED69 = 69,
142    VMX_VMEXIT_RESERVED70 = 70,
143    VMX_VMEXIT_RESERVED71 = 71,
144    VMX_VMEXIT_ENQCMD_PASID = 72,
145    VMX_VMEXIT_ENQCMDS_PASID = 73,
146    VMX_VMEXIT_LAST_REASON
147 };
148 
149 #define IS_TRAP_LIKE_VMEXIT(reason) \
150       (reason == VMX_VMEXIT_TPR_THRESHOLD || \
151        reason == VMX_VMEXIT_VIRTUALIZED_EOI || \
152        reason == VMX_VMEXIT_APIC_WRITE)
153 
154 // VMexit on CR register access
155 enum {
156    VMX_VMEXIT_CR_ACCESS_CR_WRITE = 0,
157    VMX_VMEXIT_CR_ACCESS_CR_READ,
158    VMX_VMEXIT_CR_ACCESS_CLTS,
159    VMX_VMEXIT_CR_ACCESS_LMSW
160 };
161 
162 // VMENTRY error on loading guest state qualification
163 enum VMX_vmentry_error {
164    VMENTER_ERR_NO_ERROR = 0,
165    VMENTER_ERR_GUEST_STATE_PDPTR_LOADING = 2,
166    VMENTER_ERR_GUEST_STATE_INJECT_NMI_BLOCKING_EVENTS = 3,
167    VMENTER_ERR_GUEST_STATE_LINK_POINTER = 4
168 };
169 
170 // VMABORT error code
171 enum VMX_vmabort_code {
172    VMABORT_SAVING_GUEST_MSRS_FAILURE,
173    VMABORT_HOST_PDPTR_CORRUPTED,
174    VMABORT_VMEXIT_VMCS_CORRUPTED,
175    VMABORT_LOADING_HOST_MSRS,
176    VMABORT_VMEXIT_MACHINE_CHECK_ERROR
177 };
178 
179 // VMX APIC ACCESS VMEXIT qualification
180 const Bit32u VMX_APIC_READ_INSTRUCTION_EXECUTION   = 0x0000;
181 const Bit32u VMX_APIC_WRITE_INSTRUCTION_EXECUTION  = 0x1000;
182 const Bit32u VMX_APIC_INSTRUCTION_FETCH            = 0x2000; /* won't happen because cpu::prefetch will crash */
183 const Bit32u VMX_APIC_ACCESS_DURING_EVENT_DELIVERY = 0x3000;
184 
185 // VM Functions List
186 enum VMFunctions {
187    VMX_VMFUNC_EPTP_SWITCHING = 0
188 };
189 
190 const Bit64u VMX_VMFUNC_EPTP_SWITCHING_MASK = (BX_CONST64(1) << VMX_VMFUNC_EPTP_SWITCHING);
191 
192 // =============
193 //  VMCS fields
194 // =============
195 
196 /* VMCS 16-bit control fields */
197 /* binary 0000_00xx_xxxx_xxx0 */
198 #define VMCS_16BIT_CONTROL_VPID                            0x00000000 /* VPID */
199 #define VMCS_16BIT_CONTROL_POSTED_INTERRUPT_VECTOR         0x00000002 /* Posted Interrupts - not implememted yet */
200 #define VMCS_16BIT_CONTROL_EPTP_INDEX                      0x00000004 /* #VE Exception */
201 
202 /* VMCS 16-bit guest-state fields */
203 /* binary 0000_10xx_xxxx_xxx0 */
204 #define VMCS_16BIT_GUEST_ES_SELECTOR                       0x00000800
205 #define VMCS_16BIT_GUEST_CS_SELECTOR                       0x00000802
206 #define VMCS_16BIT_GUEST_SS_SELECTOR                       0x00000804
207 #define VMCS_16BIT_GUEST_DS_SELECTOR                       0x00000806
208 #define VMCS_16BIT_GUEST_FS_SELECTOR                       0x00000808
209 #define VMCS_16BIT_GUEST_GS_SELECTOR                       0x0000080A
210 #define VMCS_16BIT_GUEST_LDTR_SELECTOR                     0x0000080C
211 #define VMCS_16BIT_GUEST_TR_SELECTOR                       0x0000080E
212 #define VMCS_16BIT_GUEST_INTERRUPT_STATUS                  0x00000810 /* Virtual Interrupt Delivery */
213 #define VMCS_16BIT_GUEST_PML_INDEX                         0x00000812 /* Page Modification Logging */
214 
215 /* VMCS 16-bit host-state fields */
216 /* binary 0000_11xx_xxxx_xxx0 */
217 #define VMCS_16BIT_HOST_ES_SELECTOR                        0x00000C00
218 #define VMCS_16BIT_HOST_CS_SELECTOR                        0x00000C02
219 #define VMCS_16BIT_HOST_SS_SELECTOR                        0x00000C04
220 #define VMCS_16BIT_HOST_DS_SELECTOR                        0x00000C06
221 #define VMCS_16BIT_HOST_FS_SELECTOR                        0x00000C08
222 #define VMCS_16BIT_HOST_GS_SELECTOR                        0x00000C0A
223 #define VMCS_16BIT_HOST_TR_SELECTOR                        0x00000C0C
224 
225 /* VMCS 64-bit control fields */
226 /* binary 0010_00xx_xxxx_xxx0 */
227 #define VMCS_64BIT_CONTROL_IO_BITMAP_A                     0x00002000
228 #define VMCS_64BIT_CONTROL_IO_BITMAP_A_HI                  0x00002001
229 #define VMCS_64BIT_CONTROL_IO_BITMAP_B                     0x00002002
230 #define VMCS_64BIT_CONTROL_IO_BITMAP_B_HI                  0x00002003
231 #define VMCS_64BIT_CONTROL_MSR_BITMAPS                     0x00002004
232 #define VMCS_64BIT_CONTROL_MSR_BITMAPS_HI                  0x00002005
233 #define VMCS_64BIT_CONTROL_VMEXIT_MSR_STORE_ADDR           0x00002006
234 #define VMCS_64BIT_CONTROL_VMEXIT_MSR_STORE_ADDR_HI        0x00002007
235 #define VMCS_64BIT_CONTROL_VMEXIT_MSR_LOAD_ADDR            0x00002008
236 #define VMCS_64BIT_CONTROL_VMEXIT_MSR_LOAD_ADDR_HI         0x00002009
237 #define VMCS_64BIT_CONTROL_VMENTRY_MSR_LOAD_ADDR           0x0000200A
238 #define VMCS_64BIT_CONTROL_VMENTRY_MSR_LOAD_ADDR_HI        0x0000200B
239 #define VMCS_64BIT_CONTROL_EXECUTIVE_VMCS_PTR              0x0000200C
240 #define VMCS_64BIT_CONTROL_EXECUTIVE_VMCS_PTR_HI           0x0000200D
241 #define VMCS_64BIT_CONTROL_PML_ADDRESS                     0x0000200E /* Page Modification Logging */
242 #define VMCS_64BIT_CONTROL_PML_ADDRESS_HI                  0x0000200F
243 #define VMCS_64BIT_CONTROL_TSC_OFFSET                      0x00002010
244 #define VMCS_64BIT_CONTROL_TSC_OFFSET_HI                   0x00002011
245 #define VMCS_64BIT_CONTROL_VIRTUAL_APIC_PAGE_ADDR          0x00002012 /* TPR shadow */
246 #define VMCS_64BIT_CONTROL_VIRTUAL_APIC_PAGE_ADDR_HI       0x00002013
247 #define VMCS_64BIT_CONTROL_APIC_ACCESS_ADDR                0x00002014 /* APIC virtualization */
248 #define VMCS_64BIT_CONTROL_APIC_ACCESS_ADDR_HI             0x00002015
249 #define VMCS_64BIT_CONTROL_POSTED_INTERRUPT_DESC_ADDR      0x00002016 /* Posted Interrupts - not implemented yet */
250 #define VMCS_64BIT_CONTROL_POSTED_INTERRUPT_DESC_ADDR_HI   0x00002017
251 #define VMCS_64BIT_CONTROL_VMFUNC_CTRLS                    0x00002018 /* VM Functions */
252 #define VMCS_64BIT_CONTROL_VMFUNC_CTRLS_HI                 0x00002019
253 #define VMCS_64BIT_CONTROL_EPTPTR                          0x0000201A /* EPT */
254 #define VMCS_64BIT_CONTROL_EPTPTR_HI                       0x0000201B
255 #define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP0                0x0000201C /* Virtual Interrupt Delivery */
256 #define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP0_HI             0x0000201D
257 #define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP1                0x0000201E
258 #define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP1_HI             0x0000201F
259 #define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP2                0x00002020
260 #define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP2_HI             0x00002021
261 #define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP3                0x00002022
262 #define VMCS_64BIT_CONTROL_EOI_EXIT_BITMAP3_HI             0x00002023
263 #define VMCS_64BIT_CONTROL_EPTP_LIST_ADDRESS               0x00002024 /* VM Functions - EPTP switching */
264 #define VMCS_64BIT_CONTROL_EPTP_LIST_ADDRESS_HI            0x00002025
265 #define VMCS_64BIT_CONTROL_VMREAD_BITMAP_ADDR              0x00002026 /* VMCS Shadowing */
266 #define VMCS_64BIT_CONTROL_VMREAD_BITMAP_ADDR_HI           0x00002027
267 #define VMCS_64BIT_CONTROL_VMWRITE_BITMAP_ADDR             0x00002028 /* VMCS Shadowing */
268 #define VMCS_64BIT_CONTROL_VMWRITE_BITMAP_ADDR_HI          0x00002029
269 #define VMCS_64BIT_CONTROL_VE_EXCEPTION_INFO_ADDR          0x0000202A /* #VE Exception */
270 #define VMCS_64BIT_CONTROL_VE_EXCEPTION_INFO_ADDR_HI       0x0000202B
271 #define VMCS_64BIT_CONTROL_XSS_EXITING_BITMAP              0x0000202C /* XSAVES */
272 #define VMCS_64BIT_CONTROL_XSS_EXITING_BITMAP_HI           0x0000202D
273 #define VMCS_64BIT_CONTROL_ENCLS_EXITING_BITMAP            0x0000202E /* ENCLS/SGX */
274 #define VMCS_64BIT_CONTROL_ENCLS_EXITING_BITMAP_HI         0x0000202F
275 #define VMCS_64BIT_CONTROL_SPPTP                           0x00002030 /* Sup-Page Write Protection */
276 #define VMCS_64BIT_CONTROL_SPPTP_HI                        0x00002031
277 #define VMCS_64BIT_CONTROL_TSC_MULTIPLIER                  0x00002032 /* TSC Scaling */
278 #define VMCS_64BIT_CONTROL_TSC_MULTIPLIER_HI               0x00002033
279 
280 /* VMCS 64-bit read only data fields */
281 /* binary 0010_01xx_xxxx_xxx0 */
282 #define VMCS_64BIT_GUEST_PHYSICAL_ADDR                     0x00002400 /* EPT */
283 #define VMCS_64BIT_GUEST_PHYSICAL_ADDR_HI                  0x00002401
284 
285 /* VMCS 64-bit guest state fields */
286 /* binary 0010_10xx_xxxx_xxx0 */
287 #define VMCS_64BIT_GUEST_LINK_POINTER                      0x00002800
288 #define VMCS_64BIT_GUEST_LINK_POINTER_HI                   0x00002801
289 #define VMCS_64BIT_GUEST_IA32_DEBUGCTL                     0x00002802
290 #define VMCS_64BIT_GUEST_IA32_DEBUGCTL_HI                  0x00002803
291 #define VMCS_64BIT_GUEST_IA32_PAT                          0x00002804 /* PAT */
292 #define VMCS_64BIT_GUEST_IA32_PAT_HI                       0x00002805
293 #define VMCS_64BIT_GUEST_IA32_EFER                         0x00002806 /* EFER */
294 #define VMCS_64BIT_GUEST_IA32_EFER_HI                      0x00002807
295 #define VMCS_64BIT_GUEST_IA32_PERF_GLOBAL_CTRL             0x00002808 /* Perf Global Ctrl */
296 #define VMCS_64BIT_GUEST_IA32_PERF_GLOBAL_CTRL_HI          0x00002809
297 #define VMCS_64BIT_GUEST_IA32_PDPTE0                       0x0000280A /* EPT */
298 #define VMCS_64BIT_GUEST_IA32_PDPTE0_HI                    0x0000280B
299 #define VMCS_64BIT_GUEST_IA32_PDPTE1                       0x0000280C
300 #define VMCS_64BIT_GUEST_IA32_PDPTE1_HI                    0x0000280D
301 #define VMCS_64BIT_GUEST_IA32_PDPTE2                       0x0000280E
302 #define VMCS_64BIT_GUEST_IA32_PDPTE2_HI                    0x0000280F
303 #define VMCS_64BIT_GUEST_IA32_PDPTE3                       0x00002810
304 #define VMCS_64BIT_GUEST_IA32_PDPTE3_HI                    0x00002811
305 #define VMCS_64BIT_GUEST_IA32_BNDCFGS                      0x00002812 /* MPX (not implemented) */
306 #define VMCS_64BIT_GUEST_IA32_BNDCFGS_HI                   0x00002813
307 #define VMCS_64BIT_GUEST_IA32_RTIT_CTL                     0x00002814 /* Processor Trace (not implemented) */
308 #define VMCS_64BIT_GUEST_IA32_RTIT_CTL_HI                  0x00002815
309 #define VMCS_64BIT_GUEST_IA32_PKRS                         0x00002818 /* Supervisor-Mode Protection Keys */
310 #define VMCS_64BIT_GUEST_IA32_PKRS_HI                      0x00002819
311 
312 /* VMCS 64-bit host state fields */
313 /* binary 0010_11xx_xxxx_xxx0 */
314 #define VMCS_64BIT_HOST_IA32_PAT                           0x00002C00 /* PAT */
315 #define VMCS_64BIT_HOST_IA32_PAT_HI                        0x00002C01
316 #define VMCS_64BIT_HOST_IA32_EFER                          0x00002C02 /* EFER */
317 #define VMCS_64BIT_HOST_IA32_EFER_HI                       0x00002C03
318 #define VMCS_64BIT_HOST_IA32_PERF_GLOBAL_CTRL              0x00002C04 /* Perf Global Ctrl */
319 #define VMCS_64BIT_HOST_IA32_PERF_GLOBAL_CTRL_HI           0x00002C05
320 #define VMCS_64BIT_HOST_IA32_PKRS                          0x00002C06 /* Supervisor-Mode Protection Keys */
321 #define VMCS_64BIT_HOST_IA32_PKRS_HI                       0x00002C07
322 
323 /* VMCS 32_bit control fields */
324 /* binary 0100_00xx_xxxx_xxx0 */
325 #define VMCS_32BIT_CONTROL_PIN_BASED_EXEC_CONTROLS         0x00004000
326 #define VMCS_32BIT_CONTROL_PROCESSOR_BASED_VMEXEC_CONTROLS 0x00004002
327 #define VMCS_32BIT_CONTROL_EXECUTION_BITMAP                0x00004004
328 #define VMCS_32BIT_CONTROL_PAGE_FAULT_ERR_CODE_MASK        0x00004006
329 #define VMCS_32BIT_CONTROL_PAGE_FAULT_ERR_CODE_MATCH       0x00004008
330 #define VMCS_32BIT_CONTROL_CR3_TARGET_COUNT                0x0000400A
331 #define VMCS_32BIT_CONTROL_VMEXIT_CONTROLS                 0x0000400C
332 #define VMCS_32BIT_CONTROL_VMEXIT_MSR_STORE_COUNT          0x0000400E
333 #define VMCS_32BIT_CONTROL_VMEXIT_MSR_LOAD_COUNT           0x00004010
334 #define VMCS_32BIT_CONTROL_VMENTRY_CONTROLS                0x00004012
335 #define VMCS_32BIT_CONTROL_VMENTRY_MSR_LOAD_COUNT          0x00004014
336 #define VMCS_32BIT_CONTROL_VMENTRY_INTERRUPTION_INFO       0x00004016
337 #define VMCS_32BIT_CONTROL_VMENTRY_EXCEPTION_ERR_CODE      0x00004018
338 #define VMCS_32BIT_CONTROL_VMENTRY_INSTRUCTION_LENGTH      0x0000401A
339 #define VMCS_32BIT_CONTROL_TPR_THRESHOLD                   0x0000401C /* TPR shadow */
340 #define VMCS_32BIT_CONTROL_SECONDARY_VMEXEC_CONTROLS       0x0000401E
341 #define VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_GAP          0x00004020 /* PAUSE loop exiting */
342 #define VMCS_32BIT_CONTROL_PAUSE_LOOP_EXITING_WINDOW       0x00004022 /* PAUSE loop exiting */
343 
344 /* VMCS 32-bit read only data fields */
345 /* binary 0100_01xx_xxxx_xxx0 */
346 #define VMCS_32BIT_INSTRUCTION_ERROR                       0x00004400
347 #define VMCS_32BIT_VMEXIT_REASON                           0x00004402
348 #define VMCS_32BIT_VMEXIT_INTERRUPTION_INFO                0x00004404
349 #define VMCS_32BIT_VMEXIT_INTERRUPTION_ERR_CODE            0x00004406
350 #define VMCS_32BIT_IDT_VECTORING_INFO                      0x00004408
351 #define VMCS_32BIT_IDT_VECTORING_ERR_CODE                  0x0000440A
352 #define VMCS_32BIT_VMEXIT_INSTRUCTION_LENGTH               0x0000440C
353 #define VMCS_32BIT_VMEXIT_INSTRUCTION_INFO                 0x0000440E
354 
355 /* VMCS 32-bit guest-state fields */
356 /* binary 0100_10xx_xxxx_xxx0 */
357 #define VMCS_32BIT_GUEST_ES_LIMIT                          0x00004800
358 #define VMCS_32BIT_GUEST_CS_LIMIT                          0x00004802
359 #define VMCS_32BIT_GUEST_SS_LIMIT                          0x00004804
360 #define VMCS_32BIT_GUEST_DS_LIMIT                          0x00004806
361 #define VMCS_32BIT_GUEST_FS_LIMIT                          0x00004808
362 #define VMCS_32BIT_GUEST_GS_LIMIT                          0x0000480A
363 #define VMCS_32BIT_GUEST_LDTR_LIMIT                        0x0000480C
364 #define VMCS_32BIT_GUEST_TR_LIMIT                          0x0000480E
365 #define VMCS_32BIT_GUEST_GDTR_LIMIT                        0x00004810
366 #define VMCS_32BIT_GUEST_IDTR_LIMIT                        0x00004812
367 #define VMCS_32BIT_GUEST_ES_ACCESS_RIGHTS                  0x00004814
368 #define VMCS_32BIT_GUEST_CS_ACCESS_RIGHTS                  0x00004816
369 #define VMCS_32BIT_GUEST_SS_ACCESS_RIGHTS                  0x00004818
370 #define VMCS_32BIT_GUEST_DS_ACCESS_RIGHTS                  0x0000481A
371 #define VMCS_32BIT_GUEST_FS_ACCESS_RIGHTS                  0x0000481C
372 #define VMCS_32BIT_GUEST_GS_ACCESS_RIGHTS                  0x0000481E
373 #define VMCS_32BIT_GUEST_LDTR_ACCESS_RIGHTS                0x00004820
374 #define VMCS_32BIT_GUEST_TR_ACCESS_RIGHTS                  0x00004822
375 #define VMCS_32BIT_GUEST_INTERRUPTIBILITY_STATE            0x00004824
376 #define VMCS_32BIT_GUEST_ACTIVITY_STATE                    0x00004826
377 #define VMCS_32BIT_GUEST_SMBASE                            0x00004828
378 #define VMCS_32BIT_GUEST_IA32_SYSENTER_CS_MSR              0x0000482A
379 #define VMCS_32BIT_GUEST_PREEMPTION_TIMER_VALUE            0x0000482E /* VMX preemption timer */
380 
381 /* VMCS 32-bit host-state fields */
382 /* binary 0100_11xx_xxxx_xxx0 */
383 #define VMCS_32BIT_HOST_IA32_SYSENTER_CS_MSR               0x00004C00
384 
385 /* VMCS natural width control fields */
386 /* binary 0110_00xx_xxxx_xxx0 */
387 #define VMCS_CONTROL_CR0_GUEST_HOST_MASK                   0x00006000
388 #define VMCS_CONTROL_CR4_GUEST_HOST_MASK                   0x00006002
389 #define VMCS_CONTROL_CR0_READ_SHADOW                       0x00006004
390 #define VMCS_CONTROL_CR4_READ_SHADOW                       0x00006006
391 #define VMCS_CR3_TARGET0                                   0x00006008
392 #define VMCS_CR3_TARGET1                                   0x0000600A
393 #define VMCS_CR3_TARGET2                                   0x0000600C
394 #define VMCS_CR3_TARGET3                                   0x0000600E
395 
396 /* VMCS natural width read only data fields */
397 /* binary 0110_01xx_xxxx_xxx0 */
398 #define VMCS_VMEXIT_QUALIFICATION                          0x00006400
399 #define VMCS_IO_RCX                                        0x00006402
400 #define VMCS_IO_RSI                                        0x00006404
401 #define VMCS_IO_RDI                                        0x00006406
402 #define VMCS_IO_RIP                                        0x00006408
403 #define VMCS_GUEST_LINEAR_ADDR                             0x0000640A
404 
405 /* VMCS natural width guest state fields */
406 /* binary 0110_10xx_xxxx_xxx0 */
407 #define VMCS_GUEST_CR0                                     0x00006800
408 #define VMCS_GUEST_CR3                                     0x00006802
409 #define VMCS_GUEST_CR4                                     0x00006804
410 #define VMCS_GUEST_ES_BASE                                 0x00006806
411 #define VMCS_GUEST_CS_BASE                                 0x00006808
412 #define VMCS_GUEST_SS_BASE                                 0x0000680A
413 #define VMCS_GUEST_DS_BASE                                 0x0000680C
414 #define VMCS_GUEST_FS_BASE                                 0x0000680E
415 #define VMCS_GUEST_GS_BASE                                 0x00006810
416 #define VMCS_GUEST_LDTR_BASE                               0x00006812
417 #define VMCS_GUEST_TR_BASE                                 0x00006814
418 #define VMCS_GUEST_GDTR_BASE                               0x00006816
419 #define VMCS_GUEST_IDTR_BASE                               0x00006818
420 #define VMCS_GUEST_DR7                                     0x0000681A
421 #define VMCS_GUEST_RSP                                     0x0000681C
422 #define VMCS_GUEST_RIP                                     0x0000681E
423 #define VMCS_GUEST_RFLAGS                                  0x00006820
424 #define VMCS_GUEST_PENDING_DBG_EXCEPTIONS                  0x00006822
425 #define VMCS_GUEST_IA32_SYSENTER_ESP_MSR                   0x00006824
426 #define VMCS_GUEST_IA32_SYSENTER_EIP_MSR                   0x00006826
427 #define VMCS_GUEST_IA32_S_CET                              0x00006828
428 #define VMCS_GUEST_SSP                                     0x0000682A
429 #define VMCS_GUEST_INTERRUPT_SSP_TABLE_ADDR                0x0000682C
430 
431 /* VMCS natural width host state fields */
432 /* binary 0110_11xx_xxxx_xxx0 */
433 #define VMCS_HOST_CR0                                      0x00006C00
434 #define VMCS_HOST_CR3                                      0x00006C02
435 #define VMCS_HOST_CR4                                      0x00006C04
436 #define VMCS_HOST_FS_BASE                                  0x00006C06
437 #define VMCS_HOST_GS_BASE                                  0x00006C08
438 #define VMCS_HOST_TR_BASE                                  0x00006C0A
439 #define VMCS_HOST_GDTR_BASE                                0x00006C0C
440 #define VMCS_HOST_IDTR_BASE                                0x00006C0E
441 #define VMCS_HOST_IA32_SYSENTER_ESP_MSR                    0x00006C10
442 #define VMCS_HOST_IA32_SYSENTER_EIP_MSR                    0x00006C12
443 #define VMCS_HOST_RSP                                      0x00006C14
444 #define VMCS_HOST_RIP                                      0x00006C16
445 #define VMCS_HOST_IA32_S_CET                               0x00006C18
446 #define VMCS_HOST_SSP                                      0x00006C1A
447 #define VMCS_HOST_INTERRUPT_SSP_TABLE_ADDR                 0x00006C1C
448 
449 #define VMX_HIGHEST_VMCS_ENCODING   (0x34)
450 
451 // ===============================
452 //  VMCS fields encoding/decoding
453 // ===============================
454 
455 // extract VMCS field using its encoding
456 #define VMCS_FIELD(encoding)        ((encoding) & 0x3ff)
457 
458 // check if the VMCS field encoding corresponding to HI part of 64-bit value
459 #define IS_VMCS_FIELD_HI(encoding)  ((encoding) & 1)
460 
461 // bits 11:10 of VMCS field encoding indicate field's type
462 #define VMCS_FIELD_TYPE(encoding)   (((encoding) >> 10) & 3)
463 
464 enum {
465   VMCS_FIELD_TYPE_CONTROL     = 0x0,
466   VMCS_FIELD_TYPE_READ_ONLY   = 0x1,
467   VMCS_FIELD_TYPE_GUEST_STATE = 0x2,
468   VMCS_FIELD_TYPE_HOST_STATE  = 0x3
469 };
470 
471 // bits 14:13 of VMCS field encoding indicate field's width
472 #define VMCS_FIELD_WIDTH(encoding)  (((encoding) >> 13) & 3)
473 
474 enum {
475   VMCS_FIELD_WIDTH_16BIT = 0x0,
476   VMCS_FIELD_WIDTH_64BIT = 0x1,
477   VMCS_FIELD_WIDTH_32BIT = 0x2,
478   VMCS_FIELD_WIDTH_NATURAL_WIDTH = 0x3
479 };
480 
481 #define VMCS_FIELD_INDEX(encoding) \
482     ((VMCS_FIELD_WIDTH(encoding) << 2) + VMCS_FIELD_TYPE(encoding))
483 
484 const Bit32u VMCS_ENCODING_RESERVED_BITS = 0xffff9000;
485 
486 // =============
487 //  VMCS layout
488 // =============
489 
490 #define BX_VMX_VMCS_REVISION_ID 0x2B /* better to be unique bochs VMCS revision id */
491 
492 enum VMCS_Access_Rights_Format {
493    VMCS_AR_ROTATE,
494    VMCS_AR_PACK		// Intel Skylake packs AR into 16 bit form
495 };
496 
497 #define VMCS_LAUNCH_STATE_FIELD_ENCODING         (0xfffffffe)
498 #define VMCS_VMX_ABORT_FIELD_ENCODING            (0xfffffffc)
499 #define VMCS_REVISION_ID_FIELD_ENCODING          (0xfffffffa)
500 
501 class VMCS_Mapping {
502 private:
503    Bit32u revision_id;
504 
505    unsigned vmcs_revision_id_field_offset;
506    unsigned vmx_abort_field_offset;
507    unsigned vmcs_launch_state_field_offset;
508 
509    VMCS_Access_Rights_Format ar_format; // in which form segment selectors Access Rights are stored in the VMCS
510 
511    // assume 16 VMCS field types (encoded with 4 bits: 2 bits for VMCS_FIELD_TYPE and 2 bits for VMCS_FIELD_WIDTH)
512    unsigned vmcs_map[16][VMX_HIGHEST_VMCS_ENCODING];
513 
514    void init_generic_mapping();
515 
516 public:
517    VMCS_Mapping(Bit32u revision_id = BX_VMX_VMCS_REVISION_ID); // default VMCS mapping
518    VMCS_Mapping(Bit32u revision_id, const char *filename);
519 
520    void clear();
521 
522    bool clear_mapping(Bit32u encoding);
523    bool set_mapping(Bit32u encoding, Bit32u offset);
524 
set_vmcs_revision_id(Bit32u revision)525    void set_vmcs_revision_id(Bit32u revision) { revision_id = revision; }
get_vmcs_revision_id()526    Bit32u get_vmcs_revision_id() const { return revision_id; }
527 
set_access_rights_format(VMCS_Access_Rights_Format f)528    void set_access_rights_format(VMCS_Access_Rights_Format f) { ar_format = f; }
get_access_rights_format()529    VMCS_Access_Rights_Format get_access_rights_format() const { return ar_format; }
530 
set_vmcs_recision_id_offset(unsigned offset)531    void set_vmcs_recision_id_offset(unsigned offset) { vmcs_revision_id_field_offset = offset; }
set_vmx_abort_field_offset(unsigned offset)532    void set_vmx_abort_field_offset(unsigned offset) { vmx_abort_field_offset = offset; }
set_vmcs_launch_state_field_offset(unsigned offset)533    void set_vmcs_launch_state_field_offset(unsigned offset) { vmcs_launch_state_field_offset = offset; }
534 
535    unsigned vmcs_field_offset(Bit32u encoding) const;
536 
is_reserved(Bit32u encoding)537    bool is_reserved(Bit32u encoding) const {
538      return (encoding & VMCS_ENCODING_RESERVED_BITS) != 0;
539    }
540 
is_valid(Bit32u encoding)541    bool is_valid(Bit32u encoding) const {
542      return ! is_reserved(encoding) && (vmcs_field_offset(encoding) != 0xffffffff);
543    }
544 };
545 
546 #define VMCS_DATA_OFFSET                         (0x0010)
547 
548 #if ((VMCS_DATA_OFFSET + 4*(64*15 + VMX_HIGHEST_VMCS_ENCODING)) > VMX_VMCS_AREA_SIZE)
549   #error "VMCS area size exceeded !"
550 #endif
551 
552 // =============
553 //  VMCS state
554 // =============
555 
556 enum VMX_state {
557    VMCS_STATE_CLEAR = 0,
558    VMCS_STATE_LAUNCHED
559 };
560 
561 // ================
562 //  VMCS structure
563 // ================
564 
565 typedef struct bx_VMCS_GUEST_STATE
566 {
567    bx_address cr0;
568    bx_address cr3;
569    bx_address cr4;
570    bx_address dr7;
571 
572    bx_address rip;
573    bx_address rsp;
574    bx_address rflags;
575 
576    bx_segment_reg_t sregs[6];
577 
578    bx_global_segment_reg_t gdtr;
579    bx_global_segment_reg_t idtr;
580    bx_segment_reg_t        ldtr;
581    bx_segment_reg_t        tr;
582 
583    Bit64u ia32_debugctl_msr;
584    bx_address sysenter_esp_msr;
585    bx_address sysenter_eip_msr;
586    Bit32u sysenter_cs_msr;
587 
588    Bit32u smbase;
589    Bit32u activity_state;
590    Bit32u interruptibility_state;
591    Bit32u tmpDR6;
592 
593 #if BX_SUPPORT_VMX >= 2
594 #if BX_SUPPORT_X86_64
595    Bit64u efer_msr;
596 #endif
597    Bit64u pat_msr;
598    Bit64u pdptr[4];
599 #endif
600 
601 #if BX_SUPPORT_CET
602    Bit64u msr_ia32_s_cet;
603    bx_address ssp;
604    bx_address interrupt_ssp_table_address;
605 #endif
606 
607 #if BX_SUPPORT_PKEYS
608    Bit32u pkrs;
609 #endif
610 } VMCS_GUEST_STATE;
611 
612 typedef struct bx_VMCS_HOST_STATE
613 {
614    bx_address cr0;
615    bx_address cr3;
616    bx_address cr4;
617 
618    Bit16u segreg_selector[6];
619 
620    bx_address fs_base;
621    bx_address gs_base;
622 
623    bx_address gdtr_base;
624    bx_address idtr_base;
625 
626    Bit32u tr_selector;
627    bx_address tr_base;
628 
629    bx_address rsp;
630    bx_address rip;
631 
632    bx_address sysenter_esp_msr;
633    bx_address sysenter_eip_msr;
634    Bit32u sysenter_cs_msr;
635 
636 #if BX_SUPPORT_VMX >= 2
637 #if BX_SUPPORT_X86_64
638    Bit64u efer_msr;
639 #endif
640    Bit64u pat_msr;
641 #endif
642 
643 #if BX_SUPPORT_CET
644    Bit64u msr_ia32_s_cet;
645    bx_address ssp;
646    bx_address interrupt_ssp_table_address;
647 #endif
648 
649 #if BX_SUPPORT_PKEYS
650    Bit32u pkrs;
651 #endif
652 } VMCS_HOST_STATE;
653 
654 typedef struct bx_VMX_Cap
655 {
656   //
657   // VMX Capabilities
658   //
659 
660   Bit32u vmx_pin_vmexec_ctrl_supported_bits;
661   Bit32u vmx_proc_vmexec_ctrl_supported_bits;
662   Bit32u vmx_vmexec_ctrl2_supported_bits;
663   Bit32u vmx_vmexit_ctrl_supported_bits;
664   Bit32u vmx_vmentry_ctrl_supported_bits;
665 #if BX_SUPPORT_VMX >= 2
666   Bit64u vmx_ept_vpid_cap_supported_bits;
667   Bit64u vmx_vmfunc_supported_bits;
668 #endif
669 } VMX_CAP;
670 
671 #if BX_SUPPORT_VMX >= 2
672 
673 // used for pause loop exiting
674 struct VMX_PLE {
675   Bit32u pause_loop_exiting_gap;
676   Bit32u pause_loop_exiting_window;
677   Bit64u last_pause_time;
678   Bit64u first_pause_time;
679 };
680 
681 #endif
682 
683 typedef struct bx_VMCS
684 {
685   //
686   // VM-Execution Control Fields
687   //
688 
689 #define VMX_VM_EXEC_CTRL1_EXTERNAL_INTERRUPT_VMEXIT   (1 << 0)
690 #define VMX_VM_EXEC_CTRL1_NMI_EXITING                 (1 << 3)
691 #define VMX_VM_EXEC_CTRL1_VIRTUAL_NMI                 (1 << 5) /* Virtual NMI */
692 #define VMX_VM_EXEC_CTRL1_VMX_PREEMPTION_TIMER_VMEXIT (1 << 6) /* VMX preemption timer */
693 #define VMX_VM_EXEC_CTRL1_PROCESS_POSTED_INTERRUPTS   (1 << 7) /* Posted Interrupts (not implemented) */
694 
695 #define VMX_VM_EXEC_CTRL1_SUPPORTED_BITS \
696     (BX_CPU_THIS_PTR vmx_cap.vmx_pin_vmexec_ctrl_supported_bits)
697 
698    Bit32u vmexec_ctrls1;
699 
700 #define VMX_VM_EXEC_CTRL2_INTERRUPT_WINDOW_VMEXIT   (1 << 2)
701 #define VMX_VM_EXEC_CTRL2_TSC_OFFSET                (1 << 3)
702 #define VMX_VM_EXEC_CTRL2_HLT_VMEXIT                (1 << 7)
703 #define VMX_VM_EXEC_CTRL2_INVLPG_VMEXIT             (1 << 9)
704 #define VMX_VM_EXEC_CTRL2_MWAIT_VMEXIT              (1 << 10)
705 #define VMX_VM_EXEC_CTRL2_RDPMC_VMEXIT              (1 << 11)
706 #define VMX_VM_EXEC_CTRL2_RDTSC_VMEXIT              (1 << 12)
707 #define VMX_VM_EXEC_CTRL2_CR3_WRITE_VMEXIT          (1 << 15) /* legacy must be '1 */
708 #define VMX_VM_EXEC_CTRL2_CR3_READ_VMEXIT           (1 << 16) /* legacy must be '1 */
709 #define VMX_VM_EXEC_CTRL2_CR8_WRITE_VMEXIT          (1 << 19) /* TPR shadow */
710 #define VMX_VM_EXEC_CTRL2_CR8_READ_VMEXIT           (1 << 20) /* TPR shadow */
711 #define VMX_VM_EXEC_CTRL2_TPR_SHADOW                (1 << 21) /* TPR shadow */
712 #define VMX_VM_EXEC_CTRL2_NMI_WINDOW_EXITING        (1 << 22) /* Virtual NMI */
713 #define VMX_VM_EXEC_CTRL2_DRx_ACCESS_VMEXIT         (1 << 23)
714 #define VMX_VM_EXEC_CTRL2_IO_VMEXIT                 (1 << 24)
715 #define VMX_VM_EXEC_CTRL2_IO_BITMAPS                (1 << 25)
716 #define VMX_VM_EXEC_CTRL2_MONITOR_TRAP_FLAG         (1 << 27) /* Monitor Trap Flag */
717 #define VMX_VM_EXEC_CTRL2_MSR_BITMAPS               (1 << 28)
718 #define VMX_VM_EXEC_CTRL2_MONITOR_VMEXIT            (1 << 29)
719 #define VMX_VM_EXEC_CTRL2_PAUSE_VMEXIT              (1 << 30)
720 #define VMX_VM_EXEC_CTRL2_SECONDARY_CONTROLS        (1 << 31)
721 
722 #define VMX_VM_EXEC_CTRL2_SUPPORTED_BITS \
723     (BX_CPU_THIS_PTR vmx_cap.vmx_proc_vmexec_ctrl_supported_bits)
724 
725    Bit32u vmexec_ctrls2;
726 
727 #define VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_ACCESSES  (1 <<  0) /* APIC virtualization */
728 #define VMX_VM_EXEC_CTRL3_EPT_ENABLE                (1 <<  1) /* EPT */
729 #define VMX_VM_EXEC_CTRL3_DESCRIPTOR_TABLE_VMEXIT   (1 <<  2) /* Descriptor Table VMEXIT */
730 #define VMX_VM_EXEC_CTRL3_RDTSCP                    (1 <<  3)
731 #define VMX_VM_EXEC_CTRL3_VIRTUALIZE_X2APIC_MODE    (1 <<  4) /* Virtualize X2APIC */
732 #define VMX_VM_EXEC_CTRL3_VPID_ENABLE               (1 <<  5) /* VPID */
733 #define VMX_VM_EXEC_CTRL3_WBINVD_VMEXIT             (1 <<  6) /* WBINVD VMEXIT */
734 #define VMX_VM_EXEC_CTRL3_UNRESTRICTED_GUEST        (1 <<  7) /* Unrestricted Guest */
735 #define VMX_VM_EXEC_CTRL3_VIRTUALIZE_APIC_REGISTERS (1 <<  8)
736 #define VMX_VM_EXEC_CTRL3_VIRTUAL_INT_DELIVERY      (1 <<  9)
737 #define VMX_VM_EXEC_CTRL3_PAUSE_LOOP_VMEXIT         (1 << 10) /* PAUSE loop exiting */
738 #define VMX_VM_EXEC_CTRL3_RDRAND_VMEXIT             (1 << 11)
739 #define VMX_VM_EXEC_CTRL3_INVPCID                   (1 << 12)
740 #define VMX_VM_EXEC_CTRL3_VMFUNC_ENABLE             (1 << 13) /* VM Functions */
741 #define VMX_VM_EXEC_CTRL3_VMCS_SHADOWING            (1 << 14) /* VMCS Shadowing */
742 #define VMX_VM_EXEC_CTRL3_SGX_ENCLS_VMEXIT          (1 << 15) /* ENCLS/SGX */
743 #define VMX_VM_EXEC_CTRL3_RDSEED_VMEXIT             (1 << 16)
744 #define VMX_VM_EXEC_CTRL3_PML_ENABLE                (1 << 17) /* Page Modification Logging */
745 #define VMX_VM_EXEC_CTRL3_EPT_VIOLATION_EXCEPTION   (1 << 18) /* #VE Exception */
746 #define VMX_VM_EXEC_CTRL3_SUPPRESS_GUEST_VMX_TRACE  (1 << 19) /* Processor Trace (not implemented) */
747 #define VMX_VM_EXEC_CTRL3_XSAVES_XRSTORS            (1 << 20) /* XSAVES */
748 #define VMX_VM_EXEC_CTRL3_MBE_CTRL                  (1 << 22) /* Mode Based Execution Control (not implemented yet) */
749 #define VMX_VM_EXEC_CTRL3_SUBPAGE_WR_PROTECT_CTRL   (1 << 23) /* Sub-Page Write Protection Control */
750 #define VMX_VM_EXEC_CTRL3_TSC_SCALING               (1 << 25) /* TSC Scaling */
751 
752 #define VMX_VM_EXEC_CTRL3_SUPPORTED_BITS \
753     (BX_CPU_THIS_PTR vmx_cap.vmx_vmexec_ctrl2_supported_bits)
754 
755    Bit32u vmexec_ctrls3;
756 
757    Bit64u vmcs_linkptr;
758 
759    Bit64u tsc_multiplier;
760 
761    Bit32u vm_exceptions_bitmap;
762    Bit32u vm_pf_mask;
763    Bit32u vm_pf_match;
764    Bit64u io_bitmap_addr[2];
765    bx_phy_address msr_bitmap_addr;
766 
767    bx_address vm_cr0_mask;
768    bx_address vm_cr0_read_shadow;
769    bx_address vm_cr4_mask;
770    bx_address vm_cr4_read_shadow;
771 
772 #define VMX_CR3_TARGET_MAX_CNT 4
773 
774    Bit32u vm_cr3_target_cnt;
775    bx_address vm_cr3_target_value[VMX_CR3_TARGET_MAX_CNT];
776 
777 #if BX_SUPPORT_X86_64
778    bx_phy_address virtual_apic_page_addr;
779    Bit32u vm_tpr_threshold;
780    bx_phy_address apic_access_page;
781    unsigned apic_access;
782 #endif
783 
784 #if BX_SUPPORT_VMX >= 2
785    Bit64u eptptr;
786    Bit16u vpid;
787    Bit64u pml_address;
788    Bit16u pml_index;
789    Bit64u spptp;
790 #endif
791 
792 #if BX_SUPPORT_VMX >= 2
793    VMX_PLE ple;
794 #endif
795 
796 #if BX_SUPPORT_VMX >= 2
797    Bit8u svi; /* Servicing Virtual Interrupt */
798    Bit8u rvi; /* Requesting Virtual Interrupt */
799    Bit8u vppr;
800 
801    Bit32u eoi_exit_bitmap[8];
802 #endif
803 
804 #if BX_SUPPORT_VMX >= 2
805    bx_phy_address vmread_bitmap_addr, vmwrite_bitmap_addr;
806 #endif
807 
808 #if BX_SUPPORT_VMX >= 2
809    bx_phy_address ve_info_addr;
810    Bit16u eptp_index;
811 #endif
812 
813 #if BX_SUPPORT_VMX >= 2
814    Bit64u xss_exiting_bitmap;
815 #endif
816 
817    //
818    // VM-Exit Control Fields
819    //
820 
821 #define VMX_VMEXIT_CTRL1_SAVE_DBG_CTRLS             (1 <<  2) /* legacy must be '1 */
822 #define VMX_VMEXIT_CTRL1_HOST_ADDR_SPACE_SIZE       (1 <<  9)
823 #define VMX_VMEXIT_CTRL1_LOAD_PERF_GLOBAL_CTRL_MSR  (1 << 12) /* Perf Global Control */
824 #define VMX_VMEXIT_CTRL1_INTA_ON_VMEXIT             (1 << 15)
825 #define VMX_VMEXIT_CTRL1_STORE_PAT_MSR              (1 << 18) /* PAT */
826 #define VMX_VMEXIT_CTRL1_LOAD_PAT_MSR               (1 << 19) /* PAT */
827 #define VMX_VMEXIT_CTRL1_STORE_EFER_MSR             (1 << 20) /* EFER */
828 #define VMX_VMEXIT_CTRL1_LOAD_EFER_MSR              (1 << 21) /* EFER */
829 #define VMX_VMEXIT_CTRL1_STORE_VMX_PREEMPTION_TIMER (1 << 22) /* VMX preemption timer */
830 #define VMX_VMEXIT_CTRL1_CLEAR_BNDCFGS              (1 << 23) /* MPX (not implemented) */
831 #define VMX_VMEXIT_CTRL1_SUPPRESS_HOST_VMX_TRACE    (1 << 24) /* Processor Trace (not implemented) */
832 #define VMX_VMEXIT_CTRL1_LOAD_HOST_CET_STATE        (1 << 28) /* CET */
833 #define VMX_VMEXIT_CTRL1_LOAD_HOST_PKRS             (1 << 29) /* Supervisor-Mode Protection Keys */
834 
835 #define VMX_VMEXIT_CTRL1_SUPPORTED_BITS \
836     (BX_CPU_THIS_PTR vmx_cap.vmx_vmexit_ctrl_supported_bits)
837 
838    Bit32u vmexit_ctrls;
839 
840    Bit32u vmexit_msr_store_cnt;
841    bx_phy_address vmexit_msr_store_addr;
842    Bit32u vmexit_msr_load_cnt;
843    bx_phy_address vmexit_msr_load_addr;
844 
845    //
846    // VM-Entry Control Fields
847    //
848 
849 #define VMX_VMENTRY_CTRL1_LOAD_DBG_CTRLS                    (1 <<  2) /* legacy must be '1 */
850 #define VMX_VMENTRY_CTRL1_X86_64_GUEST                      (1 <<  9)
851 #define VMX_VMENTRY_CTRL1_SMM_ENTER                         (1 << 10)
852 #define VMX_VMENTRY_CTRL1_DEACTIVATE_DUAL_MONITOR_TREATMENT (1 << 11)
853 #define VMX_VMENTRY_CTRL1_LOAD_PERF_GLOBAL_CTRL_MSR         (1 << 13) /* Perf Global Ctrl */
854 #define VMX_VMENTRY_CTRL1_LOAD_PAT_MSR                      (1 << 14) /* PAT */
855 #define VMX_VMENTRY_CTRL1_LOAD_EFER_MSR                     (1 << 15) /* EFER */
856 #define VMX_VMENTRY_CTRL1_LOAD_BNDCFGS                      (1 << 16) /* MPX (not implemented) */
857 #define VMX_VMENTRY_CTRL1_SUPPRESS_VMX_PACKETS              (1 << 17) /* Processor Trace (not implemented) */
858 #define VMX_VMENTRY_CTRL1_LOAD_GUEST_CET_STATE              (1 << 20) /* CET */
859 #define VMX_VMENTRY_CTRL1_LOAD_GUEST_PKRS                   (1 << 22) /* Supervisor-Mode Protection Keys */
860 
861 #define VMX_VMENTRY_CTRL1_SUPPORTED_BITS \
862     (BX_CPU_THIS_PTR vmx_cap.vmx_vmentry_ctrl_supported_bits)
863 
864    Bit32u vmentry_ctrls;
865 
866    Bit32u vmentry_msr_load_cnt;
867    bx_phy_address vmentry_msr_load_addr;
868 
869    Bit32u vmentry_interr_info;
870    Bit32u vmentry_excep_err_code;
871    Bit32u vmentry_instr_length;
872 
873    //
874    // VM Functions
875    //
876 
877 #if BX_SUPPORT_VMX >= 2
878 
879 #define VMX_VMFUNC_CTRL1_SUPPORTED_BITS \
880     (BX_CPU_THIS_PTR vmx_cap.vmx_vmfunc_supported_bits)
881 
882    Bit64u vmfunc_ctrls;
883 
884    Bit64u eptp_list_address;
885 
886 #endif
887 
888    //
889    // VMCS Hidden and Read-Only Fields
890    //
891    Bit32u idt_vector_info;
892    Bit32u idt_vector_error_code;
893 
894    //
895    // VMCS Host State
896    //
897 
898    VMCS_HOST_STATE host_state;
899 
900 } VMCS_CACHE;
901 
902 #define PIN_VMEXIT(ctrl) (BX_CPU_THIS_PTR vmcs.vmexec_ctrls1 & (ctrl))
903 #define     VMEXIT(ctrl) (BX_CPU_THIS_PTR vmcs.vmexec_ctrls2 & (ctrl))
904 
905 #define SECONDARY_VMEXEC_CONTROL(ctrl) (BX_CPU_THIS_PTR vmcs.vmexec_ctrls3 & (ctrl))
906 
907 const Bit32u BX_VMX_INTERRUPTS_BLOCKED_BY_STI      = (1 << 0);
908 const Bit32u BX_VMX_INTERRUPTS_BLOCKED_BY_MOV_SS   = (1 << 1);
909 const Bit32u BX_VMX_INTERRUPTS_BLOCKED_SMI_BLOCKED = (1 << 2);
910 const Bit32u BX_VMX_INTERRUPTS_BLOCKED_NMI_BLOCKED = (1 << 3);
911 
912 const Bit32u BX_VMX_INTERRUPTIBILITY_STATE_MASK = \
913   (BX_VMX_INTERRUPTS_BLOCKED_BY_STI | BX_VMX_INTERRUPTS_BLOCKED_BY_MOV_SS | BX_VMX_INTERRUPTS_BLOCKED_SMI_BLOCKED | BX_VMX_INTERRUPTS_BLOCKED_NMI_BLOCKED);
914 
915 //
916 // IA32_VMX_BASIC MSR (0x480)
917 // --------------
918 
919 const Bit32u BX_VMCS_SHADOW_BIT_MASK = 0x80000000;
920 
921 //
922 // 30:00 VMCS revision id
923 // 31:31 shadow VMCS indicator
924 // -----------------------------
925 // 32:47 VMCS region size, 0 <= size <= 4096
926 // 48:48 use 32-bit physical address, set when x86_64 disabled
927 // 49:49 support of dual-monitor treatment of SMI and SMM
928 // 53:50 memory type used for VMCS access
929 // 54:54 logical processor reports information in the VM-exit
930 //       instruction-information field on VM exits due to
931 //       execution of INS/OUTS
932 // 55:55 set if any VMX controls that default to `1 may be
933 //       cleared to `0, also indicates that IA32_VMX_TRUE_PINBASED_CTLS,
934 //       IA32_VMX_TRUE_PROCBASED_CTLS, IA32_VMX_TRUE_EXIT_CTLS and
935 //       IA32_VMX_TRUE_ENTRY_CTLS MSRs are supported.
936 // 56:56 if set software can use VM entry to deliver a hardware exception
937 //       with or without an error code, regardless of vector
938 // 57:63 reserved, must be zero
939 //
940 
941 #define VMX_MSR_VMX_BASIC_LO (BX_CPU_THIS_PTR vmcs_map->get_vmcs_revision_id())
942 #define VMX_MSR_VMX_BASIC_HI \
943      (VMX_VMCS_AREA_SIZE | ((!is_cpu_extension_supported(BX_ISA_LONG_MODE)) << 16) | \
944      (BX_MEMTYPE_WB << 18) | (1<<22)) | ((BX_SUPPORT_VMX >= 2) ? (1<<23) : 0) | \
945      (is_cpu_extension_supported(BX_ISA_CET) ? (1<<24) : 0)
946 
947 #define VMX_MSR_VMX_BASIC \
948    ((((Bit64u) VMX_MSR_VMX_BASIC_HI) << 32) | VMX_MSR_VMX_BASIC_LO)
949 
950 
951 // ------------------------------------------------------------------------
952 //              reserved bit (must be '1) settings for VMX MSRs
953 // ------------------------------------------------------------------------
954 
955 // -----------------------------------------
956 //  3322|2222|2222|1111|1111|11  |    |
957 //  1098|7654|3210|9876|5432|1098|7654|3210
958 // -----------------------------------------
959 //  ----.----.----.----.----.----.---1.-11-  MSR (0x481) IA32_MSR_VMX_PINBASED_CTRLS
960 //  ----.-1--.----.---1.111-.---1.-111.--1-  MSR (0x482) IA32_MSR_VMX_PROCBASED_CTRLS
961 //  ----.----.----.--11.-11-.11-1.1111.1111  MSR (0x483) IA32_MSR_VMX_VMEXIT_CTRLS
962 //  ----.----.----.----.---1.---1.1111.1111  MSR (0x484) IA32_MSR_VMX_VMENTRY_CTRLS
963 //
964 
965 // IA32_MSR_VMX_PINBASED_CTRLS MSR (0x481)
966 // ---------------------------
967 
968 // Bits 1, 2 and 4 must be '1
969 
970 // Allowed 0-settings: VMentry fail if a bit is '0 in pin-based vmexec controls
971 // but set to '1 in this MSR
972 #define VMX_MSR_VMX_PINBASED_CTRLS_LO (0x00000016)
973 // Allowed 1-settings: VMentry fail if a bit is '1 in pin-based vmexec controls
974 // but set to '0 in this MSR.
975 #define VMX_MSR_VMX_PINBASED_CTRLS_HI \
976        (VMX_VM_EXEC_CTRL1_SUPPORTED_BITS | VMX_MSR_VMX_PINBASED_CTRLS_LO)
977 
978 #define VMX_MSR_VMX_PINBASED_CTRLS \
979    ((((Bit64u) VMX_MSR_VMX_PINBASED_CTRLS_HI) << 32) | VMX_MSR_VMX_PINBASED_CTRLS_LO)
980 
981 // IA32_MSR_VMX_TRUE_PINBASED_CTRLS MSR (0x48d)
982 // --------------------------------
983 
984 // no changes from original IA32_MSR_VMX_PINBASED_CTRLS
985 #define VMX_MSR_VMX_TRUE_PINBASED_CTRLS_LO (VMX_MSR_VMX_PINBASED_CTRLS_LO)
986 #define VMX_MSR_VMX_TRUE_PINBASED_CTRLS_HI (VMX_MSR_VMX_PINBASED_CTRLS_HI)
987 
988 #define VMX_MSR_VMX_TRUE_PINBASED_CTRLS \
989    ((((Bit64u) VMX_MSR_VMX_TRUE_PINBASED_CTRLS_HI) << 32) | VMX_MSR_VMX_TRUE_PINBASED_CTRLS_LO)
990 
991 
992 // IA32_MSR_VMX_PROCBASED_CTRLS MSR (0x482)
993 // ----------------------------
994 
995 // Bits 1, 4-6, 8, 13-16, 26 must be '1
996 // Bits 0, 17, 18 must be '0
997 // Bits 19-21 also must be '0 when x86-64 is not supported
998 
999 // Allowed 0-settings (must be '1 bits)
1000 #define VMX_MSR_VMX_PROCBASED_CTRLS_LO (0x0401E172)
1001 // Allowed 1-settings
1002 #define VMX_MSR_VMX_PROCBASED_CTRLS_HI \
1003        (VMX_VM_EXEC_CTRL2_SUPPORTED_BITS | VMX_MSR_VMX_PROCBASED_CTRLS_LO)
1004 
1005 #define VMX_MSR_VMX_PROCBASED_CTRLS \
1006    ((((Bit64u) VMX_MSR_VMX_PROCBASED_CTRLS_HI) << 32) | VMX_MSR_VMX_PROCBASED_CTRLS_LO)
1007 
1008 // IA32_MSR_VMX_TRUE_PROCBASED_CTRLS MSR (0x48e)
1009 // ---------------------------------
1010 
1011 // Bits 15 and 16 no longer must be '1
1012 #define VMX_MSR_VMX_TRUE_PROCBASED_CTRLS_LO (0x04006172)
1013 #define VMX_MSR_VMX_TRUE_PROCBASED_CTRLS_HI (VMX_MSR_VMX_PROCBASED_CTRLS_HI)
1014 
1015 #define VMX_MSR_VMX_TRUE_PROCBASED_CTRLS \
1016    ((((Bit64u) VMX_MSR_VMX_TRUE_PROCBASED_CTRLS_HI) << 32) | VMX_MSR_VMX_TRUE_PROCBASED_CTRLS_LO)
1017 
1018 
1019 // IA32_MSR_VMX_VMEXIT_CTRLS MSR (0x483)
1020 // -------------------------
1021 
1022 // Bits 0-8, 10, 11, 13, 14, 16, 17 must be '1
1023 
1024 // Allowed 0-settings (must be '1 bits)
1025 #define VMX_MSR_VMX_VMEXIT_CTRLS_LO (0x00036DFF)
1026 // Allowed 1-settings
1027 #define VMX_MSR_VMX_VMEXIT_CTRLS_HI \
1028        (VMX_VMEXIT_CTRL1_SUPPORTED_BITS | VMX_MSR_VMX_VMEXIT_CTRLS_LO)
1029 
1030 #define VMX_MSR_VMX_VMEXIT_CTRLS \
1031    ((((Bit64u) VMX_MSR_VMX_VMEXIT_CTRLS_HI) << 32) | VMX_MSR_VMX_VMEXIT_CTRLS_LO)
1032 
1033 // IA32_MSR_VMX_TRUE_VMEXIT_CTRLS MSR (0x48f)
1034 // ------------------------------
1035 
1036 // Bit 2 no longer must be '1
1037 #define VMX_MSR_VMX_TRUE_VMEXIT_CTRLS_LO (0x00036DFB)
1038 #define VMX_MSR_VMX_TRUE_VMEXIT_CTRLS_HI (VMX_MSR_VMX_VMEXIT_CTRLS_HI)
1039 
1040 #define VMX_MSR_VMX_TRUE_VMEXIT_CTRLS \
1041    ((((Bit64u) VMX_MSR_VMX_TRUE_VMEXIT_CTRLS_HI) << 32) | VMX_MSR_VMX_TRUE_VMEXIT_CTRLS_LO)
1042 
1043 
1044 // IA32_MSR_VMX_VMENTRY_CTRLS MSR (0x484)
1045 // --------------------------
1046 
1047 // Bits 0-8, 12 must be '1
1048 
1049 // Allowed 0-settings (must be '1 bits)
1050 #define VMX_MSR_VMX_VMENTRY_CTRLS_LO (0x000011FF)
1051 // Allowed 1-settings
1052 #define VMX_MSR_VMX_VMENTRY_CTRLS_HI \
1053        (VMX_VMENTRY_CTRL1_SUPPORTED_BITS | VMX_MSR_VMX_VMENTRY_CTRLS_LO)
1054 
1055 #define VMX_MSR_VMX_VMENTRY_CTRLS \
1056    ((((Bit64u) VMX_MSR_VMX_VMENTRY_CTRLS_HI) << 32) | VMX_MSR_VMX_VMENTRY_CTRLS_LO)
1057 
1058 // IA32_MSR_VMX_TRUE_VMENTRY_CTRLS MSR (0x490)
1059 // -------------------------------
1060 
1061 // Bit 2 is longer must be '1
1062 #define VMX_MSR_VMX_TRUE_VMENTRY_CTRLS_LO (0x000011FB)
1063 #define VMX_MSR_VMX_TRUE_VMENTRY_CTRLS_HI (VMX_MSR_VMX_VMENTRY_CTRLS_HI)
1064 
1065 #define VMX_MSR_VMX_TRUE_VMENTRY_CTRLS \
1066    ((((Bit64u) VMX_MSR_VMX_TRUE_VMENTRY_CTRLS_HI) << 32) | VMX_MSR_VMX_TRUE_VMENTRY_CTRLS_LO)
1067 
1068 
1069 // IA32_MSR_VMX_MISC MSR (0x485)
1070 // -----------------
1071 
1072 //   [4:0] - TSC:VMX_PREEMPTION_TIMER ratio
1073 //     [5] - VMEXITs store the value of EFER.LMA into the �x86-64 guest"
1074 //           VMENTRY control (must set to '1 if 'unrestricted guest' is supported)
1075 //     [6] - support VMENTER to HLT state
1076 //     [7] - support VMENTER to SHUTDOWN state
1077 //     [8] - support VMENTER to WAIT_FOR_SIPI state
1078 //    [14] - Intel Processor Trace (Intel PT) can be used in VMX operation
1079 //    [15] - RDMSR can be used in SMM to read the SMBASE MSR
1080 // [24:16] - number of CR3 target values supported
1081 // [27:25] - (N+1)*512 - recommended maximum MSRs in MSR store list
1082 //    [28] - MSR_IA32_SMM_MONITOR_CTL[2] enable
1083 //    [29] - Allow VMWRITE to R/O VMCS fields (to be used with VMCS Shadowing)
1084 //    [30] - Allow injection of a software interrupt, software exception, or privileged
1085 //           software exception with an instruction length of 0
1086 //    [31] - Reserved
1087 // --------------------------------------------
1088 // [63:32] - MSEG revision ID used by processor
1089 
1090 #if BX_SUPPORT_VMX >= 2
1091 const Bit32u VMX_MISC_STORE_LMA_TO_X86_64_GUEST_VMENTRY_CONTROL = (1<<5);
1092 #else
1093 const Bit32u VMX_MISC_STORE_LMA_TO_X86_64_GUEST_VMENTRY_CONTROL = 0;
1094 #endif
1095 
1096 const Bit32u VMX_SUPPORT_VMENTER_TO_NON_ACTIVE_STATE = (1<<6) | (1<<7) | (1<<8);
1097 
1098 const Bit32u VMX_MISC_SUPPORT_VMWRITE_READ_ONLY_FIELDS            = (1<<29);
1099 const Bit32u VMX_MISC_ALLOW_INJECTION_OF_SW_INTERRUPT_WITH_ILEN_0 = (1<<30);
1100 
1101 //Rate to increase VMX preemtion timer
1102 const Bit32u VMX_MISC_PREEMPTION_TIMER_RATE = 0;
1103 
1104 #define VMX_MSR_MISC (VMX_MISC_PREEMPTION_TIMER_RATE | \
1105                       VMX_MISC_STORE_LMA_TO_X86_64_GUEST_VMENTRY_CONTROL | \
1106                       VMX_SUPPORT_VMENTER_TO_NON_ACTIVE_STATE | \
1107                      (VMX_CR3_TARGET_MAX_CNT << 16) | \
1108                      (BX_SUPPORT_VMX_EXTENSION(BX_VMX_VMCS_SHADOWING) ? VMX_MISC_SUPPORT_VMWRITE_READ_ONLY_FIELDS : 0) | \
1109                      (BX_SUPPORT_VMX_EXTENSION(BX_VMX_SW_INTERRUPT_INJECTION_ILEN_0) ? VMX_MISC_ALLOW_INJECTION_OF_SW_INTERRUPT_WITH_ILEN_0 : 0))
1110 
1111 //
1112 // IA32_VMX_CR0_FIXED0 MSR (0x486)   IA32_VMX_CR0_FIXED1 MSR (0x487)
1113 // -------------------               -------------------
1114 
1115 // allowed 0-setting in CR0 in VMX mode
1116 // bits PE(0), NE(5) and PG(31) required to be set in CR0 to enter VMX mode
1117 const Bit32u VMX_MSR_CR0_FIXED0_LO = 0x80000021;
1118 const Bit32u VMX_MSR_CR0_FIXED0_HI = 0x00000000;
1119 
1120 const Bit64u VMX_MSR_CR0_FIXED0 =
1121    ((((Bit64u) VMX_MSR_CR0_FIXED0_HI) << 32) | VMX_MSR_CR0_FIXED0_LO);
1122 
1123 // allowed 1-setting in CR0 in VMX mode
1124 const Bit32u VMX_MSR_CR0_FIXED1_LO = 0xFFFFFFFF;
1125 const Bit32u VMX_MSR_CR0_FIXED1_HI = 0x00000000;
1126 
1127 const Bit64u VMX_MSR_CR0_FIXED1 =
1128    ((((Bit64u) VMX_MSR_CR0_FIXED1_HI) << 32) | VMX_MSR_CR0_FIXED1_LO);
1129 
1130 //
1131 // IA32_VMX_CR4_FIXED0 MSR (0x488)   IA32_VMX_CR4_FIXED1 MSR (0x489)
1132 // -------------------               -------------------
1133 
1134 // allowed 0-setting in CR0 in VMX mode
1135 // bit VMXE(13) required to be set in CR4 to enter VMX mode
1136 const Bit32u VMX_MSR_CR4_FIXED0_LO = 0x00002000;
1137 const Bit32u VMX_MSR_CR4_FIXED0_HI = 0x00000000;
1138 
1139 const Bit64u VMX_MSR_CR4_FIXED0 =
1140    ((((Bit64u) VMX_MSR_CR4_FIXED0_HI) << 32) | VMX_MSR_CR4_FIXED0_LO);
1141 
1142 // allowed 1-setting in CR0 in VMX mode
1143 #define VMX_MSR_CR4_FIXED1_LO (BX_CPU_THIS_PTR cr4_suppmask)
1144 #define VMX_MSR_CR4_FIXED1_HI (0)
1145 
1146 #define VMX_MSR_CR4_FIXED1 \
1147    ((((Bit64u) VMX_MSR_CR4_FIXED1_HI) << 32) | VMX_MSR_CR4_FIXED1_LO)
1148 
1149 
1150 //
1151 // IA32_VMX_VMCS_ENUM MSR (0x48a)
1152 // ------------------
1153 
1154 //
1155 // 09:01 highest index value used for any VMCS encoding
1156 // 63:10 reserved, must be zero
1157 //
1158 
1159 #define VMX_MSR_VMCS_ENUM_LO (VMX_HIGHEST_VMCS_ENCODING)
1160 #define VMX_MSR_VMCS_ENUM_HI (0x00000000)
1161 
1162 #define VMX_MSR_VMCS_ENUM \
1163    ((((Bit64u) VMX_MSR_VMCS_ENUM_HI) << 32) | VMX_MSR_VMCS_ENUM_LO)
1164 
1165 
1166 // IA32_VMX_MSR_PROCBASED_CTRLS2 MSR (0x48b)
1167 // -----------------------------
1168 
1169 // Allowed 0-settings (must be '1 bits)
1170 #define VMX_MSR_VMX_PROCBASED_CTRLS2_LO (0x00000000)
1171 // Allowed 1-settings
1172 #define VMX_MSR_VMX_PROCBASED_CTRLS2_HI \
1173        (VMX_VM_EXEC_CTRL3_SUPPORTED_BITS | VMX_MSR_VMX_PROCBASED_CTRLS2_LO)
1174 
1175 #define VMX_MSR_VMX_PROCBASED_CTRLS2 \
1176    ((((Bit64u) VMX_MSR_VMX_PROCBASED_CTRLS2_HI) << 32) | VMX_MSR_VMX_PROCBASED_CTRLS2_LO)
1177 
1178 #if BX_SUPPORT_VMX >= 2
1179 
1180 // IA32_VMX_EPT_VPID_CAP MSR (0x48c)
1181 // ---------------------
1182 
1183 enum VMX_INVEPT_INVVPID_type {
1184   BX_INVEPT_INVVPID_INDIVIDUAL_ADDRESS_INVALIDATION = 0,
1185   BX_INVEPT_INVVPID_SINGLE_CONTEXT_INVALIDATION,
1186   BX_INVEPT_INVVPID_ALL_CONTEXT_INVALIDATION,
1187   BX_INVEPT_INVVPID_SINGLE_CONTEXT_NON_GLOBAL_INVALIDATION
1188 };
1189 
1190 #define VMX_MSR_VMX_EPT_VPID_CAP \
1191    (BX_CPU_THIS_PTR vmx_cap.vmx_ept_vpid_cap_supported_bits)
1192 
1193 #endif
1194 
1195 #endif // _BX_VMX_INTEL_H_
1196