VirtualBox

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

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

CPUM: Save and restore the internal selector fields.

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