VirtualBox

source: vbox/trunk/src/VBox/VMM/include/HMVMXCommon.h@ 107044

Last change on this file since 107044 was 106061, checked in by vboxsync, 2 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.9 KB
Line 
1/* $Id: HMVMXCommon.h 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * HM/VMX - Internal header file for sharing common bits between the
4 * VMX template code (which is also used with NEM on darwin) and HM.
5 */
6
7/*
8 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
9 *
10 * This file is part of VirtualBox base platform packages, as
11 * available from https://www.virtualbox.org.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation, in version 3 of the
16 * License.
17 *
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <https://www.gnu.org/licenses>.
25 *
26 * SPDX-License-Identifier: GPL-3.0-only
27 */
28
29#ifndef VMM_INCLUDED_SRC_include_HMVMXCommon_h
30#define VMM_INCLUDED_SRC_include_HMVMXCommon_h
31#ifndef RT_WITHOUT_PRAGMA_ONCE
32# pragma once
33#endif
34
35#include <VBox/cdefs.h>
36#include <VBox/types.h>
37
38RT_C_DECLS_BEGIN
39
40
41/** @defgroup grp_hm_int Internal
42 * @ingroup grp_hm
43 * @internal
44 * @{
45 */
46
47/** @name HM_CHANGED_XXX
48 * HM CPU-context changed flags.
49 *
50 * These flags are used to keep track of which registers and state has been
51 * modified since they were imported back into the guest-CPU context.
52 *
53 * @{
54 */
55#define HM_CHANGED_HOST_CONTEXT UINT64_C(0x0000000000000001)
56#define HM_CHANGED_GUEST_RIP UINT64_C(0x0000000000000004)
57#define HM_CHANGED_GUEST_RFLAGS UINT64_C(0x0000000000000008)
58
59#define HM_CHANGED_GUEST_RAX UINT64_C(0x0000000000000010)
60#define HM_CHANGED_GUEST_RCX UINT64_C(0x0000000000000020)
61#define HM_CHANGED_GUEST_RDX UINT64_C(0x0000000000000040)
62#define HM_CHANGED_GUEST_RBX UINT64_C(0x0000000000000080)
63#define HM_CHANGED_GUEST_RSP UINT64_C(0x0000000000000100)
64#define HM_CHANGED_GUEST_RBP UINT64_C(0x0000000000000200)
65#define HM_CHANGED_GUEST_RSI UINT64_C(0x0000000000000400)
66#define HM_CHANGED_GUEST_RDI UINT64_C(0x0000000000000800)
67#define HM_CHANGED_GUEST_R8_R15 UINT64_C(0x0000000000001000)
68#define HM_CHANGED_GUEST_GPRS_MASK UINT64_C(0x0000000000001ff0)
69
70#define HM_CHANGED_GUEST_ES UINT64_C(0x0000000000002000)
71#define HM_CHANGED_GUEST_CS UINT64_C(0x0000000000004000)
72#define HM_CHANGED_GUEST_SS UINT64_C(0x0000000000008000)
73#define HM_CHANGED_GUEST_DS UINT64_C(0x0000000000010000)
74#define HM_CHANGED_GUEST_FS UINT64_C(0x0000000000020000)
75#define HM_CHANGED_GUEST_GS UINT64_C(0x0000000000040000)
76#define HM_CHANGED_GUEST_SREG_MASK UINT64_C(0x000000000007e000)
77
78#define HM_CHANGED_GUEST_GDTR UINT64_C(0x0000000000080000)
79#define HM_CHANGED_GUEST_IDTR UINT64_C(0x0000000000100000)
80#define HM_CHANGED_GUEST_LDTR UINT64_C(0x0000000000200000)
81#define HM_CHANGED_GUEST_TR UINT64_C(0x0000000000400000)
82#define HM_CHANGED_GUEST_TABLE_MASK UINT64_C(0x0000000000780000)
83
84#define HM_CHANGED_GUEST_CR0 UINT64_C(0x0000000000800000)
85#define HM_CHANGED_GUEST_CR2 UINT64_C(0x0000000001000000)
86#define HM_CHANGED_GUEST_CR3 UINT64_C(0x0000000002000000)
87#define HM_CHANGED_GUEST_CR4 UINT64_C(0x0000000004000000)
88#define HM_CHANGED_GUEST_CR_MASK UINT64_C(0x0000000007800000)
89
90#define HM_CHANGED_GUEST_APIC_TPR UINT64_C(0x0000000008000000)
91#define HM_CHANGED_GUEST_EFER_MSR UINT64_C(0x0000000010000000)
92
93#define HM_CHANGED_GUEST_DR0_DR3 UINT64_C(0x0000000020000000)
94#define HM_CHANGED_GUEST_DR6 UINT64_C(0x0000000040000000)
95#define HM_CHANGED_GUEST_DR7 UINT64_C(0x0000000080000000)
96#define HM_CHANGED_GUEST_DR_MASK UINT64_C(0x00000000e0000000)
97
98#define HM_CHANGED_GUEST_X87 UINT64_C(0x0000000100000000)
99#define HM_CHANGED_GUEST_SSE_AVX UINT64_C(0x0000000200000000)
100#define HM_CHANGED_GUEST_OTHER_XSAVE UINT64_C(0x0000000400000000)
101#define HM_CHANGED_GUEST_XCRx UINT64_C(0x0000000800000000)
102
103#define HM_CHANGED_GUEST_KERNEL_GS_BASE UINT64_C(0x0000001000000000)
104#define HM_CHANGED_GUEST_SYSCALL_MSRS UINT64_C(0x0000002000000000)
105#define HM_CHANGED_GUEST_SYSENTER_CS_MSR UINT64_C(0x0000004000000000)
106#define HM_CHANGED_GUEST_SYSENTER_EIP_MSR UINT64_C(0x0000008000000000)
107#define HM_CHANGED_GUEST_SYSENTER_ESP_MSR UINT64_C(0x0000010000000000)
108#define HM_CHANGED_GUEST_SYSENTER_MSR_MASK UINT64_C(0x000001c000000000)
109#define HM_CHANGED_GUEST_TSC_AUX UINT64_C(0x0000020000000000)
110#define HM_CHANGED_GUEST_OTHER_MSRS UINT64_C(0x0000040000000000)
111#define HM_CHANGED_GUEST_ALL_MSRS ( HM_CHANGED_GUEST_EFER \
112 | HM_CHANGED_GUEST_KERNEL_GS_BASE \
113 | HM_CHANGED_GUEST_SYSCALL_MSRS \
114 | HM_CHANGED_GUEST_SYSENTER_MSR_MASK \
115 | HM_CHANGED_GUEST_TSC_AUX \
116 | HM_CHANGED_GUEST_OTHER_MSRS)
117
118#define HM_CHANGED_GUEST_HWVIRT UINT64_C(0x0000080000000000)
119#define HM_CHANGED_GUEST_MASK UINT64_C(0x00000ffffffffffc)
120
121#define HM_CHANGED_KEEPER_STATE_MASK UINT64_C(0xffff000000000000)
122
123#define HM_CHANGED_VMX_XCPT_INTERCEPTS UINT64_C(0x0001000000000000)
124#define HM_CHANGED_VMX_GUEST_AUTO_MSRS UINT64_C(0x0002000000000000)
125#define HM_CHANGED_VMX_GUEST_LAZY_MSRS UINT64_C(0x0004000000000000)
126#define HM_CHANGED_VMX_ENTRY_EXIT_CTLS UINT64_C(0x0008000000000000)
127#define HM_CHANGED_VMX_MASK UINT64_C(0x000f000000000000)
128#define HM_CHANGED_VMX_HOST_GUEST_SHARED_STATE ( HM_CHANGED_GUEST_DR_MASK \
129 | HM_CHANGED_VMX_GUEST_LAZY_MSRS)
130
131#define HM_CHANGED_SVM_XCPT_INTERCEPTS UINT64_C(0x0001000000000000)
132#define HM_CHANGED_SVM_MASK UINT64_C(0x0001000000000000)
133#define HM_CHANGED_SVM_HOST_GUEST_SHARED_STATE HM_CHANGED_GUEST_DR_MASK
134
135#define HM_CHANGED_ALL_GUEST ( HM_CHANGED_GUEST_MASK \
136 | HM_CHANGED_KEEPER_STATE_MASK)
137
138/** Mask of what state might have changed when IEM raised an exception.
139 * This is a based on IEM_CPUMCTX_EXTRN_XCPT_MASK. */
140#define HM_CHANGED_RAISED_XCPT_MASK ( HM_CHANGED_GUEST_GPRS_MASK \
141 | HM_CHANGED_GUEST_RIP \
142 | HM_CHANGED_GUEST_RFLAGS \
143 | HM_CHANGED_GUEST_SS \
144 | HM_CHANGED_GUEST_CS \
145 | HM_CHANGED_GUEST_CR0 \
146 | HM_CHANGED_GUEST_CR3 \
147 | HM_CHANGED_GUEST_CR4 \
148 | HM_CHANGED_GUEST_APIC_TPR \
149 | HM_CHANGED_GUEST_EFER_MSR \
150 | HM_CHANGED_GUEST_DR7 \
151 | HM_CHANGED_GUEST_CR2 \
152 | HM_CHANGED_GUEST_SREG_MASK \
153 | HM_CHANGED_GUEST_TABLE_MASK)
154
155#ifdef VBOX_WITH_NESTED_HWVIRT_SVM
156/** Mask of what state might have changed when \#VMEXIT is emulated. */
157# define HM_CHANGED_SVM_VMEXIT_MASK ( HM_CHANGED_GUEST_RSP \
158 | HM_CHANGED_GUEST_RAX \
159 | HM_CHANGED_GUEST_RIP \
160 | HM_CHANGED_GUEST_RFLAGS \
161 | HM_CHANGED_GUEST_CS \
162 | HM_CHANGED_GUEST_SS \
163 | HM_CHANGED_GUEST_DS \
164 | HM_CHANGED_GUEST_ES \
165 | HM_CHANGED_GUEST_GDTR \
166 | HM_CHANGED_GUEST_IDTR \
167 | HM_CHANGED_GUEST_CR_MASK \
168 | HM_CHANGED_GUEST_EFER_MSR \
169 | HM_CHANGED_GUEST_DR6 \
170 | HM_CHANGED_GUEST_DR7 \
171 | HM_CHANGED_GUEST_OTHER_MSRS \
172 | HM_CHANGED_GUEST_HWVIRT \
173 | HM_CHANGED_SVM_MASK \
174 | HM_CHANGED_GUEST_APIC_TPR)
175
176/** Mask of what state might have changed when VMRUN is emulated. */
177# define HM_CHANGED_SVM_VMRUN_MASK HM_CHANGED_SVM_VMEXIT_MASK
178#endif
179#ifdef VBOX_WITH_NESTED_HWVIRT_VMX
180/** Mask of what state might have changed when VM-exit is emulated.
181 *
182 * This is currently unused, but keeping it here in case we can get away a bit more
183 * fine-grained state handling.
184 *
185 * @note Update IEM_CPUMCTX_EXTRN_VMX_VMEXIT_MASK when this changes. */
186# define HM_CHANGED_VMX_VMEXIT_MASK ( HM_CHANGED_GUEST_CR0 | HM_CHANGED_GUEST_CR3 | HM_CHANGED_GUEST_CR4 \
187 | HM_CHANGED_GUEST_DR7 | HM_CHANGED_GUEST_DR6 \
188 | HM_CHANGED_GUEST_EFER_MSR \
189 | HM_CHANGED_GUEST_SYSENTER_MSR_MASK \
190 | HM_CHANGED_GUEST_OTHER_MSRS /* for PAT MSR */ \
191 | HM_CHANGED_GUEST_RIP | HM_CHANGED_GUEST_RSP | HM_CHANGED_GUEST_RFLAGS \
192 | HM_CHANGED_GUEST_SREG_MASK \
193 | HM_CHANGED_GUEST_TR \
194 | HM_CHANGED_GUEST_LDTR | HM_CHANGED_GUEST_GDTR | HM_CHANGED_GUEST_IDTR \
195 | HM_CHANGED_GUEST_HWVIRT )
196#endif
197/** @} */
198
199
200/** Maximum number of exit reason statistics counters. */
201#define MAX_EXITREASON_STAT 0x100
202#define MASK_EXITREASON_STAT 0xff
203#define MASK_INJECT_IRQ_STAT 0xff
204
205
206/**
207 * HM event.
208 *
209 * VT-x and AMD-V common event injection structure.
210 */
211typedef struct HMEVENT
212{
213 /** Whether the event is pending. */
214 uint32_t fPending;
215 /** The error-code associated with the event. */
216 uint32_t u32ErrCode;
217 /** The length of the instruction in bytes (only relevant for software
218 * interrupts or software exceptions). */
219 uint32_t cbInstr;
220 /** Alignment. */
221 uint32_t u32Padding;
222 /** The encoded event (VM-entry interruption-information for VT-x or EVENTINJ
223 * for SVM). */
224 uint64_t u64IntInfo;
225 /** Guest virtual address if this is a page-fault event. */
226 RTGCUINTPTR GCPtrFaultAddress;
227} HMEVENT;
228/** Pointer to a HMEVENT struct. */
229typedef HMEVENT *PHMEVENT;
230/** Pointer to a const HMEVENT struct. */
231typedef const HMEVENT *PCHMEVENT;
232AssertCompileSizeAlignment(HMEVENT, 8);
233
234/** Initializer for a HMEVENT structure with */
235#define HMEVENT_INIT_ONLY_INT_INFO(a_uIntInfo) { 0, 0, 0, 0, (a_uIntInfo), 0 }
236
237/**
238 * VMX VMCS information, shared.
239 *
240 * This structure provides information maintained for and during the executing of a
241 * guest (or nested-guest) VMCS (VM control structure) using hardware-assisted VMX.
242 *
243 * Note! The members here are ordered and aligned based on estimated frequency of
244 * usage and grouped to fit within a cache line in hot code paths. Even subtle
245 * changes here have a noticeable effect in the bootsector benchmarks. Modify with
246 * care.
247 */
248typedef struct VMXVMCSINFOSHARED
249{
250 /** @name Real-mode emulation state.
251 * @{ */
252 /** Set if guest was executing in real mode (extra checks). */
253 bool fWasInRealMode;
254 /** Padding. */
255 bool afPadding0[7];
256 struct
257 {
258 X86DESCATTR AttrCS;
259 X86DESCATTR AttrDS;
260 X86DESCATTR AttrES;
261 X86DESCATTR AttrFS;
262 X86DESCATTR AttrGS;
263 X86DESCATTR AttrSS;
264 X86EFLAGS Eflags;
265 bool fRealOnV86Active;
266 bool afPadding1[3];
267 } RealMode;
268 /** @} */
269
270 /** @name LBR MSR data.
271 * @{ */
272 /** List of LastBranch-From-IP MSRs. */
273 uint64_t au64LbrFromIpMsr[32];
274 /** List of LastBranch-To-IP MSRs. */
275 uint64_t au64LbrToIpMsr[32];
276 /** List of LastBranch-Info MSRs. */
277 uint64_t au64LbrInfoMsr[32];
278 /** The MSR containing the index to the most recent branch record. */
279 uint64_t u64LbrTosMsr;
280 /** The MSR containing the last event record from IP value. */
281 uint64_t u64LerFromIpMsr;
282 /** The MSR containing the last event record to IP value. */
283 uint64_t u64LerToIpMsr;
284 /** @} */
285} VMXVMCSINFOSHARED;
286/** Pointer to a VMXVMCSINFOSHARED struct. */
287typedef VMXVMCSINFOSHARED *PVMXVMCSINFOSHARED;
288/** Pointer to a const VMXVMCSINFOSHARED struct. */
289typedef const VMXVMCSINFOSHARED *PCVMXVMCSINFOSHARED;
290AssertCompileSizeAlignment(VMXVMCSINFOSHARED, 8);
291
292
293/**
294 * VMX VMCS information, ring-0 only.
295 *
296 * This structure provides information maintained for and during the executing of a
297 * guest (or nested-guest) VMCS (VM control structure) using hardware-assisted VMX.
298 *
299 * Note! The members here are ordered and aligned based on estimated frequency of
300 * usage and grouped to fit within a cache line in hot code paths. Even subtle
301 * changes here have a noticeable effect in the bootsector benchmarks. Modify with
302 * care.
303 */
304typedef struct VMXVMCSINFO
305{
306 /** Pointer to the bits we share with ring-3. */
307 R3R0PTRTYPE(PVMXVMCSINFOSHARED) pShared;
308
309 /** @name Auxiliary information.
310 * @{ */
311 /** Host-physical address of the EPTP. */
312 RTHCPHYS HCPhysEPTP;
313 /** The VMCS launch state, see VMX_V_VMCS_LAUNCH_STATE_XXX. */
314 uint32_t fVmcsState;
315 /** The VMCS launch state of the shadow VMCS, see VMX_V_VMCS_LAUNCH_STATE_XXX. */
316 uint32_t fShadowVmcsState;
317 /** The host CPU for which its state has been exported to this VMCS. */
318 RTCPUID idHostCpuState;
319 /** The host CPU on which we last executed this VMCS. */
320 RTCPUID idHostCpuExec;
321 /** Number of guest MSRs in the VM-entry MSR-load area. */
322 uint32_t cEntryMsrLoad;
323 /** Number of guest MSRs in the VM-exit MSR-store area. */
324 uint32_t cExitMsrStore;
325 /** Number of host MSRs in the VM-exit MSR-load area. */
326 uint32_t cExitMsrLoad;
327 /** @} */
328
329 /** @name Cache of execution related VMCS fields.
330 * @{ */
331 /** Pin-based VM-execution controls. */
332 uint32_t u32PinCtls;
333 /** Processor-based VM-execution controls. */
334 uint32_t u32ProcCtls;
335 /** Secondary processor-based VM-execution controls. */
336 uint32_t u32ProcCtls2;
337 /** Tertiary processor-based VM-execution controls. */
338 uint64_t u64ProcCtls3;
339 /** VM-entry controls. */
340 uint32_t u32EntryCtls;
341 /** VM-exit controls. */
342 uint32_t u32ExitCtls;
343 /** Exception bitmap. */
344 uint32_t u32XcptBitmap;
345 /** Page-fault exception error-code mask. */
346 uint32_t u32XcptPFMask;
347 /** Page-fault exception error-code match. */
348 uint32_t u32XcptPFMatch;
349 /** Padding. */
350 uint32_t u32Alignment0;
351 /** TSC offset. */
352 uint64_t u64TscOffset;
353 /** VMCS link pointer. */
354 uint64_t u64VmcsLinkPtr;
355 /** CR0 guest/host mask. */
356 uint64_t u64Cr0Mask;
357 /** CR4 guest/host mask. */
358 uint64_t u64Cr4Mask;
359#ifndef IN_NEM_DARWIN
360 /** Current VMX_VMCS_HOST_RIP value (only used in HMR0A.asm). */
361 uint64_t uHostRip;
362 /** Current VMX_VMCS_HOST_RSP value (only used in HMR0A.asm). */
363 uint64_t uHostRsp;
364#endif
365 /** @} */
366
367 /** @name Host-virtual address of VMCS and related data structures.
368 * @{ */
369 /** The VMCS. */
370 R3R0PTRTYPE(void *) pvVmcs;
371 /** The shadow VMCS. */
372 R3R0PTRTYPE(void *) pvShadowVmcs;
373 /** The virtual-APIC page. */
374 R3R0PTRTYPE(uint8_t *) pbVirtApic;
375 /** The MSR bitmap. */
376 R3R0PTRTYPE(void *) pvMsrBitmap;
377 /** The VM-entry MSR-load area. */
378 R3R0PTRTYPE(void *) pvGuestMsrLoad;
379 /** The VM-exit MSR-store area. */
380 R3R0PTRTYPE(void *) pvGuestMsrStore;
381 /** The VM-exit MSR-load area. */
382 R3R0PTRTYPE(void *) pvHostMsrLoad;
383 /** @} */
384
385#ifndef IN_NEM_DARWIN
386 /** @name Host-physical address of VMCS and related data structures.
387 * @{ */
388 /** The VMCS. */
389 RTHCPHYS HCPhysVmcs;
390 /** The shadow VMCS. */
391 RTHCPHYS HCPhysShadowVmcs;
392 /** The virtual APIC page. */
393 RTHCPHYS HCPhysVirtApic;
394 /** The MSR bitmap. */
395 RTHCPHYS HCPhysMsrBitmap;
396 /** The VM-entry MSR-load area. */
397 RTHCPHYS HCPhysGuestMsrLoad;
398 /** The VM-exit MSR-store area. */
399 RTHCPHYS HCPhysGuestMsrStore;
400 /** The VM-exit MSR-load area. */
401 RTHCPHYS HCPhysHostMsrLoad;
402 /** @} */
403
404 /** @name R0-memory objects address for VMCS and related data structures.
405 * @{ */
406 /** R0-memory object for VMCS and related data structures. */
407 RTR0MEMOBJ hMemObj;
408 /** @} */
409#endif
410} VMXVMCSINFO;
411/** Pointer to a VMXVMCSINFOR0 struct. */
412typedef VMXVMCSINFO *PVMXVMCSINFO;
413/** Pointer to a const VMXVMCSINFO struct. */
414typedef const VMXVMCSINFO *PCVMXVMCSINFO;
415AssertCompileSizeAlignment(VMXVMCSINFO, 8);
416AssertCompileMemberAlignment(VMXVMCSINFO, u32PinCtls, 4);
417AssertCompileMemberAlignment(VMXVMCSINFO, u64VmcsLinkPtr, 8);
418AssertCompileMemberAlignment(VMXVMCSINFO, pvVmcs, 8);
419AssertCompileMemberAlignment(VMXVMCSINFO, pvShadowVmcs, 8);
420AssertCompileMemberAlignment(VMXVMCSINFO, pbVirtApic, 8);
421AssertCompileMemberAlignment(VMXVMCSINFO, pvMsrBitmap, 8);
422AssertCompileMemberAlignment(VMXVMCSINFO, pvGuestMsrLoad, 8);
423AssertCompileMemberAlignment(VMXVMCSINFO, pvGuestMsrStore, 8);
424AssertCompileMemberAlignment(VMXVMCSINFO, pvHostMsrLoad, 8);
425#ifndef IN_NEM_DARWIN
426AssertCompileMemberAlignment(VMXVMCSINFO, HCPhysVmcs, 8);
427AssertCompileMemberAlignment(VMXVMCSINFO, hMemObj, 8);
428#endif
429
430/** @} */
431
432RT_C_DECLS_END
433
434#endif /* !VMM_INCLUDED_SRC_include_HMVMXCommon_h */
435
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