VirtualBox

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

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

backed out r99268 as it causes serious regressions on Windows hosts

  • 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 /** FPU state. (16-byte alignment)
250 * @todo This doesn't have to be in X86FXSTATE on CPUs without fxsr - we need a type for the
251 * actual format or convert it (waste of time). */
252 X86XSAVEAREA XState;
253
254 /** CPUMCTXCORE Part.
255 * @{ */
256
257 /** @name General Register.
258 * @note These follow the encoding order (X86_GREG_XXX) and can be accessed as
259 * an array starting at rax.
260 * @{ */
261 union
262 {
263 uint8_t al;
264 uint16_t ax;
265 uint32_t eax;
266 uint64_t rax;
267 } CPUM_UNION_NAME(rax);
268 union
269 {
270 uint8_t cl;
271 uint16_t cx;
272 uint32_t ecx;
273 uint64_t rcx;
274 } CPUM_UNION_NAME(rcx);
275 union
276 {
277 uint8_t dl;
278 uint16_t dx;
279 uint32_t edx;
280 uint64_t rdx;
281 } CPUM_UNION_NAME(rdx);
282 union
283 {
284 uint8_t bl;
285 uint16_t bx;
286 uint32_t ebx;
287 uint64_t rbx;
288 } CPUM_UNION_NAME(rbx);
289 union
290 {
291 uint16_t sp;
292 uint32_t esp;
293 uint64_t rsp;
294 } CPUM_UNION_NAME(rsp);
295 union
296 {
297 uint16_t bp;
298 uint32_t ebp;
299 uint64_t rbp;
300 } CPUM_UNION_NAME(rbp);
301 union
302 {
303 uint8_t sil;
304 uint16_t si;
305 uint32_t esi;
306 uint64_t rsi;
307 } CPUM_UNION_NAME(rsi);
308 union
309 {
310 uint8_t dil;
311 uint16_t di;
312 uint32_t edi;
313 uint64_t rdi;
314 } CPUM_UNION_NAME(rdi);
315 uint64_t r8;
316 uint64_t r9;
317 uint64_t r10;
318 uint64_t r11;
319 uint64_t r12;
320 uint64_t r13;
321 uint64_t r14;
322 uint64_t r15;
323 /** @} */
324
325 /** @name Segment registers.
326 * @note These follow the encoding order (X86_SREG_XXX) and can be accessed as
327 * an array starting at es.
328 * @{ */
329 CPUMSELREG es;
330 CPUMSELREG cs;
331 CPUMSELREG ss;
332 CPUMSELREG ds;
333 CPUMSELREG fs;
334 CPUMSELREG gs;
335 /** @} */
336
337 /** The program counter. */
338 union
339 {
340 uint16_t ip;
341 uint32_t eip;
342 uint64_t rip;
343 } CPUM_UNION_NAME(rip);
344
345 /** The flags register. */
346 union
347 {
348 X86EFLAGS eflags;
349 X86RFLAGS rflags;
350 } CPUM_UNION_NAME(rflags);
351
352 /** @} */ /*(CPUMCTXCORE)*/
353
354
355 /** @name Control registers.
356 * @{ */
357 uint64_t cr0;
358 uint64_t cr2;
359 uint64_t cr3;
360 uint64_t cr4;
361 /** @} */
362
363 /** Debug registers.
364 * @remarks DR4 and DR5 should not be used since they are aliases for
365 * DR6 and DR7 respectively on both AMD and Intel CPUs.
366 * @remarks DR8-15 are currently not supported by AMD or Intel, so
367 * neither do we.
368 */
369 uint64_t dr[8];
370
371 /** Padding before the structure so the 64-bit member is correctly aligned.
372 * @todo fix this structure! */
373 uint16_t gdtrPadding[3];
374 /** Global Descriptor Table register. */
375 VBOXGDTR gdtr;
376
377 /** Padding before the structure so the 64-bit member is correctly aligned.
378 * @todo fix this structure! */
379 uint16_t idtrPadding[3];
380 /** Interrupt Descriptor Table register. */
381 VBOXIDTR idtr;
382
383 /** The task register.
384 * Only the guest context uses all the members. */
385 CPUMSELREG ldtr;
386 /** The task register.
387 * Only the guest context uses all the members. */
388 CPUMSELREG tr;
389
390 /** The sysenter msr registers.
391 * This member is not used by the hypervisor context. */
392 CPUMSYSENTER SysEnter;
393
394 /** @name System MSRs.
395 * @{ */
396 uint64_t msrEFER;
397 uint64_t msrSTAR; /**< Legacy syscall eip, cs & ss. */
398 uint64_t msrPAT; /**< Page attribute table. */
399 uint64_t msrLSTAR; /**< 64 bits mode syscall rip. */
400 uint64_t msrCSTAR; /**< Compatibility mode syscall rip. */
401 uint64_t msrSFMASK; /**< syscall flag mask. */
402 uint64_t msrKERNELGSBASE; /**< swapgs exchange value. */
403 uint64_t msrApicBase; /**< The local APIC base (IA32_APIC_BASE MSR). */
404 /** @} */
405
406 /** Size padding. */
407 uint32_t au32SizePadding[6];
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