VirtualBox

source: vbox/trunk/include/VBox/vmm/cpum.h@ 74102

Last change on this file since 74102 was 74102, checked in by vboxsync, 6 years ago

VMM/CPUM: Naming nit.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 86.5 KB
Line 
1/** @file
2 * CPUM - CPU Monitor(/ Manager).
3 */
4
5/*
6 * Copyright (C) 2006-2017 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_cpum_h
27#define ___VBox_vmm_cpum_h
28
29#include <iprt/x86.h>
30#include <VBox/types.h>
31#include <VBox/vmm/cpumctx.h>
32#include <VBox/vmm/stam.h>
33#include <VBox/vmm/vmapi.h>
34
35RT_C_DECLS_BEGIN
36
37/** @defgroup grp_cpum The CPU Monitor / Manager API
38 * @ingroup grp_vmm
39 * @{
40 */
41
42/**
43 * CPUID feature to set or clear.
44 */
45typedef enum CPUMCPUIDFEATURE
46{
47 CPUMCPUIDFEATURE_INVALID = 0,
48 /** The APIC feature bit. (Std+Ext)
49 * Note! There is a per-cpu flag for masking this CPUID feature bit when the
50 * APICBASE.ENABLED bit is zero. So, this feature is only set/cleared
51 * at VM construction time like all the others. This didn't used to be
52 * that way, this is new with 5.1. */
53 CPUMCPUIDFEATURE_APIC,
54 /** The sysenter/sysexit feature bit. (Std) */
55 CPUMCPUIDFEATURE_SEP,
56 /** The SYSCALL/SYSEXIT feature bit (64 bits mode only for Intel CPUs). (Ext) */
57 CPUMCPUIDFEATURE_SYSCALL,
58 /** The PAE feature bit. (Std+Ext) */
59 CPUMCPUIDFEATURE_PAE,
60 /** The NX feature bit. (Ext) */
61 CPUMCPUIDFEATURE_NX,
62 /** The LAHF/SAHF feature bit (64 bits mode only). (Ext) */
63 CPUMCPUIDFEATURE_LAHF,
64 /** The LONG MODE feature bit. (Ext) */
65 CPUMCPUIDFEATURE_LONG_MODE,
66 /** The PAT feature bit. (Std+Ext) */
67 CPUMCPUIDFEATURE_PAT,
68 /** The x2APIC feature bit. (Std) */
69 CPUMCPUIDFEATURE_X2APIC,
70 /** The RDTSCP feature bit. (Ext) */
71 CPUMCPUIDFEATURE_RDTSCP,
72 /** The Hypervisor Present bit. (Std) */
73 CPUMCPUIDFEATURE_HVP,
74 /** The MWait Extensions bits (Std) */
75 CPUMCPUIDFEATURE_MWAIT_EXTS,
76 /** The speculation control feature bits. (StExt) */
77 CPUMCPUIDFEATURE_SPEC_CTRL,
78 /** 32bit hackishness. */
79 CPUMCPUIDFEATURE_32BIT_HACK = 0x7fffffff
80} CPUMCPUIDFEATURE;
81
82/**
83 * CPU Vendor.
84 */
85typedef enum CPUMCPUVENDOR
86{
87 CPUMCPUVENDOR_INVALID = 0,
88 CPUMCPUVENDOR_INTEL,
89 CPUMCPUVENDOR_AMD,
90 CPUMCPUVENDOR_VIA,
91 CPUMCPUVENDOR_CYRIX,
92 CPUMCPUVENDOR_UNKNOWN,
93 /** 32bit hackishness. */
94 CPUMCPUVENDOR_32BIT_HACK = 0x7fffffff
95} CPUMCPUVENDOR;
96
97
98/**
99 * X86 and AMD64 CPU microarchitectures and in processor generations.
100 *
101 * @remarks The separation here is sometimes a little bit too finely grained,
102 * and the differences is more like processor generation than micro
103 * arch. This can be useful, so we'll provide functions for getting at
104 * more coarse grained info.
105 */
106typedef enum CPUMMICROARCH
107{
108 kCpumMicroarch_Invalid = 0,
109
110 kCpumMicroarch_Intel_First,
111
112 kCpumMicroarch_Intel_8086 = kCpumMicroarch_Intel_First,
113 kCpumMicroarch_Intel_80186,
114 kCpumMicroarch_Intel_80286,
115 kCpumMicroarch_Intel_80386,
116 kCpumMicroarch_Intel_80486,
117 kCpumMicroarch_Intel_P5,
118
119 kCpumMicroarch_Intel_P6_Core_Atom_First,
120 kCpumMicroarch_Intel_P6 = kCpumMicroarch_Intel_P6_Core_Atom_First,
121 kCpumMicroarch_Intel_P6_II,
122 kCpumMicroarch_Intel_P6_III,
123
124 kCpumMicroarch_Intel_P6_M_Banias,
125 kCpumMicroarch_Intel_P6_M_Dothan,
126 kCpumMicroarch_Intel_Core_Yonah, /**< Core, also known as Enhanced Pentium M. */
127
128 kCpumMicroarch_Intel_Core2_First,
129 kCpumMicroarch_Intel_Core2_Merom = kCpumMicroarch_Intel_Core2_First, /**< 65nm, Merom/Conroe/Kentsfield/Tigerton */
130 kCpumMicroarch_Intel_Core2_Penryn, /**< 45nm, Penryn/Wolfdale/Yorkfield/Harpertown */
131 kCpumMicroarch_Intel_Core2_End,
132
133 kCpumMicroarch_Intel_Core7_First,
134 kCpumMicroarch_Intel_Core7_Nehalem = kCpumMicroarch_Intel_Core7_First,
135 kCpumMicroarch_Intel_Core7_Westmere,
136 kCpumMicroarch_Intel_Core7_SandyBridge,
137 kCpumMicroarch_Intel_Core7_IvyBridge,
138 kCpumMicroarch_Intel_Core7_Haswell,
139 kCpumMicroarch_Intel_Core7_Broadwell,
140 kCpumMicroarch_Intel_Core7_Skylake,
141 kCpumMicroarch_Intel_Core7_KabyLake,
142 kCpumMicroarch_Intel_Core7_CoffeeLake,
143 kCpumMicroarch_Intel_Core7_CannonLake,
144 kCpumMicroarch_Intel_Core7_IceLake,
145 kCpumMicroarch_Intel_Core7_TigerLake,
146 kCpumMicroarch_Intel_Core7_End,
147
148 kCpumMicroarch_Intel_Atom_First,
149 kCpumMicroarch_Intel_Atom_Bonnell = kCpumMicroarch_Intel_Atom_First,
150 kCpumMicroarch_Intel_Atom_Lincroft, /**< Second generation bonnell (44nm). */
151 kCpumMicroarch_Intel_Atom_Saltwell, /**< 32nm shrink of Bonnell. */
152 kCpumMicroarch_Intel_Atom_Silvermont, /**< 22nm */
153 kCpumMicroarch_Intel_Atom_Airmount, /**< 14nm */
154 kCpumMicroarch_Intel_Atom_Goldmont, /**< 14nm */
155 kCpumMicroarch_Intel_Atom_GoldmontPlus, /**< 14nm */
156 kCpumMicroarch_Intel_Atom_Unknown,
157 kCpumMicroarch_Intel_Atom_End,
158
159
160 kCpumMicroarch_Intel_Phi_First,
161 kCpumMicroarch_Intel_Phi_KnightsFerry = kCpumMicroarch_Intel_Phi_First,
162 kCpumMicroarch_Intel_Phi_KnightsCorner,
163 kCpumMicroarch_Intel_Phi_KnightsLanding,
164 kCpumMicroarch_Intel_Phi_KnightsHill,
165 kCpumMicroarch_Intel_Phi_KnightsMill,
166 kCpumMicroarch_Intel_Phi_End,
167
168 kCpumMicroarch_Intel_P6_Core_Atom_End,
169
170 kCpumMicroarch_Intel_NB_First,
171 kCpumMicroarch_Intel_NB_Willamette = kCpumMicroarch_Intel_NB_First, /**< 180nm */
172 kCpumMicroarch_Intel_NB_Northwood, /**< 130nm */
173 kCpumMicroarch_Intel_NB_Prescott, /**< 90nm */
174 kCpumMicroarch_Intel_NB_Prescott2M, /**< 90nm */
175 kCpumMicroarch_Intel_NB_CedarMill, /**< 65nm */
176 kCpumMicroarch_Intel_NB_Gallatin, /**< 90nm Xeon, Pentium 4 Extreme Edition ("Emergency Edition"). */
177 kCpumMicroarch_Intel_NB_Unknown,
178 kCpumMicroarch_Intel_NB_End,
179
180 kCpumMicroarch_Intel_Unknown,
181 kCpumMicroarch_Intel_End,
182
183 kCpumMicroarch_AMD_First,
184 kCpumMicroarch_AMD_Am286 = kCpumMicroarch_AMD_First,
185 kCpumMicroarch_AMD_Am386,
186 kCpumMicroarch_AMD_Am486,
187 kCpumMicroarch_AMD_Am486Enh, /**< Covers Am5x86 as well. */
188 kCpumMicroarch_AMD_K5,
189 kCpumMicroarch_AMD_K6,
190
191 kCpumMicroarch_AMD_K7_First,
192 kCpumMicroarch_AMD_K7_Palomino = kCpumMicroarch_AMD_K7_First,
193 kCpumMicroarch_AMD_K7_Spitfire,
194 kCpumMicroarch_AMD_K7_Thunderbird,
195 kCpumMicroarch_AMD_K7_Morgan,
196 kCpumMicroarch_AMD_K7_Thoroughbred,
197 kCpumMicroarch_AMD_K7_Barton,
198 kCpumMicroarch_AMD_K7_Unknown,
199 kCpumMicroarch_AMD_K7_End,
200
201 kCpumMicroarch_AMD_K8_First,
202 kCpumMicroarch_AMD_K8_130nm = kCpumMicroarch_AMD_K8_First, /**< 130nm Clawhammer, Sledgehammer, Newcastle, Paris, Odessa, Dublin */
203 kCpumMicroarch_AMD_K8_90nm, /**< 90nm shrink */
204 kCpumMicroarch_AMD_K8_90nm_DualCore, /**< 90nm with two cores. */
205 kCpumMicroarch_AMD_K8_90nm_AMDV, /**< 90nm with AMD-V (usually) and two cores (usually). */
206 kCpumMicroarch_AMD_K8_65nm, /**< 65nm shrink. */
207 kCpumMicroarch_AMD_K8_End,
208
209 kCpumMicroarch_AMD_K10,
210 kCpumMicroarch_AMD_K10_Lion,
211 kCpumMicroarch_AMD_K10_Llano,
212 kCpumMicroarch_AMD_Bobcat,
213 kCpumMicroarch_AMD_Jaguar,
214
215 kCpumMicroarch_AMD_15h_First,
216 kCpumMicroarch_AMD_15h_Bulldozer = kCpumMicroarch_AMD_15h_First,
217 kCpumMicroarch_AMD_15h_Piledriver,
218 kCpumMicroarch_AMD_15h_Steamroller, /**< Yet to be released, might have different family. */
219 kCpumMicroarch_AMD_15h_Excavator, /**< Yet to be released, might have different family. */
220 kCpumMicroarch_AMD_15h_Unknown,
221 kCpumMicroarch_AMD_15h_End,
222
223 kCpumMicroarch_AMD_16h_First,
224 kCpumMicroarch_AMD_16h_End,
225
226 kCpumMicroarch_AMD_Zen_First,
227 kCpumMicroarch_AMD_Zen_Ryzen = kCpumMicroarch_AMD_Zen_First,
228 kCpumMicroarch_AMD_Zen_End,
229
230 kCpumMicroarch_AMD_Unknown,
231 kCpumMicroarch_AMD_End,
232
233 kCpumMicroarch_VIA_First,
234 kCpumMicroarch_Centaur_C6 = kCpumMicroarch_VIA_First,
235 kCpumMicroarch_Centaur_C2,
236 kCpumMicroarch_Centaur_C3,
237 kCpumMicroarch_VIA_C3_M2,
238 kCpumMicroarch_VIA_C3_C5A, /**< 180nm Samuel - Cyrix III, C3, 1GigaPro. */
239 kCpumMicroarch_VIA_C3_C5B, /**< 150nm Samuel 2 - Cyrix III, C3, 1GigaPro, Eden ESP, XP 2000+. */
240 kCpumMicroarch_VIA_C3_C5C, /**< 130nm Ezra - C3, Eden ESP. */
241 kCpumMicroarch_VIA_C3_C5N, /**< 130nm Ezra-T - C3. */
242 kCpumMicroarch_VIA_C3_C5XL, /**< 130nm Nehemiah - C3, Eden ESP, Eden-N. */
243 kCpumMicroarch_VIA_C3_C5P, /**< 130nm Nehemiah+ - C3. */
244 kCpumMicroarch_VIA_C7_C5J, /**< 90nm Esther - C7, C7-D, C7-M, Eden, Eden ULV. */
245 kCpumMicroarch_VIA_Isaiah,
246 kCpumMicroarch_VIA_Unknown,
247 kCpumMicroarch_VIA_End,
248
249 kCpumMicroarch_Cyrix_First,
250 kCpumMicroarch_Cyrix_5x86 = kCpumMicroarch_Cyrix_First,
251 kCpumMicroarch_Cyrix_M1,
252 kCpumMicroarch_Cyrix_MediaGX,
253 kCpumMicroarch_Cyrix_MediaGXm,
254 kCpumMicroarch_Cyrix_M2,
255 kCpumMicroarch_Cyrix_Unknown,
256 kCpumMicroarch_Cyrix_End,
257
258 kCpumMicroarch_NEC_First,
259 kCpumMicroarch_NEC_V20 = kCpumMicroarch_NEC_First,
260 kCpumMicroarch_NEC_V30,
261 kCpumMicroarch_NEC_End,
262
263 kCpumMicroarch_Unknown,
264
265 kCpumMicroarch_32BitHack = 0x7fffffff
266} CPUMMICROARCH;
267
268
269/** Predicate macro for catching netburst CPUs. */
270#define CPUMMICROARCH_IS_INTEL_NETBURST(a_enmMicroarch) \
271 ((a_enmMicroarch) >= kCpumMicroarch_Intel_NB_First && (a_enmMicroarch) <= kCpumMicroarch_Intel_NB_End)
272
273/** Predicate macro for catching Core7 CPUs. */
274#define CPUMMICROARCH_IS_INTEL_CORE7(a_enmMicroarch) \
275 ((a_enmMicroarch) >= kCpumMicroarch_Intel_Core7_First && (a_enmMicroarch) <= kCpumMicroarch_Intel_Core7_End)
276
277/** Predicate macro for catching Core 2 CPUs. */
278#define CPUMMICROARCH_IS_INTEL_CORE2(a_enmMicroarch) \
279 ((a_enmMicroarch) >= kCpumMicroarch_Intel_Core2_First && (a_enmMicroarch) <= kCpumMicroarch_Intel_Core2_End)
280
281/** Predicate macro for catching Atom CPUs, Silvermont and upwards. */
282#define CPUMMICROARCH_IS_INTEL_SILVERMONT_PLUS(a_enmMicroarch) \
283 ((a_enmMicroarch) >= kCpumMicroarch_Intel_Atom_Silvermont && (a_enmMicroarch) <= kCpumMicroarch_Intel_Atom_End)
284
285/** Predicate macro for catching AMD Family OFh CPUs (aka K8). */
286#define CPUMMICROARCH_IS_AMD_FAM_0FH(a_enmMicroarch) \
287 ((a_enmMicroarch) >= kCpumMicroarch_AMD_K8_First && (a_enmMicroarch) <= kCpumMicroarch_AMD_K8_End)
288
289/** Predicate macro for catching AMD Family 10H CPUs (aka K10). */
290#define CPUMMICROARCH_IS_AMD_FAM_10H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_K10)
291
292/** Predicate macro for catching AMD Family 11H CPUs (aka Lion). */
293#define CPUMMICROARCH_IS_AMD_FAM_11H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_K10_Lion)
294
295/** Predicate macro for catching AMD Family 12H CPUs (aka Llano). */
296#define CPUMMICROARCH_IS_AMD_FAM_12H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_K10_Llano)
297
298/** Predicate macro for catching AMD Family 14H CPUs (aka Bobcat). */
299#define CPUMMICROARCH_IS_AMD_FAM_14H(a_enmMicroarch) ((a_enmMicroarch) == kCpumMicroarch_AMD_Bobcat)
300
301/** Predicate macro for catching AMD Family 15H CPUs (bulldozer and it's
302 * decendants). */
303#define CPUMMICROARCH_IS_AMD_FAM_15H(a_enmMicroarch) \
304 ((a_enmMicroarch) >= kCpumMicroarch_AMD_15h_First && (a_enmMicroarch) <= kCpumMicroarch_AMD_15h_End)
305
306/** Predicate macro for catching AMD Family 16H CPUs. */
307#define CPUMMICROARCH_IS_AMD_FAM_16H(a_enmMicroarch) \
308 ((a_enmMicroarch) >= kCpumMicroarch_AMD_16h_First && (a_enmMicroarch) <= kCpumMicroarch_AMD_16h_End)
309
310
311
312/**
313 * CPUID leaf.
314 *
315 * @remarks This structure is used by the patch manager and is therefore
316 * more or less set in stone.
317 */
318typedef struct CPUMCPUIDLEAF
319{
320 /** The leaf number. */
321 uint32_t uLeaf;
322 /** The sub-leaf number. */
323 uint32_t uSubLeaf;
324 /** Sub-leaf mask. This is 0 when sub-leaves aren't used. */
325 uint32_t fSubLeafMask;
326
327 /** The EAX value. */
328 uint32_t uEax;
329 /** The EBX value. */
330 uint32_t uEbx;
331 /** The ECX value. */
332 uint32_t uEcx;
333 /** The EDX value. */
334 uint32_t uEdx;
335
336 /** Flags. */
337 uint32_t fFlags;
338} CPUMCPUIDLEAF;
339#ifndef VBOX_FOR_DTRACE_LIB
340AssertCompileSize(CPUMCPUIDLEAF, 32);
341#endif
342/** Pointer to a CPUID leaf. */
343typedef CPUMCPUIDLEAF *PCPUMCPUIDLEAF;
344/** Pointer to a const CPUID leaf. */
345typedef CPUMCPUIDLEAF const *PCCPUMCPUIDLEAF;
346
347/** @name CPUMCPUIDLEAF::fFlags
348 * @{ */
349/** Indicates working intel leaf 0xb where the lower 8 ECX bits are not modified
350 * and EDX containing the extended APIC ID. */
351#define CPUMCPUIDLEAF_F_INTEL_TOPOLOGY_SUBLEAVES RT_BIT_32(0)
352/** The leaf contains an APIC ID that needs changing to that of the current CPU. */
353#define CPUMCPUIDLEAF_F_CONTAINS_APIC_ID RT_BIT_32(1)
354/** The leaf contains an OSXSAVE which needs individual handling on each CPU. */
355#define CPUMCPUIDLEAF_F_CONTAINS_OSXSAVE RT_BIT_32(2)
356/** The leaf contains an APIC feature bit which is tied to APICBASE.EN. */
357#define CPUMCPUIDLEAF_F_CONTAINS_APIC RT_BIT_32(3)
358/** Mask of the valid flags. */
359#define CPUMCPUIDLEAF_F_VALID_MASK UINT32_C(0xf)
360/** @} */
361
362/**
363 * Method used to deal with unknown CPUID leaves.
364 * @remarks Used in patch code.
365 */
366typedef enum CPUMUNKNOWNCPUID
367{
368 /** Invalid zero value. */
369 CPUMUNKNOWNCPUID_INVALID = 0,
370 /** Use given default values (DefCpuId). */
371 CPUMUNKNOWNCPUID_DEFAULTS,
372 /** Return the last standard leaf.
373 * Intel Sandy Bridge has been observed doing this. */
374 CPUMUNKNOWNCPUID_LAST_STD_LEAF,
375 /** Return the last standard leaf, with ecx observed.
376 * Intel Sandy Bridge has been observed doing this. */
377 CPUMUNKNOWNCPUID_LAST_STD_LEAF_WITH_ECX,
378 /** The register values are passed thru unmodified. */
379 CPUMUNKNOWNCPUID_PASSTHRU,
380 /** End of valid value. */
381 CPUMUNKNOWNCPUID_END,
382 /** Ensure 32-bit type. */
383 CPUMUNKNOWNCPUID_32BIT_HACK = 0x7fffffff
384} CPUMUNKNOWNCPUID;
385/** Pointer to unknown CPUID leaf method. */
386typedef CPUMUNKNOWNCPUID *PCPUMUNKNOWNCPUID;
387
388
389/**
390 * MSR read functions.
391 */
392typedef enum CPUMMSRRDFN
393{
394 /** Invalid zero value. */
395 kCpumMsrRdFn_Invalid = 0,
396 /** Return the CPUMMSRRANGE::uValue. */
397 kCpumMsrRdFn_FixedValue,
398 /** Alias to the MSR range starting at the MSR given by
399 * CPUMMSRRANGE::uValue. Must be used in pair with
400 * kCpumMsrWrFn_MsrAlias. */
401 kCpumMsrRdFn_MsrAlias,
402 /** Write only register, GP all read attempts. */
403 kCpumMsrRdFn_WriteOnly,
404
405 kCpumMsrRdFn_Ia32P5McAddr,
406 kCpumMsrRdFn_Ia32P5McType,
407 kCpumMsrRdFn_Ia32TimestampCounter,
408 kCpumMsrRdFn_Ia32PlatformId, /**< Takes real CPU value for reference. */
409 kCpumMsrRdFn_Ia32ApicBase,
410 kCpumMsrRdFn_Ia32FeatureControl,
411 kCpumMsrRdFn_Ia32BiosSignId, /**< Range value returned. */
412 kCpumMsrRdFn_Ia32SmmMonitorCtl,
413 kCpumMsrRdFn_Ia32PmcN,
414 kCpumMsrRdFn_Ia32MonitorFilterLineSize,
415 kCpumMsrRdFn_Ia32MPerf,
416 kCpumMsrRdFn_Ia32APerf,
417 kCpumMsrRdFn_Ia32MtrrCap, /**< Takes real CPU value for reference. */
418 kCpumMsrRdFn_Ia32MtrrPhysBaseN, /**< Takes register number. */
419 kCpumMsrRdFn_Ia32MtrrPhysMaskN, /**< Takes register number. */
420 kCpumMsrRdFn_Ia32MtrrFixed, /**< Takes CPUMCPU offset. */
421 kCpumMsrRdFn_Ia32MtrrDefType,
422 kCpumMsrRdFn_Ia32Pat,
423 kCpumMsrRdFn_Ia32SysEnterCs,
424 kCpumMsrRdFn_Ia32SysEnterEsp,
425 kCpumMsrRdFn_Ia32SysEnterEip,
426 kCpumMsrRdFn_Ia32McgCap,
427 kCpumMsrRdFn_Ia32McgStatus,
428 kCpumMsrRdFn_Ia32McgCtl,
429 kCpumMsrRdFn_Ia32DebugCtl,
430 kCpumMsrRdFn_Ia32SmrrPhysBase,
431 kCpumMsrRdFn_Ia32SmrrPhysMask,
432 kCpumMsrRdFn_Ia32PlatformDcaCap,
433 kCpumMsrRdFn_Ia32CpuDcaCap,
434 kCpumMsrRdFn_Ia32Dca0Cap,
435 kCpumMsrRdFn_Ia32PerfEvtSelN, /**< Range value indicates the register number. */
436 kCpumMsrRdFn_Ia32PerfStatus, /**< Range value returned. */
437 kCpumMsrRdFn_Ia32PerfCtl, /**< Range value returned. */
438 kCpumMsrRdFn_Ia32FixedCtrN, /**< Takes register number of start of range. */
439 kCpumMsrRdFn_Ia32PerfCapabilities, /**< Takes reference value. */
440 kCpumMsrRdFn_Ia32FixedCtrCtrl,
441 kCpumMsrRdFn_Ia32PerfGlobalStatus, /**< Takes reference value. */
442 kCpumMsrRdFn_Ia32PerfGlobalCtrl,
443 kCpumMsrRdFn_Ia32PerfGlobalOvfCtrl,
444 kCpumMsrRdFn_Ia32PebsEnable,
445 kCpumMsrRdFn_Ia32ClockModulation, /**< Range value returned. */
446 kCpumMsrRdFn_Ia32ThermInterrupt, /**< Range value returned. */
447 kCpumMsrRdFn_Ia32ThermStatus, /**< Range value returned. */
448 kCpumMsrRdFn_Ia32Therm2Ctl, /**< Range value returned. */
449 kCpumMsrRdFn_Ia32MiscEnable, /**< Range value returned. */
450 kCpumMsrRdFn_Ia32McCtlStatusAddrMiscN, /**< Takes bank number. */
451 kCpumMsrRdFn_Ia32McNCtl2, /**< Takes register number of start of range. */
452 kCpumMsrRdFn_Ia32DsArea,
453 kCpumMsrRdFn_Ia32TscDeadline,
454 kCpumMsrRdFn_Ia32X2ApicN,
455 kCpumMsrRdFn_Ia32DebugInterface,
456 kCpumMsrRdFn_Ia32VmxBasic, /**< Takes real value as reference. */
457 kCpumMsrRdFn_Ia32VmxPinbasedCtls, /**< Takes real value as reference. */
458 kCpumMsrRdFn_Ia32VmxProcbasedCtls, /**< Takes real value as reference. */
459 kCpumMsrRdFn_Ia32VmxExitCtls, /**< Takes real value as reference. */
460 kCpumMsrRdFn_Ia32VmxEntryCtls, /**< Takes real value as reference. */
461 kCpumMsrRdFn_Ia32VmxMisc, /**< Takes real value as reference. */
462 kCpumMsrRdFn_Ia32VmxCr0Fixed0, /**< Takes real value as reference. */
463 kCpumMsrRdFn_Ia32VmxCr0Fixed1, /**< Takes real value as reference. */
464 kCpumMsrRdFn_Ia32VmxCr4Fixed0, /**< Takes real value as reference. */
465 kCpumMsrRdFn_Ia32VmxCr4Fixed1, /**< Takes real value as reference. */
466 kCpumMsrRdFn_Ia32VmxVmcsEnum, /**< Takes real value as reference. */
467 kCpumMsrRdFn_Ia32VmxProcBasedCtls2, /**< Takes real value as reference. */
468 kCpumMsrRdFn_Ia32VmxEptVpidCap, /**< Takes real value as reference. */
469 kCpumMsrRdFn_Ia32VmxTruePinbasedCtls, /**< Takes real value as reference. */
470 kCpumMsrRdFn_Ia32VmxTrueProcbasedCtls, /**< Takes real value as reference. */
471 kCpumMsrRdFn_Ia32VmxTrueExitCtls, /**< Takes real value as reference. */
472 kCpumMsrRdFn_Ia32VmxTrueEntryCtls, /**< Takes real value as reference. */
473 kCpumMsrRdFn_Ia32VmxVmFunc, /**< Takes real value as reference. */
474 kCpumMsrRdFn_Ia32SpecCtrl,
475 kCpumMsrRdFn_Ia32ArchCapabilities,
476
477 kCpumMsrRdFn_Amd64Efer,
478 kCpumMsrRdFn_Amd64SyscallTarget,
479 kCpumMsrRdFn_Amd64LongSyscallTarget,
480 kCpumMsrRdFn_Amd64CompSyscallTarget,
481 kCpumMsrRdFn_Amd64SyscallFlagMask,
482 kCpumMsrRdFn_Amd64FsBase,
483 kCpumMsrRdFn_Amd64GsBase,
484 kCpumMsrRdFn_Amd64KernelGsBase,
485 kCpumMsrRdFn_Amd64TscAux,
486
487 kCpumMsrRdFn_IntelEblCrPowerOn,
488 kCpumMsrRdFn_IntelI7CoreThreadCount,
489 kCpumMsrRdFn_IntelP4EbcHardPowerOn,
490 kCpumMsrRdFn_IntelP4EbcSoftPowerOn,
491 kCpumMsrRdFn_IntelP4EbcFrequencyId,
492 kCpumMsrRdFn_IntelP6FsbFrequency, /**< Takes real value as reference. */
493 kCpumMsrRdFn_IntelPlatformInfo,
494 kCpumMsrRdFn_IntelFlexRatio, /**< Takes real value as reference. */
495 kCpumMsrRdFn_IntelPkgCStConfigControl,
496 kCpumMsrRdFn_IntelPmgIoCaptureBase,
497 kCpumMsrRdFn_IntelLastBranchFromToN,
498 kCpumMsrRdFn_IntelLastBranchFromN,
499 kCpumMsrRdFn_IntelLastBranchToN,
500 kCpumMsrRdFn_IntelLastBranchTos,
501 kCpumMsrRdFn_IntelBblCrCtl,
502 kCpumMsrRdFn_IntelBblCrCtl3,
503 kCpumMsrRdFn_IntelI7TemperatureTarget, /**< Range value returned. */
504 kCpumMsrRdFn_IntelI7MsrOffCoreResponseN,/**< Takes register number. */
505 kCpumMsrRdFn_IntelI7MiscPwrMgmt,
506 kCpumMsrRdFn_IntelP6CrN,
507 kCpumMsrRdFn_IntelCpuId1FeatureMaskEcdx,
508 kCpumMsrRdFn_IntelCpuId1FeatureMaskEax,
509 kCpumMsrRdFn_IntelCpuId80000001FeatureMaskEcdx,
510 kCpumMsrRdFn_IntelI7SandyAesNiCtl,
511 kCpumMsrRdFn_IntelI7TurboRatioLimit, /**< Returns range value. */
512 kCpumMsrRdFn_IntelI7LbrSelect,
513 kCpumMsrRdFn_IntelI7SandyErrorControl,
514 kCpumMsrRdFn_IntelI7VirtualLegacyWireCap,/**< Returns range value. */
515 kCpumMsrRdFn_IntelI7PowerCtl,
516 kCpumMsrRdFn_IntelI7SandyPebsNumAlt,
517 kCpumMsrRdFn_IntelI7PebsLdLat,
518 kCpumMsrRdFn_IntelI7PkgCnResidencyN, /**< Takes C-state number. */
519 kCpumMsrRdFn_IntelI7CoreCnResidencyN, /**< Takes C-state number. */
520 kCpumMsrRdFn_IntelI7SandyVrCurrentConfig,/**< Takes real value as reference. */
521 kCpumMsrRdFn_IntelI7SandyVrMiscConfig, /**< Takes real value as reference. */
522 kCpumMsrRdFn_IntelI7SandyRaplPowerUnit, /**< Takes real value as reference. */
523 kCpumMsrRdFn_IntelI7SandyPkgCnIrtlN, /**< Takes real value as reference. */
524 kCpumMsrRdFn_IntelI7SandyPkgC2Residency, /**< Takes real value as reference. */
525 kCpumMsrRdFn_IntelI7RaplPkgPowerLimit, /**< Takes real value as reference. */
526 kCpumMsrRdFn_IntelI7RaplPkgEnergyStatus, /**< Takes real value as reference. */
527 kCpumMsrRdFn_IntelI7RaplPkgPerfStatus, /**< Takes real value as reference. */
528 kCpumMsrRdFn_IntelI7RaplPkgPowerInfo, /**< Takes real value as reference. */
529 kCpumMsrRdFn_IntelI7RaplDramPowerLimit, /**< Takes real value as reference. */
530 kCpumMsrRdFn_IntelI7RaplDramEnergyStatus,/**< Takes real value as reference. */
531 kCpumMsrRdFn_IntelI7RaplDramPerfStatus, /**< Takes real value as reference. */
532 kCpumMsrRdFn_IntelI7RaplDramPowerInfo, /**< Takes real value as reference. */
533 kCpumMsrRdFn_IntelI7RaplPp0PowerLimit, /**< Takes real value as reference. */
534 kCpumMsrRdFn_IntelI7RaplPp0EnergyStatus, /**< Takes real value as reference. */
535 kCpumMsrRdFn_IntelI7RaplPp0Policy, /**< Takes real value as reference. */
536 kCpumMsrRdFn_IntelI7RaplPp0PerfStatus, /**< Takes real value as reference. */
537 kCpumMsrRdFn_IntelI7RaplPp1PowerLimit, /**< Takes real value as reference. */
538 kCpumMsrRdFn_IntelI7RaplPp1EnergyStatus, /**< Takes real value as reference. */
539 kCpumMsrRdFn_IntelI7RaplPp1Policy, /**< Takes real value as reference. */
540 kCpumMsrRdFn_IntelI7IvyConfigTdpNominal, /**< Takes real value as reference. */
541 kCpumMsrRdFn_IntelI7IvyConfigTdpLevel1, /**< Takes real value as reference. */
542 kCpumMsrRdFn_IntelI7IvyConfigTdpLevel2, /**< Takes real value as reference. */
543 kCpumMsrRdFn_IntelI7IvyConfigTdpControl,
544 kCpumMsrRdFn_IntelI7IvyTurboActivationRatio,
545 kCpumMsrRdFn_IntelI7UncPerfGlobalCtrl,
546 kCpumMsrRdFn_IntelI7UncPerfGlobalStatus,
547 kCpumMsrRdFn_IntelI7UncPerfGlobalOvfCtrl,
548 kCpumMsrRdFn_IntelI7UncPerfFixedCtrCtrl,
549 kCpumMsrRdFn_IntelI7UncPerfFixedCtr,
550 kCpumMsrRdFn_IntelI7UncCBoxConfig,
551 kCpumMsrRdFn_IntelI7UncArbPerfCtrN,
552 kCpumMsrRdFn_IntelI7UncArbPerfEvtSelN,
553 kCpumMsrRdFn_IntelI7SmiCount,
554 kCpumMsrRdFn_IntelCore2EmttmCrTablesN, /**< Range value returned. */
555 kCpumMsrRdFn_IntelCore2SmmCStMiscInfo,
556 kCpumMsrRdFn_IntelCore1ExtConfig,
557 kCpumMsrRdFn_IntelCore1DtsCalControl,
558 kCpumMsrRdFn_IntelCore2PeciControl,
559 kCpumMsrRdFn_IntelAtSilvCoreC1Recidency,
560
561 kCpumMsrRdFn_P6LastBranchFromIp,
562 kCpumMsrRdFn_P6LastBranchToIp,
563 kCpumMsrRdFn_P6LastIntFromIp,
564 kCpumMsrRdFn_P6LastIntToIp,
565
566 kCpumMsrRdFn_AmdFam15hTscRate,
567 kCpumMsrRdFn_AmdFam15hLwpCfg,
568 kCpumMsrRdFn_AmdFam15hLwpCbAddr,
569 kCpumMsrRdFn_AmdFam10hMc4MiscN,
570 kCpumMsrRdFn_AmdK8PerfCtlN,
571 kCpumMsrRdFn_AmdK8PerfCtrN,
572 kCpumMsrRdFn_AmdK8SysCfg, /**< Range value returned. */
573 kCpumMsrRdFn_AmdK8HwCr,
574 kCpumMsrRdFn_AmdK8IorrBaseN,
575 kCpumMsrRdFn_AmdK8IorrMaskN,
576 kCpumMsrRdFn_AmdK8TopOfMemN,
577 kCpumMsrRdFn_AmdK8NbCfg1,
578 kCpumMsrRdFn_AmdK8McXcptRedir,
579 kCpumMsrRdFn_AmdK8CpuNameN,
580 kCpumMsrRdFn_AmdK8HwThermalCtrl, /**< Range value returned. */
581 kCpumMsrRdFn_AmdK8SwThermalCtrl,
582 kCpumMsrRdFn_AmdK8FidVidControl, /**< Range value returned. */
583 kCpumMsrRdFn_AmdK8FidVidStatus, /**< Range value returned. */
584 kCpumMsrRdFn_AmdK8McCtlMaskN,
585 kCpumMsrRdFn_AmdK8SmiOnIoTrapN,
586 kCpumMsrRdFn_AmdK8SmiOnIoTrapCtlSts,
587 kCpumMsrRdFn_AmdK8IntPendingMessage,
588 kCpumMsrRdFn_AmdK8SmiTriggerIoCycle,
589 kCpumMsrRdFn_AmdFam10hMmioCfgBaseAddr,
590 kCpumMsrRdFn_AmdFam10hTrapCtlMaybe,
591 kCpumMsrRdFn_AmdFam10hPStateCurLimit, /**< Returns range value. */
592 kCpumMsrRdFn_AmdFam10hPStateControl, /**< Returns range value. */
593 kCpumMsrRdFn_AmdFam10hPStateStatus, /**< Returns range value. */
594 kCpumMsrRdFn_AmdFam10hPStateN, /**< Returns range value. This isn't an register index! */
595 kCpumMsrRdFn_AmdFam10hCofVidControl, /**< Returns range value. */
596 kCpumMsrRdFn_AmdFam10hCofVidStatus, /**< Returns range value. */
597 kCpumMsrRdFn_AmdFam10hCStateIoBaseAddr,
598 kCpumMsrRdFn_AmdFam10hCpuWatchdogTimer,
599 kCpumMsrRdFn_AmdK8SmmBase,
600 kCpumMsrRdFn_AmdK8SmmAddr,
601 kCpumMsrRdFn_AmdK8SmmMask,
602 kCpumMsrRdFn_AmdK8VmCr,
603 kCpumMsrRdFn_AmdK8IgnNe,
604 kCpumMsrRdFn_AmdK8SmmCtl,
605 kCpumMsrRdFn_AmdK8VmHSavePa,
606 kCpumMsrRdFn_AmdFam10hVmLockKey,
607 kCpumMsrRdFn_AmdFam10hSmmLockKey,
608 kCpumMsrRdFn_AmdFam10hLocalSmiStatus,
609 kCpumMsrRdFn_AmdFam10hOsVisWrkIdLength,
610 kCpumMsrRdFn_AmdFam10hOsVisWrkStatus,
611 kCpumMsrRdFn_AmdFam16hL2IPerfCtlN,
612 kCpumMsrRdFn_AmdFam16hL2IPerfCtrN,
613 kCpumMsrRdFn_AmdFam15hNorthbridgePerfCtlN,
614 kCpumMsrRdFn_AmdFam15hNorthbridgePerfCtrN,
615 kCpumMsrRdFn_AmdK7MicrocodeCtl, /**< Returns range value. */
616 kCpumMsrRdFn_AmdK7ClusterIdMaybe, /**< Returns range value. */
617 kCpumMsrRdFn_AmdK8CpuIdCtlStd07hEbax,
618 kCpumMsrRdFn_AmdK8CpuIdCtlStd06hEcx,
619 kCpumMsrRdFn_AmdK8CpuIdCtlStd01hEdcx,
620 kCpumMsrRdFn_AmdK8CpuIdCtlExt01hEdcx,
621 kCpumMsrRdFn_AmdK8PatchLevel, /**< Returns range value. */
622 kCpumMsrRdFn_AmdK7DebugStatusMaybe,
623 kCpumMsrRdFn_AmdK7BHTraceBaseMaybe,
624 kCpumMsrRdFn_AmdK7BHTracePtrMaybe,
625 kCpumMsrRdFn_AmdK7BHTraceLimitMaybe,
626 kCpumMsrRdFn_AmdK7HardwareDebugToolCfgMaybe,
627 kCpumMsrRdFn_AmdK7FastFlushCountMaybe,
628 kCpumMsrRdFn_AmdK7NodeId,
629 kCpumMsrRdFn_AmdK7DrXAddrMaskN, /**< Takes register index. */
630 kCpumMsrRdFn_AmdK7Dr0DataMatchMaybe,
631 kCpumMsrRdFn_AmdK7Dr0DataMaskMaybe,
632 kCpumMsrRdFn_AmdK7LoadStoreCfg,
633 kCpumMsrRdFn_AmdK7InstrCacheCfg,
634 kCpumMsrRdFn_AmdK7DataCacheCfg,
635 kCpumMsrRdFn_AmdK7BusUnitCfg,
636 kCpumMsrRdFn_AmdK7DebugCtl2Maybe,
637 kCpumMsrRdFn_AmdFam15hFpuCfg,
638 kCpumMsrRdFn_AmdFam15hDecoderCfg,
639 kCpumMsrRdFn_AmdFam10hBusUnitCfg2,
640 kCpumMsrRdFn_AmdFam15hCombUnitCfg,
641 kCpumMsrRdFn_AmdFam15hCombUnitCfg2,
642 kCpumMsrRdFn_AmdFam15hCombUnitCfg3,
643 kCpumMsrRdFn_AmdFam15hExecUnitCfg,
644 kCpumMsrRdFn_AmdFam15hLoadStoreCfg2,
645 kCpumMsrRdFn_AmdFam10hIbsFetchCtl,
646 kCpumMsrRdFn_AmdFam10hIbsFetchLinAddr,
647 kCpumMsrRdFn_AmdFam10hIbsFetchPhysAddr,
648 kCpumMsrRdFn_AmdFam10hIbsOpExecCtl,
649 kCpumMsrRdFn_AmdFam10hIbsOpRip,
650 kCpumMsrRdFn_AmdFam10hIbsOpData,
651 kCpumMsrRdFn_AmdFam10hIbsOpData2,
652 kCpumMsrRdFn_AmdFam10hIbsOpData3,
653 kCpumMsrRdFn_AmdFam10hIbsDcLinAddr,
654 kCpumMsrRdFn_AmdFam10hIbsDcPhysAddr,
655 kCpumMsrRdFn_AmdFam10hIbsCtl,
656 kCpumMsrRdFn_AmdFam14hIbsBrTarget,
657
658 kCpumMsrRdFn_Gim,
659
660 /** End of valid MSR read function indexes. */
661 kCpumMsrRdFn_End
662} CPUMMSRRDFN;
663
664/**
665 * MSR write functions.
666 */
667typedef enum CPUMMSRWRFN
668{
669 /** Invalid zero value. */
670 kCpumMsrWrFn_Invalid = 0,
671 /** Writes are ignored, the fWrGpMask is observed though. */
672 kCpumMsrWrFn_IgnoreWrite,
673 /** Writes cause GP(0) to be raised, the fWrGpMask should be UINT64_MAX. */
674 kCpumMsrWrFn_ReadOnly,
675 /** Alias to the MSR range starting at the MSR given by
676 * CPUMMSRRANGE::uValue. Must be used in pair with
677 * kCpumMsrRdFn_MsrAlias. */
678 kCpumMsrWrFn_MsrAlias,
679
680 kCpumMsrWrFn_Ia32P5McAddr,
681 kCpumMsrWrFn_Ia32P5McType,
682 kCpumMsrWrFn_Ia32TimestampCounter,
683 kCpumMsrWrFn_Ia32ApicBase,
684 kCpumMsrWrFn_Ia32FeatureControl,
685 kCpumMsrWrFn_Ia32BiosSignId,
686 kCpumMsrWrFn_Ia32BiosUpdateTrigger,
687 kCpumMsrWrFn_Ia32SmmMonitorCtl,
688 kCpumMsrWrFn_Ia32PmcN,
689 kCpumMsrWrFn_Ia32MonitorFilterLineSize,
690 kCpumMsrWrFn_Ia32MPerf,
691 kCpumMsrWrFn_Ia32APerf,
692 kCpumMsrWrFn_Ia32MtrrPhysBaseN, /**< Takes register number. */
693 kCpumMsrWrFn_Ia32MtrrPhysMaskN, /**< Takes register number. */
694 kCpumMsrWrFn_Ia32MtrrFixed, /**< Takes CPUMCPU offset. */
695 kCpumMsrWrFn_Ia32MtrrDefType,
696 kCpumMsrWrFn_Ia32Pat,
697 kCpumMsrWrFn_Ia32SysEnterCs,
698 kCpumMsrWrFn_Ia32SysEnterEsp,
699 kCpumMsrWrFn_Ia32SysEnterEip,
700 kCpumMsrWrFn_Ia32McgStatus,
701 kCpumMsrWrFn_Ia32McgCtl,
702 kCpumMsrWrFn_Ia32DebugCtl,
703 kCpumMsrWrFn_Ia32SmrrPhysBase,
704 kCpumMsrWrFn_Ia32SmrrPhysMask,
705 kCpumMsrWrFn_Ia32PlatformDcaCap,
706 kCpumMsrWrFn_Ia32Dca0Cap,
707 kCpumMsrWrFn_Ia32PerfEvtSelN, /**< Range value indicates the register number. */
708 kCpumMsrWrFn_Ia32PerfStatus,
709 kCpumMsrWrFn_Ia32PerfCtl,
710 kCpumMsrWrFn_Ia32FixedCtrN, /**< Takes register number of start of range. */
711 kCpumMsrWrFn_Ia32PerfCapabilities,
712 kCpumMsrWrFn_Ia32FixedCtrCtrl,
713 kCpumMsrWrFn_Ia32PerfGlobalStatus,
714 kCpumMsrWrFn_Ia32PerfGlobalCtrl,
715 kCpumMsrWrFn_Ia32PerfGlobalOvfCtrl,
716 kCpumMsrWrFn_Ia32PebsEnable,
717 kCpumMsrWrFn_Ia32ClockModulation,
718 kCpumMsrWrFn_Ia32ThermInterrupt,
719 kCpumMsrWrFn_Ia32ThermStatus,
720 kCpumMsrWrFn_Ia32Therm2Ctl,
721 kCpumMsrWrFn_Ia32MiscEnable,
722 kCpumMsrWrFn_Ia32McCtlStatusAddrMiscN, /**< Takes bank number. */
723 kCpumMsrWrFn_Ia32McNCtl2, /**< Takes register number of start of range. */
724 kCpumMsrWrFn_Ia32DsArea,
725 kCpumMsrWrFn_Ia32TscDeadline,
726 kCpumMsrWrFn_Ia32X2ApicN,
727 kCpumMsrWrFn_Ia32DebugInterface,
728 kCpumMsrWrFn_Ia32SpecCtrl,
729 kCpumMsrWrFn_Ia32PredCmd,
730
731 kCpumMsrWrFn_Amd64Efer,
732 kCpumMsrWrFn_Amd64SyscallTarget,
733 kCpumMsrWrFn_Amd64LongSyscallTarget,
734 kCpumMsrWrFn_Amd64CompSyscallTarget,
735 kCpumMsrWrFn_Amd64SyscallFlagMask,
736 kCpumMsrWrFn_Amd64FsBase,
737 kCpumMsrWrFn_Amd64GsBase,
738 kCpumMsrWrFn_Amd64KernelGsBase,
739 kCpumMsrWrFn_Amd64TscAux,
740 kCpumMsrWrFn_IntelEblCrPowerOn,
741 kCpumMsrWrFn_IntelP4EbcHardPowerOn,
742 kCpumMsrWrFn_IntelP4EbcSoftPowerOn,
743 kCpumMsrWrFn_IntelP4EbcFrequencyId,
744 kCpumMsrWrFn_IntelFlexRatio,
745 kCpumMsrWrFn_IntelPkgCStConfigControl,
746 kCpumMsrWrFn_IntelPmgIoCaptureBase,
747 kCpumMsrWrFn_IntelLastBranchFromToN,
748 kCpumMsrWrFn_IntelLastBranchFromN,
749 kCpumMsrWrFn_IntelLastBranchToN,
750 kCpumMsrWrFn_IntelLastBranchTos,
751 kCpumMsrWrFn_IntelBblCrCtl,
752 kCpumMsrWrFn_IntelBblCrCtl3,
753 kCpumMsrWrFn_IntelI7TemperatureTarget,
754 kCpumMsrWrFn_IntelI7MsrOffCoreResponseN, /**< Takes register number. */
755 kCpumMsrWrFn_IntelI7MiscPwrMgmt,
756 kCpumMsrWrFn_IntelP6CrN,
757 kCpumMsrWrFn_IntelCpuId1FeatureMaskEcdx,
758 kCpumMsrWrFn_IntelCpuId1FeatureMaskEax,
759 kCpumMsrWrFn_IntelCpuId80000001FeatureMaskEcdx,
760 kCpumMsrWrFn_IntelI7SandyAesNiCtl,
761 kCpumMsrWrFn_IntelI7TurboRatioLimit,
762 kCpumMsrWrFn_IntelI7LbrSelect,
763 kCpumMsrWrFn_IntelI7SandyErrorControl,
764 kCpumMsrWrFn_IntelI7PowerCtl,
765 kCpumMsrWrFn_IntelI7SandyPebsNumAlt,
766 kCpumMsrWrFn_IntelI7PebsLdLat,
767 kCpumMsrWrFn_IntelI7SandyVrCurrentConfig,
768 kCpumMsrWrFn_IntelI7SandyVrMiscConfig,
769 kCpumMsrWrFn_IntelI7SandyRaplPowerUnit, /**< R/O but found writable bits on a Silvermont CPU here. */
770 kCpumMsrWrFn_IntelI7SandyPkgCnIrtlN,
771 kCpumMsrWrFn_IntelI7SandyPkgC2Residency, /**< R/O but found writable bits on a Silvermont CPU here. */
772 kCpumMsrWrFn_IntelI7RaplPkgPowerLimit,
773 kCpumMsrWrFn_IntelI7RaplDramPowerLimit,
774 kCpumMsrWrFn_IntelI7RaplPp0PowerLimit,
775 kCpumMsrWrFn_IntelI7RaplPp0Policy,
776 kCpumMsrWrFn_IntelI7RaplPp1PowerLimit,
777 kCpumMsrWrFn_IntelI7RaplPp1Policy,
778 kCpumMsrWrFn_IntelI7IvyConfigTdpControl,
779 kCpumMsrWrFn_IntelI7IvyTurboActivationRatio,
780 kCpumMsrWrFn_IntelI7UncPerfGlobalCtrl,
781 kCpumMsrWrFn_IntelI7UncPerfGlobalStatus,
782 kCpumMsrWrFn_IntelI7UncPerfGlobalOvfCtrl,
783 kCpumMsrWrFn_IntelI7UncPerfFixedCtrCtrl,
784 kCpumMsrWrFn_IntelI7UncPerfFixedCtr,
785 kCpumMsrWrFn_IntelI7UncArbPerfCtrN,
786 kCpumMsrWrFn_IntelI7UncArbPerfEvtSelN,
787 kCpumMsrWrFn_IntelCore2EmttmCrTablesN,
788 kCpumMsrWrFn_IntelCore2SmmCStMiscInfo,
789 kCpumMsrWrFn_IntelCore1ExtConfig,
790 kCpumMsrWrFn_IntelCore1DtsCalControl,
791 kCpumMsrWrFn_IntelCore2PeciControl,
792
793 kCpumMsrWrFn_P6LastIntFromIp,
794 kCpumMsrWrFn_P6LastIntToIp,
795
796 kCpumMsrWrFn_AmdFam15hTscRate,
797 kCpumMsrWrFn_AmdFam15hLwpCfg,
798 kCpumMsrWrFn_AmdFam15hLwpCbAddr,
799 kCpumMsrWrFn_AmdFam10hMc4MiscN,
800 kCpumMsrWrFn_AmdK8PerfCtlN,
801 kCpumMsrWrFn_AmdK8PerfCtrN,
802 kCpumMsrWrFn_AmdK8SysCfg,
803 kCpumMsrWrFn_AmdK8HwCr,
804 kCpumMsrWrFn_AmdK8IorrBaseN,
805 kCpumMsrWrFn_AmdK8IorrMaskN,
806 kCpumMsrWrFn_AmdK8TopOfMemN,
807 kCpumMsrWrFn_AmdK8NbCfg1,
808 kCpumMsrWrFn_AmdK8McXcptRedir,
809 kCpumMsrWrFn_AmdK8CpuNameN,
810 kCpumMsrWrFn_AmdK8HwThermalCtrl,
811 kCpumMsrWrFn_AmdK8SwThermalCtrl,
812 kCpumMsrWrFn_AmdK8FidVidControl,
813 kCpumMsrWrFn_AmdK8McCtlMaskN,
814 kCpumMsrWrFn_AmdK8SmiOnIoTrapN,
815 kCpumMsrWrFn_AmdK8SmiOnIoTrapCtlSts,
816 kCpumMsrWrFn_AmdK8IntPendingMessage,
817 kCpumMsrWrFn_AmdK8SmiTriggerIoCycle,
818 kCpumMsrWrFn_AmdFam10hMmioCfgBaseAddr,
819 kCpumMsrWrFn_AmdFam10hTrapCtlMaybe,
820 kCpumMsrWrFn_AmdFam10hPStateControl,
821 kCpumMsrWrFn_AmdFam10hPStateStatus,
822 kCpumMsrWrFn_AmdFam10hPStateN,
823 kCpumMsrWrFn_AmdFam10hCofVidControl,
824 kCpumMsrWrFn_AmdFam10hCofVidStatus,
825 kCpumMsrWrFn_AmdFam10hCStateIoBaseAddr,
826 kCpumMsrWrFn_AmdFam10hCpuWatchdogTimer,
827 kCpumMsrWrFn_AmdK8SmmBase,
828 kCpumMsrWrFn_AmdK8SmmAddr,
829 kCpumMsrWrFn_AmdK8SmmMask,
830 kCpumMsrWrFn_AmdK8VmCr,
831 kCpumMsrWrFn_AmdK8IgnNe,
832 kCpumMsrWrFn_AmdK8SmmCtl,
833 kCpumMsrWrFn_AmdK8VmHSavePa,
834 kCpumMsrWrFn_AmdFam10hVmLockKey,
835 kCpumMsrWrFn_AmdFam10hSmmLockKey,
836 kCpumMsrWrFn_AmdFam10hLocalSmiStatus,
837 kCpumMsrWrFn_AmdFam10hOsVisWrkIdLength,
838 kCpumMsrWrFn_AmdFam10hOsVisWrkStatus,
839 kCpumMsrWrFn_AmdFam16hL2IPerfCtlN,
840 kCpumMsrWrFn_AmdFam16hL2IPerfCtrN,
841 kCpumMsrWrFn_AmdFam15hNorthbridgePerfCtlN,
842 kCpumMsrWrFn_AmdFam15hNorthbridgePerfCtrN,
843 kCpumMsrWrFn_AmdK7MicrocodeCtl,
844 kCpumMsrWrFn_AmdK7ClusterIdMaybe,
845 kCpumMsrWrFn_AmdK8CpuIdCtlStd07hEbax,
846 kCpumMsrWrFn_AmdK8CpuIdCtlStd06hEcx,
847 kCpumMsrWrFn_AmdK8CpuIdCtlStd01hEdcx,
848 kCpumMsrWrFn_AmdK8CpuIdCtlExt01hEdcx,
849 kCpumMsrWrFn_AmdK8PatchLoader,
850 kCpumMsrWrFn_AmdK7DebugStatusMaybe,
851 kCpumMsrWrFn_AmdK7BHTraceBaseMaybe,
852 kCpumMsrWrFn_AmdK7BHTracePtrMaybe,
853 kCpumMsrWrFn_AmdK7BHTraceLimitMaybe,
854 kCpumMsrWrFn_AmdK7HardwareDebugToolCfgMaybe,
855 kCpumMsrWrFn_AmdK7FastFlushCountMaybe,
856 kCpumMsrWrFn_AmdK7NodeId,
857 kCpumMsrWrFn_AmdK7DrXAddrMaskN, /**< Takes register index. */
858 kCpumMsrWrFn_AmdK7Dr0DataMatchMaybe,
859 kCpumMsrWrFn_AmdK7Dr0DataMaskMaybe,
860 kCpumMsrWrFn_AmdK7LoadStoreCfg,
861 kCpumMsrWrFn_AmdK7InstrCacheCfg,
862 kCpumMsrWrFn_AmdK7DataCacheCfg,
863 kCpumMsrWrFn_AmdK7BusUnitCfg,
864 kCpumMsrWrFn_AmdK7DebugCtl2Maybe,
865 kCpumMsrWrFn_AmdFam15hFpuCfg,
866 kCpumMsrWrFn_AmdFam15hDecoderCfg,
867 kCpumMsrWrFn_AmdFam10hBusUnitCfg2,
868 kCpumMsrWrFn_AmdFam15hCombUnitCfg,
869 kCpumMsrWrFn_AmdFam15hCombUnitCfg2,
870 kCpumMsrWrFn_AmdFam15hCombUnitCfg3,
871 kCpumMsrWrFn_AmdFam15hExecUnitCfg,
872 kCpumMsrWrFn_AmdFam15hLoadStoreCfg2,
873 kCpumMsrWrFn_AmdFam10hIbsFetchCtl,
874 kCpumMsrWrFn_AmdFam10hIbsFetchLinAddr,
875 kCpumMsrWrFn_AmdFam10hIbsFetchPhysAddr,
876 kCpumMsrWrFn_AmdFam10hIbsOpExecCtl,
877 kCpumMsrWrFn_AmdFam10hIbsOpRip,
878 kCpumMsrWrFn_AmdFam10hIbsOpData,
879 kCpumMsrWrFn_AmdFam10hIbsOpData2,
880 kCpumMsrWrFn_AmdFam10hIbsOpData3,
881 kCpumMsrWrFn_AmdFam10hIbsDcLinAddr,
882 kCpumMsrWrFn_AmdFam10hIbsDcPhysAddr,
883 kCpumMsrWrFn_AmdFam10hIbsCtl,
884 kCpumMsrWrFn_AmdFam14hIbsBrTarget,
885
886 kCpumMsrWrFn_Gim,
887
888 /** End of valid MSR write function indexes. */
889 kCpumMsrWrFn_End
890} CPUMMSRWRFN;
891
892/**
893 * MSR range.
894 */
895typedef struct CPUMMSRRANGE
896{
897 /** The first MSR. [0] */
898 uint32_t uFirst;
899 /** The last MSR. [4] */
900 uint32_t uLast;
901 /** The read function (CPUMMSRRDFN). [8] */
902 uint16_t enmRdFn;
903 /** The write function (CPUMMSRWRFN). [10] */
904 uint16_t enmWrFn;
905 /** The offset of the 64-bit MSR value relative to the start of CPUMCPU.
906 * UINT16_MAX if not used by the read and write functions. [12] */
907 uint16_t offCpumCpu;
908 /** Reserved for future hacks. [14] */
909 uint16_t fReserved;
910 /** The init/read value. [16]
911 * When enmRdFn is kCpumMsrRdFn_INIT_VALUE, this is the value returned on RDMSR.
912 * offCpumCpu must be UINT16_MAX in that case, otherwise it must be a valid
913 * offset into CPUM. */
914 uint64_t uValue;
915 /** The bits to ignore when writing. [24] */
916 uint64_t fWrIgnMask;
917 /** The bits that will cause a GP(0) when writing. [32]
918 * This is always checked prior to calling the write function. Using
919 * UINT64_MAX effectively marks the MSR as read-only. */
920 uint64_t fWrGpMask;
921 /** The register name, if applicable. [40] */
922 char szName[56];
923
924#ifdef VBOX_WITH_STATISTICS
925 /** The number of reads. */
926 STAMCOUNTER cReads;
927 /** The number of writes. */
928 STAMCOUNTER cWrites;
929 /** The number of times ignored bits were written. */
930 STAMCOUNTER cIgnoredBits;
931 /** The number of GPs generated. */
932 STAMCOUNTER cGps;
933#endif
934} CPUMMSRRANGE;
935#ifndef VBOX_FOR_DTRACE_LIB
936# ifdef VBOX_WITH_STATISTICS
937AssertCompileSize(CPUMMSRRANGE, 128);
938# else
939AssertCompileSize(CPUMMSRRANGE, 96);
940# endif
941#endif
942/** Pointer to an MSR range. */
943typedef CPUMMSRRANGE *PCPUMMSRRANGE;
944/** Pointer to a const MSR range. */
945typedef CPUMMSRRANGE const *PCCPUMMSRRANGE;
946
947
948/**
949 * CPU features and quirks.
950 * This is mostly exploded CPUID info.
951 */
952typedef struct CPUMFEATURES
953{
954 /** The CPU vendor (CPUMCPUVENDOR). */
955 uint8_t enmCpuVendor;
956 /** The CPU family. */
957 uint8_t uFamily;
958 /** The CPU model. */
959 uint8_t uModel;
960 /** The CPU stepping. */
961 uint8_t uStepping;
962 /** The microarchitecture. */
963#ifndef VBOX_FOR_DTRACE_LIB
964 CPUMMICROARCH enmMicroarch;
965#else
966 uint32_t enmMicroarch;
967#endif
968 /** The maximum physical address with of the CPU. */
969 uint8_t cMaxPhysAddrWidth;
970 /** Alignment padding. */
971 uint8_t abPadding[1];
972 /** Max size of the extended state (or FPU state if no XSAVE). */
973 uint16_t cbMaxExtendedState;
974
975 /** Supports MSRs. */
976 uint32_t fMsr : 1;
977 /** Supports the page size extension (4/2 MB pages). */
978 uint32_t fPse : 1;
979 /** Supports 36-bit page size extension (4 MB pages can map memory above
980 * 4GB). */
981 uint32_t fPse36 : 1;
982 /** Supports physical address extension (PAE). */
983 uint32_t fPae : 1;
984 /** Page attribute table (PAT) support (page level cache control). */
985 uint32_t fPat : 1;
986 /** Supports the FXSAVE and FXRSTOR instructions. */
987 uint32_t fFxSaveRstor : 1;
988 /** Supports the XSAVE and XRSTOR instructions. */
989 uint32_t fXSaveRstor : 1;
990 /** The XSAVE/XRSTOR bit in CR4 has been set (only applicable for host!). */
991 uint32_t fOpSysXSaveRstor : 1;
992 /** Supports MMX. */
993 uint32_t fMmx : 1;
994 /** Supports AMD extensions to MMX instructions. */
995 uint32_t fAmdMmxExts : 1;
996 /** Supports SSE. */
997 uint32_t fSse : 1;
998 /** Supports SSE2. */
999 uint32_t fSse2 : 1;
1000 /** Supports SSE3. */
1001 uint32_t fSse3 : 1;
1002 /** Supports SSSE3. */
1003 uint32_t fSsse3 : 1;
1004 /** Supports SSE4.1. */
1005 uint32_t fSse41 : 1;
1006 /** Supports SSE4.2. */
1007 uint32_t fSse42 : 1;
1008 /** Supports AVX. */
1009 uint32_t fAvx : 1;
1010 /** Supports AVX2. */
1011 uint32_t fAvx2 : 1;
1012 /** Supports AVX512 foundation. */
1013 uint32_t fAvx512Foundation : 1;
1014 /** Supports RDTSC. */
1015 uint32_t fTsc : 1;
1016 /** Intel SYSENTER/SYSEXIT support */
1017 uint32_t fSysEnter : 1;
1018 /** First generation APIC. */
1019 uint32_t fApic : 1;
1020 /** Second generation APIC. */
1021 uint32_t fX2Apic : 1;
1022 /** Hypervisor present. */
1023 uint32_t fHypervisorPresent : 1;
1024 /** MWAIT & MONITOR instructions supported. */
1025 uint32_t fMonitorMWait : 1;
1026 /** MWAIT Extensions present. */
1027 uint32_t fMWaitExtensions : 1;
1028 /** Supports CMPXCHG16B in 64-bit mode. */
1029 uint32_t fMovCmpXchg16b : 1;
1030 /** Supports CLFLUSH. */
1031 uint32_t fClFlush : 1;
1032 /** Supports CLFLUSHOPT. */
1033 uint32_t fClFlushOpt : 1;
1034 /** Supports IA32_PRED_CMD.IBPB. */
1035 uint32_t fIbpb : 1;
1036 /** Supports IA32_SPEC_CTRL.IBRS. */
1037 uint32_t fIbrs : 1;
1038 /** Supports IA32_SPEC_CTRL.STIBP. */
1039 uint32_t fStibp : 1;
1040 /** Supports IA32_ARCH_CAP. */
1041 uint32_t fArchCap : 1;
1042 /** Supports PCID. */
1043 uint32_t fPcid : 1;
1044 /** Supports INVPCID. */
1045 uint32_t fInvpcid : 1;
1046 /** Supports read/write FSGSBASE instructions. */
1047 uint32_t fFsGsBase : 1;
1048
1049 /** Supports AMD 3DNow instructions. */
1050 uint32_t f3DNow : 1;
1051 /** Supports the 3DNow/AMD64 prefetch instructions (could be nops). */
1052 uint32_t f3DNowPrefetch : 1;
1053
1054 /** AMD64: Supports long mode. */
1055 uint32_t fLongMode : 1;
1056 /** AMD64: SYSCALL/SYSRET support. */
1057 uint32_t fSysCall : 1;
1058 /** AMD64: No-execute page table bit. */
1059 uint32_t fNoExecute : 1;
1060 /** AMD64: Supports LAHF & SAHF instructions in 64-bit mode. */
1061 uint32_t fLahfSahf : 1;
1062 /** AMD64: Supports RDTSCP. */
1063 uint32_t fRdTscP : 1;
1064 /** AMD64: Supports MOV CR8 in 32-bit code (lock prefix hack). */
1065 uint32_t fMovCr8In32Bit : 1;
1066 /** AMD64: Supports XOP (similar to VEX3/AVX). */
1067 uint32_t fXop : 1;
1068
1069 /** Indicates that FPU instruction and data pointers may leak.
1070 * This generally applies to recent AMD CPUs, where the FPU IP and DP pointer
1071 * is only saved and restored if an exception is pending. */
1072 uint32_t fLeakyFxSR : 1;
1073
1074 /** AMD64: Supports AMD SVM. */
1075 uint32_t fSvm : 1;
1076
1077 /** Support for Intel VMX. */
1078 uint32_t fVmx : 1;
1079
1080 /** Indicates that speculative execution control CPUID bits and
1081 * MSRs are exposed. The details are different for Intel and
1082 * AMD but both have similar functionality. */
1083 uint32_t fSpeculationControl : 1;
1084
1085 /** Alignment padding / reserved for future use. */
1086 uint32_t fPadding : 15;
1087
1088 /** SVM: Supports Nested-paging. */
1089 uint32_t fSvmNestedPaging : 1;
1090 /** SVM: Support LBR (Last Branch Record) virtualization. */
1091 uint32_t fSvmLbrVirt : 1;
1092 /** SVM: Supports SVM lock. */
1093 uint32_t fSvmSvmLock : 1;
1094 /** SVM: Supports Next RIP save. */
1095 uint32_t fSvmNextRipSave : 1;
1096 /** SVM: Supports TSC rate MSR. */
1097 uint32_t fSvmTscRateMsr : 1;
1098 /** SVM: Supports VMCB clean bits. */
1099 uint32_t fSvmVmcbClean : 1;
1100 /** SVM: Supports Flush-by-ASID. */
1101 uint32_t fSvmFlusbByAsid : 1;
1102 /** SVM: Supports decode assist. */
1103 uint32_t fSvmDecodeAssists : 1;
1104 /** SVM: Supports Pause filter. */
1105 uint32_t fSvmPauseFilter : 1;
1106 /** SVM: Supports Pause filter threshold. */
1107 uint32_t fSvmPauseFilterThreshold : 1;
1108 /** SVM: Supports AVIC (Advanced Virtual Interrupt Controller). */
1109 uint32_t fSvmAvic : 1;
1110 /** SVM: Supports Virtualized VMSAVE/VMLOAD. */
1111 uint32_t fSvmVirtVmsaveVmload : 1;
1112 /** SVM: Supports VGIF (Virtual Global Interrupt Flag). */
1113 uint32_t fSvmVGif : 1;
1114 /** SVM: Padding / reserved for future features. */
1115 uint32_t fSvmPadding0 : 19;
1116 /** SVM: Maximum supported ASID. */
1117 uint32_t uSvmMaxAsid;
1118
1119 /** @name VMX basic controls.
1120 * @{ */
1121 /** VMX: Supports INS/OUTS VM-exit instruction info. */
1122 uint32_t fVmxInsOutInfo : 1;
1123 /** @} */
1124
1125 /** @name VMX Pin-based controls.
1126 * @{ */
1127 /** VMX: Supports external interrupt VM-exit. */
1128 uint32_t fVmxExtIntExit : 1;
1129 /** VMX: Supports NMI VM-exit. */
1130 uint32_t fVmxNmiExit : 1;
1131 /** VMX: Supports Virtual NMIs. */
1132 uint32_t fVmxVirtNmi : 1;
1133 /** VMX: Supports preemption timer. */
1134 uint32_t fVmxPreemptTimer : 1;
1135 /** VMX: Supports posted interrupts. */
1136 uint32_t fVmxPostedInt : 1;
1137 /** @} */
1138
1139 /** @name VMX Processor-based controls.
1140 * @{ */
1141 /** VMX: Supports Interrupt-window exiting. */
1142 uint32_t fVmxIntWindowExit : 1;
1143 /** VMX: Supports TSC offsetting. */
1144 uint32_t fVmxTscOffsetting : 1;
1145 /** VMX: Supports HLT exiting. */
1146 uint32_t fVmxHltExit : 1;
1147 /** VMX: Supports INVLPG exiting. */
1148 uint32_t fVmxInvlpgExit : 1;
1149 /** VMX: Supports MWAIT exiting. */
1150 uint32_t fVmxMwaitExit : 1;
1151 /** VMX: Supports RDPMC exiting. */
1152 uint32_t fVmxRdpmcExit : 1;
1153 /** VMX: Supports RDTSC exiting. */
1154 uint32_t fVmxRdtscExit : 1;
1155 /** VMX: Supports CR3-load exiting. */
1156 uint32_t fVmxCr3LoadExit : 1;
1157 /** VMX: Supports CR3-store exiting. */
1158 uint32_t fVmxCr3StoreExit : 1;
1159 /** VMX: Supports CR8-load exiting. */
1160 uint32_t fVmxCr8LoadExit : 1;
1161 /** VMX: Supports CR8-store exiting. */
1162 uint32_t fVmxCr8StoreExit : 1;
1163 /** VMX: Supports TPR shadow. */
1164 uint32_t fVmxUseTprShadow : 1;
1165 /** VMX: Supports NMI-window exiting. */
1166 uint32_t fVmxNmiWindowExit : 1;
1167 /** VMX: Supports Mov-DRx exiting. */
1168 uint32_t fVmxMovDRxExit : 1;
1169 /** VMX: Supports Unconditional I/O exiting. */
1170 uint32_t fVmxUncondIoExit : 1;
1171 /** VMX: Supportgs I/O bitmaps. */
1172 uint32_t fVmxUseIoBitmaps : 1;
1173 /** VMX: Supports Monitor Trap Flag. */
1174 uint32_t fVmxMonitorTrapFlag : 1;
1175 /** VMX: Supports MSR bitmap. */
1176 uint32_t fVmxUseMsrBitmaps : 1;
1177 /** VMX: Supports MONITOR exiting. */
1178 uint32_t fVmxMonitorExit : 1;
1179 /** VMX: Supports PAUSE exiting. */
1180 uint32_t fVmxPauseExit : 1;
1181 /** VMX: Supports secondary processor-based VM-execution controls. */
1182 uint32_t fVmxSecondaryExecCtls : 1;
1183 /** @} */
1184
1185 /** @name VMX Secondary processor-based controls.
1186 * @{ */
1187 /** VMX: Supports virtualize-APIC access. */
1188 uint32_t fVmxVirtApicAccess : 1;
1189 /** VMX: Supports EPT (Extended Page Tables). */
1190 uint32_t fVmxEpt : 1;
1191 /** VMX: Supports descriptor-table exiting. */
1192 uint32_t fVmxDescTableExit : 1;
1193 /** VMX: Supports RDTSCP. */
1194 uint32_t fVmxRdtscp : 1;
1195 /** VMX: Supports virtualize-x2APIC mode. */
1196 uint32_t fVmxVirtX2ApicMode : 1;
1197 /** VMX: Supports VPID. */
1198 uint32_t fVmxVpid : 1;
1199 /** VMX: Supports WBIND exiting. */
1200 uint32_t fVmxWbinvdExit : 1;
1201 /** VMX: Supports Unrestricted guest. */
1202 uint32_t fVmxUnrestrictedGuest : 1;
1203 /** VMX: Supports APIC-register virtualization. */
1204 uint32_t fVmxApicRegVirt : 1;
1205 /** VMX: Supports virtual-interrupt delivery. */
1206 uint32_t fVmxVirtIntDelivery : 1;
1207 /** VMX: Supports Pause-loop exiting. */
1208 uint32_t fVmxPauseLoopExit : 1;
1209 /** VMX: Supports RDRAND exiting. */
1210 uint32_t fVmxRdrandExit : 1;
1211 /** VMX: Supports INVPCID. */
1212 uint32_t fVmxInvpcid : 1;
1213 /** VMX: Supports VM functions. */
1214 uint32_t fVmxVmFunc : 1;
1215 /** VMX: Supports VMCS shadowing. */
1216 uint32_t fVmxVmcsShadowing : 1;
1217 /** VMX: Supports RDSEED exiting. */
1218 uint32_t fVmxRdseedExit : 1;
1219 /** VMX: Supports PML. */
1220 uint32_t fVmxPml : 1;
1221 /** VMX: Supports EPT-violations \#VE. */
1222 uint32_t fVmxEptXcptVe : 1;
1223 /** VMX: Supports XSAVES/XRSTORS. */
1224 uint32_t fVmxXsavesXrstors : 1;
1225 /** VMX: Supports TSC scaling. */
1226 uint32_t fVmxUseTscScaling : 1;
1227 /** @} */
1228
1229 /** @name VMX VM-entry controls.
1230 * @{ */
1231 /** VMX: Supports load-debug controls on VM-entry. */
1232 uint32_t fVmxEntryLoadDebugCtls : 1;
1233 /** VMX: Supports IA32e mode guest. */
1234 uint32_t fVmxIa32eModeGuest : 1;
1235 /** VMX: Supports load guest EFER MSR on VM-entry. */
1236 uint32_t fVmxEntryLoadEferMsr : 1;
1237 /** VMX: Supports load guest PAT MSR on VM-entry. */
1238 uint32_t fVmxEntryLoadPatMsr : 1;
1239 /** @} */
1240
1241 /** @name VMX VM-exit controls.
1242 * @{ */
1243 /** VMX: Supports save debug controls on VM-exit. */
1244 uint32_t fVmxExitSaveDebugCtls : 1;
1245 /** VMX: Supports host-address space size. */
1246 uint32_t fVmxHostAddrSpaceSize : 1;
1247 /** VMX: Supports acknowledge external interrupt on VM-exit. */
1248 uint32_t fVmxExitAckExtInt : 1;
1249 /** VMX: Supports save guest PAT MSR on VM-exit. */
1250 uint32_t fVmxExitSavePatMsr : 1;
1251 /** VMX: Supports load hsot PAT MSR on VM-exit. */
1252 uint32_t fVmxExitLoadPatMsr : 1;
1253 /** VMX: Supports save guest EFER MSR on VM-exit. */
1254 uint32_t fVmxExitSaveEferMsr : 1;
1255 /** VMX: Supports load host EFER MSR on VM-exit. */
1256 uint32_t fVmxExitLoadEferMsr : 1;
1257 /** VMX: Supports save VMX preemption timer on VM-exit. */
1258 uint32_t fVmxSavePreemptTimer : 1;
1259 /** @} */
1260
1261 /** @name VMX Miscellaneous data.
1262 * @{ */
1263 /** VMX: Supports storing EFER.LMA on VM-exits into IA32e-mode guest field. */
1264 uint32_t fVmxExitStoreEferLma : 1;
1265 /** VMX: Supports VMWRITE to any valid VMCS field incl. read-only fields, otherwise
1266 * VMWRITE cannot modify read-only VM-exit information fields. */
1267 uint32_t fVmxVmwriteAll : 1;
1268 /** VMX: Supports injection of software interrupts, ICEBP on VM-entry for zero
1269 * length instructions. */
1270 uint32_t fVmxEntryInjectSoftInt : 1;
1271 /** @} */
1272
1273 /** VMX: Padding / reserved for future features. */
1274 uint32_t fVmxPadding0 : 2;
1275 uint32_t fVmxPadding1;
1276} CPUMFEATURES;
1277#ifndef VBOX_FOR_DTRACE_LIB
1278AssertCompileSize(CPUMFEATURES, 40);
1279#endif
1280/** Pointer to a CPU feature structure. */
1281typedef CPUMFEATURES *PCPUMFEATURES;
1282/** Pointer to a const CPU feature structure. */
1283typedef CPUMFEATURES const *PCCPUMFEATURES;
1284
1285
1286#ifndef VBOX_FOR_DTRACE_LIB
1287
1288/** @name Guest Register Getters.
1289 * @{ */
1290VMMDECL(void) CPUMGetGuestGDTR(PVMCPU pVCpu, PVBOXGDTR pGDTR);
1291VMMDECL(RTGCPTR) CPUMGetGuestIDTR(PVMCPU pVCpu, uint16_t *pcbLimit);
1292VMMDECL(RTSEL) CPUMGetGuestTR(PVMCPU pVCpu, PCPUMSELREGHID pHidden);
1293VMMDECL(RTSEL) CPUMGetGuestLDTR(PVMCPU pVCpu);
1294VMMDECL(RTSEL) CPUMGetGuestLdtrEx(PVMCPU pVCpu, uint64_t *pGCPtrBase, uint32_t *pcbLimit);
1295VMMDECL(uint64_t) CPUMGetGuestCR0(PVMCPU pVCpu);
1296VMMDECL(uint64_t) CPUMGetGuestCR2(PVMCPU pVCpu);
1297VMMDECL(uint64_t) CPUMGetGuestCR3(PVMCPU pVCpu);
1298VMMDECL(uint64_t) CPUMGetGuestCR4(PVMCPU pVCpu);
1299VMMDECL(uint64_t) CPUMGetGuestCR8(PVMCPU pVCpu);
1300VMMDECL(int) CPUMGetGuestCRx(PVMCPU pVCpu, unsigned iReg, uint64_t *pValue);
1301VMMDECL(uint32_t) CPUMGetGuestEFlags(PVMCPU pVCpu);
1302VMMDECL(uint32_t) CPUMGetGuestEIP(PVMCPU pVCpu);
1303VMMDECL(uint64_t) CPUMGetGuestRIP(PVMCPU pVCpu);
1304VMMDECL(uint32_t) CPUMGetGuestEAX(PVMCPU pVCpu);
1305VMMDECL(uint32_t) CPUMGetGuestEBX(PVMCPU pVCpu);
1306VMMDECL(uint32_t) CPUMGetGuestECX(PVMCPU pVCpu);
1307VMMDECL(uint32_t) CPUMGetGuestEDX(PVMCPU pVCpu);
1308VMMDECL(uint32_t) CPUMGetGuestESI(PVMCPU pVCpu);
1309VMMDECL(uint32_t) CPUMGetGuestEDI(PVMCPU pVCpu);
1310VMMDECL(uint32_t) CPUMGetGuestESP(PVMCPU pVCpu);
1311VMMDECL(uint32_t) CPUMGetGuestEBP(PVMCPU pVCpu);
1312VMMDECL(RTSEL) CPUMGetGuestCS(PVMCPU pVCpu);
1313VMMDECL(RTSEL) CPUMGetGuestDS(PVMCPU pVCpu);
1314VMMDECL(RTSEL) CPUMGetGuestES(PVMCPU pVCpu);
1315VMMDECL(RTSEL) CPUMGetGuestFS(PVMCPU pVCpu);
1316VMMDECL(RTSEL) CPUMGetGuestGS(PVMCPU pVCpu);
1317VMMDECL(RTSEL) CPUMGetGuestSS(PVMCPU pVCpu);
1318VMMDECL(uint64_t) CPUMGetGuestFlatPC(PVMCPU pVCpu);
1319VMMDECL(uint64_t) CPUMGetGuestFlatSP(PVMCPU pVCpu);
1320VMMDECL(uint64_t) CPUMGetGuestDR0(PVMCPU pVCpu);
1321VMMDECL(uint64_t) CPUMGetGuestDR1(PVMCPU pVCpu);
1322VMMDECL(uint64_t) CPUMGetGuestDR2(PVMCPU pVCpu);
1323VMMDECL(uint64_t) CPUMGetGuestDR3(PVMCPU pVCpu);
1324VMMDECL(uint64_t) CPUMGetGuestDR6(PVMCPU pVCpu);
1325VMMDECL(uint64_t) CPUMGetGuestDR7(PVMCPU pVCpu);
1326VMMDECL(int) CPUMGetGuestDRx(PVMCPU pVCpu, uint32_t iReg, uint64_t *pValue);
1327VMMDECL(void) CPUMGetGuestCpuId(PVMCPU pVCpu, uint32_t iLeaf, uint32_t iSubLeaf,
1328 uint32_t *pEax, uint32_t *pEbx, uint32_t *pEcx, uint32_t *pEdx);
1329VMMDECL(uint64_t) CPUMGetGuestEFER(PVMCPU pVCpu);
1330VMM_INT_DECL(uint64_t) CPUMGetGuestIa32MtrrCap(PVMCPU pVCpu);
1331VMM_INT_DECL(uint64_t) CPUMGetGuestIa32FeatureControl(PVMCPU pVCpu);
1332VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxBasic(PVMCPU pVCpu);
1333VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxPinbasedCtls(PVMCPU pVCpu);
1334VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxProcbasedCtls(PVMCPU pVCpu);
1335VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxProcbasedCtls2(PVMCPU pVCpu);
1336VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxExitCtls(PVMCPU pVCpu);
1337VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxEntryCtls(PVMCPU pVCpu);
1338VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxMisc(PVMCPU pVCpu);
1339VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxCr0Fixed0(PVMCPU pVCpu);
1340VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxCr0Fixed1(PVMCPU pVCpu);
1341VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxCr4Fixed0(PVMCPU pVCpu);
1342VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxCr4Fixed1(PVMCPU pVCpu);
1343VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxVmcsEnum(PVMCPU pVCpu);
1344VMM_INT_DECL(uint64_t) CPUMGetGuestIa32VmxVmFunc(PVMCPU pVCpu);
1345VMM_INT_DECL(uint64_t) CPUMGetGuestIa32SmmMonitorCtl(PVMCPU pVCpu);
1346VMMDECL(VBOXSTRICTRC) CPUMQueryGuestMsr(PVMCPU pVCpu, uint32_t idMsr, uint64_t *puValue);
1347VMMDECL(VBOXSTRICTRC) CPUMSetGuestMsr(PVMCPU pVCpu, uint32_t idMsr, uint64_t uValue);
1348VMMDECL(CPUMCPUVENDOR) CPUMGetGuestCpuVendor(PVM pVM);
1349VMMDECL(CPUMCPUVENDOR) CPUMGetHostCpuVendor(PVM pVM);
1350/** @} */
1351
1352/** @name Guest Register Setters.
1353 * @{ */
1354VMMDECL(int) CPUMSetGuestGDTR(PVMCPU pVCpu, uint64_t GCPtrBase, uint16_t cbLimit);
1355VMMDECL(int) CPUMSetGuestIDTR(PVMCPU pVCpu, uint64_t GCPtrBase, uint16_t cbLimit);
1356VMMDECL(int) CPUMSetGuestTR(PVMCPU pVCpu, uint16_t tr);
1357VMMDECL(int) CPUMSetGuestLDTR(PVMCPU pVCpu, uint16_t ldtr);
1358VMMDECL(int) CPUMSetGuestCR0(PVMCPU pVCpu, uint64_t cr0);
1359VMMDECL(int) CPUMSetGuestCR2(PVMCPU pVCpu, uint64_t cr2);
1360VMMDECL(int) CPUMSetGuestCR3(PVMCPU pVCpu, uint64_t cr3);
1361VMMDECL(int) CPUMSetGuestCR4(PVMCPU pVCpu, uint64_t cr4);
1362VMMDECL(int) CPUMSetGuestDR0(PVMCPU pVCpu, uint64_t uDr0);
1363VMMDECL(int) CPUMSetGuestDR1(PVMCPU pVCpu, uint64_t uDr1);
1364VMMDECL(int) CPUMSetGuestDR2(PVMCPU pVCpu, uint64_t uDr2);
1365VMMDECL(int) CPUMSetGuestDR3(PVMCPU pVCpu, uint64_t uDr3);
1366VMMDECL(int) CPUMSetGuestDR6(PVMCPU pVCpu, uint64_t uDr6);
1367VMMDECL(int) CPUMSetGuestDR7(PVMCPU pVCpu, uint64_t uDr7);
1368VMMDECL(int) CPUMSetGuestDRx(PVMCPU pVCpu, uint32_t iReg, uint64_t Value);
1369VMM_INT_DECL(int) CPUMSetGuestXcr0(PVMCPU pVCpu, uint64_t uNewValue);
1370VMMDECL(int) CPUMSetGuestEFlags(PVMCPU pVCpu, uint32_t eflags);
1371VMMDECL(int) CPUMSetGuestEIP(PVMCPU pVCpu, uint32_t eip);
1372VMMDECL(int) CPUMSetGuestEAX(PVMCPU pVCpu, uint32_t eax);
1373VMMDECL(int) CPUMSetGuestEBX(PVMCPU pVCpu, uint32_t ebx);
1374VMMDECL(int) CPUMSetGuestECX(PVMCPU pVCpu, uint32_t ecx);
1375VMMDECL(int) CPUMSetGuestEDX(PVMCPU pVCpu, uint32_t edx);
1376VMMDECL(int) CPUMSetGuestESI(PVMCPU pVCpu, uint32_t esi);
1377VMMDECL(int) CPUMSetGuestEDI(PVMCPU pVCpu, uint32_t edi);
1378VMMDECL(int) CPUMSetGuestESP(PVMCPU pVCpu, uint32_t esp);
1379VMMDECL(int) CPUMSetGuestEBP(PVMCPU pVCpu, uint32_t ebp);
1380VMMDECL(int) CPUMSetGuestCS(PVMCPU pVCpu, uint16_t cs);
1381VMMDECL(int) CPUMSetGuestDS(PVMCPU pVCpu, uint16_t ds);
1382VMMDECL(int) CPUMSetGuestES(PVMCPU pVCpu, uint16_t es);
1383VMMDECL(int) CPUMSetGuestFS(PVMCPU pVCpu, uint16_t fs);
1384VMMDECL(int) CPUMSetGuestGS(PVMCPU pVCpu, uint16_t gs);
1385VMMDECL(int) CPUMSetGuestSS(PVMCPU pVCpu, uint16_t ss);
1386VMMDECL(void) CPUMSetGuestEFER(PVMCPU pVCpu, uint64_t val);
1387VMMR3_INT_DECL(void) CPUMR3SetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
1388VMMR3_INT_DECL(void) CPUMR3ClearGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
1389VMMR3_INT_DECL(bool) CPUMR3GetGuestCpuIdFeature(PVM pVM, CPUMCPUIDFEATURE enmFeature);
1390VMMDECL(bool) CPUMSetGuestCpuIdPerCpuApicFeature(PVMCPU pVCpu, bool fVisible);
1391VMMDECL(void) CPUMSetGuestCtx(PVMCPU pVCpu, const PCPUMCTX pCtx);
1392VMM_INT_DECL(void) CPUMGuestLazyLoadHiddenCsAndSs(PVMCPU pVCpu);
1393VMM_INT_DECL(void) CPUMGuestLazyLoadHiddenSelectorReg(PVMCPU pVCpu, PCPUMSELREG pSReg);
1394VMM_INT_DECL(void) CPUMSetGuestTscAux(PVMCPU pVCpu, uint64_t uValue);
1395VMM_INT_DECL(uint64_t) CPUMGetGuestTscAux(PVMCPU pVCpu);
1396VMM_INT_DECL(void) CPUMSetGuestSpecCtrl(PVMCPU pVCpu, uint64_t uValue);
1397VMM_INT_DECL(uint64_t) CPUMGetGuestSpecCtrl(PVMCPU pVCpu);
1398/** @} */
1399
1400
1401/** @name Misc Guest Predicate Functions.
1402 * @{ */
1403VMMDECL(bool) CPUMIsGuestIn16BitCode(PVMCPU pVCpu);
1404VMMDECL(bool) CPUMIsGuestIn32BitCode(PVMCPU pVCpu);
1405VMMDECL(bool) CPUMIsGuestIn64BitCode(PVMCPU pVCpu);
1406VMMDECL(bool) CPUMIsGuestNXEnabled(PVMCPU pVCpu);
1407VMMDECL(bool) CPUMIsGuestPageSizeExtEnabled(PVMCPU pVCpu);
1408VMMDECL(bool) CPUMIsGuestPagingEnabled(PVMCPU pVCpu);
1409VMMDECL(bool) CPUMIsGuestR0WriteProtEnabled(PVMCPU pVCpu);
1410VMMDECL(bool) CPUMIsGuestInRealMode(PVMCPU pVCpu);
1411VMMDECL(bool) CPUMIsGuestInRealOrV86Mode(PVMCPU pVCpu);
1412VMMDECL(bool) CPUMIsGuestInProtectedMode(PVMCPU pVCpu);
1413VMMDECL(bool) CPUMIsGuestInPagedProtectedMode(PVMCPU pVCpu);
1414VMMDECL(bool) CPUMIsGuestInLongMode(PVMCPU pVCpu);
1415VMMDECL(bool) CPUMIsGuestInPAEMode(PVMCPU pVCpu);
1416VMM_INT_DECL(bool) CPUMIsGuestInRawMode(PVMCPU pVCpu);
1417/** @} */
1418
1419/** @name Nested Hardware-Virtualization Helpers.
1420 * @{ */
1421VMM_INT_DECL(bool) CPUMCanSvmNstGstTakePhysIntr(PVMCPU pVCpu, PCCPUMCTX pCtx);
1422VMM_INT_DECL(bool) CPUMCanSvmNstGstTakeVirtIntr(PVMCPU pVCpu, PCCPUMCTX pCtx);
1423VMM_INT_DECL(uint8_t) CPUMGetSvmNstGstInterrupt(PCCPUMCTX pCtx);
1424VMM_INT_DECL(bool) CPUMGetSvmNstGstVGif(PCCPUMCTX pCtx);
1425VMM_INT_DECL(void) CPUMSvmVmExitRestoreHostState(PVMCPU pVCpu, PCPUMCTX pCtx);
1426VMM_INT_DECL(void) CPUMSvmVmRunSaveHostState(PCPUMCTX pCtx, uint8_t cbInstr);
1427VMM_INT_DECL(uint64_t) CPUMApplyNestedGuestTscOffset(PVMCPU pVCpu, uint64_t uTicks);
1428/** @} */
1429
1430/** @name Externalized State Helpers.
1431 * @{ */
1432/** @def CPUM_ASSERT_NOT_EXTRN
1433 * Macro for asserting that @a a_fNotExtrn are present.
1434 *
1435 * @param a_pVCpu The cross context virtual CPU structure of the calling EMT.
1436 * @param a_fNotExtrn Mask of CPUMCTX_EXTRN_XXX bits to check.
1437 *
1438 * @remarks Requires VMCPU_INCL_CPUM_GST_CTX to be defined.
1439 */
1440#define CPUM_ASSERT_NOT_EXTRN(a_pVCpu, a_fNotExtrn) \
1441 AssertMsg(!((a_pVCpu)->cpum.GstCtx.fExtrn & (a_fNotExtrn)), \
1442 ("%#RX64; a_fNotExtrn=%#RX64\n", (a_pVCpu)->cpum.GstCtx.fExtrn, (a_fNotExtrn)))
1443
1444/** @def CPUM_IMPORT_EXTRN_RET
1445 * Macro for making sure the state specified by @a fExtrnImport is present,
1446 * calling CPUMImportGuestStateOnDemand() to get it if necessary.
1447 *
1448 * Will return if CPUMImportGuestStateOnDemand() fails.
1449 *
1450 * @param a_pVCpu The cross context virtual CPU structure of the calling EMT.
1451 * @param a_fExtrnImport Mask of CPUMCTX_EXTRN_XXX bits to get.
1452 * @thread EMT(a_pVCpu)
1453 *
1454 * @remarks Requires VMCPU_INCL_CPUM_GST_CTX to be defined.
1455 */
1456#define CPUM_IMPORT_EXTRN_RET(a_pVCpu, a_fExtrnImport) \
1457 do { \
1458 if (!((a_pVCpu)->cpum.GstCtx.fExtrn & (a_fExtrnImport))) \
1459 { /* already present, consider this likely */ } \
1460 else \
1461 { \
1462 int rcCpumImport = CPUMImportGuestStateOnDemand(a_pVCpu, a_fExtrnImport); \
1463 AssertRCReturn(rcCpumImport, rcCpumImport); \
1464 } \
1465 } while (0)
1466
1467/** @def CPUM_IMPORT_EXTRN_RCSTRICT
1468 * Macro for making sure the state specified by @a fExtrnImport is present,
1469 * calling CPUMImportGuestStateOnDemand() to get it if necessary.
1470 *
1471 * Will update a_rcStrict if CPUMImportGuestStateOnDemand() fails.
1472 *
1473 * @param a_pVCpu The cross context virtual CPU structure of the calling EMT.
1474 * @param a_fExtrnImport Mask of CPUMCTX_EXTRN_XXX bits to get.
1475 * @param a_rcStrict Strict status code variable to update on failure.
1476 * @thread EMT(a_pVCpu)
1477 *
1478 * @remarks Requires VMCPU_INCL_CPUM_GST_CTX to be defined.
1479 */
1480#define CPUM_IMPORT_EXTRN_RCSTRICT(a_pVCpu, a_fExtrnImport, a_rcStrict) \
1481 do { \
1482 if (!((a_pVCpu)->cpum.GstCtx.fExtrn & (a_fExtrnImport))) \
1483 { /* already present, consider this likely */ } \
1484 else \
1485 { \
1486 int rcCpumImport = CPUMImportGuestStateOnDemand(a_pVCpu, a_fExtrnImport); \
1487 AssertStmt(RT_SUCCESS(rcCpumImport) || RT_FAILURE_NP(a_rcStrict), a_rcStrict = rcCpumImport); \
1488 } \
1489 } while (0)
1490
1491VMM_INT_DECL(int) CPUMImportGuestStateOnDemand(PVMCPU pVCpu, uint64_t fExtrnImport);
1492/** @} */
1493
1494#ifndef IPRT_WITHOUT_NAMED_UNIONS_AND_STRUCTS
1495
1496/**
1497 * Tests if the guest is running in real mode or not.
1498 *
1499 * @returns true if in real mode, otherwise false.
1500 * @param pCtx Current CPU context.
1501 */
1502DECLINLINE(bool) CPUMIsGuestInRealModeEx(PCCPUMCTX pCtx)
1503{
1504 return !(pCtx->cr0 & X86_CR0_PE);
1505}
1506
1507/**
1508 * Tests if the guest is running in real or virtual 8086 mode.
1509 *
1510 * @returns @c true if it is, @c false if not.
1511 * @param pCtx Current CPU context.
1512 */
1513DECLINLINE(bool) CPUMIsGuestInRealOrV86ModeEx(PCCPUMCTX pCtx)
1514{
1515 return !(pCtx->cr0 & X86_CR0_PE)
1516 || pCtx->eflags.Bits.u1VM; /* Cannot be set in long mode. Intel spec 2.3.1 "System Flags and Fields in IA-32e Mode". */
1517}
1518
1519/**
1520 * Tests if the guest is running in virtual 8086 mode.
1521 *
1522 * @returns @c true if it is, @c false if not.
1523 * @param pCtx Current CPU context.
1524 */
1525DECLINLINE(bool) CPUMIsGuestInV86ModeEx(PCCPUMCTX pCtx)
1526{
1527 return (pCtx->eflags.Bits.u1VM == 1);
1528}
1529
1530/**
1531 * Tests if the guest is running in paged protected or not.
1532 *
1533 * @returns true if in paged protected mode, otherwise false.
1534 * @param pCtx Current CPU context.
1535 */
1536DECLINLINE(bool) CPUMIsGuestInPagedProtectedModeEx(PCPUMCTX pCtx)
1537{
1538 return (pCtx->cr0 & (X86_CR0_PE | X86_CR0_PG)) == (X86_CR0_PE | X86_CR0_PG);
1539}
1540
1541/**
1542 * Tests if the guest is running in long mode or not.
1543 *
1544 * @returns true if in long mode, otherwise false.
1545 * @param pCtx Current CPU context.
1546 */
1547DECLINLINE(bool) CPUMIsGuestInLongModeEx(PCCPUMCTX pCtx)
1548{
1549 return (pCtx->msrEFER & MSR_K6_EFER_LMA) == MSR_K6_EFER_LMA;
1550}
1551
1552VMM_INT_DECL(bool) CPUMIsGuestIn64BitCodeSlow(PCPUMCTX pCtx);
1553
1554/**
1555 * Tests if the guest is running in 64 bits mode or not.
1556 *
1557 * @returns true if in 64 bits protected mode, otherwise false.
1558 * @param pCtx Current CPU context.
1559 */
1560DECLINLINE(bool) CPUMIsGuestIn64BitCodeEx(PCPUMCTX pCtx)
1561{
1562 if (!(pCtx->msrEFER & MSR_K6_EFER_LMA))
1563 return false;
1564 if (!CPUMSELREG_ARE_HIDDEN_PARTS_VALID(NULL, &pCtx->cs))
1565 return CPUMIsGuestIn64BitCodeSlow(pCtx);
1566 return pCtx->cs.Attr.n.u1Long;
1567}
1568
1569/**
1570 * Tests if the guest has paging enabled or not.
1571 *
1572 * @returns true if paging is enabled, otherwise false.
1573 * @param pCtx Current CPU context.
1574 */
1575DECLINLINE(bool) CPUMIsGuestPagingEnabledEx(PCCPUMCTX pCtx)
1576{
1577 return !!(pCtx->cr0 & X86_CR0_PG);
1578}
1579
1580/**
1581 * Tests if the guest is running in PAE mode or not.
1582 *
1583 * @returns true if in PAE mode, otherwise false.
1584 * @param pCtx Current CPU context.
1585 */
1586DECLINLINE(bool) CPUMIsGuestInPAEModeEx(PCCPUMCTX pCtx)
1587{
1588 /* Intel mentions EFER.LMA and EFER.LME in different parts of their spec. We shall use EFER.LMA rather
1589 than EFER.LME as it reflects if the CPU has entered paging with EFER.LME set. */
1590 return ( (pCtx->cr4 & X86_CR4_PAE)
1591 && CPUMIsGuestPagingEnabledEx(pCtx)
1592 && !(pCtx->msrEFER & MSR_K6_EFER_LMA));
1593}
1594
1595/**
1596 * Tests if the guest has AMD SVM enabled or not.
1597 *
1598 * @returns true if SMV is enabled, otherwise false.
1599 * @param pCtx Current CPU context.
1600 */
1601DECLINLINE(bool) CPUMIsGuestSvmEnabled(PCCPUMCTX pCtx)
1602{
1603 return RT_BOOL(pCtx->msrEFER & MSR_K6_EFER_SVME);
1604}
1605
1606/**
1607 * Tests if the guest has Intel VT-x enabled or not.
1608 *
1609 * @returns true if VMX is enabled, otherwise false.
1610 * @param pCtx Current CPU context.
1611 */
1612DECLINLINE(bool) CPUMIsGuestVmxEnabled(PCCPUMCTX pCtx)
1613{
1614 return RT_BOOL(pCtx->cr4 & X86_CR4_VMXE);
1615}
1616
1617#ifndef IN_RC
1618
1619/**
1620 * Checks if the nested-guest VMCB has the specified ctrl/instruction intercept
1621 * active.
1622 *
1623 * @returns @c true if in intercept is set, @c false otherwise.
1624 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
1625 * @param pCtx Pointer to the context.
1626 * @param fIntercept The SVM control/instruction intercept, see
1627 * SVM_CTRL_INTERCEPT_*.
1628 */
1629DECLINLINE(bool) CPUMIsGuestSvmCtrlInterceptSet(PVMCPU pVCpu, PCPUMCTX pCtx, uint64_t fIntercept)
1630{
1631 PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
1632 if (!pVmcb)
1633 return false;
1634 if (HMHasGuestSvmVmcbCached(pVCpu))
1635 return HMIsGuestSvmCtrlInterceptSet(pVCpu, fIntercept);
1636 return RT_BOOL(pVmcb->ctrl.u64InterceptCtrl & fIntercept);
1637}
1638
1639/**
1640 * Checks if the nested-guest VMCB has the specified CR read intercept active.
1641 *
1642 * @returns @c true if in intercept is set, @c false otherwise.
1643 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
1644 * @param pCtx Pointer to the context.
1645 * @param uCr The CR register number (0 to 15).
1646 */
1647DECLINLINE(bool) CPUMIsGuestSvmReadCRxInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uCr)
1648{
1649 Assert(uCr < 16);
1650 PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
1651 if (!pVmcb)
1652 return false;
1653 if (HMHasGuestSvmVmcbCached(pVCpu))
1654 return HMIsGuestSvmReadCRxInterceptSet(pVCpu, uCr);
1655 return RT_BOOL(pVmcb->ctrl.u16InterceptRdCRx & (UINT16_C(1) << uCr));
1656}
1657
1658/**
1659 * Checks if the nested-guest VMCB has the specified CR write intercept active.
1660 *
1661 * @returns @c true if in intercept is set, @c false otherwise.
1662 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
1663 * @param pCtx Pointer to the context.
1664 * @param uCr The CR register number (0 to 15).
1665 */
1666DECLINLINE(bool) CPUMIsGuestSvmWriteCRxInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uCr)
1667{
1668 Assert(uCr < 16);
1669 PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
1670 if (!pVmcb)
1671 return false;
1672 if (HMHasGuestSvmVmcbCached(pVCpu))
1673 return HMIsGuestSvmWriteCRxInterceptSet(pVCpu, uCr);
1674 return RT_BOOL(pVmcb->ctrl.u16InterceptWrCRx & (UINT16_C(1) << uCr));
1675}
1676
1677/**
1678 * Checks if the nested-guest VMCB has the specified DR read intercept active.
1679 *
1680 * @returns @c true if in intercept is set, @c false otherwise.
1681 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
1682 * @param pCtx Pointer to the context.
1683 * @param uDr The DR register number (0 to 15).
1684 */
1685DECLINLINE(bool) CPUMIsGuestSvmReadDRxInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uDr)
1686{
1687 Assert(uDr < 16);
1688 PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
1689 if (!pVmcb)
1690 return false;
1691 if (HMHasGuestSvmVmcbCached(pVCpu))
1692 return HMIsGuestSvmReadDRxInterceptSet(pVCpu, uDr);
1693 return RT_BOOL(pVmcb->ctrl.u16InterceptRdDRx & (UINT16_C(1) << uDr));
1694}
1695
1696/**
1697 * Checks if the nested-guest VMCB has the specified DR write intercept active.
1698 *
1699 * @returns @c true if in intercept is set, @c false otherwise.
1700 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
1701 * @param pCtx Pointer to the context.
1702 * @param uDr The DR register number (0 to 15).
1703 */
1704DECLINLINE(bool) CPUMIsGuestSvmWriteDRxInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uDr)
1705{
1706 Assert(uDr < 16);
1707 PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
1708 if (!pVmcb)
1709 return false;
1710 if (HMHasGuestSvmVmcbCached(pVCpu))
1711 return HMIsGuestSvmWriteDRxInterceptSet(pVCpu, uDr);
1712 return RT_BOOL(pVmcb->ctrl.u16InterceptWrDRx & (UINT16_C(1) << uDr));
1713}
1714
1715/**
1716 * Checks if the nested-guest VMCB has the specified exception intercept active.
1717 *
1718 * @returns @c true if in intercept is active, @c false otherwise.
1719 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
1720 * @param pCtx Pointer to the context.
1721 * @param uVector The exception / interrupt vector.
1722 */
1723DECLINLINE(bool) CPUMIsGuestSvmXcptInterceptSet(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t uVector)
1724{
1725 Assert(uVector < 32);
1726 PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
1727 if (!pVmcb)
1728 return false;
1729 if (HMHasGuestSvmVmcbCached(pVCpu))
1730 return HMIsGuestSvmXcptInterceptSet(pVCpu, uVector);
1731 return RT_BOOL(pVmcb->ctrl.u32InterceptXcpt & (UINT32_C(1) << uVector));
1732}
1733
1734/**
1735 * Checks if the nested-guest VMCB has virtual-interrupt masking enabled.
1736 *
1737 * @returns @c true if virtual-interrupts are masked, @c false otherwise.
1738 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
1739 * @param pCtx Pointer to the context.
1740 *
1741 * @remarks Should only be called when SVM feature is exposed to the guest.
1742 */
1743DECLINLINE(bool) CPUMIsGuestSvmVirtIntrMasking(PVMCPU pVCpu, PCCPUMCTX pCtx)
1744{
1745 PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
1746 if (!pVmcb)
1747 return false;
1748 if (HMHasGuestSvmVmcbCached(pVCpu))
1749 return HMIsGuestSvmVirtIntrMasking(pVCpu);
1750 return pVmcb->ctrl.IntCtrl.n.u1VIntrMasking;
1751}
1752
1753/**
1754 * Checks if the nested-guest VMCB has nested-paging enabled.
1755 *
1756 * @returns @c true if nested-paging is enabled, @c false otherwise.
1757 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
1758 * @param pCtx Pointer to the context.
1759 *
1760 * @remarks Should only be called when SVM feature is exposed to the guest.
1761 */
1762DECLINLINE(bool) CPUMIsGuestSvmNestedPagingEnabled(PVMCPU pVCpu, PCCPUMCTX pCtx)
1763{
1764 PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
1765 if (!pVmcb)
1766 return false;
1767 if (HMHasGuestSvmVmcbCached(pVCpu))
1768 return HMIsGuestSvmNestedPagingEnabled(pVCpu);
1769 return pVmcb->ctrl.NestedPagingCtrl.n.u1NestedPaging;
1770}
1771
1772/**
1773 * Gets the nested-guest VMCB pause-filter count.
1774 *
1775 * @returns The pause-filter count.
1776 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
1777 * @param pCtx Pointer to the context.
1778 *
1779 * @remarks Should only be called when SVM feature is exposed to the guest.
1780 */
1781DECLINLINE(uint16_t) CPUMGetGuestSvmPauseFilterCount(PVMCPU pVCpu, PCCPUMCTX pCtx)
1782{
1783 PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
1784 if (!pVmcb)
1785 return false;
1786 if (HMHasGuestSvmVmcbCached(pVCpu))
1787 return HMGetGuestSvmPauseFilterCount(pVCpu);
1788 return pVmcb->ctrl.u16PauseFilterCount;
1789}
1790
1791/**
1792 * Updates the NextRIP (NRIP) field in the nested-guest VMCB.
1793 *
1794 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
1795 * @param pCtx Pointer to the context.
1796 * @param cbInstr The length of the current instruction in bytes.
1797 *
1798 * @remarks Should only be called when SVM feature is exposed to the guest.
1799 */
1800DECLINLINE(void) CPUMGuestSvmUpdateNRip(PVMCPU pVCpu, PCCPUMCTX pCtx, uint8_t cbInstr)
1801{
1802 RT_NOREF(pVCpu);
1803 PSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
1804 Assert(pVmcb);
1805 pVmcb->ctrl.u64NextRIP = pCtx->rip + cbInstr;
1806}
1807
1808#endif /* !IN_RC */
1809
1810/**
1811 * Checks if we are executing inside an SVM nested hardware-virtualized guest.
1812 *
1813 * @returns @c true if in SVM nested-guest mode, @c false otherwise.
1814 * @param pCtx Pointer to the context.
1815 */
1816DECLINLINE(bool) CPUMIsGuestInSvmNestedHwVirtMode(PCCPUMCTX pCtx)
1817{
1818 /*
1819 * With AMD-V, the VMRUN intercept is a pre-requisite to entering SVM guest-mode.
1820 * See AMD spec. 15.5 "VMRUN instruction" subsection "Canonicalization and Consistency Checks".
1821 */
1822#ifndef IN_RC
1823 PCSVMVMCB pVmcb = pCtx->hwvirt.svm.CTX_SUFF(pVmcb);
1824 return pVmcb && (pVmcb->ctrl.u64InterceptCtrl & SVM_CTRL_INTERCEPT_VMRUN);
1825#else
1826 NOREF(pCtx);
1827 return false;
1828#endif
1829}
1830
1831/**
1832 * Checks if the guest is in VMX non-root operation.
1833 *
1834 * @returns @c true if in VMX non-root operation, @c false otherwise.
1835 * @param pCtx Current CPU context.
1836 */
1837DECLINLINE(bool) CPUMIsGuestInVmxNonRootMode(PCCPUMCTX pCtx)
1838{
1839#ifndef IN_RC
1840 Assert(!pCtx->hwvirt.vmx.fInVmxNonRootMode || pCtx->hwvirt.vmx.fInVmxRootMode);
1841 return pCtx->hwvirt.vmx.fInVmxNonRootMode;
1842#else
1843 NOREF(pCtx);
1844 return false;
1845#endif
1846}
1847
1848/**
1849 * Checks if the guest is in VMX root operation.
1850 *
1851 * @returns @c true if in VMX root operation, @c false otherwise.
1852 * @param pCtx Current CPU context.
1853 */
1854DECLINLINE(bool) CPUMIsGuestInVmxRootMode(PCCPUMCTX pCtx)
1855{
1856#ifndef IN_RC
1857 return pCtx->hwvirt.vmx.fInVmxRootMode;
1858#else
1859 NOREF(pCtx);
1860 return false;
1861#endif
1862}
1863
1864#endif /* IPRT_WITHOUT_NAMED_UNIONS_AND_STRUCTS */
1865
1866/** @} */
1867
1868
1869/** @name Hypervisor Register Getters.
1870 * @{ */
1871VMMDECL(RTSEL) CPUMGetHyperCS(PVMCPU pVCpu);
1872VMMDECL(RTSEL) CPUMGetHyperDS(PVMCPU pVCpu);
1873VMMDECL(RTSEL) CPUMGetHyperES(PVMCPU pVCpu);
1874VMMDECL(RTSEL) CPUMGetHyperFS(PVMCPU pVCpu);
1875VMMDECL(RTSEL) CPUMGetHyperGS(PVMCPU pVCpu);
1876VMMDECL(RTSEL) CPUMGetHyperSS(PVMCPU pVCpu);
1877#if 0 /* these are not correct. */
1878VMMDECL(uint32_t) CPUMGetHyperCR0(PVMCPU pVCpu);
1879VMMDECL(uint32_t) CPUMGetHyperCR2(PVMCPU pVCpu);
1880VMMDECL(uint32_t) CPUMGetHyperCR3(PVMCPU pVCpu);
1881VMMDECL(uint32_t) CPUMGetHyperCR4(PVMCPU pVCpu);
1882#endif
1883/** This register is only saved on fatal traps. */
1884VMMDECL(uint32_t) CPUMGetHyperEAX(PVMCPU pVCpu);
1885VMMDECL(uint32_t) CPUMGetHyperEBX(PVMCPU pVCpu);
1886/** This register is only saved on fatal traps. */
1887VMMDECL(uint32_t) CPUMGetHyperECX(PVMCPU pVCpu);
1888/** This register is only saved on fatal traps. */
1889VMMDECL(uint32_t) CPUMGetHyperEDX(PVMCPU pVCpu);
1890VMMDECL(uint32_t) CPUMGetHyperESI(PVMCPU pVCpu);
1891VMMDECL(uint32_t) CPUMGetHyperEDI(PVMCPU pVCpu);
1892VMMDECL(uint32_t) CPUMGetHyperEBP(PVMCPU pVCpu);
1893VMMDECL(uint32_t) CPUMGetHyperESP(PVMCPU pVCpu);
1894VMMDECL(uint32_t) CPUMGetHyperEFlags(PVMCPU pVCpu);
1895VMMDECL(uint32_t) CPUMGetHyperEIP(PVMCPU pVCpu);
1896VMMDECL(uint64_t) CPUMGetHyperRIP(PVMCPU pVCpu);
1897VMMDECL(uint32_t) CPUMGetHyperIDTR(PVMCPU pVCpu, uint16_t *pcbLimit);
1898VMMDECL(uint32_t) CPUMGetHyperGDTR(PVMCPU pVCpu, uint16_t *pcbLimit);
1899VMMDECL(RTSEL) CPUMGetHyperLDTR(PVMCPU pVCpu);
1900VMMDECL(RTGCUINTREG) CPUMGetHyperDR0(PVMCPU pVCpu);
1901VMMDECL(RTGCUINTREG) CPUMGetHyperDR1(PVMCPU pVCpu);
1902VMMDECL(RTGCUINTREG) CPUMGetHyperDR2(PVMCPU pVCpu);
1903VMMDECL(RTGCUINTREG) CPUMGetHyperDR3(PVMCPU pVCpu);
1904VMMDECL(RTGCUINTREG) CPUMGetHyperDR6(PVMCPU pVCpu);
1905VMMDECL(RTGCUINTREG) CPUMGetHyperDR7(PVMCPU pVCpu);
1906VMMDECL(void) CPUMGetHyperCtx(PVMCPU pVCpu, PCPUMCTX pCtx);
1907VMMDECL(uint32_t) CPUMGetHyperCR3(PVMCPU pVCpu);
1908/** @} */
1909
1910/** @name Hypervisor Register Setters.
1911 * @{ */
1912VMMDECL(void) CPUMSetHyperGDTR(PVMCPU pVCpu, uint32_t addr, uint16_t limit);
1913VMMDECL(void) CPUMSetHyperLDTR(PVMCPU pVCpu, RTSEL SelLDTR);
1914VMMDECL(void) CPUMSetHyperIDTR(PVMCPU pVCpu, uint32_t addr, uint16_t limit);
1915VMMDECL(void) CPUMSetHyperCR3(PVMCPU pVCpu, uint32_t cr3);
1916VMMDECL(void) CPUMSetHyperTR(PVMCPU pVCpu, RTSEL SelTR);
1917VMMDECL(void) CPUMSetHyperCS(PVMCPU pVCpu, RTSEL SelCS);
1918VMMDECL(void) CPUMSetHyperDS(PVMCPU pVCpu, RTSEL SelDS);
1919VMMDECL(void) CPUMSetHyperES(PVMCPU pVCpu, RTSEL SelDS);
1920VMMDECL(void) CPUMSetHyperFS(PVMCPU pVCpu, RTSEL SelDS);
1921VMMDECL(void) CPUMSetHyperGS(PVMCPU pVCpu, RTSEL SelDS);
1922VMMDECL(void) CPUMSetHyperSS(PVMCPU pVCpu, RTSEL SelSS);
1923VMMDECL(void) CPUMSetHyperESP(PVMCPU pVCpu, uint32_t u32ESP);
1924VMMDECL(int) CPUMSetHyperEFlags(PVMCPU pVCpu, uint32_t Efl);
1925VMMDECL(void) CPUMSetHyperEIP(PVMCPU pVCpu, uint32_t u32EIP);
1926VMM_INT_DECL(void) CPUMSetHyperState(PVMCPU pVCpu, uint32_t u32EIP, uint32_t u32ESP, uint32_t u32EAX, uint32_t u32EDX);
1927VMMDECL(void) CPUMSetHyperDR0(PVMCPU pVCpu, RTGCUINTREG uDr0);
1928VMMDECL(void) CPUMSetHyperDR1(PVMCPU pVCpu, RTGCUINTREG uDr1);
1929VMMDECL(void) CPUMSetHyperDR2(PVMCPU pVCpu, RTGCUINTREG uDr2);
1930VMMDECL(void) CPUMSetHyperDR3(PVMCPU pVCpu, RTGCUINTREG uDr3);
1931VMMDECL(void) CPUMSetHyperDR6(PVMCPU pVCpu, RTGCUINTREG uDr6);
1932VMMDECL(void) CPUMSetHyperDR7(PVMCPU pVCpu, RTGCUINTREG uDr7);
1933VMMDECL(void) CPUMSetHyperCtx(PVMCPU pVCpu, const PCPUMCTX pCtx);
1934VMMDECL(int) CPUMRecalcHyperDRx(PVMCPU pVCpu, uint8_t iGstReg, bool fForceHyper);
1935/** @} */
1936
1937VMMDECL(void) CPUMPushHyper(PVMCPU pVCpu, uint32_t u32);
1938VMMDECL(int) CPUMQueryHyperCtxPtr(PVMCPU pVCpu, PCPUMCTX *ppCtx);
1939VMMDECL(PCPUMCTX) CPUMGetHyperCtxPtr(PVMCPU pVCpu);
1940VMMDECL(PCCPUMCTXCORE) CPUMGetHyperCtxCore(PVMCPU pVCpu);
1941VMMDECL(PCPUMCTX) CPUMQueryGuestCtxPtr(PVMCPU pVCpu);
1942VMM_INT_DECL(PCPUMCTXMSRS) CPUMQueryGuestCtxMsrsPtr(PVMCPU pVCpu);
1943VMMDECL(PCCPUMCTXCORE) CPUMGetGuestCtxCore(PVMCPU pVCpu);
1944VMM_INT_DECL(int) CPUMRawEnter(PVMCPU pVCpu);
1945VMM_INT_DECL(int) CPUMRawLeave(PVMCPU pVCpu, int rc);
1946VMMDECL(uint32_t) CPUMRawGetEFlags(PVMCPU pVCpu);
1947VMMDECL(void) CPUMRawSetEFlags(PVMCPU pVCpu, uint32_t fEfl);
1948
1949/** @name Changed flags.
1950 * These flags are used to keep track of which important register that
1951 * have been changed since last they were reset. The only one allowed
1952 * to clear them is REM!
1953 * @{
1954 */
1955#define CPUM_CHANGED_FPU_REM RT_BIT(0)
1956#define CPUM_CHANGED_CR0 RT_BIT(1)
1957#define CPUM_CHANGED_CR4 RT_BIT(2)
1958#define CPUM_CHANGED_GLOBAL_TLB_FLUSH RT_BIT(3)
1959#define CPUM_CHANGED_CR3 RT_BIT(4)
1960#define CPUM_CHANGED_GDTR RT_BIT(5)
1961#define CPUM_CHANGED_IDTR RT_BIT(6)
1962#define CPUM_CHANGED_LDTR RT_BIT(7)
1963#define CPUM_CHANGED_TR RT_BIT(8) /**@< Currently unused. */
1964#define CPUM_CHANGED_SYSENTER_MSR RT_BIT(9)
1965#define CPUM_CHANGED_HIDDEN_SEL_REGS RT_BIT(10) /**@< Currently unused. */
1966#define CPUM_CHANGED_CPUID RT_BIT(11)
1967#define CPUM_CHANGED_ALL ( CPUM_CHANGED_FPU_REM \
1968 | CPUM_CHANGED_CR0 \
1969 | CPUM_CHANGED_CR4 \
1970 | CPUM_CHANGED_GLOBAL_TLB_FLUSH \
1971 | CPUM_CHANGED_CR3 \
1972 | CPUM_CHANGED_GDTR \
1973 | CPUM_CHANGED_IDTR \
1974 | CPUM_CHANGED_LDTR \
1975 | CPUM_CHANGED_TR \
1976 | CPUM_CHANGED_SYSENTER_MSR \
1977 | CPUM_CHANGED_HIDDEN_SEL_REGS \
1978 | CPUM_CHANGED_CPUID )
1979/** @} */
1980
1981VMMDECL(void) CPUMSetChangedFlags(PVMCPU pVCpu, uint32_t fChangedAdd);
1982VMMR3DECL(uint32_t) CPUMR3RemEnter(PVMCPU pVCpu, uint32_t *puCpl);
1983VMMR3DECL(void) CPUMR3RemLeave(PVMCPU pVCpu, bool fNoOutOfSyncSels);
1984VMMDECL(bool) CPUMSupportsXSave(PVM pVM);
1985VMMDECL(bool) CPUMIsHostUsingSysEnter(PVM pVM);
1986VMMDECL(bool) CPUMIsHostUsingSysCall(PVM pVM);
1987VMMDECL(bool) CPUMIsGuestFPUStateActive(PVMCPU pVCpu);
1988VMMDECL(bool) CPUMIsGuestFPUStateLoaded(PVMCPU pVCpu);
1989VMMDECL(bool) CPUMIsHostFPUStateSaved(PVMCPU pVCpu);
1990VMMDECL(bool) CPUMIsGuestDebugStateActive(PVMCPU pVCpu);
1991VMMDECL(bool) CPUMIsGuestDebugStateActivePending(PVMCPU pVCpu);
1992VMMDECL(void) CPUMDeactivateGuestDebugState(PVMCPU pVCpu);
1993VMMDECL(bool) CPUMIsHyperDebugStateActive(PVMCPU pVCpu);
1994VMMDECL(bool) CPUMIsHyperDebugStateActivePending(PVMCPU pVCpu);
1995VMMDECL(uint32_t) CPUMGetGuestCPL(PVMCPU pVCpu);
1996VMMDECL(CPUMMODE) CPUMGetGuestMode(PVMCPU pVCpu);
1997VMMDECL(uint32_t) CPUMGetGuestCodeBits(PVMCPU pVCpu);
1998VMMDECL(DISCPUMODE) CPUMGetGuestDisMode(PVMCPU pVCpu);
1999VMMDECL(uint32_t) CPUMGetGuestMxCsrMask(PVM pVM);
2000VMMDECL(uint64_t) CPUMGetGuestScalableBusFrequency(PVM pVM);
2001VMMDECL(uint64_t) CPUMGetGuestEferMsrValidMask(PVM pVM);
2002VMMDECL(int) CPUMIsGuestEferMsrWriteValid(PVM pVM, uint64_t uCr0, uint64_t uOldEfer, uint64_t uNewEfer,
2003 uint64_t *puValidEfer);
2004VMMDECL(void) CPUMSetGuestEferMsrNoChecks(PVMCPU pVCpu, uint64_t uOldEfer, uint64_t uValidEfer);
2005VMMDECL(bool) CPUMIsPatMsrValid(uint64_t uValue);
2006
2007/** @name Typical scalable bus frequency values.
2008 * @{ */
2009/** Special internal value indicating that we don't know the frequency.
2010 * @internal */
2011#define CPUM_SBUSFREQ_UNKNOWN UINT64_C(1)
2012#define CPUM_SBUSFREQ_100MHZ UINT64_C(100000000)
2013#define CPUM_SBUSFREQ_133MHZ UINT64_C(133333333)
2014#define CPUM_SBUSFREQ_167MHZ UINT64_C(166666666)
2015#define CPUM_SBUSFREQ_200MHZ UINT64_C(200000000)
2016#define CPUM_SBUSFREQ_267MHZ UINT64_C(266666666)
2017#define CPUM_SBUSFREQ_333MHZ UINT64_C(333333333)
2018#define CPUM_SBUSFREQ_400MHZ UINT64_C(400000000)
2019/** @} */
2020
2021
2022#ifdef IN_RING3
2023/** @defgroup grp_cpum_r3 The CPUM ring-3 API
2024 * @{
2025 */
2026
2027VMMR3DECL(int) CPUMR3Init(PVM pVM);
2028VMMR3DECL(int) CPUMR3InitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
2029VMMR3DECL(void) CPUMR3LogCpuIds(PVM pVM);
2030VMMR3DECL(void) CPUMR3Relocate(PVM pVM);
2031VMMR3DECL(int) CPUMR3Term(PVM pVM);
2032VMMR3DECL(void) CPUMR3Reset(PVM pVM);
2033VMMR3DECL(void) CPUMR3ResetCpu(PVM pVM, PVMCPU pVCpu);
2034VMMDECL(bool) CPUMR3IsStateRestorePending(PVM pVM);
2035VMMR3DECL(int) CPUMR3SetCR4Feature(PVM pVM, RTHCUINTREG fOr, RTHCUINTREG fAnd);
2036
2037VMMR3DECL(int) CPUMR3CpuIdInsert(PVM pVM, PCPUMCPUIDLEAF pNewLeaf);
2038VMMR3DECL(int) CPUMR3CpuIdGetLeaf(PVM pVM, PCPUMCPUIDLEAF pLeaf, uint32_t uLeaf, uint32_t uSubLeaf);
2039VMMR3DECL(CPUMMICROARCH) CPUMR3CpuIdDetermineMicroarchEx(CPUMCPUVENDOR enmVendor, uint8_t bFamily,
2040 uint8_t bModel, uint8_t bStepping);
2041VMMR3DECL(const char *) CPUMR3MicroarchName(CPUMMICROARCH enmMicroarch);
2042VMMR3DECL(int) CPUMR3CpuIdCollectLeaves(PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves);
2043VMMR3DECL(int) CPUMR3CpuIdDetectUnknownLeafMethod(PCPUMUNKNOWNCPUID penmUnknownMethod, PCPUMCPUID pDefUnknown);
2044VMMR3DECL(const char *) CPUMR3CpuIdUnknownLeafMethodName(CPUMUNKNOWNCPUID enmUnknownMethod);
2045VMMR3DECL(CPUMCPUVENDOR) CPUMR3CpuIdDetectVendorEx(uint32_t uEAX, uint32_t uEBX, uint32_t uECX, uint32_t uEDX);
2046VMMR3DECL(const char *) CPUMR3CpuVendorName(CPUMCPUVENDOR enmVendor);
2047VMMR3DECL(uint32_t) CPUMR3DeterminHostMxCsrMask(void);
2048
2049VMMR3DECL(int) CPUMR3MsrRangesInsert(PVM pVM, PCCPUMMSRRANGE pNewRange);
2050
2051# if defined(VBOX_WITH_RAW_MODE) || defined(DOXYGEN_RUNNING)
2052/** @name APIs for the CPUID raw-mode patch (legacy).
2053 * @{ */
2054VMMR3_INT_DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdPatmDefRCPtr(PVM pVM);
2055VMMR3_INT_DECL(uint32_t) CPUMR3GetGuestCpuIdPatmStdMax(PVM pVM);
2056VMMR3_INT_DECL(uint32_t) CPUMR3GetGuestCpuIdPatmExtMax(PVM pVM);
2057VMMR3_INT_DECL(uint32_t) CPUMR3GetGuestCpuIdPatmCentaurMax(PVM pVM);
2058VMMR3_INT_DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdPatmStdRCPtr(PVM pVM);
2059VMMR3_INT_DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdPatmExtRCPtr(PVM pVM);
2060VMMR3_INT_DECL(RCPTRTYPE(PCCPUMCPUID)) CPUMR3GetGuestCpuIdPatmCentaurRCPtr(PVM pVM);
2061/** @} */
2062# endif
2063
2064/** @} */
2065#endif /* IN_RING3 */
2066
2067#ifdef IN_RC
2068/** @defgroup grp_cpum_rc The CPUM Raw-mode Context API
2069 * @{
2070 */
2071
2072/**
2073 * Calls a guest trap/interrupt handler directly
2074 *
2075 * Assumes a trap stack frame has already been setup on the guest's stack!
2076 * This function does not return!
2077 *
2078 * @param pRegFrame Original trap/interrupt context
2079 * @param selCS Code selector of handler
2080 * @param pHandler GC virtual address of handler
2081 * @param eflags Callee's EFLAGS
2082 * @param selSS Stack selector for handler
2083 * @param pEsp Stack address for handler
2084 */
2085DECLASM(void) CPUMGCCallGuestTrapHandler(PCPUMCTXCORE pRegFrame, uint32_t selCS, RTRCPTR pHandler,
2086 uint32_t eflags, uint32_t selSS, RTRCPTR pEsp);
2087
2088/**
2089 * Call guest V86 code directly.
2090 *
2091 * This function does not return!
2092 *
2093 * @param pRegFrame Original trap/interrupt context
2094 */
2095DECLASM(void) CPUMGCCallV86Code(PCPUMCTXCORE pRegFrame);
2096
2097VMMDECL(int) CPUMHandleLazyFPU(PVMCPU pVCpu);
2098VMMDECL(uint32_t) CPUMRCGetGuestCPL(PVMCPU pVCpu, PCPUMCTXCORE pRegFrame);
2099#ifdef VBOX_WITH_RAW_RING1
2100VMMDECL(void) CPUMRCRecheckRawState(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore);
2101#endif
2102VMMRCDECL(void) CPUMRCProcessForceFlag(PVMCPU pVCpu);
2103
2104/** @} */
2105#endif /* IN_RC */
2106
2107#ifdef IN_RING0
2108/** @defgroup grp_cpum_r0 The CPUM ring-0 API
2109 * @{
2110 */
2111VMMR0_INT_DECL(int) CPUMR0ModuleInit(void);
2112VMMR0_INT_DECL(int) CPUMR0ModuleTerm(void);
2113VMMR0_INT_DECL(int) CPUMR0InitVM(PVM pVM);
2114DECLASM(void) CPUMR0RegisterVCpuThread(PVMCPU pVCpu);
2115DECLASM(void) CPUMR0TouchHostFpu(void);
2116VMMR0_INT_DECL(int) CPUMR0Trap07Handler(PVM pVM, PVMCPU pVCpu);
2117VMMR0_INT_DECL(int) CPUMR0LoadGuestFPU(PVM pVM, PVMCPU pVCpu);
2118VMMR0_INT_DECL(bool) CPUMR0FpuStateMaybeSaveGuestAndRestoreHost(PVMCPU pVCpu);
2119VMMR0_INT_DECL(int) CPUMR0SaveHostDebugState(PVM pVM, PVMCPU pVCpu);
2120VMMR0_INT_DECL(bool) CPUMR0DebugStateMaybeSaveGuestAndRestoreHost(PVMCPU pVCpu, bool fDr6);
2121VMMR0_INT_DECL(bool) CPUMR0DebugStateMaybeSaveGuest(PVMCPU pVCpu, bool fDr6);
2122
2123VMMR0_INT_DECL(void) CPUMR0LoadGuestDebugState(PVMCPU pVCpu, bool fDr6);
2124VMMR0_INT_DECL(void) CPUMR0LoadHyperDebugState(PVMCPU pVCpu, bool fDr6);
2125#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
2126VMMR0_INT_DECL(void) CPUMR0SetLApic(PVMCPU pVCpu, uint32_t iHostCpuSet);
2127#endif
2128
2129/** @} */
2130#endif /* IN_RING0 */
2131
2132/** @defgroup grp_cpum_rz The CPUM raw-mode and ring-0 context API
2133 * @{
2134 */
2135VMMRZ_INT_DECL(void) CPUMRZFpuStatePrepareHostCpuForUse(PVMCPU pVCpu);
2136VMMRZ_INT_DECL(void) CPUMRZFpuStateActualizeForRead(PVMCPU pVCpu);
2137VMMRZ_INT_DECL(void) CPUMRZFpuStateActualizeForChange(PVMCPU pVCpu);
2138VMMRZ_INT_DECL(void) CPUMRZFpuStateActualizeSseForRead(PVMCPU pVCpu);
2139VMMRZ_INT_DECL(void) CPUMRZFpuStateActualizeAvxForRead(PVMCPU pVCpu);
2140/** @} */
2141
2142
2143#endif /* !VBOX_FOR_DTRACE_LIB */
2144/** @} */
2145RT_C_DECLS_END
2146
2147
2148#endif
2149
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