VirtualBox

source: vbox/trunk/src/VBox/VMM/include/CPUMInternal.h@ 60189

Last change on this file since 60189 was 58996, checked in by vboxsync, 9 years ago

CPUM: dtrace library fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 18.4 KB
Line 
1/* $Id: CPUMInternal.h 58996 2015-12-04 17:05:11Z vboxsync $ */
2/** @file
3 * CPUM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#ifndef ___CPUMInternal_h
19#define ___CPUMInternal_h
20
21#ifndef VBOX_FOR_DTRACE_LIB
22# include <VBox/cdefs.h>
23# include <VBox/types.h>
24# include <VBox/vmm/stam.h>
25# include <iprt/x86.h>
26#else
27# pragma D depends_on library x86.d
28# pragma D depends_on library cpumctx.d
29# pragma D depends_on library cpum.d
30
31/* Some fudging. */
32typedef uint64_t STAMCOUNTER;
33#endif
34
35
36
37
38/** @defgroup grp_cpum_int Internals
39 * @ingroup grp_cpum
40 * @internal
41 * @{
42 */
43
44/** Flags and types for CPUM fault handlers
45 * @{ */
46/** Type: Load DS */
47#define CPUM_HANDLER_DS 1
48/** Type: Load ES */
49#define CPUM_HANDLER_ES 2
50/** Type: Load FS */
51#define CPUM_HANDLER_FS 3
52/** Type: Load GS */
53#define CPUM_HANDLER_GS 4
54/** Type: IRET */
55#define CPUM_HANDLER_IRET 5
56/** Type mask. */
57#define CPUM_HANDLER_TYPEMASK 0xff
58/** If set EBP points to the CPUMCTXCORE that's being used. */
59#define CPUM_HANDLER_CTXCORE_IN_EBP RT_BIT(31)
60/** @} */
61
62
63/** Use flags (CPUM::fUseFlags).
64 * (Don't forget to sync this with CPUMInternal.mac !)
65 * @{ */
66/** Used the FPU, SSE or such stuff. */
67#define CPUM_USED_FPU RT_BIT(0)
68/** Used the FPU, SSE or such stuff since last we were in REM.
69 * REM syncing is clearing this, lazy FPU is setting it. */
70#define CPUM_USED_FPU_SINCE_REM RT_BIT(1)
71/** The XMM state was manually restored. (AMD only) */
72#define CPUM_USED_MANUAL_XMM_RESTORE RT_BIT(2)
73
74/** Host OS is using SYSENTER and we must NULL the CS. */
75#define CPUM_USE_SYSENTER RT_BIT(3)
76/** Host OS is using SYSENTER and we must NULL the CS. */
77#define CPUM_USE_SYSCALL RT_BIT(4)
78
79/** Debug registers are used by host and that DR7 and DR6 must be saved and
80 * disabled when switching to raw-mode. */
81#define CPUM_USE_DEBUG_REGS_HOST RT_BIT(5)
82/** Records that we've saved the host DRx registers.
83 * In ring-0 this means all (DR0-7), while in raw-mode context this means DR0-3
84 * since DR6 and DR7 are covered by CPUM_USE_DEBUG_REGS_HOST. */
85#define CPUM_USED_DEBUG_REGS_HOST RT_BIT(6)
86/** Set to indicate that we should save host DR0-7 and load the hypervisor debug
87 * registers in the raw-mode world switchers. (See CPUMRecalcHyperDRx.) */
88#define CPUM_USE_DEBUG_REGS_HYPER RT_BIT(7)
89/** Used in ring-0 to indicate that we have loaded the hypervisor debug
90 * registers. */
91#define CPUM_USED_DEBUG_REGS_HYPER RT_BIT(8)
92/** Used in ring-0 to indicate that we have loaded the guest debug
93 * registers (DR0-3 and maybe DR6) for direct use by the guest.
94 * DR7 (and AMD-V DR6) are handled via the VMCB. */
95#define CPUM_USED_DEBUG_REGS_GUEST RT_BIT(9)
96
97
98/** Sync the FPU state on next entry (32->64 switcher only). */
99#define CPUM_SYNC_FPU_STATE RT_BIT(16)
100/** Sync the debug state on next entry (32->64 switcher only). */
101#define CPUM_SYNC_DEBUG_REGS_GUEST RT_BIT(17)
102/** Sync the debug state on next entry (32->64 switcher only).
103 * Almost the same as CPUM_USE_DEBUG_REGS_HYPER in the raw-mode switchers. */
104#define CPUM_SYNC_DEBUG_REGS_HYPER RT_BIT(18)
105/** Host CPU requires fxsave/fxrstor leaky bit handling. */
106#define CPUM_USE_FFXSR_LEAKY RT_BIT(19)
107/** Set if the VM supports long-mode. */
108#define CPUM_USE_SUPPORTS_LONGMODE RT_BIT(20)
109/** @} */
110
111
112/** @name CPUM Saved State Version.
113 * @{ */
114/** The current saved state version. */
115#define CPUM_SAVED_STATE_VERSION CPUM_SAVED_STATE_VERSION_XSAVE
116/** The saved state version including XSAVE state. */
117#define CPUM_SAVED_STATE_VERSION_XSAVE 17
118/** The saved state version with good CPUID leaf count. */
119#define CPUM_SAVED_STATE_VERSION_GOOD_CPUID_COUNT 16
120/** CPUID changes with explode forgetting to update the leaf count on
121 * restore, resulting in garbage being saved restoring+saving old states). */
122#define CPUM_SAVED_STATE_VERSION_BAD_CPUID_COUNT 15
123/** The saved state version before the CPUIDs changes. */
124#define CPUM_SAVED_STATE_VERSION_PUT_STRUCT 14
125/** The saved state version before using SSMR3PutStruct. */
126#define CPUM_SAVED_STATE_VERSION_MEM 13
127/** The saved state version before introducing the MSR size field. */
128#define CPUM_SAVED_STATE_VERSION_NO_MSR_SIZE 12
129/** The saved state version of 3.2, 3.1 and 3.3 trunk before the hidden
130 * selector register change (CPUM_CHANGED_HIDDEN_SEL_REGS_INVALID). */
131#define CPUM_SAVED_STATE_VERSION_VER3_2 11
132/** The saved state version of 3.0 and 3.1 trunk before the teleportation
133 * changes. */
134#define CPUM_SAVED_STATE_VERSION_VER3_0 10
135/** The saved state version for the 2.1 trunk before the MSR changes. */
136#define CPUM_SAVED_STATE_VERSION_VER2_1_NOMSR 9
137/** The saved state version of 2.0, used for backwards compatibility. */
138#define CPUM_SAVED_STATE_VERSION_VER2_0 8
139/** The saved state version of 1.6, used for backwards compatibility. */
140#define CPUM_SAVED_STATE_VERSION_VER1_6 6
141/** @} */
142
143
144/**
145 * CPU info
146 */
147typedef struct CPUMINFO
148{
149 /** The number of MSR ranges (CPUMMSRRANGE) in the array pointed to below. */
150 uint32_t cMsrRanges;
151 /** Mask applied to ECX before looking up the MSR for a RDMSR/WRMSR
152 * instruction. Older hardware has been observed to ignore higher bits. */
153 uint32_t fMsrMask;
154
155 /** The number of CPUID leaves (CPUMCPUIDLEAF) in the array pointed to below. */
156 uint32_t cCpuIdLeaves;
157 /** The index of the first extended CPUID leaf in the array.
158 * Set to cCpuIdLeaves if none present. */
159 uint32_t iFirstExtCpuIdLeaf;
160 /** Alignment padding. */
161 uint32_t uPadding;
162 /** How to handle unknown CPUID leaves. */
163 CPUMUNKNOWNCPUID enmUnknownCpuIdMethod;
164 /** For use with CPUMUNKNOWNCPUID_DEFAULTS (DB & VM),
165 * CPUMUNKNOWNCPUID_LAST_STD_LEAF (VM) and CPUMUNKNOWNCPUID_LAST_STD_LEAF_WITH_ECX (VM). */
166 CPUMCPUID DefCpuId;
167
168 /** Scalable bus frequency used for reporting other frequencies. */
169 uint64_t uScalableBusFreq;
170
171 /** Pointer to the MSR ranges (ring-0 pointer). */
172 R0PTRTYPE(PCPUMMSRRANGE) paMsrRangesR0;
173 /** Pointer to the CPUID leaves (ring-0 pointer). */
174 R0PTRTYPE(PCPUMCPUIDLEAF) paCpuIdLeavesR0;
175
176 /** Pointer to the MSR ranges (ring-3 pointer). */
177 R3PTRTYPE(PCPUMMSRRANGE) paMsrRangesR3;
178 /** Pointer to the CPUID leaves (ring-3 pointer). */
179 R3PTRTYPE(PCPUMCPUIDLEAF) paCpuIdLeavesR3;
180
181 /** Pointer to the MSR ranges (raw-mode context pointer). */
182 RCPTRTYPE(PCPUMMSRRANGE) paMsrRangesRC;
183 /** Pointer to the CPUID leaves (raw-mode context pointer). */
184 RCPTRTYPE(PCPUMCPUIDLEAF) paCpuIdLeavesRC;
185} CPUMINFO;
186/** Pointer to a CPU info structure. */
187typedef CPUMINFO *PCPUMINFO;
188/** Pointer to a const CPU info structure. */
189typedef CPUMINFO const *CPCPUMINFO;
190
191
192/**
193 * The saved host CPU state.
194 */
195typedef struct CPUMHOSTCTX
196{
197 /** General purpose register, selectors, flags and more
198 * @{ */
199#if HC_ARCH_BITS == 64
200 /** General purpose register ++
201 * { */
202 /*uint64_t rax; - scratch*/
203 uint64_t rbx;
204 /*uint64_t rcx; - scratch*/
205 /*uint64_t rdx; - scratch*/
206 uint64_t rdi;
207 uint64_t rsi;
208 uint64_t rbp;
209 uint64_t rsp;
210 /*uint64_t r8; - scratch*/
211 /*uint64_t r9; - scratch*/
212 uint64_t r10;
213 uint64_t r11;
214 uint64_t r12;
215 uint64_t r13;
216 uint64_t r14;
217 uint64_t r15;
218 /*uint64_t rip; - scratch*/
219 uint64_t rflags;
220#endif
221
222#if HC_ARCH_BITS == 32
223 /*uint32_t eax; - scratch*/
224 uint32_t ebx;
225 /*uint32_t ecx; - scratch*/
226 /*uint32_t edx; - scratch*/
227 uint32_t edi;
228 uint32_t esi;
229 uint32_t ebp;
230 X86EFLAGS eflags;
231 /*uint32_t eip; - scratch*/
232 /* lss pair! */
233 uint32_t esp;
234#endif
235 /** @} */
236
237 /** Selector registers
238 * @{ */
239 RTSEL ss;
240 RTSEL ssPadding;
241 RTSEL gs;
242 RTSEL gsPadding;
243 RTSEL fs;
244 RTSEL fsPadding;
245 RTSEL es;
246 RTSEL esPadding;
247 RTSEL ds;
248 RTSEL dsPadding;
249 RTSEL cs;
250 RTSEL csPadding;
251 /** @} */
252
253#if HC_ARCH_BITS == 32
254 /** Control registers.
255 * @{ */
256 uint32_t cr0;
257 /*uint32_t cr2; - scratch*/
258 uint32_t cr3;
259 uint32_t cr4;
260 /** @} */
261
262 /** Debug registers.
263 * @{ */
264 uint32_t dr0;
265 uint32_t dr1;
266 uint32_t dr2;
267 uint32_t dr3;
268 uint32_t dr6;
269 uint32_t dr7;
270 /** @} */
271
272 /** Global Descriptor Table register. */
273 X86XDTR32 gdtr;
274 uint16_t gdtrPadding;
275 /** Interrupt Descriptor Table register. */
276 X86XDTR32 idtr;
277 uint16_t idtrPadding;
278 /** The task register. */
279 RTSEL ldtr;
280 RTSEL ldtrPadding;
281 /** The task register. */
282 RTSEL tr;
283 RTSEL trPadding;
284 uint32_t SysEnterPadding;
285
286 /** The sysenter msr registers.
287 * This member is not used by the hypervisor context. */
288 CPUMSYSENTER SysEnter;
289
290 /** MSRs
291 * @{ */
292 uint64_t efer;
293 /** @} */
294
295 /* padding to get 64byte aligned size */
296 uint8_t auPadding[20];
297
298#elif HC_ARCH_BITS == 64
299
300 /** Control registers.
301 * @{ */
302 uint64_t cr0;
303 /*uint64_t cr2; - scratch*/
304 uint64_t cr3;
305 uint64_t cr4;
306 uint64_t cr8;
307 /** @} */
308
309 /** Debug registers.
310 * @{ */
311 uint64_t dr0;
312 uint64_t dr1;
313 uint64_t dr2;
314 uint64_t dr3;
315 uint64_t dr6;
316 uint64_t dr7;
317 /** @} */
318
319 /** Global Descriptor Table register. */
320 X86XDTR64 gdtr;
321 uint16_t gdtrPadding;
322 /** Interrupt Descriptor Table register. */
323 X86XDTR64 idtr;
324 uint16_t idtrPadding;
325 /** The task register. */
326 RTSEL ldtr;
327 RTSEL ldtrPadding;
328 /** The task register. */
329 RTSEL tr;
330 RTSEL trPadding;
331
332 /** MSRs
333 * @{ */
334 CPUMSYSENTER SysEnter;
335 uint64_t FSbase;
336 uint64_t GSbase;
337 uint64_t efer;
338 /** @} */
339
340 /* padding to get 32byte aligned size */
341 uint8_t auPadding[4];
342
343#else
344# error HC_ARCH_BITS not defined or unsupported
345#endif
346
347 /** Pointer to the FPU/SSE/AVX/XXXX state raw-mode mapping. */
348 RCPTRTYPE(PX86XSAVEAREA) pXStateRC;
349 /** Pointer to the FPU/SSE/AVX/XXXX state ring-0 mapping. */
350 R0PTRTYPE(PX86XSAVEAREA) pXStateR0;
351 /** Pointer to the FPU/SSE/AVX/XXXX state ring-3 mapping. */
352 R3PTRTYPE(PX86XSAVEAREA) pXStateR3;
353 /** The XCR0 register. */
354 uint64_t xcr0;
355 /** The mask to pass to XSAVE/XRSTOR in EDX:EAX. If zero we use
356 * FXSAVE/FXRSTOR (since bit 0 will always be set, we only need to test it). */
357 uint64_t fXStateMask;
358} CPUMHOSTCTX;
359#ifndef VBOX_FOR_DTRACE_LIB
360AssertCompileSizeAlignment(CPUMHOSTCTX, 64);
361#endif
362/** Pointer to the saved host CPU state. */
363typedef CPUMHOSTCTX *PCPUMHOSTCTX;
364
365
366/**
367 * CPUM Data (part of VM)
368 */
369typedef struct CPUM
370{
371 /** Offset from CPUM to CPUMCPU for the first CPU. */
372 uint32_t offCPUMCPU0;
373
374 /** Use flags.
375 * These flags indicates which CPU features the host uses.
376 */
377 uint32_t fHostUseFlags;
378
379 /** CR4 mask */
380 struct
381 {
382 uint32_t AndMask; /**< @todo Move these to the per-CPU structure and fix the switchers. Saves a register! */
383 uint32_t OrMask;
384 } CR4;
385
386 /** The (more) portable CPUID level. */
387 uint8_t u8PortableCpuIdLevel;
388 /** Indicates that a state restore is pending.
389 * This is used to verify load order dependencies (PGM). */
390 bool fPendingRestore;
391 uint8_t abPadding0[6];
392
393 /** XSAVE/XRTOR components we can expose to the guest mask. */
394 uint64_t fXStateGuestMask;
395 /** XSAVE/XRSTOR host mask. Only state components in this mask can be exposed
396 * to the guest. This is 0 if no XSAVE/XRSTOR bits can be exposed. */
397 uint64_t fXStateHostMask;
398 uint8_t abPadding1[24];
399
400 /** Host CPU feature information.
401 * Externaly visible via the VM structure, aligned on 64-byte boundrary. */
402 CPUMFEATURES HostFeatures;
403 /** Guest CPU feature information.
404 * Externaly visible via that VM structure, aligned with HostFeatures. */
405 CPUMFEATURES GuestFeatures;
406 /** Guest CPU info. */
407 CPUMINFO GuestInfo;
408
409
410 /** The standard set of CpuId leaves. */
411 CPUMCPUID aGuestCpuIdPatmStd[6];
412 /** The extended set of CpuId leaves. */
413 CPUMCPUID aGuestCpuIdPatmExt[10];
414 /** The centaur set of CpuId leaves. */
415 CPUMCPUID aGuestCpuIdPatmCentaur[4];
416
417 /** @name MSR statistics.
418 * @{ */
419 STAMCOUNTER cMsrWrites;
420 STAMCOUNTER cMsrWritesToIgnoredBits;
421 STAMCOUNTER cMsrWritesRaiseGp;
422 STAMCOUNTER cMsrWritesUnknown;
423 STAMCOUNTER cMsrReads;
424 STAMCOUNTER cMsrReadsRaiseGp;
425 STAMCOUNTER cMsrReadsUnknown;
426 /** @} */
427} CPUM;
428#ifndef VBOX_FOR_DTRACE_LIB
429AssertCompileMemberOffset(CPUM, HostFeatures, 64);
430AssertCompileMemberOffset(CPUM, GuestFeatures, 96);
431#endif
432/** Pointer to the CPUM instance data residing in the shared VM structure. */
433typedef CPUM *PCPUM;
434
435/**
436 * CPUM Data (part of VMCPU)
437 */
438typedef struct CPUMCPU
439{
440 /**
441 * Guest context.
442 * Aligned on a 64-byte boundary.
443 */
444 CPUMCTX Guest;
445
446 /**
447 * Guest context - misc MSRs
448 * Aligned on a 64-byte boundary.
449 */
450 CPUMCTXMSRS GuestMsrs;
451
452 /** Use flags.
453 * These flags indicates both what is to be used and what has been used.
454 */
455 uint32_t fUseFlags;
456
457 /** Changed flags.
458 * These flags indicates to REM (and others) which important guest
459 * registers which has been changed since last time the flags were cleared.
460 * See the CPUM_CHANGED_* defines for what we keep track of.
461 */
462 uint32_t fChanged;
463
464 /** Offset from CPUM to CPUMCPU. */
465 uint32_t offCPUM;
466
467 /** Temporary storage for the return code of the function called in the
468 * 32-64 switcher. */
469 uint32_t u32RetCode;
470
471#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
472 /** The address of the APIC mapping, NULL if no APIC.
473 * Call CPUMR0SetLApic to update this before doing a world switch. */
474 RTHCPTR pvApicBase;
475 /** Used by the world switcher code to store which vectors needs restoring on
476 * the way back. */
477 uint32_t fApicDisVectors;
478 /** Set if the CPU has the X2APIC mode enabled.
479 * Call CPUMR0SetLApic to update this before doing a world switch. */
480 bool fX2Apic;
481#else
482 uint8_t abPadding3[(HC_ARCH_BITS == 64 ? 8 : 4) + 4 + 1];
483#endif
484
485 /** Have we entered raw-mode? */
486 bool fRawEntered;
487 /** Have we entered the recompiler? */
488 bool fRemEntered;
489
490 /** Align the next member on a 64-bit boundrary. */
491 uint8_t abPadding2[64 - 16 - (HC_ARCH_BITS == 64 ? 8 : 4) - 4 - 1 - 2];
492
493 /** Saved host context. Only valid while inside RC or HM contexts.
494 * Must be aligned on a 64-byte boundary. */
495 CPUMHOSTCTX Host;
496 /** Hypervisor context. Must be aligned on a 64-byte boundary. */
497 CPUMCTX Hyper;
498
499#ifdef VBOX_WITH_CRASHDUMP_MAGIC
500 uint8_t aMagic[56];
501 uint64_t uMagic;
502#endif
503} CPUMCPU;
504/** Pointer to the CPUMCPU instance data residing in the shared VMCPU structure. */
505typedef CPUMCPU *PCPUMCPU;
506
507#ifndef VBOX_FOR_DTRACE_LIB
508RT_C_DECLS_BEGIN
509
510PCPUMCPUIDLEAF cpumCpuIdGetLeaf(PVM pVM, uint32_t uLeaf);
511PCPUMCPUIDLEAF cpumCpuIdGetLeafEx(PVM pVM, uint32_t uLeaf, uint32_t uSubLeaf, bool *pfExactSubLeafHit);
512
513#ifdef IN_RING3
514int cpumR3DbgInit(PVM pVM);
515int cpumR3CpuIdExplodeFeatures(PCCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, PCPUMFEATURES pFeatures);
516int cpumR3InitCpuIdAndMsrs(PVM pVM);
517void cpumR3SaveCpuId(PVM pVM, PSSMHANDLE pSSM);
518int cpumR3LoadCpuId(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion);
519int cpumR3LoadCpuIdPre32(PVM pVM, PSSMHANDLE pSSM, uint32_t uVersion);
520DECLCALLBACK(void) cpumR3CpuIdInfo(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs);
521
522int cpumR3DbGetCpuInfo(const char *pszName, PCPUMINFO pInfo);
523int cpumR3MsrRangesInsert(PVM pVM, PCPUMMSRRANGE *ppaMsrRanges, uint32_t *pcMsrRanges, PCCPUMMSRRANGE pNewRange);
524int cpumR3MsrApplyFudge(PVM pVM);
525int cpumR3MsrRegStats(PVM pVM);
526int cpumR3MsrStrictInitChecks(void);
527PCPUMMSRRANGE cpumLookupMsrRange(PVM pVM, uint32_t idMsr);
528#endif
529
530#ifdef IN_RC
531DECLASM(int) cpumHandleLazyFPUAsm(PCPUMCPU pCPUM);
532#endif
533
534#ifdef IN_RING0
535DECLASM(int) cpumR0SaveHostRestoreGuestFPUState(PCPUMCPU pCPUM);
536DECLASM(int) cpumR0SaveGuestRestoreHostFPUState(PCPUMCPU pCPUM);
537DECLASM(int) cpumR0SaveHostFPUState(PCPUMCPU pCPUM);
538DECLASM(int) cpumR0RestoreHostFPUState(PCPUMCPU pCPUM);
539DECLASM(void) cpumR0LoadFPU(PCPUMCTX pCtx);
540DECLASM(void) cpumR0SaveFPU(PCPUMCTX pCtx);
541DECLASM(void) cpumR0LoadXMM(PCPUMCTX pCtx);
542DECLASM(void) cpumR0SaveXMM(PCPUMCTX pCtx);
543DECLASM(void) cpumR0SetFCW(uint16_t u16FCW);
544DECLASM(uint16_t) cpumR0GetFCW(void);
545DECLASM(void) cpumR0SetMXCSR(uint32_t u32MXCSR);
546DECLASM(uint32_t) cpumR0GetMXCSR(void);
547#endif
548
549RT_C_DECLS_END
550#endif /* !VBOX_FOR_DTRACE_LIB */
551
552/** @} */
553
554#endif
555
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