VirtualBox

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

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

We must intercept X86_XCPT_DB for VT-x as DR6 is modified by X86_EFL_TF.

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