VirtualBox

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

Last change on this file since 42407 was 42407, checked in by vboxsync, 12 years ago

VMM: Futher work on dealing with hidden segment register, esp. when going stale.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.9 KB
Line 
1/** @file
2 * CPUM - CPU Monitor(/ Manager), Context Structures.
3 */
4
5/*
6 * Copyright (C) 2006-2012 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_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 */
140#pragma pack(1)
141typedef struct CPUMCTXCORE
142{
143 /** @name General Register.
144 * @note These follow the encoding order (X86_GREG_XXX) and can be accessed as
145 * an array starting a rax.
146 * @{ */
147 union
148 {
149 uint8_t al;
150 uint16_t ax;
151 uint32_t eax;
152 uint64_t rax;
153 } CPUM_UNION_NAME(rax);
154 union
155 {
156 uint8_t cl;
157 uint16_t cx;
158 uint32_t ecx;
159 uint64_t rcx;
160 } CPUM_UNION_NAME(rcx);
161 union
162 {
163 uint8_t dl;
164 uint16_t dx;
165 uint32_t edx;
166 uint64_t rdx;
167 } CPUM_UNION_NAME(rdx);
168 union
169 {
170 uint8_t bl;
171 uint16_t bx;
172 uint32_t ebx;
173 uint64_t rbx;
174 } CPUM_UNION_NAME(rbx);
175 union
176 {
177 uint16_t sp;
178 uint32_t esp;
179 uint64_t rsp;
180 } CPUM_UNION_NAME(rsp);
181 union
182 {
183 uint16_t bp;
184 uint32_t ebp;
185 uint64_t rbp;
186 } CPUM_UNION_NAME(rbp);
187 union
188 {
189 uint8_t sil;
190 uint16_t si;
191 uint32_t esi;
192 uint64_t rsi;
193 } CPUM_UNION_NAME(rsi);
194 union
195 {
196 uint8_t dil;
197 uint16_t di;
198 uint32_t edi;
199 uint64_t rdi;
200 } CPUM_UNION_NAME(rdi);
201 uint64_t r8;
202 uint64_t r9;
203 uint64_t r10;
204 uint64_t r11;
205 uint64_t r12;
206 uint64_t r13;
207 uint64_t r14;
208 uint64_t r15;
209 /** @} */
210
211 /** @name Segment registers.
212 * @note These follow the encoding order (X86_SREG_XXX) and can be accessed as
213 * an array starting a es.
214 * @{ */
215 CPUMSELREG es;
216 CPUMSELREG cs;
217 CPUMSELREG ss;
218 CPUMSELREG ds;
219 CPUMSELREG fs;
220 CPUMSELREG gs;
221 /** @} */
222
223 /** The program counter. */
224 union
225 {
226 uint16_t ip;
227 uint32_t eip;
228 uint64_t rip;
229 } CPUM_UNION_NAME(rip);
230
231 /** The flags register. */
232 union
233 {
234 X86EFLAGS eflags;
235 X86RFLAGS rflags;
236 } CPUM_UNION_NAME(rflags);
237
238} CPUMCTXCORE;
239#pragma pack()
240
241
242/**
243 * CPU context.
244 */
245#pragma pack(1) /* for VBOXIDTR / VBOXGDTR. */
246typedef struct CPUMCTX
247{
248 /** FPU state. (16-byte alignment)
249 * @todo This doesn't have to be in X86FXSTATE on CPUs without fxsr - we need a type for the
250 * actual format or convert it (waste of time). */
251 X86FXSTATE fpu;
252
253 /** CPUMCTXCORE Part.
254 * @{ */
255
256 /** @name General Register.
257 * @note These follow the encoding order (X86_GREG_XXX) and can be accessed as
258 * an array starting at rax.
259 * @{ */
260 union
261 {
262 uint8_t al;
263 uint16_t ax;
264 uint32_t eax;
265 uint64_t rax;
266 } CPUM_UNION_NAME(rax);
267 union
268 {
269 uint8_t cl;
270 uint16_t cx;
271 uint32_t ecx;
272 uint64_t rcx;
273 } CPUM_UNION_NAME(rcx);
274 union
275 {
276 uint8_t dl;
277 uint16_t dx;
278 uint32_t edx;
279 uint64_t rdx;
280 } CPUM_UNION_NAME(rdx);
281 union
282 {
283 uint8_t bl;
284 uint16_t bx;
285 uint32_t ebx;
286 uint64_t rbx;
287 } CPUM_UNION_NAME(rbx);
288 union
289 {
290 uint16_t sp;
291 uint32_t esp;
292 uint64_t rsp;
293 } CPUM_UNION_NAME(rsp);
294 union
295 {
296 uint16_t bp;
297 uint32_t ebp;
298 uint64_t rbp;
299 } CPUM_UNION_NAME(rbp);
300 union
301 {
302 uint8_t sil;
303 uint16_t si;
304 uint32_t esi;
305 uint64_t rsi;
306 } CPUM_UNION_NAME(rsi);
307 union
308 {
309 uint8_t dil;
310 uint16_t di;
311 uint32_t edi;
312 uint64_t rdi;
313 } CPUM_UNION_NAME(rdi);
314 uint64_t r8;
315 uint64_t r9;
316 uint64_t r10;
317 uint64_t r11;
318 uint64_t r12;
319 uint64_t r13;
320 uint64_t r14;
321 uint64_t r15;
322 /** @} */
323
324 /** @name Segment registers.
325 * @note These follow the encoding order (X86_SREG_XXX) and can be accessed as
326 * an array starting at es.
327 * @{ */
328 CPUMSELREG es;
329 CPUMSELREG cs;
330 CPUMSELREG ss;
331 CPUMSELREG ds;
332 CPUMSELREG fs;
333 CPUMSELREG gs;
334 /** @} */
335
336 /** The program counter. */
337 union
338 {
339 uint16_t ip;
340 uint32_t eip;
341 uint64_t rip;
342 } CPUM_UNION_NAME(rip);
343
344 /** The flags register. */
345 union
346 {
347 X86EFLAGS eflags;
348 X86RFLAGS rflags;
349 } CPUM_UNION_NAME(rflags);
350
351 /** @} */ /*(CPUMCTXCORE)*/
352
353
354 /** @name Control registers.
355 * @{ */
356 uint64_t cr0;
357 uint64_t cr2;
358 uint64_t cr3;
359 uint64_t cr4;
360 /** @} */
361
362 /** Debug registers.
363 * @remarks DR4 and DR5 should not be used since they are aliases for
364 * DR6 and DR7 respectively on both AMD and Intel CPUs.
365 * @remarks DR8-15 are currently not supported by AMD or Intel, so
366 * neither do we.
367 */
368 uint64_t dr[8];
369
370 /** Padding before the structure so the 64-bit member is correctly aligned.
371 * @todo fix this structure! */
372 uint16_t gdtrPadding[3];
373 /** Global Descriptor Table register. */
374 VBOXGDTR gdtr;
375
376 /** Padding before the structure so the 64-bit member is correctly aligned.
377 * @todo fix this structure! */
378 uint16_t idtrPadding[3];
379 /** Interrupt Descriptor Table register. */
380 VBOXIDTR idtr;
381
382 /** The task register.
383 * Only the guest context uses all the members. */
384 CPUMSELREG ldtr;
385 /** The task register.
386 * Only the guest context uses all the members. */
387 CPUMSELREG tr;
388
389 /** The sysenter msr registers.
390 * This member is not used by the hypervisor context. */
391 CPUMSYSENTER SysEnter;
392
393 /** @name System MSRs.
394 * @{ */
395 uint64_t msrEFER;
396 uint64_t msrSTAR; /**< Legacy syscall eip, cs & ss. */
397 uint64_t msrPAT; /**< Page attribute table. */
398 uint64_t msrLSTAR; /**< 64 bits mode syscall rip. */
399 uint64_t msrCSTAR; /**< Compatibility mode syscall rip. */
400 uint64_t msrSFMASK; /**< syscall flag mask. */
401 uint64_t msrKERNELGSBASE; /**< swapgs exchange value. */
402 /** @} */
403
404 /** Size padding. */
405 uint32_t au32SizePadding[8];
406} CPUMCTX;
407#pragma pack()
408
409#ifndef VBOX_FOR_DTRACE_LIB
410
411/**
412 * Gets the CPUMCTXCORE part of a CPUMCTX.
413 */
414# define CPUMCTX2CORE(pCtx) ((PCPUMCTXCORE)(void *)&(pCtx)->rax)
415
416/**
417 * Gets the first selector register of a CPUMCTX.
418 *
419 * Use this with X86_SREG_COUNT to loop thru the selector registers.
420 */
421# define CPUMCTX_FIRST_SREG(a_pCtx) (&(a_pCtx)->es)
422
423#endif /* !VBOX_FOR_DTRACE_LIB */
424
425/**
426 * Additional guest MSRs (i.e. not part of the CPU context structure).
427 *
428 * @remarks Never change the order here because of the saved stated! The size
429 * can in theory be changed, but keep older VBox versions in mind.
430 */
431typedef union CPUMCTXMSRS
432{
433 struct
434 {
435 uint64_t TscAux; /**< MSR_K8_TSC_AUX */
436 uint64_t MiscEnable; /**< MSR_IA32_MISC_ENABLE */
437 uint64_t MtrrDefType; /**< IA32_MTRR_DEF_TYPE */
438 uint64_t MtrrFix64K_00000; /**< IA32_MTRR_FIX16K_80000 */
439 uint64_t MtrrFix16K_80000; /**< IA32_MTRR_FIX16K_80000 */
440 uint64_t MtrrFix16K_A0000; /**< IA32_MTRR_FIX16K_A0000 */
441 uint64_t MtrrFix4K_C0000; /**< IA32_MTRR_FIX4K_C0000 */
442 uint64_t MtrrFix4K_C8000; /**< IA32_MTRR_FIX4K_C8000 */
443 uint64_t MtrrFix4K_D0000; /**< IA32_MTRR_FIX4K_D0000 */
444 uint64_t MtrrFix4K_D8000; /**< IA32_MTRR_FIX4K_D8000 */
445 uint64_t MtrrFix4K_E0000; /**< IA32_MTRR_FIX4K_E0000 */
446 uint64_t MtrrFix4K_E8000; /**< IA32_MTRR_FIX4K_E8000 */
447 uint64_t MtrrFix4K_F0000; /**< IA32_MTRR_FIX4K_F0000 */
448 uint64_t MtrrFix4K_F8000; /**< IA32_MTRR_FIX4K_F8000 */
449 } msr;
450 uint64_t au64[64];
451} CPUMCTXMSRS;
452/** Pointer to the guest MSR state. */
453typedef CPUMCTXMSRS *PCPUMCTXMSRS;
454/** Pointer to the const guest MSR state. */
455typedef const CPUMCTXMSRS *PCCPUMCTXMSRS;
456
457/**
458 * The register set returned by a CPUID operation.
459 */
460typedef struct CPUMCPUID
461{
462 uint32_t eax;
463 uint32_t ebx;
464 uint32_t ecx;
465 uint32_t edx;
466} CPUMCPUID;
467/** Pointer to a CPUID leaf. */
468typedef CPUMCPUID *PCPUMCPUID;
469/** Pointer to a const CPUID leaf. */
470typedef const CPUMCPUID *PCCPUMCPUID;
471
472/** @} */
473
474RT_C_DECLS_END
475
476#endif
477
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