VirtualBox

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

Last change on this file since 34219 was 33935, checked in by vboxsync, 14 years ago

VMM: mask all Local APIC interrupt vectors which are set up to NMI mode during world switch (raw mode only)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 12.0 KB
Line 
1/* $Id: CPUMInternal.h 33935 2010-11-10 15:37:02Z vboxsync $ */
2/** @file
3 * CPUM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2007 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#include <VBox/cdefs.h>
22#include <VBox/types.h>
23#include <VBox/x86.h>
24
25
26
27/** @defgroup grp_cpum_int Internals
28 * @ingroup grp_cpum
29 * @internal
30 * @{
31 */
32
33/** Flags and types for CPUM fault handlers
34 * @{ */
35/** Type: Load DS */
36#define CPUM_HANDLER_DS 1
37/** Type: Load ES */
38#define CPUM_HANDLER_ES 2
39/** Type: Load FS */
40#define CPUM_HANDLER_FS 3
41/** Type: Load GS */
42#define CPUM_HANDLER_GS 4
43/** Type: IRET */
44#define CPUM_HANDLER_IRET 5
45/** Type mask. */
46#define CPUM_HANDLER_TYPEMASK 0xff
47/** If set EBP points to the CPUMCTXCORE that's being used. */
48#define CPUM_HANDLER_CTXCORE_IN_EBP RT_BIT(31)
49/** @} */
50
51
52/** Use flags (CPUM::fUseFlags).
53 * (Don't forget to sync this with CPUMInternal.mac!)
54 * @{ */
55/** Used the FPU, SSE or such stuff. */
56#define CPUM_USED_FPU RT_BIT(0)
57/** Used the FPU, SSE or such stuff since last we were in REM.
58 * REM syncing is clearing this, lazy FPU is setting it. */
59#define CPUM_USED_FPU_SINCE_REM RT_BIT(1)
60/** Host OS is using SYSENTER and we must NULL the CS. */
61#define CPUM_USE_SYSENTER RT_BIT(2)
62/** Host OS is using SYSENTER and we must NULL the CS. */
63#define CPUM_USE_SYSCALL RT_BIT(3)
64/** Debug registers are used by host and must be disabled. */
65#define CPUM_USE_DEBUG_REGS_HOST RT_BIT(4)
66/** Enabled use of debug registers in guest context. */
67#define CPUM_USE_DEBUG_REGS RT_BIT(5)
68/** The XMM state was manually restored. (AMD only) */
69#define CPUM_MANUAL_XMM_RESTORE RT_BIT(6)
70/** Sync the FPU state on entry (32->64 switcher only). */
71#define CPUM_SYNC_FPU_STATE RT_BIT(7)
72/** Sync the debug state on entry (32->64 switcher only). */
73#define CPUM_SYNC_DEBUG_STATE RT_BIT(8)
74/** Enabled use of hypervisor debug registers in guest context. */
75#define CPUM_USE_DEBUG_REGS_HYPER RT_BIT(9)
76/** @} */
77
78/* Sanity check. */
79#if defined(VBOX_WITH_HYBRID_32BIT_KERNEL) && (HC_ARCH_BITS != 32 || R0_ARCH_BITS != 32)
80# error "VBOX_WITH_HYBRID_32BIT_KERNEL is only for 32 bit builds."
81#endif
82
83
84/**
85 * The saved host CPU state.
86 *
87 * @remark The special VBOX_WITH_HYBRID_32BIT_KERNEL checks here are for the 10.4.x series
88 * of Mac OS X where the OS is essentially 32-bit but the cpu mode can be 64-bit.
89 */
90typedef struct CPUMHOSTCTX
91{
92 /** FPU state. (16-byte alignment)
93 * @remark On x86, the format isn't necessarily X86FXSTATE (not important). */
94 X86FXSTATE fpu;
95
96 /** General purpose register, selectors, flags and more
97 * @{ */
98#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
99 /** General purpose register ++
100 * { */
101 //uint64_t rax; - scratch
102 uint64_t rbx;
103 //uint64_t rcx; - scratch
104 //uint64_t rdx; - scratch
105 uint64_t rdi;
106 uint64_t rsi;
107 uint64_t rbp;
108 uint64_t rsp;
109 //uint64_t r8; - scratch
110 //uint64_t r9; - scratch
111 uint64_t r10;
112 uint64_t r11;
113 uint64_t r12;
114 uint64_t r13;
115 uint64_t r14;
116 uint64_t r15;
117 //uint64_t rip; - scratch
118 uint64_t rflags;
119#endif
120
121#if HC_ARCH_BITS == 32
122 //uint32_t eax; - scratch
123 uint32_t ebx;
124 //uint32_t ecx; - scratch
125 //uint32_t edx; - scratch
126 uint32_t edi;
127 uint32_t esi;
128 uint32_t ebp;
129 X86EFLAGS eflags;
130 //uint32_t eip; - scratch
131 /* lss pair! */
132 uint32_t esp;
133#endif
134 /** @} */
135
136 /** Selector registers
137 * @{ */
138 RTSEL ss;
139 RTSEL ssPadding;
140 RTSEL gs;
141 RTSEL gsPadding;
142 RTSEL fs;
143 RTSEL fsPadding;
144 RTSEL es;
145 RTSEL esPadding;
146 RTSEL ds;
147 RTSEL dsPadding;
148 RTSEL cs;
149 RTSEL csPadding;
150 /** @} */
151
152#if HC_ARCH_BITS == 32 && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
153 /** Control registers.
154 * @{ */
155 uint32_t cr0;
156 //uint32_t cr2; - scratch
157 uint32_t cr3;
158 uint32_t cr4;
159 /** @} */
160
161 /** Debug registers.
162 * @{ */
163 uint32_t dr0;
164 uint32_t dr1;
165 uint32_t dr2;
166 uint32_t dr3;
167 uint32_t dr6;
168 uint32_t dr7;
169 /** @} */
170
171 /** Global Descriptor Table register. */
172 X86XDTR32 gdtr;
173 uint16_t gdtrPadding;
174 /** Interrupt Descriptor Table register. */
175 X86XDTR32 idtr;
176 uint16_t idtrPadding;
177 /** The task register. */
178 RTSEL ldtr;
179 RTSEL ldtrPadding;
180 /** The task register. */
181 RTSEL tr;
182 RTSEL trPadding;
183 uint32_t SysEnterPadding;
184
185 /** The sysenter msr registers.
186 * This member is not used by the hypervisor context. */
187 CPUMSYSENTER SysEnter;
188
189 /** MSRs
190 * @{ */
191 uint64_t efer;
192 /** @} */
193
194 /* padding to get 64byte aligned size */
195 uint8_t auPadding[16+32];
196
197#elif HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
198
199 /** Control registers.
200 * @{ */
201 uint64_t cr0;
202 //uint64_t cr2; - scratch
203 uint64_t cr3;
204 uint64_t cr4;
205 uint64_t cr8;
206 /** @} */
207
208 /** Debug registers.
209 * @{ */
210 uint64_t dr0;
211 uint64_t dr1;
212 uint64_t dr2;
213 uint64_t dr3;
214 uint64_t dr6;
215 uint64_t dr7;
216 /** @} */
217
218 /** Global Descriptor Table register. */
219 X86XDTR64 gdtr;
220 uint16_t gdtrPadding;
221 /** Interrupt Descriptor Table register. */
222 X86XDTR64 idtr;
223 uint16_t idtrPadding;
224 /** The task register. */
225 RTSEL ldtr;
226 RTSEL ldtrPadding;
227 /** The task register. */
228 RTSEL tr;
229 RTSEL trPadding;
230
231 /** MSRs
232 * @{ */
233 CPUMSYSENTER SysEnter;
234 uint64_t FSbase;
235 uint64_t GSbase;
236 uint64_t efer;
237 /** @} */
238
239 /* padding to get 32byte aligned size */
240# ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
241 uint8_t auPadding[16];
242# else
243 uint8_t auPadding[8+32];
244# endif
245
246#else
247# error HC_ARCH_BITS not defined
248#endif
249} CPUMHOSTCTX;
250/** Pointer to the saved host CPU state. */
251typedef CPUMHOSTCTX *PCPUMHOSTCTX;
252
253
254/**
255 * CPUM Data (part of VM)
256 */
257typedef struct CPUM
258{
259 /** Offset from CPUM to CPUMCPU for the first CPU. */
260 uint32_t offCPUMCPU0;
261
262 /** Use flags.
263 * These flags indicates which CPU features the host uses.
264 */
265 uint32_t fHostUseFlags;
266
267 /** Host CPU Features - ECX */
268 struct
269 {
270 /** edx part */
271 X86CPUIDFEATEDX edx;
272 /** ecx part */
273 X86CPUIDFEATECX ecx;
274 } CPUFeatures;
275 /** Host extended CPU features. */
276 struct
277 {
278 /** edx part */
279 uint32_t edx;
280 /** ecx part */
281 uint32_t ecx;
282 } CPUFeaturesExt;
283
284 /** Host CPU manufacturer. */
285 CPUMCPUVENDOR enmHostCpuVendor;
286 /** Guest CPU manufacturer. */
287 CPUMCPUVENDOR enmGuestCpuVendor;
288
289 /** CR4 mask */
290 struct
291 {
292 uint32_t AndMask;
293 uint32_t OrMask;
294 } CR4;
295
296 /** Synthetic CPU type? */
297 bool fSyntheticCpu;
298 /** The (more) portable CPUID level. */
299 uint8_t u8PortableCpuIdLevel;
300 /** Indicates that a state restore is pending.
301 * This is used to verify load order dependencies (PGM). */
302 bool fPendingRestore;
303 uint8_t abPadding[HC_ARCH_BITS == 64 ? 5 : 1];
304
305 /** The standard set of CpuId leafs. */
306 CPUMCPUID aGuestCpuIdStd[6];
307 /** The extended set of CpuId leafs. */
308 CPUMCPUID aGuestCpuIdExt[10];
309 /** The centaur set of CpuId leafs. */
310 CPUMCPUID aGuestCpuIdCentaur[4];
311 /** The default set of CpuId leafs. */
312 CPUMCPUID GuestCpuIdDef;
313
314#if HC_ARCH_BITS == 32
315 uint8_t abPadding2[4];
316#endif
317
318#ifdef VBOX_WITH_VMMR0_DISABLE_LAPIC_NMI
319 RTHCPTR pvApicBase;
320 uint32_t fApicDisVectors;
321 uint8_t abPadding3[HC_ARCH_BITS == 32 ? 56 : 52];
322#endif
323
324 /**
325 * Guest context on raw mode entry. 64-byte aligned!
326 * This a debug feature, see CPUMR3SaveEntryCtx.
327 */
328 CPUMCTX GuestEntry;
329} CPUM;
330/** Pointer to the CPUM instance data residing in the shared VM structure. */
331typedef CPUM *PCPUM;
332
333/**
334 * CPUM Data (part of VMCPU)
335 */
336typedef struct CPUMCPU
337{
338 /**
339 * Hypervisor context.
340 * Aligned on a 64-byte boundary.
341 */
342 CPUMCTX Hyper;
343
344 /**
345 * Saved host context. Only valid while inside GC.
346 * Aligned on a 64-byte boundary.
347 */
348 CPUMHOSTCTX Host;
349
350#ifdef VBOX_WITH_CRASHDUMP_MAGIC
351 uint8_t aMagic[56];
352 uint64_t uMagic;
353#endif
354
355 /**
356 * Guest context.
357 * Aligned on a 64-byte boundary.
358 */
359 CPUMCTX Guest;
360
361 /**
362 * Guest context - misc MSRs
363 * Aligned on a 64-byte boundary.
364 */
365 CPUMCTXMSR GuestMsr;
366
367 /** Pointer to the current hypervisor core context - R3Ptr. */
368 R3PTRTYPE(PCPUMCTXCORE) pHyperCoreR3;
369 /** Pointer to the current hypervisor core context - R0Ptr. */
370 R0PTRTYPE(PCPUMCTXCORE) pHyperCoreR0;
371 /** Pointer to the current hypervisor core context - RCPtr. */
372 RCPTRTYPE(PCPUMCTXCORE) pHyperCoreRC;
373
374 /** Use flags.
375 * These flags indicates both what is to be used and what has been used.
376 */
377 uint32_t fUseFlags;
378
379 /** Changed flags.
380 * These flags indicates to REM (and others) which important guest
381 * registers which has been changed since last time the flags were cleared.
382 * See the CPUM_CHANGED_* defines for what we keep track of.
383 */
384 uint32_t fChanged;
385
386 /** Offset from CPUM to CPUMCPU. */
387 uint32_t offCPUM;
388
389 /** Temporary storage for the return code of the function called in the
390 * 32-64 switcher. */
391 uint32_t u32RetCode;
392
393 /** Have we entered raw-mode? */
394 bool fRawEntered;
395 /** Have we entered the recompiler? */
396 bool fRemEntered;
397
398 /** Align the structure on a 64-byte boundary. */
399 uint8_t abPadding2[HC_ARCH_BITS == 32 ? 34 : 26];
400} CPUMCPU, *PCPUMCPU;
401/** Pointer to the CPUMCPU instance data residing in the shared VMCPU structure. */
402typedef CPUMCPU *PCPUMCPU;
403
404RT_C_DECLS_BEGIN
405
406DECLASM(int) cpumHandleLazyFPUAsm(PCPUMCPU pCPUM);
407
408#ifdef IN_RING0
409DECLASM(int) cpumR0SaveHostRestoreGuestFPUState(PCPUMCPU pCPUM);
410DECLASM(int) cpumR0SaveGuestRestoreHostFPUState(PCPUMCPU pCPUM);
411DECLASM(int) cpumR0SaveHostFPUState(PCPUMCPU pCPUM);
412DECLASM(int) cpumR0RestoreHostFPUState(PCPUMCPU pCPUM);
413DECLASM(void) cpumR0LoadFPU(PCPUMCTX pCtx);
414DECLASM(void) cpumR0SaveFPU(PCPUMCTX pCtx);
415DECLASM(void) cpumR0LoadXMM(PCPUMCTX pCtx);
416DECLASM(void) cpumR0SaveXMM(PCPUMCTX pCtx);
417DECLASM(void) cpumR0SetFCW(uint16_t u16FCW);
418DECLASM(uint16_t) cpumR0GetFCW(void);
419DECLASM(void) cpumR0SetMXCSR(uint32_t u32MXCSR);
420DECLASM(uint32_t) cpumR0GetMXCSR(void);
421DECLASM(void) cpumR0LoadDRx(uint64_t const *pa4Regs);
422DECLASM(void) cpumR0SaveDRx(uint64_t *pa4Regs);
423#endif
424
425RT_C_DECLS_END
426
427/** @} */
428
429#endif
430
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