VirtualBox

source: vbox/trunk/src/VBox/VMM/HWACCMInternal.h@ 23487

Last change on this file since 23487 was 23476, checked in by vboxsync, 15 years ago

Use global (one shot on all cpus) or local (each time we want to execute guest code) initialization for VT-x and AMD-V.
Darwin and Windows hosts default to local. Linux and Solaris to global. Configurable.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 32.8 KB
Line 
1/* $Id: HWACCMInternal.h 23476 2009-10-01 12:57:36Z vboxsync $ */
2/** @file
3 * HWACCM - 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 ___HWACCMInternal_h
23#define ___HWACCMInternal_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/cpum.h>
33#include <iprt/memobj.h>
34#include <iprt/cpuset.h>
35#include <iprt/mp.h>
36#include <iprt/avl.h>
37
38#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) || defined (VBOX_WITH_64_BITS_GUESTS)
39/* Enable 64 bits guest support. */
40# define VBOX_ENABLE_64_BITS_GUESTS
41#endif
42
43#define VMX_USE_CACHED_VMCS_ACCESSES
44#define HWACCM_VMX_EMULATE_REALMODE
45#define HWACCM_VTX_WITH_EPT
46#define HWACCM_VTX_WITH_VPID
47
48
49#if 0
50/* Seeing somewhat random behaviour on my Nehalem system with auto-save of guest MSRs;
51 * for some strange reason the CPU doesn't save the MSRs during the VM-exit.
52 * Clearly visible with a dual VCPU configured OpenSolaris 200906 live cd VM.
53 *
54 * Note: change the assembly files when enabling this! (remove the manual auto load/save)
55 */
56#define VBOX_WITH_AUTO_MSR_LOAD_RESTORE
57#endif
58
59RT_C_DECLS_BEGIN
60
61
62/** @defgroup grp_hwaccm_int Internal
63 * @ingroup grp_hwaccm
64 * @internal
65 * @{
66 */
67
68
69/** Maximum number of exit reason statistics counters. */
70#define MAX_EXITREASON_STAT 0x100
71#define MASK_EXITREASON_STAT 0xff
72#define MASK_INJECT_IRQ_STAT 0xff
73
74/** @name Changed flags
75 * These flags are used to keep track of which important registers that
76 * have been changed since last they were reset.
77 * @{
78 */
79#define HWACCM_CHANGED_GUEST_FPU RT_BIT(0)
80#define HWACCM_CHANGED_GUEST_CR0 RT_BIT(1)
81#define HWACCM_CHANGED_GUEST_CR3 RT_BIT(2)
82#define HWACCM_CHANGED_GUEST_CR4 RT_BIT(3)
83#define HWACCM_CHANGED_GUEST_GDTR RT_BIT(4)
84#define HWACCM_CHANGED_GUEST_IDTR RT_BIT(5)
85#define HWACCM_CHANGED_GUEST_LDTR RT_BIT(6)
86#define HWACCM_CHANGED_GUEST_TR RT_BIT(7)
87#define HWACCM_CHANGED_GUEST_SYSENTER_MSR RT_BIT(8)
88#define HWACCM_CHANGED_GUEST_SEGMENT_REGS RT_BIT(9)
89#define HWACCM_CHANGED_GUEST_DEBUG RT_BIT(10)
90#define HWACCM_CHANGED_HOST_CONTEXT RT_BIT(11)
91
92#define HWACCM_CHANGED_ALL ( HWACCM_CHANGED_GUEST_SEGMENT_REGS \
93 | HWACCM_CHANGED_GUEST_CR0 \
94 | HWACCM_CHANGED_GUEST_CR3 \
95 | HWACCM_CHANGED_GUEST_CR4 \
96 | HWACCM_CHANGED_GUEST_GDTR \
97 | HWACCM_CHANGED_GUEST_IDTR \
98 | HWACCM_CHANGED_GUEST_LDTR \
99 | HWACCM_CHANGED_GUEST_TR \
100 | HWACCM_CHANGED_GUEST_SYSENTER_MSR \
101 | HWACCM_CHANGED_GUEST_FPU \
102 | HWACCM_CHANGED_GUEST_DEBUG \
103 | HWACCM_CHANGED_HOST_CONTEXT)
104
105#define HWACCM_CHANGED_ALL_GUEST ( HWACCM_CHANGED_GUEST_SEGMENT_REGS \
106 | HWACCM_CHANGED_GUEST_CR0 \
107 | HWACCM_CHANGED_GUEST_CR3 \
108 | HWACCM_CHANGED_GUEST_CR4 \
109 | HWACCM_CHANGED_GUEST_GDTR \
110 | HWACCM_CHANGED_GUEST_IDTR \
111 | HWACCM_CHANGED_GUEST_LDTR \
112 | HWACCM_CHANGED_GUEST_TR \
113 | HWACCM_CHANGED_GUEST_SYSENTER_MSR \
114 | HWACCM_CHANGED_GUEST_DEBUG \
115 | HWACCM_CHANGED_GUEST_FPU)
116
117/** @} */
118
119/** @name Intercepted traps
120 * Traps that need to be intercepted so we can correctly dispatch them to the guest if required.
121 * Currently #NM and #PF only
122 */
123#ifdef VBOX_STRICT
124#define HWACCM_VMX_TRAP_MASK RT_BIT(X86_XCPT_DE) | RT_BIT(X86_XCPT_NM) | RT_BIT(X86_XCPT_PF) | RT_BIT(X86_XCPT_UD) | RT_BIT(X86_XCPT_NP) | RT_BIT(X86_XCPT_SS) | RT_BIT(X86_XCPT_GP) | RT_BIT(X86_XCPT_MF)
125#define HWACCM_SVM_TRAP_MASK HWACCM_VMX_TRAP_MASK
126#else
127#define HWACCM_VMX_TRAP_MASK RT_BIT(X86_XCPT_NM) | RT_BIT(X86_XCPT_PF)
128#define HWACCM_SVM_TRAP_MASK RT_BIT(X86_XCPT_NM) | RT_BIT(X86_XCPT_PF)
129#endif
130/* All exceptions have to be intercept in emulated real-mode (minues NM & PF as they are always intercepted. */
131#define HWACCM_VMX_TRAP_MASK_REALMODE RT_BIT(X86_XCPT_DE) | RT_BIT(X86_XCPT_DB) | RT_BIT(X86_XCPT_NMI) | RT_BIT(X86_XCPT_BP) | RT_BIT(X86_XCPT_OF) | RT_BIT(X86_XCPT_BR) | RT_BIT(X86_XCPT_UD) | RT_BIT(X86_XCPT_DF) | RT_BIT(X86_XCPT_CO_SEG_OVERRUN) | RT_BIT(X86_XCPT_TS) | RT_BIT(X86_XCPT_NP) | RT_BIT(X86_XCPT_SS) | RT_BIT(X86_XCPT_GP) | RT_BIT(X86_XCPT_MF) | RT_BIT(X86_XCPT_AC) | RT_BIT(X86_XCPT_MC) | RT_BIT(X86_XCPT_XF)
132/** @} */
133
134
135/** Maximum number of page flushes we are willing to remember before considering a full TLB flush. */
136#define HWACCM_MAX_TLB_SHOOTDOWN_PAGES 8
137
138/** Size for the EPT identity page table (1024 4 MB pages to cover the entire address space). */
139#define HWACCM_EPT_IDENTITY_PG_TABLE_SIZE PAGE_SIZE
140/** Size of the TSS structure + 2 pages for the IO bitmap + end byte. */
141#define HWACCM_VTX_TSS_SIZE (sizeof(VBOXTSS) + 2*PAGE_SIZE + 1)
142/** Total guest mapped memory needed. */
143#define HWACCM_VTX_TOTAL_DEVHEAP_MEM (HWACCM_EPT_IDENTITY_PG_TABLE_SIZE + HWACCM_VTX_TSS_SIZE)
144
145/* Enable for TPR guest patching. */
146#define VBOX_HWACCM_WITH_GUEST_PATCHING
147
148/** HWACCM SSM version
149 */
150#ifdef VBOX_HWACCM_WITH_GUEST_PATCHING
151#define HWACCM_SSM_VERSION 5
152#define HWACCM_SSM_VERSION_NO_PATCHING 4
153#else
154#define HWACCM_SSM_VERSION 4
155#define HWACCM_SSM_VERSION_NO_PATCHING 4
156#endif
157#define HWACCM_SSM_VERSION_2_0_X 3
158
159/* Per-cpu information. (host) */
160typedef struct
161{
162 RTCPUID idCpu;
163
164 RTR0MEMOBJ pMemObj;
165 /* Current ASID (AMD-V)/VPID (Intel) */
166 uint32_t uCurrentASID;
167 /* TLB flush count */
168 uint32_t cTLBFlushes;
169
170 /* Set the first time a cpu is used to make sure we start with a clean TLB. */
171 bool fFlushTLB;
172
173 /** Configured for VT-x or AMD-V. */
174 bool fConfigured;
175
176 /** In use by our code. (for power suspend) */
177 volatile bool fInUse;
178} HWACCM_CPUINFO;
179typedef HWACCM_CPUINFO *PHWACCM_CPUINFO;
180
181/* VT-x capability qword. */
182typedef union
183{
184 struct
185 {
186 uint32_t disallowed0;
187 uint32_t allowed1;
188 } n;
189 uint64_t u;
190} VMX_CAPABILITY;
191
192typedef enum
193{
194 HWACCMPENDINGIO_INVALID = 0,
195 HWACCMPENDINGIO_PORT_READ,
196 HWACCMPENDINGIO_PORT_WRITE,
197 HWACCMPENDINGIO_STRING_READ,
198 HWACCMPENDINGIO_STRING_WRITE,
199 /** The usual 32-bit paranoia. */
200 HWACCMPENDINGIO_32BIT_HACK = 0x7fffffff
201} HWACCMPENDINGIO;
202
203
204typedef enum
205{
206 HWACCMTPRINSTR_INVALID,
207 HWACCMTPRINSTR_READ,
208 HWACCMTPRINSTR_READ_SHR4,
209 HWACCMTPRINSTR_WRITE_REG,
210 HWACCMTPRINSTR_WRITE_IMM,
211 HWACCMTPRINSTR_JUMP_REPLACEMENT,
212 /** The usual 32-bit paranoia. */
213 HWACCMTPRINSTR_32BIT_HACK = 0x7fffffff
214} HWACCMTPRINSTR;
215
216typedef struct
217{
218 /** The key is the address of patched instruction. (32 bits GC ptr) */
219 AVLOU32NODECORE Core;
220 /** Original opcode. */
221 uint8_t aOpcode[16];
222 /** Instruction size. */
223 uint32_t cbOp;
224 /** Replacement opcode. */
225 uint8_t aNewOpcode[16];
226 /** Replacement instruction size. */
227 uint32_t cbNewOp;
228 /** Instruction type. */
229 HWACCMTPRINSTR enmType;
230 /** Source operand. */
231 uint32_t uSrcOperand;
232 /** Destination operand. */
233 uint32_t uDstOperand;
234 /** Number of times the instruction caused a fault. */
235 uint32_t cFaults;
236 /** Patch address of the jump replacement. */
237 RTGCPTR32 pJumpTarget;
238} HWACCMTPRPATCH;
239/** Pointer to HWACCMTPRPATCH. */
240typedef HWACCMTPRPATCH *PHWACCMTPRPATCH;
241
242/**
243 * Switcher function, HC to RC.
244 *
245 * @param pVM The VM handle.
246 * @returns Return code indicating the action to take.
247 */
248typedef DECLASMTYPE(int) FNHWACCMSWITCHERHC(PVM pVM);
249/** Pointer to switcher function. */
250typedef FNHWACCMSWITCHERHC *PFNHWACCMSWITCHERHC;
251
252/**
253 * HWACCM VM Instance data.
254 * Changes to this must checked against the padding of the cfgm union in VM!
255 */
256typedef struct HWACCM
257{
258 /** Set when we've initialized VMX or SVM. */
259 bool fInitialized;
260
261 /** Set when hardware acceleration is allowed. */
262 bool fAllowed;
263
264 /** Set if nested paging is enabled. */
265 bool fNestedPaging;
266
267 /** Set if nested paging is allowed. */
268 bool fAllowNestedPaging;
269
270 /** Set if we can support 64-bit guests or not. */
271 bool fAllow64BitGuests;
272
273 /** Set if an IO-APIC is configured for this VM. */
274 bool fHasIoApic;
275
276 /** Set when TPR patching is allowed. */
277 bool fTRPPatchingAllowed;
278
279 /** Set when we initialize VT-x or AMD-V once for all CPUs. */
280 bool fGlobalInit;
281
282 /** And mask for copying register contents. */
283 uint64_t u64RegisterMask;
284
285 /** Maximum ASID allowed. */
286 RTUINT uMaxASID;
287
288 /** The maximum number of resumes loops allowed in ring-0 (safety precaution).
289 * This number is set much higher when RTThreadPreemptIsPending is reliable. */
290 uint32_t cMaxResumeLoops;
291
292 /** Guest allocated memory for patching purposes. */
293 RTGCPTR pGuestPatchMem;
294 /** Current free pointer inside the patch block. */
295 RTGCPTR pFreeGuestPatchMem;
296 /** Size of the guest patch memory block. */
297 uint32_t cbGuestPatchMem;
298 uint32_t uPadding1;
299
300#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
301 /** 32 to 64 bits switcher entrypoint. */
302 R0PTRTYPE(PFNHWACCMSWITCHERHC) pfnHost32ToGuest64R0;
303
304 /* AMD-V 64 bits vmrun handler */
305 RTRCPTR pfnSVMGCVMRun64;
306
307 /* VT-x 64 bits vmlaunch handler */
308 RTRCPTR pfnVMXGCStartVM64;
309
310 /* RC handler to setup the 64 bits FPU state. */
311 RTRCPTR pfnSaveGuestFPU64;
312
313 /* RC handler to setup the 64 bits debug state. */
314 RTRCPTR pfnSaveGuestDebug64;
315
316 /* Test handler */
317 RTRCPTR pfnTest64;
318
319 RTRCPTR uAlignment[2];
320/*#elif defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
321 uint32_t u32Alignment[1]; */
322#endif
323
324 struct
325 {
326 /** Set by the ring-0 driver to indicate VMX is supported by the CPU. */
327 bool fSupported;
328
329 /** Set when we've enabled VMX. */
330 bool fEnabled;
331
332 /** Set if VPID is supported. */
333 bool fVPID;
334
335 /** Set if VT-x VPID is allowed. */
336 bool fAllowVPID;
337
338 /** Virtual address of the TSS page used for real mode emulation. */
339 R3PTRTYPE(PVBOXTSS) pRealModeTSS;
340
341 /** Virtual address of the identity page table used for real mode and protected mode without paging emulation in EPT mode. */
342 R3PTRTYPE(PX86PD) pNonPagingModeEPTPageTable;
343
344 /** R0 memory object for the APIC physical page (serves for filtering accesses). */
345 RTR0MEMOBJ pMemObjAPIC;
346 /** Physical address of the APIC physical page (serves for filtering accesses). */
347 RTHCPHYS pAPICPhys;
348 /** Virtual address of the APIC physical page (serves for filtering accesses). */
349 R0PTRTYPE(uint8_t *) pAPIC;
350
351 /** R0 memory object for the MSR entry load page (guest MSRs). */
352 RTR0MEMOBJ pMemObjMSREntryLoad;
353 /** Physical address of the MSR entry load page (guest MSRs). */
354 RTHCPHYS pMSREntryLoadPhys;
355 /** Virtual address of the MSR entry load page (guest MSRs). */
356 R0PTRTYPE(uint8_t *) pMSREntryLoad;
357
358#ifdef VBOX_WITH_CRASHDUMP_MAGIC
359 RTR0MEMOBJ pMemObjScratch;
360 RTHCPHYS pScratchPhys;
361 R0PTRTYPE(uint8_t *) pScratch;
362#endif
363 /** R0 memory object for the MSR exit store page (guest MSRs). */
364 RTR0MEMOBJ pMemObjMSRExitStore;
365 /** Physical address of the MSR exit store page (guest MSRs). */
366 RTHCPHYS pMSRExitStorePhys;
367 /** Virtual address of the MSR exit store page (guest MSRs). */
368 R0PTRTYPE(uint8_t *) pMSRExitStore;
369
370 /** R0 memory object for the MSR exit load page (host MSRs). */
371 RTR0MEMOBJ pMemObjMSRExitLoad;
372 /** Physical address of the MSR exit load page (host MSRs). */
373 RTHCPHYS pMSRExitLoadPhys;
374 /** Virtual address of the MSR exit load page (host MSRs). */
375 R0PTRTYPE(uint8_t *) pMSRExitLoad;
376
377 /** Ring 0 handlers for VT-x. */
378 DECLR0CALLBACKMEMBER(void, pfnSetupTaggedTLB, (PVM pVM, PVMCPU pVCpu));
379
380 /** Host CR4 value (set by ring-0 VMX init) */
381 uint64_t hostCR4;
382
383 /** VMX MSR values */
384 struct
385 {
386 uint64_t feature_ctrl;
387 uint64_t vmx_basic_info;
388 VMX_CAPABILITY vmx_pin_ctls;
389 VMX_CAPABILITY vmx_proc_ctls;
390 VMX_CAPABILITY vmx_proc_ctls2;
391 VMX_CAPABILITY vmx_exit;
392 VMX_CAPABILITY vmx_entry;
393 uint64_t vmx_misc;
394 uint64_t vmx_cr0_fixed0;
395 uint64_t vmx_cr0_fixed1;
396 uint64_t vmx_cr4_fixed0;
397 uint64_t vmx_cr4_fixed1;
398 uint64_t vmx_vmcs_enum;
399 uint64_t vmx_eptcaps;
400 } msr;
401
402 /** Flush types for invept & invvpid; they depend on capabilities. */
403 VMX_FLUSH enmFlushPage;
404 VMX_FLUSH enmFlushContext;
405 } vmx;
406
407 struct
408 {
409 /** Set by the ring-0 driver to indicate SVM is supported by the CPU. */
410 bool fSupported;
411 /** Set when we've enabled SVM. */
412 bool fEnabled;
413 /** Set if erratum 170 affects the AMD cpu. */
414 bool fAlwaysFlushTLB;
415 /** Set when TPR patching is active. */
416 bool fTPRPatchingActive;
417
418 /** R0 memory object for the IO bitmap (12kb). */
419 RTR0MEMOBJ pMemObjIOBitmap;
420 /** Physical address of the IO bitmap (12kb). */
421 RTHCPHYS pIOBitmapPhys;
422 /** Virtual address of the IO bitmap. */
423 R0PTRTYPE(void *) pIOBitmap;
424
425 /** SVM revision. */
426 uint32_t u32Rev;
427
428 /** SVM feature bits from cpuid 0x8000000a */
429 uint32_t u32Features;
430
431 /**
432 * AVL tree with all patches (active or disabled) sorted by guest instruction address
433 */
434 AVLOU32TREE PatchTree;
435 uint32_t cPatches;
436 HWACCMTPRPATCH aPatches[64];
437 } svm;
438
439 struct
440 {
441 uint32_t u32AMDFeatureECX;
442 uint32_t u32AMDFeatureEDX;
443 } cpuid;
444
445 /** Saved error from detection */
446 int32_t lLastError;
447
448 /** HWACCMR0Init was run */
449 bool fHWACCMR0Init;
450 bool u8Alignment[7];
451
452 STAMCOUNTER StatTPRPatchSuccess;
453 STAMCOUNTER StatTPRPatchFailure;
454 STAMCOUNTER StatTPRReplaceSuccess;
455 STAMCOUNTER StatTPRReplaceFailure;
456} HWACCM;
457/** Pointer to HWACCM VM instance data. */
458typedef HWACCM *PHWACCM;
459
460/* Maximum number of cached entries. */
461#define VMCSCACHE_MAX_ENTRY 128
462
463/* Structure for storing read and write VMCS actions. */
464typedef struct VMCSCACHE
465{
466#ifdef VBOX_WITH_CRASHDUMP_MAGIC
467 /* Magic marker for searching in crash dumps. */
468 uint8_t aMagic[16];
469 uint64_t uMagic;
470 uint64_t u64TimeEntry;
471 uint64_t u64TimeSwitch;
472 uint64_t cResume;
473 uint64_t interPD;
474 uint64_t pSwitcher;
475 uint32_t uPos;
476 uint32_t idCpu;
477#endif
478 /* CR2 is saved here for EPT syncing. */
479 uint64_t cr2;
480 struct
481 {
482 uint32_t cValidEntries;
483 uint32_t uAlignment;
484 uint32_t aField[VMCSCACHE_MAX_ENTRY];
485 uint64_t aFieldVal[VMCSCACHE_MAX_ENTRY];
486 } Write;
487 struct
488 {
489 uint32_t cValidEntries;
490 uint32_t uAlignment;
491 uint32_t aField[VMCSCACHE_MAX_ENTRY];
492 uint64_t aFieldVal[VMCSCACHE_MAX_ENTRY];
493 } Read;
494#ifdef DEBUG
495 struct
496 {
497 RTHCPHYS pPageCpuPhys;
498 RTHCPHYS pVMCSPhys;
499 RTGCPTR pCache;
500 RTGCPTR pCtx;
501 } TestIn;
502 struct
503 {
504 RTHCPHYS pVMCSPhys;
505 RTGCPTR pCache;
506 RTGCPTR pCtx;
507 uint64_t eflags;
508 uint64_t cr8;
509 } TestOut;
510 struct
511 {
512 uint64_t param1;
513 uint64_t param2;
514 uint64_t param3;
515 uint64_t param4;
516 } ScratchPad;
517#endif
518} VMCSCACHE;
519/** Pointer to VMCSCACHE. */
520typedef VMCSCACHE *PVMCSCACHE;
521
522/** VMX StartVM function. */
523typedef DECLCALLBACK(int) FNHWACCMVMXSTARTVM(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu);
524/** Pointer to a VMX StartVM function. */
525typedef R0PTRTYPE(FNHWACCMVMXSTARTVM *) PFNHWACCMVMXSTARTVM;
526
527/** SVM VMRun function. */
528typedef DECLCALLBACK(int) FNHWACCMSVMVMRUN(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx, PVM pVM, PVMCPU pVCpu);
529/** Pointer to a SVM VMRun function. */
530typedef R0PTRTYPE(FNHWACCMSVMVMRUN *) PFNHWACCMSVMVMRUN;
531
532/**
533 * HWACCM VMCPU Instance data.
534 */
535typedef struct HWACCMCPU
536{
537 /** Old style FPU reporting trap mask override performed (optimization) */
538 bool fFPUOldStyleOverride;
539
540 /** Set if we don't have to flush the TLB on VM entry. */
541 bool fResumeVM;
542
543 /** Set if we need to flush the TLB during the world switch. */
544 bool fForceTLBFlush;
545
546 /** Set when we're using VT-x or AMD-V at that moment. */
547 bool fActive;
548
549 /** Set when the TLB has been checked until we return from the world switch. */
550 volatile uint8_t fCheckedTLBFlush;
551 uint8_t bAlignment[3];
552
553 /** HWACCM_CHANGED_* flags. */
554 RTUINT fContextUseFlags;
555
556 /** Id of the last cpu we were executing code on (NIL_RTCPUID for the first time) */
557 RTCPUID idLastCpu;
558
559 /** TLB flush count */
560 RTUINT cTLBFlushes;
561
562 /** Current ASID in use by the VM */
563 RTUINT uCurrentASID;
564
565 /** World switch exit counter. */
566 volatile uint32_t cWorldSwitchExit;
567 uint32_t u32Alignment;
568
569 struct
570 {
571 /** Physical address of the VM control structure (VMCS). */
572 RTHCPHYS pVMCSPhys;
573 /** R0 memory object for the VM control structure (VMCS). */
574 RTR0MEMOBJ pMemObjVMCS;
575 /** Virtual address of the VM control structure (VMCS). */
576 R0PTRTYPE(void *) pVMCS;
577
578 /** Ring 0 handlers for VT-x. */
579 PFNHWACCMVMXSTARTVM pfnStartVM;
580
581#if HC_ARCH_BITS == 32
582 uint32_t u32Alignment;
583#endif
584
585 /** Current VMX_VMCS_CTRL_PROC_EXEC_CONTROLS. */
586 uint64_t proc_ctls;
587
588 /** Current VMX_VMCS_CTRL_PROC_EXEC2_CONTROLS. */
589 uint64_t proc_ctls2;
590
591 /** Physical address of the virtual APIC page for TPR caching. */
592 RTHCPHYS pVAPICPhys;
593 /** R0 memory object for the virtual APIC page for TPR caching. */
594 RTR0MEMOBJ pMemObjVAPIC;
595 /** Virtual address of the virtual APIC page for TPR caching. */
596 R0PTRTYPE(uint8_t *) pVAPIC;
597
598 /** Current CR0 mask. */
599 uint64_t cr0_mask;
600 /** Current CR4 mask. */
601 uint64_t cr4_mask;
602
603 /** Current EPTP. */
604 RTHCPHYS GCPhysEPTP;
605
606 /** Physical address of the MSR bitmap (1 page). */
607 RTHCPHYS pMSRBitmapPhys;
608 /** R0 memory object for the MSR bitmap (1 page). */
609 RTR0MEMOBJ pMemObjMSRBitmap;
610 /** Virtual address of the MSR bitmap (1 page). */
611 R0PTRTYPE(uint8_t *) pMSRBitmap;
612
613#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
614 /** Physical address of the guest MSR load area (1 page). */
615 RTHCPHYS pGuestMSRPhys;
616 /** R0 memory object for the guest MSR load area (1 page). */
617 RTR0MEMOBJ pMemObjGuestMSR;
618 /** Virtual address of the guest MSR load area (1 page). */
619 R0PTRTYPE(uint8_t *) pGuestMSR;
620
621 /** Physical address of the MSR load area (1 page). */
622 RTHCPHYS pHostMSRPhys;
623 /** R0 memory object for the MSR load area (1 page). */
624 RTR0MEMOBJ pMemObjHostMSR;
625 /** Virtual address of the MSR load area (1 page). */
626 R0PTRTYPE(uint8_t *) pHostMSR;
627#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
628
629 /* Number of automatically loaded/restored MSRs. */
630 uint32_t cCachedMSRs;
631 uint32_t uAlignement;
632
633 /* Last use TSC offset value. (cached) */
634 uint64_t u64TSCOffset;
635
636 /** VMCS cache. */
637 VMCSCACHE VMCSCache;
638
639 /** Real-mode emulation state. */
640 struct
641 {
642 X86EFLAGS eflags;
643 uint32_t fValid;
644 } RealMode;
645
646 struct
647 {
648 uint64_t u64VMCSPhys;
649 uint32_t ulVMCSRevision;
650 uint32_t ulInstrError;
651 uint32_t ulExitReason;
652 RTCPUID idEnteredCpu;
653 RTCPUID idCurrentCpu;
654 uint32_t padding;
655 } lasterror;
656
657 /** The last seen guest paging mode (by VT-x). */
658 PGMMODE enmLastSeenGuestMode;
659 /** Current guest paging mode (as seen by HWACCMR3PagingModeChanged). */
660 PGMMODE enmCurrGuestMode;
661 /** Previous guest paging mode (as seen by HWACCMR3PagingModeChanged). */
662 PGMMODE enmPrevGuestMode;
663 } vmx;
664
665 struct
666 {
667 /** R0 memory object for the host VM control block (VMCB). */
668 RTR0MEMOBJ pMemObjVMCBHost;
669 /** Physical address of the host VM control block (VMCB). */
670 RTHCPHYS pVMCBHostPhys;
671 /** Virtual address of the host VM control block (VMCB). */
672 R0PTRTYPE(void *) pVMCBHost;
673
674 /** R0 memory object for the VM control block (VMCB). */
675 RTR0MEMOBJ pMemObjVMCB;
676 /** Physical address of the VM control block (VMCB). */
677 RTHCPHYS pVMCBPhys;
678 /** Virtual address of the VM control block (VMCB). */
679 R0PTRTYPE(void *) pVMCB;
680
681 /** Ring 0 handlers for VT-x. */
682 PFNHWACCMSVMVMRUN pfnVMRun;
683
684 /** R0 memory object for the MSR bitmap (8kb). */
685 RTR0MEMOBJ pMemObjMSRBitmap;
686 /** Physical address of the MSR bitmap (8kb). */
687 RTHCPHYS pMSRBitmapPhys;
688 /** Virtual address of the MSR bitmap. */
689 R0PTRTYPE(void *) pMSRBitmap;
690 } svm;
691
692 /** Event injection state. */
693 struct
694 {
695 uint32_t fPending;
696 uint32_t errCode;
697 uint64_t intInfo;
698 } Event;
699
700 /** IO Block emulation state. */
701 struct
702 {
703 bool fEnabled;
704 uint8_t u8Align[7];
705
706 /** RIP at the start of the io code we wish to emulate in the recompiler. */
707 RTGCPTR GCPtrFunctionEip;
708
709 uint64_t cr0;
710 } EmulateIoBlock;
711
712 struct
713 {
714 /* Pending IO operation type. */
715 HWACCMPENDINGIO enmType;
716 uint32_t uPadding;
717 RTGCPTR GCPtrRip;
718 RTGCPTR GCPtrRipNext;
719 union
720 {
721 struct
722 {
723 unsigned uPort;
724 unsigned uAndVal;
725 unsigned cbSize;
726 } Port;
727 uint64_t aRaw[2];
728 } s;
729 } PendingIO;
730
731 /** Currenty shadow paging mode. */
732 PGMMODE enmShadowMode;
733
734 /** The CPU ID of the CPU currently owning the VMCS. Set in
735 * HWACCMR0Enter and cleared in HWACCMR0Leave. */
736 RTCPUID idEnteredCpu;
737
738 /** To keep track of pending TLB shootdown pages. (SMP guest only) */
739 struct
740 {
741 RTGCPTR aPages[HWACCM_MAX_TLB_SHOOTDOWN_PAGES];
742 unsigned cPages;
743 } TlbShootdown;
744
745 /** For saving stack space, the disassembler state is allocated here instead of
746 * on the stack.
747 * @note The DISCPUSTATE structure is not R3/R0/RZ clean! */
748 union
749 {
750 /** The disassembler scratch space. */
751 DISCPUSTATE DisState;
752 /** Padding. */
753 uint8_t abDisStatePadding[DISCPUSTATE_PADDING_SIZE];
754 };
755
756 RTUINT padding2[1];
757
758 STAMPROFILEADV StatEntry;
759 STAMPROFILEADV StatExit1;
760 STAMPROFILEADV StatExit2;
761#if 1 /* temporary for tracking down darwin issues. */
762 STAMPROFILEADV StatExit2Sub1;
763 STAMPROFILEADV StatExit2Sub2;
764 STAMPROFILEADV StatExit2Sub3;
765#endif
766 STAMPROFILEADV StatInGC;
767
768#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
769 STAMPROFILEADV StatWorldSwitch3264;
770#endif
771 STAMPROFILEADV StatSpinPoke;
772 STAMPROFILEADV StatSpinPokeFailed;
773
774 STAMCOUNTER StatIntInject;
775
776 STAMCOUNTER StatExitShadowNM;
777 STAMCOUNTER StatExitGuestNM;
778 STAMCOUNTER StatExitShadowPF;
779 STAMCOUNTER StatExitGuestPF;
780 STAMCOUNTER StatExitGuestUD;
781 STAMCOUNTER StatExitGuestSS;
782 STAMCOUNTER StatExitGuestNP;
783 STAMCOUNTER StatExitGuestGP;
784 STAMCOUNTER StatExitGuestDE;
785 STAMCOUNTER StatExitGuestDB;
786 STAMCOUNTER StatExitGuestMF;
787 STAMCOUNTER StatExitInvpg;
788 STAMCOUNTER StatExitInvd;
789 STAMCOUNTER StatExitCpuid;
790 STAMCOUNTER StatExitRdtsc;
791 STAMCOUNTER StatExitRdpmc;
792 STAMCOUNTER StatExitCli;
793 STAMCOUNTER StatExitSti;
794 STAMCOUNTER StatExitPushf;
795 STAMCOUNTER StatExitPopf;
796 STAMCOUNTER StatExitIret;
797 STAMCOUNTER StatExitInt;
798 STAMCOUNTER StatExitCRxWrite[16];
799 STAMCOUNTER StatExitCRxRead[16];
800 STAMCOUNTER StatExitDRxWrite;
801 STAMCOUNTER StatExitDRxRead;
802 STAMCOUNTER StatExitRdmsr;
803 STAMCOUNTER StatExitWrmsr;
804 STAMCOUNTER StatExitCLTS;
805 STAMCOUNTER StatExitHlt;
806 STAMCOUNTER StatExitMwait;
807 STAMCOUNTER StatExitLMSW;
808 STAMCOUNTER StatExitIOWrite;
809 STAMCOUNTER StatExitIORead;
810 STAMCOUNTER StatExitIOStringWrite;
811 STAMCOUNTER StatExitIOStringRead;
812 STAMCOUNTER StatExitIrqWindow;
813 STAMCOUNTER StatExitMaxResume;
814 STAMCOUNTER StatExitPreemptPending;
815 STAMCOUNTER StatIntReinject;
816 STAMCOUNTER StatPendingHostIrq;
817
818 STAMCOUNTER StatFlushPageManual;
819 STAMCOUNTER StatFlushPhysPageManual;
820 STAMCOUNTER StatFlushTLBManual;
821 STAMCOUNTER StatFlushPageInvlpg;
822 STAMCOUNTER StatFlushTLBWorldSwitch;
823 STAMCOUNTER StatNoFlushTLBWorldSwitch;
824 STAMCOUNTER StatFlushTLBCRxChange;
825 STAMCOUNTER StatFlushASID;
826 STAMCOUNTER StatFlushTLBInvlpga;
827 STAMCOUNTER StatTlbShootdown;
828 STAMCOUNTER StatTlbShootdownFlush;
829
830 STAMCOUNTER StatSwitchGuestIrq;
831 STAMCOUNTER StatSwitchToR3;
832
833 STAMCOUNTER StatTSCOffset;
834 STAMCOUNTER StatTSCIntercept;
835 STAMCOUNTER StatTSCInterceptOverFlow;
836
837 STAMCOUNTER StatExitReasonNPF;
838 STAMCOUNTER StatDRxArmed;
839 STAMCOUNTER StatDRxContextSwitch;
840 STAMCOUNTER StatDRxIOCheck;
841
842
843#ifdef VBOX_WITH_STATISTICS
844 R3PTRTYPE(PSTAMCOUNTER) paStatExitReason;
845 R0PTRTYPE(PSTAMCOUNTER) paStatExitReasonR0;
846 R3PTRTYPE(PSTAMCOUNTER) paStatInjectedIrqs;
847 R0PTRTYPE(PSTAMCOUNTER) paStatInjectedIrqsR0;
848#endif
849} HWACCMCPU;
850/** Pointer to HWACCM VM instance data. */
851typedef HWACCMCPU *PHWACCMCPU;
852
853
854#ifdef IN_RING0
855
856VMMR0DECL(PHWACCM_CPUINFO) HWACCMR0GetCurrentCpu();
857VMMR0DECL(PHWACCM_CPUINFO) HWACCMR0GetCurrentCpuEx(RTCPUID idCpu);
858
859
860#ifdef VBOX_STRICT
861VMMR0DECL(void) HWACCMDumpRegs(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
862VMMR0DECL(void) HWACCMR0DumpDescriptor(PCX86DESCHC pDesc, RTSEL Sel, const char *pszMsg);
863#else
864# define HWACCMDumpRegs(a, b ,c) do { } while (0)
865# define HWACCMR0DumpDescriptor(a, b, c) do { } while (0)
866#endif
867
868/* Dummy callback handlers. */
869VMMR0DECL(int) HWACCMR0DummyEnter(PVM pVM, PVMCPU pVCpu, PHWACCM_CPUINFO pCpu);
870VMMR0DECL(int) HWACCMR0DummyLeave(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
871VMMR0DECL(int) HWACCMR0DummyEnableCpu(PHWACCM_CPUINFO pCpu, PVM pVM, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
872VMMR0DECL(int) HWACCMR0DummyDisableCpu(PHWACCM_CPUINFO pCpu, void *pvPageCpu, RTHCPHYS pPageCpuPhys);
873VMMR0DECL(int) HWACCMR0DummyInitVM(PVM pVM);
874VMMR0DECL(int) HWACCMR0DummyTermVM(PVM pVM);
875VMMR0DECL(int) HWACCMR0DummySetupVM(PVM pVM);
876VMMR0DECL(int) HWACCMR0DummyRunGuestCode(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
877VMMR0DECL(int) HWACCMR0DummySaveHostState(PVM pVM, PVMCPU pVCpu);
878VMMR0DECL(int) HWACCMR0DummyLoadGuestState(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
879
880# ifdef VBOX_WITH_KERNEL_USING_XMM
881DECLASM(int) hwaccmR0VMXStartVMWrapXMM(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu, PFNHWACCMVMXSTARTVM pfnStartVM);
882DECLASM(int) hwaccmR0SVMRunWrapXMM(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx, PVM pVM, PVMCPU pVCpu, PFNHWACCMSVMVMRUN pfnVMRun);
883# endif
884
885# ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
886/**
887 * Gets 64-bit GDTR and IDTR on darwin.
888 * @param pGdtr Where to store the 64-bit GDTR.
889 * @param pIdtr Where to store the 64-bit IDTR.
890 */
891DECLASM(void) hwaccmR0Get64bitGDTRandIDTR(PX86XDTR64 pGdtr, PX86XDTR64 pIdtr);
892
893/**
894 * Gets 64-bit CR3 on darwin.
895 * @returns CR3
896 */
897DECLASM(uint64_t) hwaccmR0Get64bitCR3(void);
898# endif
899
900#endif /* IN_RING0 */
901
902/** @} */
903
904RT_C_DECLS_END
905
906#endif
907
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