VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/HWVMXR0.h@ 15377

Last change on this file since 15377 was 15362, checked in by vboxsync, 16 years ago

Don't use RTCCUINTREG.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 17.8 KB
Line 
1/* $Id: HWVMXR0.h 15362 2008-12-12 12:49:10Z vboxsync $ */
2/** @file
3 * HWACCM VT-x - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#ifndef ___HWVMXR0_h
23#define ___HWVMXR0_h
24
25#include <VBox/cdefs.h>
26#include <VBox/types.h>
27#include <VBox/em.h>
28#include <VBox/stam.h>
29#include <VBox/dis.h>
30#include <VBox/hwaccm.h>
31#include <VBox/pgm.h>
32#include <VBox/hwacc_vmx.h>
33
34__BEGIN_DECLS
35
36/** @defgroup grp_vmx_int Internal
37 * @ingroup grp_vmx
38 * @internal
39 * @{
40 */
41
42/* Read cache indices. */
43#define VMX_VMCS64_GUEST_RIP_CACHE_IDX 0
44#define VMX_VMCS64_GUEST_RSP_CACHE_IDX 1
45#define VMX_VMCS_GUEST_RFLAGS_CACHE_IDX 2
46#define VMX_VMCS32_GUEST_INTERRUPTIBILITY_STATE_CACHE_IDX 3
47#define VMX_VMCS_CTRL_CR0_READ_SHADOW_CACHE_IDX 4
48#define VMX_VMCS64_GUEST_CR0_CACHE_IDX 5
49#define VMX_VMCS_CTRL_CR4_READ_SHADOW_CACHE_IDX 6
50#define VMX_VMCS64_GUEST_CR4_CACHE_IDX 7
51#define VMX_VMCS64_GUEST_DR7_CACHE_IDX 8
52#define VMX_VMCS32_GUEST_SYSENTER_CS_CACHE_IDX 9
53#define VMX_VMCS64_GUEST_SYSENTER_EIP_CACHE_IDX 10
54#define VMX_VMCS64_GUEST_SYSENTER_ESP_CACHE_IDX 11
55#define VMX_VMCS32_GUEST_GDTR_LIMIT_CACHE_IDX 12
56#define VMX_VMCS64_GUEST_GDTR_BASE_CACHE_IDX 13
57#define VMX_VMCS32_GUEST_IDTR_LIMIT_CACHE_IDX 14
58#define VMX_VMCS64_GUEST_IDTR_BASE_CACHE_IDX 15
59#define VMX_VMCS16_GUEST_FIELD_CS_CACHE_IDX 16
60#define VMX_VMCS32_GUEST_CS_LIMIT_CACHE_IDX 17
61#define VMX_VMCS64_GUEST_CS_BASE_CACHE_IDX 18
62#define VMX_VMCS32_GUEST_CS_ACCESS_RIGHTS_CACHE_IDX 19
63#define VMX_VMCS16_GUEST_FIELD_DS_CACHE_IDX 20
64#define VMX_VMCS32_GUEST_DS_LIMIT_CACHE_IDX 21
65#define VMX_VMCS64_GUEST_DS_BASE_CACHE_IDX 22
66#define VMX_VMCS32_GUEST_DS_ACCESS_RIGHTS_CACHE_IDX 23
67#define VMX_VMCS16_GUEST_FIELD_ES_CACHE_IDX 24
68#define VMX_VMCS32_GUEST_ES_LIMIT_CACHE_IDX 25
69#define VMX_VMCS64_GUEST_ES_BASE_CACHE_IDX 26
70#define VMX_VMCS32_GUEST_ES_ACCESS_RIGHTS_CACHE_IDX 27
71#define VMX_VMCS16_GUEST_FIELD_FS_CACHE_IDX 28
72#define VMX_VMCS32_GUEST_FS_LIMIT_CACHE_IDX 29
73#define VMX_VMCS64_GUEST_FS_BASE_CACHE_IDX 30
74#define VMX_VMCS32_GUEST_FS_ACCESS_RIGHTS_CACHE_IDX 31
75#define VMX_VMCS16_GUEST_FIELD_GS_CACHE_IDX 32
76#define VMX_VMCS32_GUEST_GS_LIMIT_CACHE_IDX 33
77#define VMX_VMCS64_GUEST_GS_BASE_CACHE_IDX 34
78#define VMX_VMCS32_GUEST_GS_ACCESS_RIGHTS_CACHE_IDX 35
79#define VMX_VMCS16_GUEST_FIELD_SS_CACHE_IDX 36
80#define VMX_VMCS32_GUEST_SS_LIMIT_CACHE_IDX 37
81#define VMX_VMCS64_GUEST_SS_BASE_CACHE_IDX 38
82#define VMX_VMCS32_GUEST_SS_ACCESS_RIGHTS_CACHE_IDX 39
83#define VMX_VMCS16_GUEST_FIELD_TR_CACHE_IDX 40
84#define VMX_VMCS32_GUEST_TR_LIMIT_CACHE_IDX 41
85#define VMX_VMCS64_GUEST_TR_BASE_CACHE_IDX 42
86#define VMX_VMCS32_GUEST_TR_ACCESS_RIGHTS_CACHE_IDX 43
87#define VMX_VMCS16_GUEST_FIELD_LDTR_CACHE_IDX 44
88#define VMX_VMCS32_GUEST_LDTR_LIMIT_CACHE_IDX 45
89#define VMX_VMCS64_GUEST_LDTR_BASE_CACHE_IDX 46
90#define VMX_VMCS32_GUEST_LDTR_ACCESS_RIGHTS_CACHE_IDX 47
91#define VMX_VMCS32_RO_EXIT_REASON_CACHE_IDX 48
92#define VMX_VMCS32_RO_VM_INSTR_ERROR_CACHE_IDX 49
93#define VMX_VMCS32_RO_EXIT_INSTR_LENGTH_CACHE_IDX 50
94#define VMX_VMCS32_RO_EXIT_INTERRUPTION_ERRCODE_CACHE_IDX 51
95#define VMX_VMCS32_RO_EXIT_INSTR_INFO_CACHE_IDX 52
96#define VMX_VMCS32_RO_EXIT_INTERRUPTION_INFO_CACHE_IDX 53
97#define VMX_VMCS_RO_EXIT_QUALIFICATION_CACHE_IDX 54
98#define VMX_VMCS32_RO_IDT_INFO_CACHE_IDX 55
99#define VMX_VMCS32_RO_IDT_ERRCODE_CACHE_IDX 56
100#define VMX_VMCS_MAX_CACHE_IDX (VMX_VMCS32_RO_IDT_ERRCODE_CACHE_IDX+1)
101#define VMX_VMCS64_GUEST_CR3_CACHE_IDX 57
102#define VMX_VMCS_EXIT_PHYS_ADDR_FULL_CACHE_IDX 58
103#define VMX_VMCS_MAX_NESTED_PAGING_CACHE_IDX (VMX_VMCS_EXIT_PHYS_ADDR_FULL_CACHE_IDX+1)
104
105
106#ifdef IN_RING0
107
108/**
109 * Enters the VT-x session
110 *
111 * @returns VBox status code.
112 * @param pVM The VM to operate on.
113 * @param pVCpu The VMCPU to operate on.
114 * @param pCpu CPU info struct
115 */
116VMMR0DECL(int) VMXR0Enter(PVM pVM, PVMCPU pVCpu, PHWACCM_CPUINFO pCpu);
117
118/**
119 * Leaves the VT-x session
120 *
121 * @returns VBox status code.
122 * @param pVM The VM to operate on.
123 * @param pVCpu The VMCPU to operate on.
124 * @param pCtx CPU context
125 */
126VMMR0DECL(int) VMXR0Leave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
127
128
129/**
130 * Sets up and activates VT-x on the current CPU
131 *
132 * @returns VBox status code.
133 * @param pCpu CPU info struct
134 * @param pVM The VM to operate on. (can be NULL after a resume)
135 * @param pvPageCpu Pointer to the global cpu page
136 * @param pPageCpuPhys Physical address of the global cpu page
137 */
138VMMR0DECL(int) VMXR0EnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
139
140/**
141 * Deactivates VT-x on the current CPU
142 *
143 * @returns VBox status code.
144 * @param pCpu CPU info struct
145 * @param pvPageCpu Pointer to the global cpu page
146 * @param pPageCpuPhys Physical address of the global cpu page
147 */
148VMMR0DECL(int) VMXR0DisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
149
150/**
151 * Does Ring-0 per VM VT-x init.
152 *
153 * @returns VBox status code.
154 * @param pVM The VM to operate on.
155 */
156VMMR0DECL(int) VMXR0InitVM(PVM pVM);
157
158/**
159 * Does Ring-0 per VM VT-x termination.
160 *
161 * @returns VBox status code.
162 * @param pVM The VM to operate on.
163 */
164VMMR0DECL(int) VMXR0TermVM(PVM pVM);
165
166/**
167 * Sets up VT-x for the specified VM
168 *
169 * @returns VBox status code.
170 * @param pVM The VM to operate on.
171 */
172VMMR0DECL(int) VMXR0SetupVM(PVM pVM);
173
174
175/**
176 * Save the host state
177 *
178 * @returns VBox status code.
179 * @param pVM The VM to operate on.
180 * @param pVCpu The VMCPU to operate on.
181 */
182VMMR0DECL(int) VMXR0SaveHostState(PVM pVM, PVMCPU pVCpu);
183
184/**
185 * Loads the guest state
186 *
187 * @returns VBox status code.
188 * @param pVM The VM to operate on.
189 * @param pVCpu The VMCPU to operate on.
190 * @param pCtx Guest context
191 */
192VMMR0DECL(int) VMXR0LoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
193
194
195/**
196 * Runs guest code in a VT-x VM.
197 *
198 * @returns VBox status code.
199 * @param pVM The VM to operate on.
200 * @param pVCpu The VMCPU to operate on.
201 * @param pCtx Guest context
202 */
203VMMR0DECL(int) VMXR0RunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
204
205
206/**
207 * Executes the specified handler in 64 mode
208 *
209 * @returns VBox status code.
210 * @param pVM The VM to operate on.
211 * @param pVCpu The VMCPU to operate on.
212 * @param pCtx Guest context
213 * @param pfnHandler RC handler
214 * @param cbParam Number of parameters
215 * @param paParam Array of 32 bits parameters
216 */
217VMMR0DECL(int) VMXR0Execute64BitsHandler(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx, RTRCPTR pfnHandler, uint32_t cbParam, uint32_t *paParam);
218
219# define VMX_WRITE_SELREG(REG, reg) \
220{ \
221 rc = VMXWriteCachedVMCS(VMX_VMCS16_GUEST_FIELD_##REG, pCtx->reg); \
222 rc |= VMXWriteCachedVMCS(VMX_VMCS32_GUEST_##REG##_LIMIT, pCtx->reg##Hid.u32Limit); \
223 rc |= VMXWriteCachedVMCS(VMX_VMCS64_GUEST_##REG##_BASE, pCtx->reg##Hid.u64Base); \
224 if ((pCtx->eflags.u32 & X86_EFL_VM)) \
225 val = pCtx->reg##Hid.Attr.u; \
226 else \
227 if (CPUMIsGuestInRealModeEx(pCtx)) \
228 { \
229 /* Must override this or else VT-x will fail with invalid guest state errors. */ \
230 /* DPL=3, present, code/data, r/w/accessed. */ \
231 val = 0xf3; \
232 } \
233 else \
234 if ( ((!pCtx->csHid.Attr.n.u1DefBig && !CPUMIsGuestIn64BitCodeEx(pCtx)) || pCtx->reg) \
235 && pCtx->reg##Hid.Attr.n.u1Present == 1) \
236 val = pCtx->reg##Hid.Attr.u | X86_SEL_TYPE_ACCESSED; \
237 else \
238 val = 0x10000; /* Invalid guest state error otherwise. (BIT(16) = Unusable) */ \
239 \
240 rc |= VMXWriteCachedVMCS(VMX_VMCS32_GUEST_##REG##_ACCESS_RIGHTS, val); \
241}
242
243# define VMX_READ_SELREG(REG, reg) \
244{ \
245 VMXReadCachedVMCS(VMX_VMCS16_GUEST_FIELD_##REG, &val); \
246 pCtx->reg = val; \
247 VMXReadCachedVMCS(VMX_VMCS32_GUEST_##REG##_LIMIT, &val); \
248 pCtx->reg##Hid.u32Limit = val; \
249 VMXReadCachedVMCS(VMX_VMCS64_GUEST_##REG##_BASE, &val); \
250 pCtx->reg##Hid.u64Base = val; \
251 VMXReadCachedVMCS(VMX_VMCS32_GUEST_##REG##_ACCESS_RIGHTS, &val); \
252 pCtx->reg##Hid.Attr.u = val; \
253}
254
255/* Don't read from the cache in this macro; used only in case of failure where the cache is out of sync. */
256# define VMX_LOG_SELREG(REG, szSelReg) \
257{ \
258 VMXReadVMCS(VMX_VMCS16_GUEST_FIELD_##REG, &val); \
259 Log(("%s Selector %x\n", szSelReg, val)); \
260 VMXReadVMCS(VMX_VMCS32_GUEST_##REG##_LIMIT, &val); \
261 Log(("%s Limit %x\n", szSelReg, val)); \
262 VMXReadVMCS(VMX_VMCS64_GUEST_##REG##_BASE, &val); \
263 Log(("%s Base %RX64\n", szSelReg, val)); \
264 VMXReadVMCS(VMX_VMCS32_GUEST_##REG##_ACCESS_RIGHTS, &val); \
265 Log(("%s Attributes %x\n", szSelReg, val)); \
266}
267
268#ifdef VMX_USE_CACHED_VMCS_ACCESSES
269/**
270 * Cache VMCS writes for performance reasons (Darwin) and for running 64 bits guests on 32 bits hosts.
271 *
272 * @param pVCpu The VMCPU to operate on.
273 * @param idxField VMCS field
274 * @param u64Val Value
275 */
276DECLINLINE(int) VMXWriteCachedVMCSEx(PVMCPU pVCpu, uint32_t idxField, uint64_t u64Val)
277{
278 PVMCSCACHE pCache = &pVCpu->hwaccm.s.vmx.VMCSCache;
279
280 AssertMsgReturn(pCache->Write.cValidEntries < VMCSCACHE_MAX_ENTRY - 1, ("entries=%x\n", pCache->Write.cValidEntries), VERR_ACCESS_DENIED);
281 pCache->Write.aField[pCache->Write.cValidEntries] = idxField;
282 pCache->Write.aFieldVal[pCache->Write.cValidEntries] = u64Val;
283 pCache->Write.cValidEntries++;
284 return VINF_SUCCESS;
285}
286
287/**
288 * Flush the write cache in order not to overflow it with frequent ring switches.
289 *
290 * @param pVCpu The VMCPU to operate on.
291 */
292VMMR0DECL(void) VMXFlushWriteCache(PVMCPU pVCpu);
293
294#else
295# define VMXFlushWriteCache(a) do { } while (0)
296#endif
297
298/**
299 * Cache VMCS writes for performance reasons (Darwin) and for running 64 bits guests on 32 bits hosts.
300 *
301 * @param idxField VMCS field
302 * @param val Field value
303 */
304#ifdef VMX_USE_CACHED_VMCS_ACCESSES
305# define VMXWriteCachedVMCS(idxField, uVal) VMXWriteCachedVMCSEx(pVCpu, idxField, uVal)
306# define VMXWriteCachedVMCS64(idxField, uVal) VMXWriteVMCS64(idxField, (uVal))
307# if 0
308# if HC_ARCH_BITS == 64 || defined(RT_OS_DARWIN)
309# define VMXWriteCachedVMCS64(idxField, uVal) VMXWriteCachedVMCSEx(pVCpu, idxField, uVal)
310# else
311# define VMXWriteCachedVMCS64(idxField, uVal) (CPUMIsGuestInLongModeEx(pCtx)) ? VMXWriteCachedVMCSEx(pVCpu, idxField, uVal) : (VMXWriteCachedVMCSEx(pVCpu, idxField, uVal) | VMXWriteCachedVMCSEx(pVCpu, idxField + 1, (uVal >> 32ULL)))
312# endif
313# endif
314#else
315# define VMXWriteCachedVMCS(idxField, uVal) VMXWriteVMCS(idxField, (uVal))
316# define VMXWriteCachedVMCS64(idxField, uVal) VMXWriteVMCS64(idxField, (uVal))
317#endif
318
319#ifdef VMX_USE_CACHED_VMCS_ACCESSES
320/**
321 * Return value of cached VMCS read for performance reasons (Darwin) and for running 64 bits guests on 32 bits hosts.
322 *
323 * @param pVCpu The VMCPU to operate on.
324 * @param idxField VMCS cache index (not VMCS field index!)
325 * @param pVal Value
326 */
327DECLINLINE(int) VMXReadCachedVMCSEx(PVMCPU pVCpu, uint32_t idxCache, RTGCUINTREG *pVal)
328{
329 Assert(idxCache <= VMX_VMCS_MAX_NESTED_PAGING_CACHE_IDX);
330 *pVal = pVCpu->hwaccm.s.vmx.VMCSCache.Read.aFieldVal[idxCache];
331 return VINF_SUCCESS;
332}
333#endif
334
335/**
336 * Return value of cached VMCS read for performance reasons (Darwin) and for running 64 bits guests on 32 bits hosts.
337 *
338 * @param idxField VMCS field
339 * @param pVal Value pointer (out)
340 */
341#ifdef VMX_USE_CACHED_VMCS_ACCESSES
342# define VMXReadCachedVMCS(idxField, pVal) VMXReadCachedVMCSEx(pVCpu, idxField##_CACHE_IDX, pVal)
343#else
344# define VMXReadCachedVMCS(idxField, pVal) VMXReadVMCS(idxField, pVal)
345#endif
346
347/**
348 * Setup cached VMCS for performance reasons (Darwin) and for running 64 bits guests on 32 bits hosts.
349 *
350 * @param pVCpu The VMCPU to operate on.
351 * @param idxField VMCS field
352 */
353#define VMXSetupCachedReadVMCS(pCache, idxField) \
354{ \
355 Assert(pCache->Read.aField[idxField##_CACHE_IDX] == 0); \
356 pCache->Read.aField[idxField##_CACHE_IDX] = idxField; \
357 pCache->Read.aFieldVal[idxField##_CACHE_IDX] = 0; \
358}
359
360#define VMX_SETUP_SELREG(REG, pCache) \
361{ \
362 VMXSetupCachedReadVMCS(pCache, VMX_VMCS16_GUEST_FIELD_##REG); \
363 VMXSetupCachedReadVMCS(pCache, VMX_VMCS32_GUEST_##REG##_LIMIT); \
364 VMXSetupCachedReadVMCS(pCache, VMX_VMCS64_GUEST_##REG##_BASE); \
365 VMXSetupCachedReadVMCS(pCache, VMX_VMCS32_GUEST_##REG##_ACCESS_RIGHTS); \
366}
367
368/**
369 * Prepares for and executes VMLAUNCH (32 bits guest mode)
370 *
371 * @returns VBox status code
372 * @param fResume vmlauch/vmresume
373 * @param pCtx Guest context
374 * @param pCache VMCS cache
375 * @param pVM The VM to operate on.
376 * @param pVCpu The VMCPU to operate on.
377 */
378DECLASM(int) VMXR0StartVM32(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu);
379
380/**
381 * Prepares for and executes VMLAUNCH (64 bits guest mode)
382 *
383 * @returns VBox status code
384 * @param fResume vmlauch/vmresume
385 * @param pCtx Guest context
386 * @param pCache VMCS cache
387 * @param pVM The VM to operate on.
388 * @param pVCpu The VMCPU to operate on.
389 */
390DECLASM(int) VMXR0StartVM64(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu);
391
392/**
393 * Prepares for and executes VMLAUNCH (64 bits guest mode)
394 *
395 * @returns VBox status code
396 * @param fResume vmlauch/vmresume
397 * @param pCtx Guest context
398 * @param pCache VMCS cache
399 * @param pVM The VM to operate on.
400 * @param pVCpu The VMCPU to operate on.
401 */
402DECLASM(int) VMXR0SwitcherStartVM64(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu);
403
404#endif /* IN_RING0 */
405
406/** @} */
407
408__END_DECLS
409
410#endif
411
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