VirtualBox

source: vbox/trunk/src/VBox/VMM/include/NEMInternal.h@ 108379

最後變更 在這個檔案從108379是 107931,由 vboxsync 提交於 2 月 前

VMM/NEM-win: Only export & import IA32_SPEC_CTRL if the host supports it and we're exposing the register to the guest. (AMD regression from r167064.) jiraref:VBP-947 bugref:10738

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 29.3 KB
 
1/* $Id: NEMInternal.h 107931 2025-01-24 10:00:36Z vboxsync $ */
2/** @file
3 * NEM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2018-2024 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.alldomusa.eu.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef VMM_INCLUDED_SRC_include_NEMInternal_h
29#define VMM_INCLUDED_SRC_include_NEMInternal_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include <VBox/cdefs.h>
35#include <VBox/types.h>
36#include <VBox/vmm/nem.h>
37#include <VBox/vmm/cpum.h> /* For CPUMCPUVENDOR. */
38#include <VBox/vmm/stam.h>
39#include <VBox/vmm/vmapi.h>
40#ifdef RT_OS_WINDOWS
41# include <iprt/nt/hyperv.h>
42# include <iprt/critsect.h>
43#elif defined(RT_OS_DARWIN)
44# ifdef VBOX_VMM_TARGET_ARMV8
45# include <Hypervisor/Hypervisor.h>
46# else
47# include "VMXInternal.h"
48# endif
49#endif
50
51RT_C_DECLS_BEGIN
52
53
54/** @defgroup grp_nem_int Internal
55 * @ingroup grp_nem
56 * @internal
57 * @{
58 */
59
60#if defined(VBOX_WITH_NATIVE_NEM) && !defined(VBOX_WITH_PGM_NEM_MODE)
61# error "VBOX_WITH_NATIVE_NEM requires VBOX_WITH_PGM_NEM_MODE to be defined"
62#endif
63
64
65#ifdef RT_OS_WINDOWS
66/*
67 * Windows: Code configuration.
68 */
69/* nothing at the moment */
70
71/**
72 * Windows VID I/O control information.
73 */
74typedef struct NEMWINIOCTL
75{
76 /** The I/O control function number. */
77 uint32_t uFunction;
78 uint32_t cbInput;
79 uint32_t cbOutput;
80} NEMWINIOCTL;
81
82/** @name Windows: Our two-bit physical page state for PGMPAGE
83 * @{ */
84# define NEM_WIN_PAGE_STATE_NOT_SET 0
85# define NEM_WIN_PAGE_STATE_UNMAPPED 1
86# define NEM_WIN_PAGE_STATE_READABLE 2
87# define NEM_WIN_PAGE_STATE_WRITABLE 3
88/** @} */
89
90/** Windows: Checks if a_GCPhys is subject to the limited A20 gate emulation. */
91# define NEM_WIN_IS_SUBJECT_TO_A20(a_GCPhys) ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K)
92/** Windows: Checks if a_GCPhys is relevant to the limited A20 gate emulation. */
93# define NEM_WIN_IS_RELEVANT_TO_A20(a_GCPhys) \
94 ( ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K) || ((RTGCPHYS)(a_GCPhys) < (RTGCPHYS)_64K) )
95
96/** The CPUMCTX_EXTRN_XXX mask for IEM. */
97# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM ( IEM_CPUMCTX_EXTRN_MUST_MASK | CPUMCTX_EXTRN_INHIBIT_INT \
98 | CPUMCTX_EXTRN_INHIBIT_NMI )
99/** The CPUMCTX_EXTRN_XXX mask for IEM when raising exceptions. */
100# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT (IEM_CPUMCTX_EXTRN_XCPT_MASK | NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM)
101
102/** @name Windows: Interrupt window flags (NEM_WIN_INTW_F_XXX).
103 * @{ */
104# define NEM_WIN_INTW_F_NMI UINT8_C(0x01)
105# define NEM_WIN_INTW_F_REGULAR UINT8_C(0x02)
106# define NEM_WIN_INTW_F_PRIO_MASK UINT8_C(0x3c)
107# define NEM_WIN_INTW_F_PRIO_SHIFT 2
108/** @} */
109
110#endif /* RT_OS_WINDOWS */
111
112
113#ifdef RT_OS_DARWIN
114# ifndef VBOX_VMM_TARGET_ARMV8
115/** vCPU ID declaration to avoid dragging in HV headers here. */
116typedef unsigned hv_vcpuid_t;
117/** The HV VM memory space ID (ASID). */
118typedef unsigned hv_vm_space_t;
119# endif
120
121
122/** @name Darwin: Our two-bit physical page state for PGMPAGE
123 * @{ */
124# define NEM_DARWIN_PAGE_STATE_UNMAPPED 0
125# define NEM_DARWIN_PAGE_STATE_RX 1
126# define NEM_DARWIN_PAGE_STATE_RW 2
127# define NEM_DARWIN_PAGE_STATE_RWX 3
128/** @} */
129
130/** The CPUMCTX_EXTRN_XXX mask for IEM. */
131# ifdef VBOX_VMM_TARGET_ARMV8
132# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM ( IEM_CPUMCTX_EXTRN_MUST_MASK )
133# else
134# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM ( IEM_CPUMCTX_EXTRN_MUST_MASK \
135 | CPUMCTX_EXTRN_INHIBIT_INT | CPUMCTX_EXTRN_INHIBIT_NMI )
136# endif
137
138/** The CPUMCTX_EXTRN_XXX mask for IEM when raising exceptions. */
139# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT (IEM_CPUMCTX_EXTRN_XCPT_MASK | NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM)
140
141
142# ifdef VBOX_VMM_TARGET_ARMV8
143/**
144 * MMIO2 tracking region.
145 */
146typedef struct
147{
148 /* Start of the region. */
149 RTGCPHYS GCPhysStart;
150 /** End of the region. */
151 RTGCPHYS GCPhysLast;
152 /** Whether the region was accessed since last time. */
153 bool fDirty;
154} NEMHVMMIO2REGION;
155/** Pointer to a MMIO2 tracking region. */
156typedef NEMHVMMIO2REGION *PNEMHVMMIO2REGION;
157# endif
158
159#endif
160
161
162/** Trick to make slickedit see the static functions in the template. */
163#ifndef IN_SLICKEDIT
164# define NEM_TMPL_STATIC static
165#else
166# define NEM_TMPL_STATIC
167#endif
168
169
170/**
171 * Generic NEM exit type enumeration for use with EMHistoryAddExit.
172 *
173 * On windows we've got two different set of exit types and they are both jumping
174 * around the place value wise, so EM can use their values.
175 *
176 * @note We only have exit types for exits not covered by EM here.
177 */
178typedef enum NEMEXITTYPE
179{
180 NEMEXITTYPE_INVALID = 0,
181
182 /* Common: */
183 NEMEXITTYPE_INTTERRUPT_WINDOW,
184 NEMEXITTYPE_HALT,
185
186 /* Windows: */
187 NEMEXITTYPE_UNRECOVERABLE_EXCEPTION,
188 NEMEXITTYPE_INVALID_VP_REGISTER_VALUE,
189 NEMEXITTYPE_XCPT_UD,
190 NEMEXITTYPE_XCPT_DB,
191 NEMEXITTYPE_XCPT_BP,
192 NEMEXITTYPE_CANCELED,
193 NEMEXITTYPE_MEMORY_ACCESS,
194
195 /* Linux: */
196 NEMEXITTYPE_INTERNAL_ERROR_EMULATION,
197 NEMEXITTYPE_INTERNAL_ERROR_FATAL,
198 NEMEXITTYPE_INTERRUPTED,
199 NEMEXITTYPE_FAILED_ENTRY,
200
201 /* End of valid types. */
202 NEMEXITTYPE_END
203} NEMEXITTYPE;
204
205
206/**
207 * NEM VM Instance data.
208 */
209typedef struct NEM
210{
211 /** NEM_MAGIC. */
212 uint32_t u32Magic;
213
214 /** Set if enabled. */
215 bool fEnabled;
216 /** Set if long mode guests are allowed. */
217 bool fAllow64BitGuests;
218 /** Set when the debug facility has breakpoints/events enabled that requires
219 * us to use the debug execution loop. */
220 bool fUseDebugLoop;
221
222#ifdef VBOX_VMM_TARGET_ARMV8
223 /** The PPI interrupt number of the vTimer. */
224 uint32_t u32GicPpiVTimer;
225#endif
226
227#if defined(RT_OS_LINUX)
228 /** The '/dev/kvm' file descriptor. */
229 int32_t fdKvm;
230 /** The KVM_CREATE_VM file descriptor. */
231 int32_t fdVm;
232
233 /** KVM_GET_VCPU_MMAP_SIZE. */
234 uint32_t cbVCpuMmap;
235 /** KVM_CAP_NR_MEMSLOTS. */
236 uint32_t cMaxMemSlots;
237# ifdef RT_ARCH_ARM64
238 /** KVM_CAP_ARM_VM_IPA_SIZE. */
239 uint32_t cIpaBits;
240# else
241 /** KVM_CAP_X86_ROBUST_SINGLESTEP. */
242 bool fRobustSingleStep;
243# endif
244
245 /** Hint where there might be a free slot. */
246 uint16_t idPrevSlot;
247 /** Memory slot ID allocation bitmap. */
248 uint64_t bmSlotIds[_32K / 8 / sizeof(uint64_t)];
249
250#elif defined(RT_OS_WINDOWS)
251 /** Set if we've created the EMTs. */
252 bool fCreatedEmts : 1;
253# ifdef VBOX_VMM_TARGET_ARMV8
254 bool fHypercallExit : 1;
255 bool fGpaAccessFaultExit : 1;
256 /** Cache line flush size as a power of two. */
257 uint8_t cPhysicalAddressWidth;
258# elif defined(VBOX_VMM_TARGET_X86)
259 /** WHvRunVpExitReasonX64Cpuid is supported. */
260 bool fExtendedMsrExit : 1;
261 /** WHvRunVpExitReasonX64MsrAccess is supported. */
262 bool fExtendedCpuIdExit : 1;
263 /** WHvRunVpExitReasonException is supported. */
264 bool fExtendedXcptExit : 1;
265 /** Copy of WHV_CAPABILITY_FEATURES::SpeculationControl. */
266 bool fSpeculationControl : 1;
267 /** Whether to export/import IA32_SPEC_CTRL. */
268 bool fDoIa32SpecCtrl : 1;
269# ifdef NEM_WIN_WITH_A20
270 /** Set if we've started more than one CPU and cannot mess with A20. */
271 bool fA20Fixed : 1;
272 /** Set if A20 is enabled. */
273 bool fA20Enabled : 1;
274# endif
275# endif
276 /** The reported CPU vendor. */
277 CPUMCPUVENDOR enmCpuVendor;
278 /** Cache line flush size as a power of two. */
279 uint8_t cCacheLineFlushShift;
280 /** The result of WHvCapabilityCodeProcessorFeatures. */
281 union
282 {
283 /** 64-bit view. */
284 uint64_t u64;
285# ifdef _WINHVAPIDEFS_H_
286 /** Interpreed features. */
287 WHV_PROCESSOR_FEATURES u;
288# endif
289 } uCpuFeatures;
290
291 /** The partition handle. */
292# ifdef _WINHVAPIDEFS_H_
293 WHV_PARTITION_HANDLE
294# else
295 RTHCUINTPTR
296# endif
297 hPartition;
298 /** The device handle for the partition, for use with Vid APIs or direct I/O
299 * controls. */
300 RTR3PTR hPartitionDevice;
301
302 /** Number of currently mapped pages. */
303 uint32_t volatile cMappedPages;
304 uint32_t u32Padding;
305 STAMCOUNTER StatMapPage;
306 STAMCOUNTER StatUnmapPage;
307 STAMCOUNTER StatMapPageFailed;
308 STAMCOUNTER StatUnmapPageFailed;
309 STAMPROFILE StatProfMapGpaRange;
310 STAMPROFILE StatProfUnmapGpaRange;
311 STAMPROFILE StatProfMapGpaRangePage;
312 STAMPROFILE StatProfUnmapGpaRangePage;
313
314 /** Statistics updated by NEMR0UpdateStatistics. */
315 struct
316 {
317 uint64_t cPagesAvailable;
318 uint64_t cPagesInUse;
319 } R0Stats;
320
321# ifdef VBOX_VMM_TARGET_ARMV8
322 /** Re-distributor memory region for all vCPUs. */
323 RTGCPHYS GCPhysMmioBaseReDist;
324 /** Number of breakpoints supported (for syncing registers). */
325 uint32_t cBreakpoints;
326 /** Number of watchpoints supported (for syncing registers). */
327 uint32_t cWatchpoints;
328# endif
329
330#elif defined(RT_OS_DARWIN)
331 /** Set if we've created the EMTs. */
332 bool fCreatedEmts : 1;
333 /** Set if hv_vm_create() was called successfully. */
334 bool fCreatedVm : 1;
335 /** Set if EL2 is enabled. */
336 bool fEl2Enabled : 1;
337# ifdef VBOX_VMM_TARGET_ARMV8
338 /** @name vTimer related state.
339 * @{ */
340 /** The counter frequency in Hz as obtained from CNTFRQ_EL0. */
341 uint64_t u64CntFrqHz;
342 /** The vTimer offset programmed. */
343 uint64_t u64VTimerOff;
344 /** Dirty tracking slots. */
345 NEMHVMMIO2REGION aMmio2DirtyTracking[8];
346 /** The vCPU config. */
347 hv_vcpu_config_t hVCpuCfg;
348 /** @} */
349# elif defined(VBOX_VMM_TARGET_X86)
350 /** Set if hv_vm_space_create() was called successfully. */
351 bool fCreatedAsid : 1;
352 /** Set if Last Branch Record (LBR) is enabled. */
353 bool fLbr;
354 /** The ASID for this VM (only valid if fCreatedAsid is true). */
355 hv_vm_space_t uVmAsid;
356 /** Number of mach time units per NS, for hv_vcpu_run_until(). */
357 uint64_t cMachTimePerNs;
358 /** Pause-loop exiting (PLE) gap in ticks. */
359 uint32_t cPleGapTicks;
360 /** Pause-loop exiting (PLE) window in ticks. */
361 uint32_t cPleWindowTicks;
362
363 /** The host LBR TOS (top-of-stack) MSR id. */
364 uint32_t idLbrTosMsr;
365 /** The host LBR select MSR id. */
366 uint32_t idLbrSelectMsr;
367 /** The host last event record from IP MSR id. */
368 uint32_t idLerFromIpMsr;
369 /** The host last event record to IP MSR id. */
370 uint32_t idLerToIpMsr;
371
372 /** The first valid host LBR branch-from-IP stack range. */
373 uint32_t idLbrFromIpMsrFirst;
374 /** The last valid host LBR branch-from-IP stack range. */
375 uint32_t idLbrFromIpMsrLast;
376
377 /** The first valid host LBR branch-to-IP stack range. */
378 uint32_t idLbrToIpMsrFirst;
379 /** The last valid host LBR branch-to-IP stack range. */
380 uint32_t idLbrToIpMsrLast;
381
382 /** The first valid host LBR info stack range. */
383 uint32_t idLbrInfoMsrFirst;
384 /** The last valid host LBR info stack range. */
385 uint32_t idLbrInfoMsrLast;
386# endif /* VBOX_VMM_TARGET_X86 */
387
388 STAMCOUNTER StatMapPage;
389 STAMCOUNTER StatUnmapPage;
390 STAMCOUNTER StatMapPageFailed;
391 STAMCOUNTER StatUnmapPageFailed;
392#endif /* RT_OS_DARWIN */
393} NEM;
394/** Pointer to NEM VM instance data. */
395typedef NEM *PNEM;
396
397/** NEM::u32Magic value. */
398#define NEM_MAGIC UINT32_C(0x004d454e)
399/** NEM::u32Magic value after termination. */
400#define NEM_MAGIC_DEAD UINT32_C(0xdead1111)
401
402
403/**
404 * NEM VMCPU Instance data.
405 */
406typedef struct NEMCPU
407{
408 /** NEMCPU_MAGIC. */
409 uint32_t u32Magic;
410 /** Whether \#UD needs to be intercepted and presented to GIM. */
411 bool fGIMTrapXcptUD : 1;
412 /** Whether \#GP needs to be intercept for mesa driver workaround. */
413 bool fTrapXcptGpForLovelyMesaDrv: 1;
414 /** Whether we should use the debug loop because of single stepping or special
415 * debug breakpoints / events are armed. */
416 bool fUseDebugLoop : 1;
417 /** Whether we're executing a single instruction. */
418 bool fSingleInstruction : 1;
419 /** Set if we using the debug loop and wish to intercept RDTSC. */
420 bool fDebugWantRdTscExit : 1;
421 /** Whether we are currently executing in the debug loop.
422 * Mainly for assertions. */
423 bool fUsingDebugLoop : 1;
424 /** Set if we need to clear the trap flag because of single stepping. */
425 bool fClearTrapFlag : 1;
426 /** Whether we're using the hyper DR7 or guest DR7. */
427 bool fUsingHyperDR7 : 1;
428 /** Whether \#DE needs to be intercepted for GIM. */
429 bool fGCMTrapXcptDE : 1;
430#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
431 /** Set if indirect branch prediction barrier on VM exit. */
432 bool fIbpbOnVmExit : 1;
433 /** Set if indirect branch prediction barrier on VM entry. */
434 bool fIbpbOnVmEntry : 1;
435 /** Set if level 1 data cache should be flushed on VM entry. */
436 bool fL1dFlushOnVmEntry : 1;
437 /** Set if level 1 data cache should be flushed on EMT scheduling. */
438 bool fL1dFlushOnSched : 1;
439 /** Set if MDS related buffers should be cleared on VM entry. */
440 bool fMdsClearOnVmEntry : 1;
441 /** Set if MDS related buffers should be cleared on EMT scheduling. */
442 bool fMdsClearOnSched : 1;
443#endif
444
445#if defined(RT_OS_LINUX)
446 uint8_t abPadding[3];
447 /** The KVM VCpu file descriptor. */
448 int32_t fdVCpu;
449 /** Pointer to the KVM_RUN data exchange region. */
450 R3PTRTYPE(struct kvm_run *) pRun;
451# ifdef VBOX_VMM_TARGET_ARMV8
452 /** The IRQ device levels from device_irq_level. */
453 uint64_t fIrqDeviceLvls;
454 /** Status of the IRQ line when last seen. */
455 bool fIrqLastSeen;
456 /** Status of the FIQ line when last seen. */
457 bool fFiqLastSeen;
458# elif defined(VBOX_VMM_TARGET_X86)
459 /** The MSR_IA32_APICBASE value known to KVM. */
460 uint64_t uKvmApicBase;
461# endif
462
463 /** @name Statistics
464 * @{ */
465 STAMCOUNTER StatExitTotal;
466 STAMCOUNTER StatExitIo;
467 STAMCOUNTER StatExitMmio;
468 STAMCOUNTER StatExitSetTpr;
469 STAMCOUNTER StatExitTprAccess;
470 STAMCOUNTER StatExitRdMsr;
471 STAMCOUNTER StatExitWrMsr;
472 STAMCOUNTER StatExitIrqWindowOpen;
473 STAMCOUNTER StatExitHalt;
474 STAMCOUNTER StatExitIntr;
475 STAMCOUNTER StatExitHypercall;
476 STAMCOUNTER StatExitDebug;
477 STAMCOUNTER StatExitBusLock;
478 STAMCOUNTER StatExitInternalErrorEmulation;
479 STAMCOUNTER StatExitInternalErrorFatal;
480# if 0
481 STAMCOUNTER StatExitCpuId;
482 STAMCOUNTER StatExitUnrecoverable;
483 STAMCOUNTER StatGetMsgTimeout;
484 STAMCOUNTER StatStopCpuSuccess;
485 STAMCOUNTER StatStopCpuPending;
486 STAMCOUNTER StatStopCpuPendingAlerts;
487 STAMCOUNTER StatStopCpuPendingOdd;
488 STAMCOUNTER StatCancelChangedState;
489 STAMCOUNTER StatCancelAlertedThread;
490# endif
491 STAMCOUNTER StatBreakOnCancel;
492 STAMCOUNTER StatBreakOnFFPre;
493 STAMCOUNTER StatBreakOnFFPost;
494 STAMCOUNTER StatBreakOnStatus;
495 STAMCOUNTER StatFlushExitOnReturn;
496 STAMCOUNTER StatFlushExitOnReturn1Loop;
497 STAMCOUNTER StatFlushExitOnReturn2Loops;
498 STAMCOUNTER StatFlushExitOnReturn3Loops;
499 STAMCOUNTER StatFlushExitOnReturn4PlusLoops;
500 STAMCOUNTER StatImportOnDemand;
501 STAMCOUNTER StatImportOnReturn;
502 STAMCOUNTER StatImportOnReturnSkipped;
503 STAMCOUNTER StatImportPendingInterrupt;
504 STAMCOUNTER StatExportPendingInterrupt;
505 STAMCOUNTER StatQueryCpuTick;
506 /** @} */
507
508
509#elif defined(RT_OS_WINDOWS)
510# ifdef VBOX_VMM_TARGET_X86
511 /** The current state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
512 uint8_t fCurrentInterruptWindows;
513 /** The desired state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
514 uint8_t fDesiredInterruptWindows;
515 /** Last copy of HV_X64_VP_EXECUTION_STATE::InterruptShadow. */
516 bool fLastInterruptShadow : 1;
517 uint32_t uPadding;
518 /** The VID_MSHAGN_F_XXX flags.
519 * Either VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE or zero. */
520 uint32_t fHandleAndGetFlags;
521 /** What VidMessageSlotMap returns and is used for passing exit info. */
522 RTR3PTR pvMsgSlotMapping;
523 /** The windows thread handle. */
524 RTR3PTR hNativeThreadHandle;
525# endif
526
527 /** @name Statistics
528 * @{ */
529 STAMCOUNTER StatExitPortIo;
530 STAMCOUNTER StatExitMemUnmapped;
531 STAMCOUNTER StatExitMemIntercept;
532 STAMCOUNTER StatExitHalt;
533 STAMCOUNTER StatExitInterruptWindow;
534 STAMCOUNTER StatExitCpuId;
535 STAMCOUNTER StatExitMsr;
536 STAMCOUNTER StatExitException;
537 STAMCOUNTER StatExitExceptionBp;
538 STAMCOUNTER StatExitExceptionDb;
539 STAMCOUNTER StatExitExceptionGp;
540 STAMCOUNTER StatExitExceptionGpMesa;
541 STAMCOUNTER StatExitExceptionUd;
542 STAMCOUNTER StatExitExceptionUdHandled;
543 STAMCOUNTER StatExitUnrecoverable;
544 STAMCOUNTER StatGetMsgTimeout;
545 STAMCOUNTER StatStopCpuSuccess;
546 STAMCOUNTER StatStopCpuPending;
547 STAMCOUNTER StatStopCpuPendingAlerts;
548 STAMCOUNTER StatStopCpuPendingOdd;
549 STAMCOUNTER StatCancelChangedState;
550 STAMCOUNTER StatCancelAlertedThread;
551 STAMCOUNTER StatBreakOnCancel;
552 STAMCOUNTER StatBreakOnFFPre;
553 STAMCOUNTER StatBreakOnFFPost;
554 STAMCOUNTER StatBreakOnStatus;
555 STAMCOUNTER StatImportOnDemand;
556 STAMCOUNTER StatImportOnReturn;
557 STAMCOUNTER StatImportOnReturnSkipped;
558 STAMCOUNTER StatQueryCpuTick;
559 /** @} */
560
561#elif defined(RT_OS_DARWIN)
562# ifdef VBOX_VMM_TARGET_ARMV8
563 /** The vCPU handle associated with the EMT executing this vCPU. */
564 hv_vcpu_t hVCpu;
565 /** Pointer to the exit information structure. */
566 hv_vcpu_exit_t *pHvExit;
567 /** Flag whether an event is pending. */
568 bool fEventPending;
569 /** Flag whether the vTimer got activated and is masked. */
570 bool fVTimerActivated;
571 /** Flag whether to update the vTimer offset. */
572 bool fVTimerOffUpdate;
573 /** Flag whether the ID registers were synced to the guest context
574 * (for first guest exec call on the EMT after loading the saved state). */
575 bool fIdRegsSynced;
576
577# elif defined(VBOX_VMM_TARGET_X86)
578 /** The vCPU handle associated with the EMT executing this vCPU. */
579 hv_vcpuid_t hVCpuId;
580
581 /** @name State shared with the VT-x code.
582 * @{ */
583 /** An additional error code used for some gurus. */
584 uint32_t u32HMError;
585 /** The last exit-to-ring-3 reason. */
586 int32_t rcLastExitToR3;
587 /** CPU-context changed flags (see HM_CHANGED_xxx). */
588 uint64_t fCtxChanged;
589
590 /** The guest VMCS information. */
591 VMXVMCSINFO VmcsInfo;
592
593 /** VT-x data. */
594 struct HMCPUVMX
595 {
596 /** @name Guest information.
597 * @{ */
598 /** Guest VMCS information shared with ring-3. */
599 VMXVMCSINFOSHARED VmcsInfo;
600 /** Nested-guest VMCS information shared with ring-3. */
601 VMXVMCSINFOSHARED VmcsInfoNstGst;
602 /** Whether the nested-guest VMCS was the last current VMCS (shadow copy for ring-3).
603 * @see HMR0PERVCPU::vmx.fSwitchedToNstGstVmcs */
604 bool fSwitchedToNstGstVmcsCopyForRing3;
605 /** Whether the static guest VMCS controls has been merged with the
606 * nested-guest VMCS controls. */
607 bool fMergedNstGstCtls;
608 /** Whether the nested-guest VMCS has been copied to the shadow VMCS. */
609 bool fCopiedNstGstToShadowVmcs;
610 /** Whether flushing the TLB is required due to switching to/from the
611 * nested-guest. */
612 bool fSwitchedNstGstFlushTlb;
613 /** Alignment. */
614 bool afAlignment0[4];
615 /** Cached guest APIC-base MSR for identifying when to map the APIC-access page. */
616 uint64_t u64GstMsrApicBase;
617 /** @} */
618
619 /** @name Error reporting and diagnostics.
620 * @{ */
621 /** VT-x error-reporting (mainly for ring-3 propagation). */
622 struct
623 {
624 RTCPUID idCurrentCpu;
625 RTCPUID idEnteredCpu;
626 RTHCPHYS HCPhysCurrentVmcs;
627 uint32_t u32VmcsRev;
628 uint32_t u32InstrError;
629 uint32_t u32ExitReason;
630 uint32_t u32GuestIntrState;
631 } LastError;
632 /** @} */
633 } vmx;
634
635 /** Event injection state. */
636 HMEVENT Event;
637
638 /** Current shadow paging mode for updating CR4.
639 * @todo move later (@bugref{9217}). */
640 PGMMODE enmShadowMode;
641 uint32_t u32TemporaryPadding;
642
643 /** The PAE PDPEs used with Nested Paging (only valid when
644 * VMCPU_FF_HM_UPDATE_PAE_PDPES is set). */
645 X86PDPE aPdpes[4];
646 /** Pointer to the VMX statistics. */
647 PVMXSTATISTICS pVmxStats;
648# endif /* VBOX_VMM_TARGET_X86 */
649
650 /** @name Statistics
651 * @{ */
652 STAMCOUNTER StatExitAll;
653 STAMCOUNTER StatBreakOnCancel;
654 STAMCOUNTER StatBreakOnFFPre;
655 STAMCOUNTER StatBreakOnFFPost;
656 STAMCOUNTER StatBreakOnStatus;
657 STAMCOUNTER StatImportOnDemand;
658 STAMCOUNTER StatImportOnReturn;
659 STAMCOUNTER StatImportOnReturnSkipped;
660 STAMCOUNTER StatQueryCpuTick;
661# ifdef VBOX_WITH_STATISTICS
662 STAMPROFILEADV StatProfGstStateImport;
663 STAMPROFILEADV StatProfGstStateExport;
664# endif
665 /** @} */
666
667 /** @} */
668#endif /* RT_OS_DARWIN */
669} NEMCPU;
670/** Pointer to NEM VMCPU instance data. */
671typedef NEMCPU *PNEMCPU;
672
673/** NEMCPU::u32Magic value. */
674#define NEMCPU_MAGIC UINT32_C(0x4d454e20)
675/** NEMCPU::u32Magic value after termination. */
676#define NEMCPU_MAGIC_DEAD UINT32_C(0xdead2222)
677
678
679#ifdef IN_RING0
680# ifdef RT_OS_WINDOWS
681/**
682 * Windows: Hypercall input/ouput page info.
683 */
684typedef struct NEMR0HYPERCALLDATA
685{
686 /** Host physical address of the hypercall input/output page. */
687 RTHCPHYS HCPhysPage;
688 /** Pointer to the hypercall input/output page. */
689 uint8_t *pbPage;
690 /** Handle to the memory object of the hypercall input/output page. */
691 RTR0MEMOBJ hMemObj;
692} NEMR0HYPERCALLDATA;
693/** Pointer to a Windows hypercall input/output page info. */
694typedef NEMR0HYPERCALLDATA *PNEMR0HYPERCALLDATA;
695# endif /* RT_OS_WINDOWS */
696
697/**
698 * NEM GVMCPU instance data.
699 */
700typedef struct NEMR0PERVCPU
701{
702 uint32_t uDummy;
703} NEMR0PERVCPU;
704
705/**
706 * NEM GVM instance data.
707 */
708typedef struct NEMR0PERVM
709{
710 uint32_t uDummy;
711} NEMR0PERVM;
712
713#endif /* IN_RING*/
714
715
716#ifdef IN_RING3
717
718int nemR3DisableCpuIsaExt(PVM pVM, const char *pszIsaExt);
719
720int nemR3NativeInit(PVM pVM, bool fFallback, bool fForced);
721int nemR3NativeInitAfterCPUM(PVM pVM);
722int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
723int nemR3NativeTerm(PVM pVM);
724void nemR3NativeReset(PVM pVM);
725void nemR3NativeResetCpu(PVMCPU pVCpu, bool fInitIpi);
726VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu);
727bool nemR3NativeCanExecuteGuest(PVM pVM, PVMCPU pVCpu);
728bool nemR3NativeSetSingleInstruction(PVM pVM, PVMCPU pVCpu, bool fEnable);
729
730/** GIC API is currently implemented in NEM rather than in GIC. */
731VMM_INT_DECL(int) NEMR3GicSetSpi(PVMCC pVM, uint32_t uIntId, bool fAsserted);
732VMM_INT_DECL(int) NEMR3GicSetPpi(PVMCPUCC pVCpu, uint32_t uIntId, bool fAsserted);
733VMM_INT_DECL(VBOXSTRICTRC) NEMR3GicReadSysReg(PVMCPUCC pVCpu, uint32_t u32Reg, uint64_t *pu64Value);
734VMM_INT_DECL(VBOXSTRICTRC) NEMR3GicWriteSysReg(PVMCPUCC pVCpu, uint32_t u32Reg, uint64_t u64Value);
735
736/**
737 * Forced flag notification call from VMEmt.h.
738 *
739 * This is only called when pVCpu is in the VMCPUSTATE_STARTED_EXEC_NEM state.
740 *
741 * @param pVM The cross context VM structure.
742 * @param pVCpu The cross context virtual CPU structure of the CPU
743 * to be notified.
744 * @param fFlags Notification flags, VMNOTIFYFF_FLAGS_XXX.
745 */
746void nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags);
747
748/**
749 * Called by NEMR3NotifyDebugEventChanged() to let the native backend take the final decision
750 * on whether to switch to the debug loop.
751 *
752 * @returns Final flag whether to switch to the debug loop.
753 * @param pVM The VM cross context VM structure.
754 * @param fUseDebugLoop The current value determined by NEMR3NotifyDebugEventChanged().
755 * @thread EMT(0)
756 */
757DECLHIDDEN(bool) nemR3NativeNotifyDebugEventChanged(PVM pVM, bool fUseDebugLoop);
758
759
760/**
761 * Called by NEMR3NotifyDebugEventChangedPerCpu() to let the native backend take the final decision
762 * on whether to switch to the debug loop.
763 *
764 * @returns Final flag whether to switch to the debug loop.
765 * @param pVM The VM cross context VM structure.
766 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
767 * @param fUseDebugLoop The current value determined by NEMR3NotifyDebugEventChangedPerCpu().
768 */
769DECLHIDDEN(bool) nemR3NativeNotifyDebugEventChangedPerCpu(PVM pVM, PVMCPU pVCpu, bool fUseDebugLoop);
770
771#endif /* IN_RING3 */
772
773void nemHCNativeNotifyHandlerPhysicalRegister(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb);
774void nemHCNativeNotifyHandlerPhysicalModify(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld,
775 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM);
776int nemHCNativeNotifyPhysPageAllocated(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
777 PGMPAGETYPE enmType, uint8_t *pu2State);
778
779
780#ifdef RT_OS_WINDOWS
781/** Maximum number of pages we can map in a single NEMR0MapPages call. */
782# define NEM_MAX_MAP_PAGES ((HOST_PAGE_SIZE - RT_UOFFSETOF(HV_INPUT_MAP_GPA_PAGES, PageList)) / sizeof(HV_SPA_PAGE_NUMBER))
783/** Maximum number of pages we can unmap in a single NEMR0UnmapPages call. */
784# define NEM_MAX_UNMAP_PAGES 4095
785
786#endif
787/** @} */
788
789RT_C_DECLS_END
790
791#endif /* !VMM_INCLUDED_SRC_include_NEMInternal_h */
792
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette