VirtualBox

source: vbox/trunk/src/VBox/VMM/include/HMInternal.h@ 45919

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

HM: Added VMX entry refused/allowed stats.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 35.4 KB
Line 
1/* $Id: HMInternal.h 45919 2013-05-06 16:01:47Z vboxsync $ */
2/** @file
3 * HM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2013 Oracle Corporation
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
18#ifndef ___HMInternal_h
19#define ___HMInternal_h
20
21#include <VBox/cdefs.h>
22#include <VBox/types.h>
23#include <VBox/vmm/em.h>
24#include <VBox/vmm/stam.h>
25#include <VBox/dis.h>
26#include <VBox/vmm/hm.h>
27#include <VBox/vmm/hm_vmx.h>
28#include <VBox/vmm/pgm.h>
29#include <VBox/vmm/cpum.h>
30#include <iprt/memobj.h>
31#include <iprt/cpuset.h>
32#include <iprt/mp.h>
33#include <iprt/avl.h>
34
35#if HC_ARCH_BITS == 64 || defined(VBOX_WITH_HYBRID_32BIT_KERNEL) || defined (VBOX_WITH_64_BITS_GUESTS)
36/* Enable 64 bits guest support. */
37# define VBOX_ENABLE_64_BITS_GUESTS
38#endif
39
40#ifdef VBOX_WITH_OLD_VTX_CODE
41# define VMX_USE_CACHED_VMCS_ACCESSES
42#elif HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
43# define VMX_USE_CACHED_VMCS_ACCESSES
44#endif
45
46/** @def HM_PROFILE_EXIT_DISPATCH
47 * Enables profiling of the VM exit handler dispatching. */
48#if 0
49# define HM_PROFILE_EXIT_DISPATCH
50#endif
51
52/* The MSR auto load/store used to not work for KERNEL_GS_BASE MSR, thus we
53 * used to handle this MSR manually. See @bugref{6208}. This was clearly visible while
54 * booting Solaris 11 (11.1 b19) VMs with 2 Cpus. This is no longer the case and we
55 * always auto load/store the KERNEL_GS_BASE MSR.
56 *
57 * Note: don't forget to update the assembly files while modifying this!
58 */
59/** @todo This define should always be in effect and the define itself removed
60 after 'sufficient' testing. */
61# define VBOX_WITH_AUTO_MSR_LOAD_RESTORE
62
63RT_C_DECLS_BEGIN
64
65
66/** @defgroup grp_hm_int Internal
67 * @ingroup grp_hm
68 * @internal
69 * @{
70 */
71
72
73/** Maximum number of exit reason statistics counters. */
74#define MAX_EXITREASON_STAT 0x100
75#define MASK_EXITREASON_STAT 0xff
76#define MASK_INJECT_IRQ_STAT 0xff
77
78/** @name Changed flags
79 * These flags are used to keep track of which important registers that
80 * have been changed since last they were reset.
81 * @{
82 */
83#ifdef VBOX_WITH_OLD_VTX_CODE
84# define HM_CHANGED_GUEST_FPU RT_BIT(0)
85# define HM_CHANGED_GUEST_CR0 RT_BIT(1)
86# define HM_CHANGED_GUEST_CR3 RT_BIT(2)
87# define HM_CHANGED_GUEST_CR4 RT_BIT(3)
88# define HM_CHANGED_GUEST_GDTR RT_BIT(4)
89# define HM_CHANGED_GUEST_IDTR RT_BIT(5)
90# define HM_CHANGED_GUEST_LDTR RT_BIT(6)
91# define HM_CHANGED_GUEST_TR RT_BIT(7)
92# define HM_CHANGED_GUEST_MSR RT_BIT(8)
93# define HM_CHANGED_GUEST_SEGMENT_REGS RT_BIT(9)
94# define HM_CHANGED_GUEST_DEBUG RT_BIT(10)
95# define HM_CHANGED_HOST_CONTEXT RT_BIT(11)
96# define HM_CHANGED_ALL_GUEST ( HM_CHANGED_GUEST_SEGMENT_REGS \
97 | HM_CHANGED_GUEST_CR0 \
98 | HM_CHANGED_GUEST_CR3 \
99 | HM_CHANGED_GUEST_CR4 \
100 | HM_CHANGED_GUEST_GDTR \
101 | HM_CHANGED_GUEST_IDTR \
102 | HM_CHANGED_GUEST_LDTR \
103 | HM_CHANGED_GUEST_TR \
104 | HM_CHANGED_GUEST_MSR \
105 | HM_CHANGED_GUEST_DEBUG \
106 | HM_CHANGED_GUEST_FPU)
107#else
108# define HM_CHANGED_GUEST_RIP RT_BIT(0)
109# define HM_CHANGED_GUEST_RSP RT_BIT(1)
110# define HM_CHANGED_GUEST_RFLAGS RT_BIT(2)
111# define HM_CHANGED_GUEST_CR0 RT_BIT(3)
112# define HM_CHANGED_GUEST_CR3 RT_BIT(4)
113# define HM_CHANGED_GUEST_CR4 RT_BIT(5)
114# define HM_CHANGED_GUEST_GDTR RT_BIT(6)
115# define HM_CHANGED_GUEST_IDTR RT_BIT(7)
116# define HM_CHANGED_GUEST_LDTR RT_BIT(8)
117# define HM_CHANGED_GUEST_TR RT_BIT(9)
118# define HM_CHANGED_GUEST_SEGMENT_REGS RT_BIT(10)
119# define HM_CHANGED_GUEST_DEBUG RT_BIT(11)
120# define HM_CHANGED_GUEST_SYSENTER_CS_MSR RT_BIT(12)
121# define HM_CHANGED_GUEST_SYSENTER_EIP_MSR RT_BIT(13)
122# define HM_CHANGED_GUEST_SYSENTER_ESP_MSR RT_BIT(14)
123# define HM_CHANGED_VMX_GUEST_AUTO_MSRS RT_BIT(15)
124# define HM_CHANGED_VMX_GUEST_ACTIVITY_STATE RT_BIT(16)
125# define HM_CHANGED_VMX_GUEST_APIC_STATE RT_BIT(17)
126# define HM_CHANGED_VMX_ENTRY_CTLS RT_BIT(18)
127# define HM_CHANGED_VMX_EXIT_CTLS RT_BIT(19)
128
129# define HM_CHANGED_HOST_CONTEXT RT_BIT(20)
130
131# define HM_CHANGED_ALL_GUEST ( HM_CHANGED_GUEST_RIP \
132 | HM_CHANGED_GUEST_RSP \
133 | HM_CHANGED_GUEST_RFLAGS \
134 | HM_CHANGED_GUEST_CR0 \
135 | HM_CHANGED_GUEST_CR3 \
136 | HM_CHANGED_GUEST_CR4 \
137 | HM_CHANGED_GUEST_GDTR \
138 | HM_CHANGED_GUEST_IDTR \
139 | HM_CHANGED_GUEST_LDTR \
140 | HM_CHANGED_GUEST_TR \
141 | HM_CHANGED_GUEST_SEGMENT_REGS \
142 | HM_CHANGED_GUEST_DEBUG \
143 | HM_CHANGED_GUEST_SYSENTER_CS_MSR \
144 | HM_CHANGED_GUEST_SYSENTER_EIP_MSR \
145 | HM_CHANGED_GUEST_SYSENTER_ESP_MSR \
146 | HM_CHANGED_VMX_GUEST_AUTO_MSRS \
147 | HM_CHANGED_VMX_GUEST_ACTIVITY_STATE \
148 | HM_CHANGED_VMX_GUEST_APIC_STATE \
149 | HM_CHANGED_VMX_ENTRY_CTLS \
150 | HM_CHANGED_VMX_EXIT_CTLS)
151#endif
152
153#define HM_CHANGED_ALL (HM_CHANGED_ALL_GUEST | HM_CHANGED_HOST_CONTEXT)
154/** @} */
155
156/** Maximum number of page flushes we are willing to remember before considering a full TLB flush. */
157#define HM_MAX_TLB_SHOOTDOWN_PAGES 8
158
159/** Size for the EPT identity page table (1024 4 MB pages to cover the entire address space). */
160#define HM_EPT_IDENTITY_PG_TABLE_SIZE PAGE_SIZE
161/** Size of the TSS structure + 2 pages for the IO bitmap + end byte. */
162#define HM_VTX_TSS_SIZE (sizeof(VBOXTSS) + 2 * PAGE_SIZE + 1)
163/** Total guest mapped memory needed. */
164#define HM_VTX_TOTAL_DEVHEAP_MEM (HM_EPT_IDENTITY_PG_TABLE_SIZE + HM_VTX_TSS_SIZE)
165
166/** Enable for TPR guest patching. */
167#define VBOX_HM_WITH_GUEST_PATCHING
168
169/** HM SSM version
170 */
171#ifdef VBOX_HM_WITH_GUEST_PATCHING
172# define HM_SSM_VERSION 5
173# define HM_SSM_VERSION_NO_PATCHING 4
174#else
175# define HM_SSM_VERSION 4
176# define HM_SSM_VERSION_NO_PATCHING 4
177#endif
178#define HM_SSM_VERSION_2_0_X 3
179
180/**
181 * Global per-cpu information. (host)
182 */
183typedef struct HMGLOBLCPUINFO
184{
185 /** The CPU ID. */
186 RTCPUID idCpu;
187 /** The memory object */
188 RTR0MEMOBJ hMemObj;
189 /** Current ASID (AMD-V) / VPID (Intel). */
190 uint32_t uCurrentAsid;
191 /** TLB flush count. */
192 uint32_t cTlbFlushes;
193 /** Whether to flush each new ASID/VPID before use. */
194 bool fFlushAsidBeforeUse;
195 /** Configured for VT-x or AMD-V. */
196 bool fConfigured;
197 /** Set if the VBOX_HWVIRTEX_IGNORE_SVM_IN_USE hack is active. */
198 bool fIgnoreAMDVInUseError;
199 /** In use by our code. (for power suspend) */
200 volatile bool fInUse;
201} HMGLOBLCPUINFO;
202/** Pointer to the per-cpu global information. */
203typedef HMGLOBLCPUINFO *PHMGLOBLCPUINFO;
204
205typedef enum
206{
207 HMPENDINGIO_INVALID = 0,
208 HMPENDINGIO_PORT_READ,
209 HMPENDINGIO_PORT_WRITE,
210 HMPENDINGIO_STRING_READ,
211 HMPENDINGIO_STRING_WRITE,
212 /** The usual 32-bit paranoia. */
213 HMPENDINGIO_32BIT_HACK = 0x7fffffff
214} HMPENDINGIO;
215
216
217typedef enum
218{
219 HMTPRINSTR_INVALID,
220 HMTPRINSTR_READ,
221 HMTPRINSTR_READ_SHR4,
222 HMTPRINSTR_WRITE_REG,
223 HMTPRINSTR_WRITE_IMM,
224 HMTPRINSTR_JUMP_REPLACEMENT,
225 /** The usual 32-bit paranoia. */
226 HMTPRINSTR_32BIT_HACK = 0x7fffffff
227} HMTPRINSTR;
228
229typedef struct
230{
231 /** The key is the address of patched instruction. (32 bits GC ptr) */
232 AVLOU32NODECORE Core;
233 /** Original opcode. */
234 uint8_t aOpcode[16];
235 /** Instruction size. */
236 uint32_t cbOp;
237 /** Replacement opcode. */
238 uint8_t aNewOpcode[16];
239 /** Replacement instruction size. */
240 uint32_t cbNewOp;
241 /** Instruction type. */
242 HMTPRINSTR enmType;
243 /** Source operand. */
244 uint32_t uSrcOperand;
245 /** Destination operand. */
246 uint32_t uDstOperand;
247 /** Number of times the instruction caused a fault. */
248 uint32_t cFaults;
249 /** Patch address of the jump replacement. */
250 RTGCPTR32 pJumpTarget;
251} HMTPRPATCH;
252/** Pointer to HMTPRPATCH. */
253typedef HMTPRPATCH *PHMTPRPATCH;
254
255/**
256 * Switcher function, HC to the special 64-bit RC.
257 *
258 * @param pVM Pointer to the VM.
259 * @param offCpumVCpu Offset from pVM->cpum to pVM->aCpus[idCpu].cpum.
260 * @returns Return code indicating the action to take.
261 */
262typedef DECLCALLBACK(int) FNHMSWITCHERHC(PVM pVM, uint32_t offCpumVCpu);
263/** Pointer to switcher function. */
264typedef FNHMSWITCHERHC *PFNHMSWITCHERHC;
265
266/**
267 * HM VM Instance data.
268 * Changes to this must checked against the padding of the hm union in VM!
269 */
270typedef struct HM
271{
272 /** Set when we've initialized VMX or SVM. */
273 bool fInitialized;
274
275 /** Set if nested paging is enabled. */
276 bool fNestedPaging;
277
278 /** Set if nested paging is allowed. */
279 bool fAllowNestedPaging;
280
281 /** Set if large pages are enabled (requires nested paging). */
282 bool fLargePages;
283
284 /** Set if we can support 64-bit guests or not. */
285 bool fAllow64BitGuests;
286
287 /** Set if an IO-APIC is configured for this VM. */
288 bool fHasIoApic;
289
290 /** Set when TPR patching is allowed. */
291 bool fTRPPatchingAllowed;
292
293 /** Set when we initialize VT-x or AMD-V once for all CPUs. */
294 bool fGlobalInit;
295
296 /** Set when TPR patching is active. */
297 bool fTPRPatchingActive;
298 bool u8Alignment[7];
299
300 /** And mask for copying register contents. */
301 uint64_t u64RegisterMask;
302
303 /** Maximum ASID allowed. */
304 uint32_t uMaxAsid;
305
306 /** The maximum number of resumes loops allowed in ring-0 (safety precaution).
307 * This number is set much higher when RTThreadPreemptIsPending is reliable. */
308 uint32_t cMaxResumeLoops;
309
310 /** Guest allocated memory for patching purposes. */
311 RTGCPTR pGuestPatchMem;
312 /** Current free pointer inside the patch block. */
313 RTGCPTR pFreeGuestPatchMem;
314 /** Size of the guest patch memory block. */
315 uint32_t cbGuestPatchMem;
316 uint32_t uPadding1;
317
318#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
319 /** 32 to 64 bits switcher entrypoint. */
320 R0PTRTYPE(PFNHMSWITCHERHC) pfnHost32ToGuest64R0;
321 RTR0PTR uPadding2;
322#endif
323
324 struct
325 {
326 /** Set by the ring-0 side of HM to indicate VMX is supported by the
327 * CPU. */
328 bool fSupported;
329
330 /** Set when we've enabled VMX. */
331 bool fEnabled;
332
333 /** Set if VPID is supported. */
334 bool fVpid;
335
336 /** Set if VT-x VPID is allowed. */
337 bool fAllowVpid;
338
339 /** Set if unrestricted guest execution is in use (real and protected mode without paging). */
340 bool fUnrestrictedGuest;
341
342 /** Set if unrestricted guest execution is allowed to be used. */
343 bool fAllowUnrestricted;
344
345 /** Whether we're using the preemption timer or not. */
346 bool fUsePreemptTimer;
347 /** The shift mask employed by the VMX-Preemption timer. */
348 uint8_t cPreemptTimerShift;
349
350 /** Virtual address of the TSS page used for real mode emulation. */
351 R3PTRTYPE(PVBOXTSS) pRealModeTSS;
352
353 /** Virtual address of the identity page table used for real mode and protected mode without paging emulation in EPT mode. */
354 R3PTRTYPE(PX86PD) pNonPagingModeEPTPageTable;
355
356 /** R0 memory object for the APIC-access page. */
357 RTR0MEMOBJ hMemObjApicAccess;
358 /** Physical address of the APIC-access page. */
359 RTHCPHYS HCPhysApicAccess;
360 /** Virtual address of the APIC-access page. */
361 R0PTRTYPE(uint8_t *) pbApicAccess;
362
363#ifdef VBOX_WITH_CRASHDUMP_MAGIC
364 RTR0MEMOBJ hMemObjScratch;
365 RTHCPHYS HCPhysScratch;
366 R0PTRTYPE(uint8_t *) pbScratch;
367#endif
368
369#ifndef VBOX_WITH_OLD_VTX_CODE
370 unsigned uFlushTaggedTlb;
371#else
372 /** Ring 0 handlers for VT-x. */
373 DECLR0CALLBACKMEMBER(void, pfnFlushTaggedTlb, (PVM pVM, PVMCPU pVCpu));
374#endif
375
376#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS)
377 uint32_t u32Alignment;
378#endif
379 /** Host CR4 value (set by ring-0 VMX init) */
380 uint64_t hostCR4;
381
382 /** Host EFER value (set by ring-0 VMX init) */
383 uint64_t hostEFER;
384
385 /** VMX MSR values */
386 struct
387 {
388 uint64_t feature_ctrl;
389 uint64_t vmx_basic_info;
390 VMX_CAPABILITY vmx_pin_ctls;
391 VMX_CAPABILITY vmx_proc_ctls;
392 VMX_CAPABILITY vmx_proc_ctls2;
393 VMX_CAPABILITY vmx_exit;
394 VMX_CAPABILITY vmx_entry;
395 uint64_t vmx_misc;
396 uint64_t vmx_cr0_fixed0;
397 uint64_t vmx_cr0_fixed1;
398 uint64_t vmx_cr4_fixed0;
399 uint64_t vmx_cr4_fixed1;
400 uint64_t vmx_vmcs_enum;
401 uint64_t vmx_ept_vpid_caps;
402 } msr;
403
404 /** Flush types for invept & invvpid; they depend on capabilities. */
405 VMX_FLUSH_EPT enmFlushEpt;
406 VMX_FLUSH_VPID enmFlushVpid;
407 } vmx;
408
409 struct
410 {
411 /** Set by the ring-0 side of HM to indicate SVM is supported by the
412 * CPU. */
413 bool fSupported;
414 /** Set when we've enabled SVM. */
415 bool fEnabled;
416 /** Set if erratum 170 affects the AMD cpu. */
417 bool fAlwaysFlushTLB;
418 /** Set when the hack to ignore VERR_SVM_IN_USE is active. */
419 bool fIgnoreInUseError;
420
421 /** R0 memory object for the IO bitmap (12kb). */
422 RTR0MEMOBJ hMemObjIOBitmap;
423 /** Physical address of the IO bitmap (12kb). */
424 RTHCPHYS HCPhysIOBitmap;
425 /** Virtual address of the IO bitmap. */
426 R0PTRTYPE(void *) pvIOBitmap;
427
428 /* HWCR MSR (for diagnostics) */
429 uint64_t msrHwcr;
430
431 /** SVM revision. */
432 uint32_t u32Rev;
433
434 /** SVM feature bits from cpuid 0x8000000a */
435 uint32_t u32Features;
436 } svm;
437
438 /**
439 * AVL tree with all patches (active or disabled) sorted by guest instruction address
440 */
441 AVLOU32TREE PatchTree;
442 uint32_t cPatches;
443 HMTPRPATCH aPatches[64];
444
445 struct
446 {
447 uint32_t u32AMDFeatureECX;
448 uint32_t u32AMDFeatureEDX;
449 } cpuid;
450
451 /** Saved error from detection */
452 int32_t lLastError;
453
454 /** HMR0Init was run */
455 bool fHMR0Init;
456 bool u8Alignment1[7];
457
458 STAMCOUNTER StatTprPatchSuccess;
459 STAMCOUNTER StatTprPatchFailure;
460 STAMCOUNTER StatTprReplaceSuccess;
461 STAMCOUNTER StatTprReplaceFailure;
462} HM;
463/** Pointer to HM VM instance data. */
464typedef HM *PHM;
465
466/* Maximum number of cached entries. */
467#define VMCSCACHE_MAX_ENTRY 128
468
469/* Structure for storing read and write VMCS actions. */
470typedef struct VMCSCACHE
471{
472#ifdef VBOX_WITH_CRASHDUMP_MAGIC
473 /* Magic marker for searching in crash dumps. */
474 uint8_t aMagic[16];
475 uint64_t uMagic;
476 uint64_t u64TimeEntry;
477 uint64_t u64TimeSwitch;
478 uint64_t cResume;
479 uint64_t interPD;
480 uint64_t pSwitcher;
481 uint32_t uPos;
482 uint32_t idCpu;
483#endif
484 /* CR2 is saved here for EPT syncing. */
485 uint64_t cr2;
486 struct
487 {
488 uint32_t cValidEntries;
489 uint32_t uAlignment;
490 uint32_t aField[VMCSCACHE_MAX_ENTRY];
491 uint64_t aFieldVal[VMCSCACHE_MAX_ENTRY];
492 } Write;
493 struct
494 {
495 uint32_t cValidEntries;
496 uint32_t uAlignment;
497 uint32_t aField[VMCSCACHE_MAX_ENTRY];
498 uint64_t aFieldVal[VMCSCACHE_MAX_ENTRY];
499 } Read;
500#ifdef DEBUG
501 struct
502 {
503 RTHCPHYS HCPhysCpuPage;
504 RTHCPHYS HCPhysVmcs;
505 RTGCPTR pCache;
506 RTGCPTR pCtx;
507 } TestIn;
508 struct
509 {
510 RTHCPHYS HCPhysVmcs;
511 RTGCPTR pCache;
512 RTGCPTR pCtx;
513 uint64_t eflags;
514 uint64_t cr8;
515 } TestOut;
516 struct
517 {
518 uint64_t param1;
519 uint64_t param2;
520 uint64_t param3;
521 uint64_t param4;
522 } ScratchPad;
523#endif
524} VMCSCACHE;
525/** Pointer to VMCSCACHE. */
526typedef VMCSCACHE *PVMCSCACHE;
527
528/** VMX StartVM function. */
529typedef DECLCALLBACK(int) FNHMVMXSTARTVM(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu);
530/** Pointer to a VMX StartVM function. */
531typedef R0PTRTYPE(FNHMVMXSTARTVM *) PFNHMVMXSTARTVM;
532
533/** SVM VMRun function. */
534typedef DECLCALLBACK(int) FNHMSVMVMRUN(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx, PVM pVM, PVMCPU pVCpu);
535/** Pointer to a SVM VMRun function. */
536typedef R0PTRTYPE(FNHMSVMVMRUN *) PFNHMSVMVMRUN;
537
538/**
539 * HM VMCPU Instance data.
540 */
541typedef struct HMCPU
542{
543 /** Old style FPU reporting trap mask override performed (optimization) */
544 bool fFPUOldStyleOverride;
545 /** Set if we don't have to flush the TLB on VM entry. */
546 bool fResumeVM;
547 /** Set if we need to flush the TLB during the world switch. */
548 bool fForceTLBFlush;
549 /** Set when we're using VT-x or AMD-V at that moment. */
550 bool fActive;
551 /** Set when the TLB has been checked until we return from the world switch. */
552 volatile bool fCheckedTLBFlush;
553 uint8_t u8Alignment[3];
554
555 /** World switch exit counter. */
556 volatile uint32_t cWorldSwitchExits;
557 /** HM_CHANGED_* flags. */
558 uint32_t fContextUseFlags;
559 /** Id of the last cpu we were executing code on (NIL_RTCPUID for the first time) */
560 RTCPUID idLastCpu;
561 /** TLB flush count */
562 uint32_t cTlbFlushes;
563 /** Current ASID in use by the VM */
564 uint32_t uCurrentAsid;
565 uint32_t u32Alignment;
566
567 /** Host's TSC_AUX MSR (used when RDTSCP doesn't cause VM-exits). */
568 uint64_t u64HostTscAux;
569
570 struct
571 {
572 /** Physical address of the VM control structure (VMCS). */
573 RTHCPHYS HCPhysVmcs;
574 /** R0 memory object for the VM control structure (VMCS). */
575 RTR0MEMOBJ hMemObjVmcs;
576 /** Virtual address of the VM control structure (VMCS). */
577 R0PTRTYPE(void *) pvVmcs;
578 /** Ring 0 handlers for VT-x. */
579 PFNHMVMXSTARTVM pfnStartVM;
580#if HC_ARCH_BITS == 32
581 uint32_t u32Alignment1;
582#endif
583
584 /** Current VMX_VMCS32_CTRL_PIN_EXEC_CONTROLS. */
585 uint32_t u32PinCtls;
586 /** Current VMX_VMCS32_CTRL_PROC_EXEC_CONTROLS. */
587 uint32_t u32ProcCtls;
588 /** Current VMX_VMCS32_CTRL_PROC_EXEC2_CONTROLS. */
589 uint32_t u32ProcCtls2;
590 /** Current VMX_VMCS32_CTRL_EXIT_CONTROLS. */
591 uint32_t u32ExitCtls;
592 /** Current VMX_VMCS32_CTRL_ENTRY_CONTROLS. */
593 uint32_t u32EntryCtls;
594 /** Physical address of the virtual APIC page for TPR caching. */
595 RTHCPHYS HCPhysVirtApic;
596 /** R0 memory object for the virtual APIC page for TPR caching. */
597 RTR0MEMOBJ hMemObjVirtApic;
598 /** Virtual address of the virtual APIC page for TPR caching. */
599 R0PTRTYPE(uint8_t *) pbVirtApic;
600#if HC_ARCH_BITS == 32
601 uint32_t u32Alignment2;
602#endif
603
604 /** Current CR0 mask. */
605 uint64_t cr0_mask;
606 /** Current CR4 mask. */
607 uint64_t cr4_mask;
608 /** Current exception bitmap. */
609 uint32_t u32XcptBitmap;
610 /** The updated-guest-state mask. */
611 uint32_t fUpdatedGuestState;
612 /** Current EPTP. */
613 RTHCPHYS HCPhysEPTP;
614
615 /** Physical address of the MSR bitmap. */
616 RTHCPHYS HCPhysMsrBitmap;
617 /** R0 memory object for the MSR bitmap. */
618 RTR0MEMOBJ hMemObjMsrBitmap;
619 /** Virtual address of the MSR bitmap. */
620 R0PTRTYPE(void *) pvMsrBitmap;
621
622#ifdef VBOX_WITH_AUTO_MSR_LOAD_RESTORE
623 /** Physical address of the VM-entry MSR-load and VM-exit MSR-store area (used
624 * for guest MSRs). */
625 RTHCPHYS HCPhysGuestMsr;
626 /** R0 memory object of the VM-entry MSR-load and VM-exit MSR-store area
627 * (used for guest MSRs). */
628 RTR0MEMOBJ hMemObjGuestMsr;
629 /** Virtual address of the VM-entry MSR-load and VM-exit MSR-store area (used
630 * for guest MSRs). */
631 R0PTRTYPE(void *) pvGuestMsr;
632
633 /** Physical address of the VM-exit MSR-load area (used for host MSRs). */
634 RTHCPHYS HCPhysHostMsr;
635 /** R0 memory object for the VM-exit MSR-load area (used for host MSRs). */
636 RTR0MEMOBJ hMemObjHostMsr;
637 /** Virtual address of the VM-exit MSR-load area (used for host MSRs). */
638 R0PTRTYPE(void *) pvHostMsr;
639
640 /** Number of automatically loaded/restored guest MSRs during the world switch. */
641 uint32_t cGuestMsrs;
642 uint32_t uAlignment;
643#endif /* VBOX_WITH_AUTO_MSR_LOAD_RESTORE */
644
645 /** The cached APIC-base MSR used for identifying when to map the HC physical APIC-access page. */
646 uint64_t u64MsrApicBase;
647 /** Last use TSC offset value. (cached) */
648 uint64_t u64TSCOffset;
649 /** VMCS cache. */
650 VMCSCACHE VMCSCache;
651
652 /** Real-mode emulation state. */
653 struct
654 {
655 X86DESCATTR uAttrCS;
656 X86DESCATTR uAttrDS;
657 X86DESCATTR uAttrES;
658 X86DESCATTR uAttrFS;
659 X86DESCATTR uAttrGS;
660 X86DESCATTR uAttrSS;
661 X86EFLAGS eflags;
662 uint32_t fRealOnV86Active;
663 } RealMode;
664
665 struct
666 {
667 uint64_t u64VMCSPhys;
668 uint32_t u32VMCSRevision;
669 uint32_t u32InstrError;
670 uint32_t u32ExitReason;
671 RTCPUID idEnteredCpu;
672 RTCPUID idCurrentCpu;
673 uint32_t padding;
674 } lasterror;
675
676#ifdef VBOX_WITH_OLD_VTX_CODE
677 /** The last seen guest paging mode (by VT-x). */
678 PGMMODE enmLastSeenGuestMode;
679 /** Current guest paging mode (as seen by HMR3PagingModeChanged). */
680 PGMMODE enmCurrGuestMode;
681 /** Previous guest paging mode (as seen by HMR3PagingModeChanged). */
682 PGMMODE enmPrevGuestMode;
683#else
684 /** Set if guest was executing in real mode (extra checks). */
685 bool fWasInRealMode;
686#endif
687 } vmx;
688
689 struct
690 {
691 /** R0 memory object for the host VM control block (VMCB). */
692 RTR0MEMOBJ hMemObjVMCBHost;
693 /** Physical address of the host VM control block (VMCB). */
694 RTHCPHYS HCPhysVMCBHost;
695 /** Virtual address of the host VM control block (VMCB). */
696 R0PTRTYPE(void *) pvVMCBHost;
697
698 /** R0 memory object for the VM control block (VMCB). */
699 RTR0MEMOBJ hMemObjVMCB;
700 /** Physical address of the VM control block (VMCB). */
701 RTHCPHYS HCPhysVMCB;
702 /** Virtual address of the VM control block (VMCB). */
703 R0PTRTYPE(void *) pvVMCB;
704
705 /** Ring 0 handlers for VT-x. */
706 PFNHMSVMVMRUN pfnVMRun;
707
708 /** R0 memory object for the MSR bitmap (8kb). */
709 RTR0MEMOBJ hMemObjMsrBitmap;
710 /** Physical address of the MSR bitmap (8kb). */
711 RTHCPHYS HCPhysMsrBitmap;
712 /** Virtual address of the MSR bitmap. */
713 R0PTRTYPE(void *) pvMsrBitmap;
714 } svm;
715
716 /** Event injection state. */
717 struct
718 {
719 uint32_t fPending;
720 uint32_t u32ErrCode;
721 uint32_t cbInstr;
722 uint32_t u32Padding; /**< Explicit alignment padding. */
723 uint64_t u64IntrInfo;
724 RTGCUINTPTR GCPtrFaultAddress;
725 } Event;
726
727 /** IO Block emulation state. */
728 struct
729 {
730 bool fEnabled;
731 uint8_t u8Align[7];
732
733 /** RIP at the start of the io code we wish to emulate in the recompiler. */
734 RTGCPTR GCPtrFunctionEip;
735
736 uint64_t cr0;
737 } EmulateIoBlock;
738
739 struct
740 {
741 /** Pending IO operation type. */
742 HMPENDINGIO enmType;
743 uint32_t uPadding;
744 RTGCPTR GCPtrRip;
745 RTGCPTR GCPtrRipNext;
746 union
747 {
748 struct
749 {
750 uint32_t uPort;
751 uint32_t uAndVal;
752 uint32_t cbSize;
753 } Port;
754 uint64_t aRaw[2];
755 } s;
756 } PendingIO;
757
758 /** The PAE PDPEs used with Nested Paging (only valid when
759 * VMCPU_FF_HM_UPDATE_PAE_PDPES is set). */
760 X86PDPE aPdpes[4];
761
762 /** Current shadow paging mode. */
763 PGMMODE enmShadowMode;
764
765 /** The CPU ID of the CPU currently owning the VMCS. Set in
766 * HMR0Enter and cleared in HMR0Leave. */
767 RTCPUID idEnteredCpu;
768
769 /** To keep track of pending TLB shootdown pages. (SMP guest only) */
770 struct
771 {
772 RTGCPTR aPages[HM_MAX_TLB_SHOOTDOWN_PAGES];
773 uint32_t cPages;
774 uint32_t u32Padding; /**< Explicit alignment padding. */
775 } TlbShootdown;
776
777 /** For saving stack space, the disassembler state is allocated here instead of
778 * on the stack. */
779 DISCPUSTATE DisState;
780
781 STAMPROFILEADV StatEntry;
782 STAMPROFILEADV StatExit1;
783 STAMPROFILEADV StatExit2;
784 STAMPROFILEADV StatExitIO;
785 STAMPROFILEADV StatExitMovCRx;
786 STAMPROFILEADV StatExitXcptNmi;
787 STAMPROFILEADV StatLoadGuestState;
788 STAMPROFILEADV StatInGC;
789
790#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
791 STAMPROFILEADV StatWorldSwitch3264;
792#endif
793 STAMPROFILEADV StatPoke;
794 STAMPROFILEADV StatSpinPoke;
795 STAMPROFILEADV StatSpinPokeFailed;
796
797 STAMCOUNTER StatIntInject;
798
799 STAMCOUNTER StatExitShadowNM;
800 STAMCOUNTER StatExitGuestNM;
801 STAMCOUNTER StatExitShadowPF; /* Misleading, currently used for MMIO #PFs as well. */
802 STAMCOUNTER StatExitShadowPFEM;
803 STAMCOUNTER StatExitGuestPF;
804 STAMCOUNTER StatExitGuestUD;
805 STAMCOUNTER StatExitGuestSS;
806 STAMCOUNTER StatExitGuestNP;
807 STAMCOUNTER StatExitGuestGP;
808 STAMCOUNTER StatExitGuestDE;
809 STAMCOUNTER StatExitGuestDB;
810 STAMCOUNTER StatExitGuestMF;
811 STAMCOUNTER StatExitGuestBP;
812 STAMCOUNTER StatExitGuestXF;
813 STAMCOUNTER StatExitGuestXcpUnk;
814 STAMCOUNTER StatExitInvlpg;
815 STAMCOUNTER StatExitInvd;
816 STAMCOUNTER StatExitWbinvd;
817 STAMCOUNTER StatExitPause;
818 STAMCOUNTER StatExitCpuid;
819 STAMCOUNTER StatExitRdtsc;
820 STAMCOUNTER StatExitRdtscp;
821 STAMCOUNTER StatExitRdpmc;
822 STAMCOUNTER StatExitRdrand;
823 STAMCOUNTER StatExitCli;
824 STAMCOUNTER StatExitSti;
825 STAMCOUNTER StatExitPushf;
826 STAMCOUNTER StatExitPopf;
827 STAMCOUNTER StatExitIret;
828 STAMCOUNTER StatExitInt;
829 STAMCOUNTER StatExitCRxWrite[16];
830 STAMCOUNTER StatExitCRxRead[16];
831 STAMCOUNTER StatExitDRxWrite;
832 STAMCOUNTER StatExitDRxRead;
833 STAMCOUNTER StatExitRdmsr;
834 STAMCOUNTER StatExitWrmsr;
835 STAMCOUNTER StatExitClts;
836 STAMCOUNTER StatExitXdtrAccess;
837 STAMCOUNTER StatExitHlt;
838 STAMCOUNTER StatExitMwait;
839 STAMCOUNTER StatExitMonitor;
840 STAMCOUNTER StatExitLmsw;
841 STAMCOUNTER StatExitIOWrite;
842 STAMCOUNTER StatExitIORead;
843 STAMCOUNTER StatExitIOStringWrite;
844 STAMCOUNTER StatExitIOStringRead;
845 STAMCOUNTER StatExitIntWindow;
846 STAMCOUNTER StatExitMaxResume;
847 STAMCOUNTER StatExitExtInt;
848 STAMCOUNTER StatExitPreemptTimer;
849 STAMCOUNTER StatExitTprBelowThreshold;
850 STAMCOUNTER StatExitTaskSwitch;
851 STAMCOUNTER StatExitMtf;
852 STAMCOUNTER StatExitApicAccess;
853 STAMCOUNTER StatIntReinject;
854 STAMCOUNTER StatPendingHostIrq;
855
856 STAMCOUNTER StatFlushPage;
857 STAMCOUNTER StatFlushPageManual;
858 STAMCOUNTER StatFlushPhysPageManual;
859 STAMCOUNTER StatFlushTlb;
860 STAMCOUNTER StatFlushTlbManual;
861 STAMCOUNTER StatFlushTlbWorldSwitch;
862 STAMCOUNTER StatNoFlushTlbWorldSwitch;
863 STAMCOUNTER StatFlushAsid;
864 STAMCOUNTER StatFlushNestedPaging;
865 STAMCOUNTER StatFlushTlbInvlpgVirt;
866 STAMCOUNTER StatFlushTlbInvlpgPhys;
867 STAMCOUNTER StatTlbShootdown;
868 STAMCOUNTER StatTlbShootdownFlush;
869
870 STAMCOUNTER StatSwitchGuestIrq;
871 STAMCOUNTER StatSwitchHmToR3FF;
872 STAMCOUNTER StatSwitchExitToR3;
873 STAMCOUNTER StatSwitchLongJmpToR3;
874
875 STAMCOUNTER StatTscOffset;
876 STAMCOUNTER StatTscIntercept;
877 STAMCOUNTER StatTscInterceptOverFlow;
878
879 STAMCOUNTER StatExitReasonNpf;
880 STAMCOUNTER StatDRxArmed;
881 STAMCOUNTER StatDRxContextSwitch;
882 STAMCOUNTER StatDRxIoCheck;
883
884 STAMCOUNTER StatLoadMinimal;
885 STAMCOUNTER StatLoadFull;
886
887 STAMCOUNTER StatVmxCheckBadRmSelBase;
888 STAMCOUNTER StatVmxCheckBadRmSelLimit;
889 STAMCOUNTER StatVmxCheckRmOk;
890
891 STAMCOUNTER StatVmxCheckBadSel;
892 STAMCOUNTER StatVmxCheckBadRpl;
893 STAMCOUNTER StatVmxCheckBadLdt;
894 STAMCOUNTER StatVmxCheckBadTr;
895 STAMCOUNTER StatVmxCheckPmOk;
896
897#if HC_ARCH_BITS == 32 && defined(VBOX_ENABLE_64_BITS_GUESTS) && !defined(VBOX_WITH_HYBRID_32BIT_KERNEL)
898 STAMCOUNTER StatFpu64SwitchBack;
899 STAMCOUNTER StatDebug64SwitchBack;
900#endif
901
902#ifdef VBOX_WITH_STATISTICS
903 R3PTRTYPE(PSTAMCOUNTER) paStatExitReason;
904 R0PTRTYPE(PSTAMCOUNTER) paStatExitReasonR0;
905 R3PTRTYPE(PSTAMCOUNTER) paStatInjectedIrqs;
906 R0PTRTYPE(PSTAMCOUNTER) paStatInjectedIrqsR0;
907#endif
908#ifdef HM_PROFILE_EXIT_DISPATCH
909 STAMPROFILEADV StatExitDispatch;
910#endif
911} HMCPU;
912/** Pointer to HM VM instance data. */
913typedef HMCPU *PHMCPU;
914
915
916#ifdef IN_RING0
917
918VMMR0DECL(PHMGLOBLCPUINFO) HMR0GetCurrentCpu(void);
919VMMR0DECL(PHMGLOBLCPUINFO) HMR0GetCurrentCpuEx(RTCPUID idCpu);
920
921
922#ifdef VBOX_STRICT
923VMMR0DECL(void) HMDumpRegs(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
924VMMR0DECL(void) HMR0DumpDescriptor(PCX86DESCHC pDesc, RTSEL Sel, const char *pszMsg);
925#else
926# define HMDumpRegs(a, b ,c) do { } while (0)
927# define HMR0DumpDescriptor(a, b, c) do { } while (0)
928#endif
929
930# ifdef VBOX_WITH_KERNEL_USING_XMM
931DECLASM(int) hmR0VMXStartVMWrapXMM(RTHCUINT fResume, PCPUMCTX pCtx, PVMCSCACHE pCache, PVM pVM, PVMCPU pVCpu, PFNHMVMXSTARTVM pfnStartVM);
932DECLASM(int) hmR0SVMRunWrapXMM(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx, PVM pVM, PVMCPU pVCpu, PFNHMSVMVMRUN pfnVMRun);
933# endif
934
935# ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
936/**
937 * Gets 64-bit GDTR and IDTR on darwin.
938 * @param pGdtr Where to store the 64-bit GDTR.
939 * @param pIdtr Where to store the 64-bit IDTR.
940 */
941DECLASM(void) hmR0Get64bitGdtrAndIdtr(PX86XDTR64 pGdtr, PX86XDTR64 pIdtr);
942
943/**
944 * Gets 64-bit CR3 on darwin.
945 * @returns CR3
946 */
947DECLASM(uint64_t) hmR0Get64bitCR3(void);
948# endif
949
950#endif /* IN_RING0 */
951
952/** @} */
953
954RT_C_DECLS_END
955
956#endif
957
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