VirtualBox

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

Last change on this file since 11424 was 10687, checked in by vboxsync, 16 years ago

Save the FPU control word and MXCSR on entry and restore them afterwards. (VT-x & AMD-V)
Security measure so the guest can't cause fpu/sse exceptions as we no longer restore the entire
host fpu state.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 10.4 KB
Line 
1/* $Id: CPUMInternal.h 10687 2008-07-16 09:22:28Z vboxsync $ */
2/** @file
3 * CPUM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#ifndef ___CPUMInternal_h
23#define ___CPUMInternal_h
24
25#include <VBox/cdefs.h>
26#include <VBox/types.h>
27#include <VBox/x86.h>
28
29
30#if !defined(IN_CPUM_R3) && !defined(IN_CPUM_R0) && !defined(IN_CPUM_GC)
31# error "Not in CPUM! This is an internal header!"
32#endif
33
34
35/** @defgroup grp_cpum_int Internals
36 * @ingroup grp_cpum
37 * @internal
38 * @{
39 */
40
41/** Flags and types for CPUM fault handlers
42 * @{ */
43/** Type: Load DS */
44#define CPUM_HANDLER_DS 1
45/** Type: Load ES */
46#define CPUM_HANDLER_ES 2
47/** Type: Load FS */
48#define CPUM_HANDLER_FS 3
49/** Type: Load GS */
50#define CPUM_HANDLER_GS 4
51/** Type: IRET */
52#define CPUM_HANDLER_IRET 5
53/** Type mask. */
54#define CPUM_HANDLER_TYPEMASK 0xff
55/** If set EBP points to the CPUMCTXCORE that's being used. */
56#define CPUM_HANDLER_CTXCORE_IN_EBP RT_BIT(31)
57/** @} */
58
59
60/** Use flags (CPUM::fUseFlags).
61 * (Don't forget to sync this with CPUMInternal.mac!)
62 * @{ */
63/** Used the FPU, SSE or such stuff. */
64#define CPUM_USED_FPU RT_BIT(0)
65/** Used the FPU, SSE or such stuff since last we were in REM.
66 * REM syncing is clearing this, lazy FPU is setting it. */
67#define CPUM_USED_FPU_SINCE_REM RT_BIT(1)
68/** Host OS is using SYSENTER and we must NULL the CS. */
69#define CPUM_USE_SYSENTER RT_BIT(2)
70/** Host OS is using SYSENTER and we must NULL the CS. */
71#define CPUM_USE_SYSCALL RT_BIT(3)
72/** Debug registers are used by host and must be disabled. */
73#define CPUM_USE_DEBUG_REGS_HOST RT_BIT(4)
74/** Enabled use of debug registers in guest context. */
75#define CPUM_USE_DEBUG_REGS RT_BIT(5)
76/** The XMM state was manually restored. (AMD only) */
77#define CPUM_MANUAL_XMM_RESTORE RT_BIT(6)
78/** @} */
79
80/* Sanity check. */
81#if defined(VBOX_WITH_HYBIRD_32BIT_KERNEL) && (HC_ARCH_BITS != 32 || R0_ARCH_BITS != 32)
82# error "VBOX_WITH_HYBIRD_32BIT_KERNEL is only for 32 bit builds."
83#endif
84
85
86/**
87 * The save host CPU state.
88 *
89 * @remark The special VBOX_WITH_HYBIRD_32BIT_KERNEL checks here are for the 10.4.x series
90 * of Mac OS X where the OS is essentially 32-bit but the cpu mode can be 64-bit.
91 */
92typedef struct CPUMHOSTCTX
93{
94 /** FPU state. (16-byte alignment)
95 * @remark On x86, the format isn't necessarily X86FXSTATE (not important). */
96 X86FXSTATE fpu;
97
98 /** General purpose register, selectors, flags and more
99 * @{ */
100#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBIRD_32BIT_KERNEL)
101 /** General purpose register ++
102 * { */
103 //uint64_t rax; - scratch
104 uint64_t rbx;
105 //uint64_t rcx; - scratch
106 //uint64_t rdx; - scratch
107 uint64_t rdi;
108 uint64_t rsi;
109 uint64_t rbp;
110 uint64_t rsp;
111 //uint64_t r8; - scratch
112 //uint64_t r9; - scratch
113 uint64_t r10;
114 uint64_t r11;
115 uint64_t r12;
116 uint64_t r13;
117 uint64_t r14;
118 uint64_t r15;
119 //uint64_t rip; - scratch
120 uint64_t rflags;
121#endif
122
123#if HC_ARCH_BITS == 32
124 //uint32_t eax; - scratch
125 uint32_t ebx;
126 //uint32_t ecx; - scratch
127 //uint32_t edx; - scratch
128 uint32_t edi;
129 uint32_t esi;
130 uint32_t ebp;
131 X86EFLAGS eflags;
132 //uint32_t eip; - scratch
133 /* lss pair! */
134 uint32_t esp;
135#endif
136 /** @} */
137
138 /** Selector registers
139 * @{ */
140 RTSEL ss;
141 RTSEL ssPadding;
142 RTSEL gs;
143 RTSEL gsPadding;
144 RTSEL fs;
145 RTSEL fsPadding;
146 RTSEL es;
147 RTSEL esPadding;
148 RTSEL ds;
149 RTSEL dsPadding;
150 RTSEL cs;
151 RTSEL csPadding;
152 /** @} */
153
154#if HC_ARCH_BITS == 32 && !defined(VBOX_WITH_HYBIRD_32BIT_KERNEL)
155 /** Control registers.
156 * @{ */
157 uint32_t cr0;
158 //uint32_t cr2; - scratch
159 uint32_t cr3;
160 uint32_t cr4;
161 /** @} */
162
163 /** Debug registers.
164 * @{ */
165 uint32_t dr0;
166 uint32_t dr1;
167 uint32_t dr2;
168 uint32_t dr3;
169 uint32_t dr6;
170 uint32_t dr7;
171 /** @} */
172
173 /** Global Descriptor Table register. */
174 X86XDTR32 gdtr;
175 uint16_t gdtrPadding;
176 /** Interrupt Descriptor Table register. */
177 X86XDTR32 idtr;
178 uint16_t idtrPadding;
179 /** The task register. */
180 RTSEL ldtr;
181 RTSEL ldtrPadding;
182 /** The task register. */
183 RTSEL tr;
184 RTSEL trPadding;
185 uint32_t SysEnterPadding;
186
187 /** The sysenter msr registers.
188 * This member is not used by the hypervisor context. */
189 CPUMSYSENTER SysEnter;
190
191 /* padding to get 32byte aligned size */
192 uint8_t auPadding[24];
193
194#elif HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBIRD_32BIT_KERNEL)
195
196 /** Control registers.
197 * @{ */
198 uint64_t cr0;
199 //uint64_t cr2; - scratch
200 uint64_t cr3;
201 uint64_t cr4;
202 uint64_t cr8;
203 /** @} */
204
205 /** Debug registers.
206 * @{ */
207 uint64_t dr0;
208 uint64_t dr1;
209 uint64_t dr2;
210 uint64_t dr3;
211 uint64_t dr6;
212 uint64_t dr7;
213 /** @} */
214
215 /** Global Descriptor Table register. */
216 X86XDTR64 gdtr;
217 uint16_t gdtrPadding;
218 /** Interrupt Descriptor Table register. */
219 X86XDTR64 idtr;
220 uint16_t idtrPadding;
221 /** The task register. */
222 RTSEL ldtr;
223 RTSEL ldtrPadding;
224 /** The task register. */
225 RTSEL tr;
226 RTSEL trPadding;
227
228 /** MSRs
229 * @{ */
230 CPUMSYSENTER SysEnter;
231 uint64_t FSbase;
232 uint64_t GSbase;
233 uint64_t efer;
234 /** @} */
235
236 /* padding to get 32byte aligned size */
237# ifdef VBOX_WITH_HYBIRD_32BIT_KERNEL
238 uint8_t auPadding[16];
239# else
240 uint8_t auPadding[8];
241# endif
242
243#else
244# error HC_ARCH_BITS not defined
245#endif
246} CPUMHOSTCTX, *PCPUMHOSTCTX;
247
248
249/**
250 * Converts a CPUM pointer into a VM pointer.
251 * @returns Pointer to the VM structure the CPUM is part of.
252 * @param pCPUM Pointer to CPUM instance data.
253 */
254#define CPUM2VM(pCPUM) ( (PVM)((char*)pCPUM - pCPUM->offVM) )
255
256
257/**
258 * CPUM Data (part of VM)
259 */
260#pragma pack(1)
261typedef struct CPUM
262{
263 /** Offset to the VM structure. */
264 RTUINT offVM;
265 /** Pointer to CPU structure in GC. */
266 RCPTRTYPE(struct CPUM *) pCPUMGC;
267 /** Pointer to CPU structure in HC. */
268 R3R0PTRTYPE(struct CPUM *) pCPUMHC;
269
270 /** Force 32byte alignment of the next member. */
271 uint32_t padding[4 + (HC_ARCH_BITS == 32)];
272
273 /**
274 * Saved host context. Only valid while inside GC.
275 * Must be aligned on 16 byte boundrary.
276 */
277 CPUMHOSTCTX Host;
278
279 /**
280 * Hypervisor context.
281 * Must be aligned on 16 byte boundrary.
282 */
283 CPUMCTX Hyper;
284
285 /**
286 * Guest context.
287 * Must be aligned on 16 byte boundrary.
288 */
289 CPUMCTX Guest;
290
291
292 /** Pointer to the current hypervisor core context - R3Ptr. */
293 R3PTRTYPE(PCPUMCTXCORE) pHyperCoreR3;
294 /** Pointer to the current hypervisor core context - R3Ptr. */
295 R0PTRTYPE(PCPUMCTXCORE) pHyperCoreR0;
296 /** Pointer to the current hypervisor core context - GCPtr. */
297 RCPTRTYPE(PCPUMCTXCORE) pHyperCoreGC;
298
299 /** Use flags.
300 * These flags indicates both what is to be used and what have been used.
301 */
302 uint32_t fUseFlags;
303
304 /** Changed flags.
305 * These flags indicates to REM (and others) which important guest
306 * registers which has been changed since last time the flags were cleared.
307 * See the CPUM_CHANGED_* defines for what we keep track of.
308 */
309 uint32_t fChanged;
310
311 /** Hidden selector registers state.
312 * Valid (hw accelerated raw mode) or not (normal raw mode)
313 */
314 uint32_t fValidHiddenSelRegs;
315
316 /** Host CPU Features - ECX */
317 struct
318 {
319 /** edx part */
320 X86CPUIDFEATEDX edx;
321 /** ecx part */
322 X86CPUIDFEATECX ecx;
323 } CPUFeatures;
324 /** Host extended CPU features. */
325 struct
326 {
327 /** edx part */
328 uint32_t edx;
329 /** ecx part */
330 uint32_t ecx;
331 } CPUFeaturesExt;
332
333 /* CPU manufacturer. */
334 CPUMCPUVENDOR enmCPUVendor;
335
336 /** CR4 mask */
337 struct
338 {
339 uint32_t AndMask;
340 uint32_t OrMask;
341 } CR4;
342
343 /** Have we entered rawmode? */
344 bool fRawEntered;
345 uint8_t abPadding[3 + (HC_ARCH_BITS == 64) * 4];
346
347 /** The standard set of CpuId leafs. */
348 CPUMCPUID aGuestCpuIdStd[6];
349 /** The extended set of CpuId leafs. */
350 CPUMCPUID aGuestCpuIdExt[10];
351 /** The centaur set of CpuId leafs. */
352 CPUMCPUID aGuestCpuIdCentaur[4];
353 /** The default set of CpuId leafs. */
354 CPUMCPUID GuestCpuIdDef;
355
356 /**
357 * Guest context on raw mode entry.
358 * This a debug feature.
359 */
360 CPUMCTX GuestEntry;
361} CPUM, *PCPUM;
362#pragma pack()
363
364#ifdef IN_RING3
365
366#endif
367
368__BEGIN_DECLS
369
370DECLASM(int) CPUMHandleLazyFPUAsm(PCPUM pCPUM);
371DECLASM(int) CPUMRestoreHostFPUStateAsm(PCPUM pCPUM);
372DECLASM(void) CPUMLoadFPUAsm(PCPUMCTX pCtx);
373DECLASM(void) CPUMSaveFPUAsm(PCPUMCTX pCtx);
374DECLASM(void) CPUMLoadXMMAsm(PCPUMCTX pCtx);
375DECLASM(void) CPUMSaveXMMAsm(PCPUMCTX pCtx);
376DECLASM(void) CPUMSetFCW(uint16_t u16FCW);
377DECLASM(uint16_t) CPUMGetFCW();
378DECLASM(void) CPUMSetMXCSR(uint32_t u32MXCSR);
379DECLASM(uint32_t) CPUMGetMXCSR();
380
381__END_DECLS
382
383/** @} */
384
385#endif
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