VirtualBox

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

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

cpumctx.h: Fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.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 /** The XCR0..XCR1 registers. */
402 uint64_t aXcr[2];
403 /** The mask to pass to XSAVE/XRSTOR in EDX:EAX. If zero we use
404 * FXSAVE/FXRSTOR (since bit 0 will always be set, we only need to test it). */
405 uint64_t fXStateMask;
406
407 /** Pointer to the FPU/SSE/AVX/XXXX state ring-0 mapping. */
408 R0PTRTYPE(PX86XSAVEAREA) pXStateR0;
409 /** Pointer to the FPU/SSE/AVX/XXXX state ring-3 mapping. */
410 R3PTRTYPE(PX86XSAVEAREA) pXStateR3;
411 /** Pointer to the FPU/SSE/AVX/XXXX state raw-mode mapping. */
412 RCPTRTYPE(PX86XSAVEAREA) pXStateRC;
413 /** State component offsets into pXState, UINT16_MAX if not present. */
414 uint16_t aoffXState[64];
415
416 /** Size padding. */
417 uint32_t au32SizePadding[HC_ARCH_BITS == 32 ? 13 : 11];
418} CPUMCTX;
419#pragma pack()
420
421#ifndef VBOX_FOR_DTRACE_LIB
422AssertCompileSizeAlignment(CPUMCTX, 64);
423
424/**
425 * Calculates the pointer to the given extended state component.
426 *
427 * @returns Pointer of type @a a_PtrType
428 * @param a_pCtx Pointer to the context.
429 * @param a_iCompBit The extended state component bit number. This bit
430 * must be set in CPUMCTX::fXStateMask.
431 * @param a_PtrType The pointer type of the extended state component.
432 *
433 */
434#if defined(VBOX_STRICT) && defined(RT_COMPILER_SUPPORTS_LAMBDA)
435# define CPUMCTX_XSAVE_C_PTR(a_pCtx, a_iCompBit, a_PtrType) \
436 ([](PCCPUMCTX a_pLambdaCtx) -> a_PtrType \
437 { \
438 AssertCompile((a_iCompBit) < 64U); \
439 AssertMsg(a_pLambdaCtx->fXStateMask & RT_BIT_64(a_iCompBit), (#a_iCompBit "\n")); \
440 AssertMsg(a_pLambdaCtx->aoffXState[(a_iCompBit)] != UINT16_MAX, (#a_iCompBit "\n")); \
441 return (a_PtrType)((uint8_t *)a_pLambdaCtx->CTX_SUFF(pXState) + a_pLambdaCtx->aoffXState[(a_iCompBit)]); \
442 }(a_pCtx))
443#elif defined(VBOX_STRICT) && defined(__GNUC__)
444# define CPUMCTX_XSAVE_C_PTR(a_pCtx, a_iCompBit, a_PtrType) \
445 __extension__ (\
446 { \
447 AssertCompile((a_iCompBit) < 64U); \
448 AssertMsg((a_pCtx)->fXStateMask & RT_BIT_64(a_iCompBit), (#a_iCompBit "\n")); \
449 AssertMsg((a_pCtx)->aoffXState[(a_iCompBit)] != UINT16_MAX, (#a_iCompBit "\n")); \
450 (a_PtrType)((uint8_t *)(a_pCtx)->CTX_SUFF(pXState) + (a_pCtx)->aoffXState[(a_iCompBit)]); \
451 })
452#else
453# define CPUMCTX_XSAVE_C_PTR(a_pCtx, a_iCompBit, a_PtrType) \
454 ((a_PtrType)((uint8_t *)(a_pCtx)->CTX_SUFF(pXState) + (a_pCtx)->aoffXState[(a_iCompBit)]))
455#endif
456
457/**
458 * Gets the CPUMCTXCORE part of a CPUMCTX.
459 */
460# define CPUMCTX2CORE(pCtx) ((PCPUMCTXCORE)(void *)&(pCtx)->rax)
461
462/**
463 * Gets the CPUMCTX part from a CPUMCTXCORE.
464 */
465# define CPUMCTX_FROM_CORE(a_pCtxCore) RT_FROM_MEMBER(a_pCtxCore, CPUMCTX, rax)
466
467/**
468 * Gets the first selector register of a CPUMCTX.
469 *
470 * Use this with X86_SREG_COUNT to loop thru the selector registers.
471 */
472# define CPUMCTX_FIRST_SREG(a_pCtx) (&(a_pCtx)->es)
473
474#endif /* !VBOX_FOR_DTRACE_LIB */
475
476/**
477 * Additional guest MSRs (i.e. not part of the CPU context structure).
478 *
479 * @remarks Never change the order here because of the saved stated! The size
480 * can in theory be changed, but keep older VBox versions in mind.
481 */
482typedef union CPUMCTXMSRS
483{
484 struct
485 {
486 uint64_t TscAux; /**< MSR_K8_TSC_AUX */
487 uint64_t MiscEnable; /**< MSR_IA32_MISC_ENABLE */
488 uint64_t MtrrDefType; /**< IA32_MTRR_DEF_TYPE */
489 uint64_t MtrrFix64K_00000; /**< IA32_MTRR_FIX16K_80000 */
490 uint64_t MtrrFix16K_80000; /**< IA32_MTRR_FIX16K_80000 */
491 uint64_t MtrrFix16K_A0000; /**< IA32_MTRR_FIX16K_A0000 */
492 uint64_t MtrrFix4K_C0000; /**< IA32_MTRR_FIX4K_C0000 */
493 uint64_t MtrrFix4K_C8000; /**< IA32_MTRR_FIX4K_C8000 */
494 uint64_t MtrrFix4K_D0000; /**< IA32_MTRR_FIX4K_D0000 */
495 uint64_t MtrrFix4K_D8000; /**< IA32_MTRR_FIX4K_D8000 */
496 uint64_t MtrrFix4K_E0000; /**< IA32_MTRR_FIX4K_E0000 */
497 uint64_t MtrrFix4K_E8000; /**< IA32_MTRR_FIX4K_E8000 */
498 uint64_t MtrrFix4K_F0000; /**< IA32_MTRR_FIX4K_F0000 */
499 uint64_t MtrrFix4K_F8000; /**< IA32_MTRR_FIX4K_F8000 */
500 uint64_t PkgCStateCfgCtrl; /**< MSR_PKG_CST_CONFIG_CONTROL */
501 } msr;
502 uint64_t au64[64];
503} CPUMCTXMSRS;
504/** Pointer to the guest MSR state. */
505typedef CPUMCTXMSRS *PCPUMCTXMSRS;
506/** Pointer to the const guest MSR state. */
507typedef const CPUMCTXMSRS *PCCPUMCTXMSRS;
508
509/**
510 * The register set returned by a CPUID operation.
511 */
512typedef struct CPUMCPUID
513{
514 uint32_t uEax;
515 uint32_t uEbx;
516 uint32_t uEcx;
517 uint32_t uEdx;
518} CPUMCPUID;
519/** Pointer to a CPUID leaf. */
520typedef CPUMCPUID *PCPUMCPUID;
521/** Pointer to a const CPUID leaf. */
522typedef const CPUMCPUID *PCCPUMCPUID;
523
524/** @} */
525
526RT_C_DECLS_END
527
528#endif
529
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