VirtualBox

source: vbox/trunk/include/VBox/vmm/cpumctx.h@ 55000

Last change on this file since 55000 was 54999, checked in by vboxsync, 10 years ago

Moved the XState to the end of the CPUMCTX structure, reducing the size of the three VMM modules by ~8KB in a win.amd6/debug build.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 13.3 KB
Line 
1/** @file
2 * CPUM - CPU Monitor(/ Manager), Context Structures.
3 */
4
5/*
6 * Copyright (C) 2006-2015 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_cpumctx_h
27#define ___VBox_vmm_cpumctx_h
28
29#ifndef VBOX_FOR_DTRACE_LIB
30# include <iprt/x86.h>
31# include <VBox/types.h>
32#else
33# pragma D depends_on library x86.d
34#endif
35
36
37RT_C_DECLS_BEGIN
38
39/** @addgroup grp_cpum_ctx The CPUM Context Structures
40 * @ingroup grp_cpum
41 * @{
42 */
43
44/**
45 * Selector hidden registers.
46 */
47typedef struct CPUMSELREG
48{
49 /** The selector register. */
50 RTSEL Sel;
51 /** Padding, don't use. */
52 RTSEL PaddingSel;
53 /** The selector which info resides in u64Base, u32Limit and Attr, provided
54 * that CPUMSELREG_FLAGS_VALID is set. */
55 RTSEL ValidSel;
56 /** Flags, see CPUMSELREG_FLAGS_XXX. */
57 uint16_t fFlags;
58
59 /** Base register.
60 *
61 * Long mode remarks:
62 * - Unused in long mode for CS, DS, ES, SS
63 * - 32 bits for FS & GS; FS(GS)_BASE msr used for the base address
64 * - 64 bits for TR & LDTR
65 */
66 uint64_t u64Base;
67 /** Limit (expanded). */
68 uint32_t u32Limit;
69 /** Flags.
70 * This is the high 32-bit word of the descriptor entry.
71 * Only the flags, dpl and type are used. */
72 X86DESCATTR Attr;
73} CPUMSELREG;
74
75/** @name CPUMSELREG_FLAGS_XXX - CPUMSELREG::fFlags values.
76 * @{ */
77#define CPUMSELREG_FLAGS_VALID UINT16_C(0x0001)
78#define CPUMSELREG_FLAGS_STALE UINT16_C(0x0002)
79#define CPUMSELREG_FLAGS_VALID_MASK UINT16_C(0x0003)
80/** @} */
81
82/** Checks if the hidden parts of the selector register are valid. */
83#ifdef VBOX_WITH_RAW_MODE_NOT_R0
84# define CPUMSELREG_ARE_HIDDEN_PARTS_VALID(a_pVCpu, a_pSelReg) \
85 ( ((a_pSelReg)->fFlags & CPUMSELREG_FLAGS_VALID) \
86 && ( (a_pSelReg)->ValidSel == (a_pSelReg)->Sel \
87 || ( (a_pVCpu) /*!= NULL*/ \
88 && (a_pSelReg)->ValidSel == ((a_pSelReg)->Sel & X86_SEL_MASK_OFF_RPL) \
89 && ((a_pSelReg)->Sel & X86_SEL_RPL) == 1 \
90 && ((a_pSelReg)->ValidSel & X86_SEL_RPL) == 0 \
91 && CPUMIsGuestInRawMode(a_pVCpu) \
92 ) \
93 ) \
94 )
95#else
96# define CPUMSELREG_ARE_HIDDEN_PARTS_VALID(a_pVCpu, a_pSelReg) \
97 ( ((a_pSelReg)->fFlags & CPUMSELREG_FLAGS_VALID) \
98 && (a_pSelReg)->ValidSel == (a_pSelReg)->Sel )
99#endif
100
101/** Old type used for the hidden register part.
102 * @deprecated */
103typedef CPUMSELREG CPUMSELREGHID;
104
105/**
106 * The sysenter register set.
107 */
108typedef struct CPUMSYSENTER
109{
110 /** Ring 0 cs.
111 * This value + 8 is the Ring 0 ss.
112 * This value + 16 is the Ring 3 cs.
113 * This value + 24 is the Ring 3 ss.
114 */
115 uint64_t cs;
116 /** Ring 0 eip. */
117 uint64_t eip;
118 /** Ring 0 esp. */
119 uint64_t esp;
120} CPUMSYSENTER;
121
122/**
123 * For compilers (like DTrace) that does not grok nameless unions, we have a
124 * little hack to make them palatable.
125 */
126#ifdef VBOX_FOR_DTRACE_LIB
127# define CPUM_UNION_NAME(a_Nm) a_Nm
128#elif defined(VBOX_WITHOUT_UNNAMED_UNIONS)
129# define CPUM_UNION_NAME(a_Nm) a_Nm
130#else
131# define CPUM_UNION_NAME(a_Nm)
132#endif
133
134
135/**
136 * CPU context core.
137 *
138 * @todo Eliminate this structure!
139 * @deprecated We don't push any context cores any more in TRPM.
140 */
141#pragma pack(1)
142typedef struct CPUMCTXCORE
143{
144 /** @name General Register.
145 * @note These follow the encoding order (X86_GREG_XXX) and can be accessed as
146 * an array starting a rax.
147 * @{ */
148 union
149 {
150 uint8_t al;
151 uint16_t ax;
152 uint32_t eax;
153 uint64_t rax;
154 } CPUM_UNION_NAME(rax);
155 union
156 {
157 uint8_t cl;
158 uint16_t cx;
159 uint32_t ecx;
160 uint64_t rcx;
161 } CPUM_UNION_NAME(rcx);
162 union
163 {
164 uint8_t dl;
165 uint16_t dx;
166 uint32_t edx;
167 uint64_t rdx;
168 } CPUM_UNION_NAME(rdx);
169 union
170 {
171 uint8_t bl;
172 uint16_t bx;
173 uint32_t ebx;
174 uint64_t rbx;
175 } CPUM_UNION_NAME(rbx);
176 union
177 {
178 uint16_t sp;
179 uint32_t esp;
180 uint64_t rsp;
181 } CPUM_UNION_NAME(rsp);
182 union
183 {
184 uint16_t bp;
185 uint32_t ebp;
186 uint64_t rbp;
187 } CPUM_UNION_NAME(rbp);
188 union
189 {
190 uint8_t sil;
191 uint16_t si;
192 uint32_t esi;
193 uint64_t rsi;
194 } CPUM_UNION_NAME(rsi);
195 union
196 {
197 uint8_t dil;
198 uint16_t di;
199 uint32_t edi;
200 uint64_t rdi;
201 } CPUM_UNION_NAME(rdi);
202 uint64_t r8;
203 uint64_t r9;
204 uint64_t r10;
205 uint64_t r11;
206 uint64_t r12;
207 uint64_t r13;
208 uint64_t r14;
209 uint64_t r15;
210 /** @} */
211
212 /** @name Segment registers.
213 * @note These follow the encoding order (X86_SREG_XXX) and can be accessed as
214 * an array starting a es.
215 * @{ */
216 CPUMSELREG es;
217 CPUMSELREG cs;
218 CPUMSELREG ss;
219 CPUMSELREG ds;
220 CPUMSELREG fs;
221 CPUMSELREG gs;
222 /** @} */
223
224 /** The program counter. */
225 union
226 {
227 uint16_t ip;
228 uint32_t eip;
229 uint64_t rip;
230 } CPUM_UNION_NAME(rip);
231
232 /** The flags register. */
233 union
234 {
235 X86EFLAGS eflags;
236 X86RFLAGS rflags;
237 } CPUM_UNION_NAME(rflags);
238
239} CPUMCTXCORE;
240#pragma pack()
241
242
243/**
244 * CPU context.
245 */
246#pragma pack(1) /* for VBOXIDTR / VBOXGDTR. */
247typedef struct CPUMCTX
248{
249 /** CPUMCTXCORE Part.
250 * @{ */
251
252 /** @name General Register.
253 * @note These follow the encoding order (X86_GREG_XXX) and can be accessed as
254 * an array starting at rax.
255 * @{ */
256 union
257 {
258 uint8_t al;
259 uint16_t ax;
260 uint32_t eax;
261 uint64_t rax;
262 } CPUM_UNION_NAME(rax);
263 union
264 {
265 uint8_t cl;
266 uint16_t cx;
267 uint32_t ecx;
268 uint64_t rcx;
269 } CPUM_UNION_NAME(rcx);
270 union
271 {
272 uint8_t dl;
273 uint16_t dx;
274 uint32_t edx;
275 uint64_t rdx;
276 } CPUM_UNION_NAME(rdx);
277 union
278 {
279 uint8_t bl;
280 uint16_t bx;
281 uint32_t ebx;
282 uint64_t rbx;
283 } CPUM_UNION_NAME(rbx);
284 union
285 {
286 uint16_t sp;
287 uint32_t esp;
288 uint64_t rsp;
289 } CPUM_UNION_NAME(rsp);
290 union
291 {
292 uint16_t bp;
293 uint32_t ebp;
294 uint64_t rbp;
295 } CPUM_UNION_NAME(rbp);
296 union
297 {
298 uint8_t sil;
299 uint16_t si;
300 uint32_t esi;
301 uint64_t rsi;
302 } CPUM_UNION_NAME(rsi);
303 union
304 {
305 uint8_t dil;
306 uint16_t di;
307 uint32_t edi;
308 uint64_t rdi;
309 } CPUM_UNION_NAME(rdi);
310 uint64_t r8;
311 uint64_t r9;
312 uint64_t r10;
313 uint64_t r11;
314 uint64_t r12;
315 uint64_t r13;
316 uint64_t r14;
317 uint64_t r15;
318 /** @} */
319
320 /** @name Segment registers.
321 * @note These follow the encoding order (X86_SREG_XXX) and can be accessed as
322 * an array starting at es.
323 * @{ */
324 CPUMSELREG es;
325 CPUMSELREG cs;
326 CPUMSELREG ss;
327 CPUMSELREG ds;
328 CPUMSELREG fs;
329 CPUMSELREG gs;
330 /** @} */
331
332 /** The program counter. */
333 union
334 {
335 uint16_t ip;
336 uint32_t eip;
337 uint64_t rip;
338 } CPUM_UNION_NAME(rip);
339
340 /** The flags register. */
341 union
342 {
343 X86EFLAGS eflags;
344 X86RFLAGS rflags;
345 } CPUM_UNION_NAME(rflags);
346
347 /** @} */ /*(CPUMCTXCORE)*/
348
349
350 /** @name Control registers.
351 * @{ */
352 uint64_t cr0;
353 uint64_t cr2;
354 uint64_t cr3;
355 uint64_t cr4;
356 /** @} */
357
358 /** Debug registers.
359 * @remarks DR4 and DR5 should not be used since they are aliases for
360 * DR6 and DR7 respectively on both AMD and Intel CPUs.
361 * @remarks DR8-15 are currently not supported by AMD or Intel, so
362 * neither do we.
363 */
364 uint64_t dr[8];
365
366 /** Padding before the structure so the 64-bit member is correctly aligned.
367 * @todo fix this structure! */
368 uint16_t gdtrPadding[3];
369 /** Global Descriptor Table register. */
370 VBOXGDTR gdtr;
371
372 /** Padding before the structure so the 64-bit member is correctly aligned.
373 * @todo fix this structure! */
374 uint16_t idtrPadding[3];
375 /** Interrupt Descriptor Table register. */
376 VBOXIDTR idtr;
377
378 /** The task register.
379 * Only the guest context uses all the members. */
380 CPUMSELREG ldtr;
381 /** The task register.
382 * Only the guest context uses all the members. */
383 CPUMSELREG tr;
384
385 /** The sysenter msr registers.
386 * This member is not used by the hypervisor context. */
387 CPUMSYSENTER SysEnter;
388
389 /** @name System MSRs.
390 * @{ */
391 uint64_t msrEFER;
392 uint64_t msrSTAR; /**< Legacy syscall eip, cs & ss. */
393 uint64_t msrPAT; /**< Page attribute table. */
394 uint64_t msrLSTAR; /**< 64 bits mode syscall rip. */
395 uint64_t msrCSTAR; /**< Compatibility mode syscall rip. */
396 uint64_t msrSFMASK; /**< syscall flag mask. */
397 uint64_t msrKERNELGSBASE; /**< swapgs exchange value. */
398 uint64_t msrApicBase; /**< The local APIC base (IA32_APIC_BASE MSR). */
399 /** @} */
400
401 /** Size padding. */
402 uint32_t au32SizePadding[6];
403
404 /** FPU state. (16-byte alignment)
405 * @todo This doesn't have to be in X86FXSTATE on CPUs without fxsr - we need a type for the
406 * actual format or convert it (waste of time). */
407 X86XSAVEAREA XState;
408} CPUMCTX;
409#pragma pack()
410
411#ifndef VBOX_FOR_DTRACE_LIB
412AssertCompileSizeAlignment(CPUMCTX, 64);
413
414/**
415 * Gets the CPUMCTXCORE part of a CPUMCTX.
416 */
417# define CPUMCTX2CORE(pCtx) ((PCPUMCTXCORE)(void *)&(pCtx)->rax)
418
419/**
420 * Gets the CPUMCTXCORE part of a CPUMCTX.
421 */
422# define CPUMCTX_FROM_CORE(a_pCtxCore) RT_FROM_MEMBER(a_pCtxCore, CPUMCTX, rax)
423
424/**
425 * Gets the first selector register of a CPUMCTX.
426 *
427 * Use this with X86_SREG_COUNT to loop thru the selector registers.
428 */
429# define CPUMCTX_FIRST_SREG(a_pCtx) (&(a_pCtx)->es)
430
431#endif /* !VBOX_FOR_DTRACE_LIB */
432
433/**
434 * Additional guest MSRs (i.e. not part of the CPU context structure).
435 *
436 * @remarks Never change the order here because of the saved stated! The size
437 * can in theory be changed, but keep older VBox versions in mind.
438 */
439typedef union CPUMCTXMSRS
440{
441 struct
442 {
443 uint64_t TscAux; /**< MSR_K8_TSC_AUX */
444 uint64_t MiscEnable; /**< MSR_IA32_MISC_ENABLE */
445 uint64_t MtrrDefType; /**< IA32_MTRR_DEF_TYPE */
446 uint64_t MtrrFix64K_00000; /**< IA32_MTRR_FIX16K_80000 */
447 uint64_t MtrrFix16K_80000; /**< IA32_MTRR_FIX16K_80000 */
448 uint64_t MtrrFix16K_A0000; /**< IA32_MTRR_FIX16K_A0000 */
449 uint64_t MtrrFix4K_C0000; /**< IA32_MTRR_FIX4K_C0000 */
450 uint64_t MtrrFix4K_C8000; /**< IA32_MTRR_FIX4K_C8000 */
451 uint64_t MtrrFix4K_D0000; /**< IA32_MTRR_FIX4K_D0000 */
452 uint64_t MtrrFix4K_D8000; /**< IA32_MTRR_FIX4K_D8000 */
453 uint64_t MtrrFix4K_E0000; /**< IA32_MTRR_FIX4K_E0000 */
454 uint64_t MtrrFix4K_E8000; /**< IA32_MTRR_FIX4K_E8000 */
455 uint64_t MtrrFix4K_F0000; /**< IA32_MTRR_FIX4K_F0000 */
456 uint64_t MtrrFix4K_F8000; /**< IA32_MTRR_FIX4K_F8000 */
457 uint64_t PkgCStateCfgCtrl; /**< MSR_PKG_CST_CONFIG_CONTROL */
458 } msr;
459 uint64_t au64[64];
460} CPUMCTXMSRS;
461/** Pointer to the guest MSR state. */
462typedef CPUMCTXMSRS *PCPUMCTXMSRS;
463/** Pointer to the const guest MSR state. */
464typedef const CPUMCTXMSRS *PCCPUMCTXMSRS;
465
466/**
467 * The register set returned by a CPUID operation.
468 */
469typedef struct CPUMCPUID
470{
471 uint32_t uEax;
472 uint32_t uEbx;
473 uint32_t uEcx;
474 uint32_t uEdx;
475} CPUMCPUID;
476/** Pointer to a CPUID leaf. */
477typedef CPUMCPUID *PCPUMCPUID;
478/** Pointer to a const CPUID leaf. */
479typedef const CPUMCPUID *PCCPUMCPUID;
480
481/** @} */
482
483RT_C_DECLS_END
484
485#endif
486
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