VirtualBox

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

Last change on this file since 100705 was 100705, checked in by vboxsync, 22 months ago

VMM/NEMR3Native-darwin-armv8.cpp: Need to implement our own simplistic dirty page tracking for MMIO2 regions as Hypervisor.framework doesn't work with guest page sizes but only with host page sized regions so it conflicts with our generic implementation in PGM. With that it is possible to get screen updates for guests which access the standard framebuffer and don't use the SVGA 3 interface to notify the device about dirty regions, bugref:10390

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 26.2 KB
Line 
1/* $Id: NEMInternal.h 100705 2023-07-26 12:57:59Z vboxsync $ */
2/** @file
3 * NEM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2018-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.215389.xyz.
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# if defined(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# if !defined(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# if defined(VBOX_VMM_TARGET_ARMV8)
131/** The CPUMCTX_EXTRN_XXX mask for IEM. */
132# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM ( IEM_CPUMCTX_EXTRN_MUST_MASK )
133# else
134/** The CPUMCTX_EXTRN_XXX mask for IEM. */
135# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM ( IEM_CPUMCTX_EXTRN_MUST_MASK | CPUMCTX_EXTRN_INHIBIT_INT \
136 | CPUMCTX_EXTRN_INHIBIT_NMI )
137#endif
138
139/** The CPUMCTX_EXTRN_XXX mask for IEM when raising exceptions. */
140# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT (IEM_CPUMCTX_EXTRN_XCPT_MASK | NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM)
141
142
143# if defined(VBOX_VMM_TARGET_ARMV8)
144/**
145 * MMIO2 tracking region.
146 */
147typedef struct
148{
149 /* Start of the region. */
150 RTGCPHYS GCPhysStart;
151 /** End of the region. */
152 RTGCPHYS GCPhysLast;
153 /** Whether the region was accessed since last time. */
154 bool fDirty;
155} NEMHVMMIO2REGION;
156/** Pointer to a MMIO2 tracking region. */
157typedef NEMHVMMIO2REGION *PNEMHVMMIO2REGION;
158# endif
159
160#endif
161
162
163/** Trick to make slickedit see the static functions in the template. */
164#ifndef IN_SLICKEDIT
165# define NEM_TMPL_STATIC static
166#else
167# define NEM_TMPL_STATIC
168#endif
169
170
171/**
172 * Generic NEM exit type enumeration for use with EMHistoryAddExit.
173 *
174 * On windows we've got two different set of exit types and they are both jumping
175 * around the place value wise, so EM can use their values.
176 *
177 * @note We only have exit types for exits not covered by EM here.
178 */
179typedef enum NEMEXITTYPE
180{
181 NEMEXITTYPE_INVALID = 0,
182
183 /* Common: */
184 NEMEXITTYPE_INTTERRUPT_WINDOW,
185 NEMEXITTYPE_HALT,
186
187 /* Windows: */
188 NEMEXITTYPE_UNRECOVERABLE_EXCEPTION,
189 NEMEXITTYPE_INVALID_VP_REGISTER_VALUE,
190 NEMEXITTYPE_XCPT_UD,
191 NEMEXITTYPE_XCPT_DB,
192 NEMEXITTYPE_XCPT_BP,
193 NEMEXITTYPE_CANCELED,
194 NEMEXITTYPE_MEMORY_ACCESS,
195
196 /* Linux: */
197 NEMEXITTYPE_INTERNAL_ERROR_EMULATION,
198 NEMEXITTYPE_INTERNAL_ERROR_FATAL,
199 NEMEXITTYPE_INTERRUPTED,
200 NEMEXITTYPE_FAILED_ENTRY,
201
202 /* End of valid types. */
203 NEMEXITTYPE_END
204} NEMEXITTYPE;
205
206
207/**
208 * NEM VM Instance data.
209 */
210typedef struct NEM
211{
212 /** NEM_MAGIC. */
213 uint32_t u32Magic;
214
215 /** Set if enabled. */
216 bool fEnabled;
217 /** Set if long mode guests are allowed. */
218 bool fAllow64BitGuests;
219 /** Set when the debug facility has breakpoints/events enabled that requires
220 * us to use the debug execution loop. */
221 bool fUseDebugLoop;
222
223#if defined(RT_OS_LINUX)
224 /** The '/dev/kvm' file descriptor. */
225 int32_t fdKvm;
226 /** The KVM_CREATE_VM file descriptor. */
227 int32_t fdVm;
228
229 /** KVM_GET_VCPU_MMAP_SIZE. */
230 uint32_t cbVCpuMmap;
231 /** KVM_CAP_NR_MEMSLOTS. */
232 uint32_t cMaxMemSlots;
233 /** KVM_CAP_X86_ROBUST_SINGLESTEP. */
234 bool fRobustSingleStep;
235
236 /** Hint where there might be a free slot. */
237 uint16_t idPrevSlot;
238 /** Memory slot ID allocation bitmap. */
239 uint64_t bmSlotIds[_32K / 8 / sizeof(uint64_t)];
240
241#elif defined(RT_OS_WINDOWS)
242 /** Set if we've created the EMTs. */
243 bool fCreatedEmts : 1;
244 /** WHvRunVpExitReasonX64Cpuid is supported. */
245 bool fExtendedMsrExit : 1;
246 /** WHvRunVpExitReasonX64MsrAccess is supported. */
247 bool fExtendedCpuIdExit : 1;
248 /** WHvRunVpExitReasonException is supported. */
249 bool fExtendedXcptExit : 1;
250# ifdef NEM_WIN_WITH_A20
251 /** Set if we've started more than one CPU and cannot mess with A20. */
252 bool fA20Fixed : 1;
253 /** Set if A20 is enabled. */
254 bool fA20Enabled : 1;
255# endif
256 /** The reported CPU vendor. */
257 CPUMCPUVENDOR enmCpuVendor;
258 /** Cache line flush size as a power of two. */
259 uint8_t cCacheLineFlushShift;
260 /** The result of WHvCapabilityCodeProcessorFeatures. */
261 union
262 {
263 /** 64-bit view. */
264 uint64_t u64;
265# ifdef _WINHVAPIDEFS_H_
266 /** Interpreed features. */
267 WHV_PROCESSOR_FEATURES u;
268# endif
269 } uCpuFeatures;
270
271 /** The partition handle. */
272# ifdef _WINHVAPIDEFS_H_
273 WHV_PARTITION_HANDLE
274# else
275 RTHCUINTPTR
276# endif
277 hPartition;
278 /** The device handle for the partition, for use with Vid APIs or direct I/O
279 * controls. */
280 RTR3PTR hPartitionDevice;
281
282 /** Number of currently mapped pages. */
283 uint32_t volatile cMappedPages;
284 uint32_t u32Padding;
285 STAMCOUNTER StatMapPage;
286 STAMCOUNTER StatUnmapPage;
287 STAMCOUNTER StatMapPageFailed;
288 STAMCOUNTER StatUnmapPageFailed;
289 STAMPROFILE StatProfMapGpaRange;
290 STAMPROFILE StatProfUnmapGpaRange;
291 STAMPROFILE StatProfMapGpaRangePage;
292 STAMPROFILE StatProfUnmapGpaRangePage;
293
294 /** Statistics updated by NEMR0UpdateStatistics. */
295 struct
296 {
297 uint64_t cPagesAvailable;
298 uint64_t cPagesInUse;
299 } R0Stats;
300
301#elif defined(RT_OS_DARWIN)
302 /** Set if we've created the EMTs. */
303 bool fCreatedEmts : 1;
304 /** Set if hv_vm_create() was called successfully. */
305 bool fCreatedVm : 1;
306# if defined(VBOX_VMM_TARGET_ARMV8)
307 /** @name vTimer related state.
308 * @{ */
309 /** The counter frequency in Hz as obtained from CNTFRQ_EL0. */
310 uint64_t u64CntFrqHz;
311 /** The vTimer offset programmed. */
312 uint64_t u64VTimerOff;
313 /** Dirty tracking slots. */
314 NEMHVMMIO2REGION aMmio2DirtyTracking[8];
315 /** @} */
316# else
317 /** Set if hv_vm_space_create() was called successfully. */
318 bool fCreatedAsid : 1;
319 /** Set if Last Branch Record (LBR) is enabled. */
320 bool fLbr;
321 /** The ASID for this VM (only valid if fCreatedAsid is true). */
322 hv_vm_space_t uVmAsid;
323 /** Number of mach time units per NS, for hv_vcpu_run_until(). */
324 uint64_t cMachTimePerNs;
325 /** Pause-loop exiting (PLE) gap in ticks. */
326 uint32_t cPleGapTicks;
327 /** Pause-loop exiting (PLE) window in ticks. */
328 uint32_t cPleWindowTicks;
329
330 /** The host LBR TOS (top-of-stack) MSR id. */
331 uint32_t idLbrTosMsr;
332 /** The host LBR select MSR id. */
333 uint32_t idLbrSelectMsr;
334 /** The host last event record from IP MSR id. */
335 uint32_t idLerFromIpMsr;
336 /** The host last event record to IP MSR id. */
337 uint32_t idLerToIpMsr;
338
339 /** The first valid host LBR branch-from-IP stack range. */
340 uint32_t idLbrFromIpMsrFirst;
341 /** The last valid host LBR branch-from-IP stack range. */
342 uint32_t idLbrFromIpMsrLast;
343
344 /** The first valid host LBR branch-to-IP stack range. */
345 uint32_t idLbrToIpMsrFirst;
346 /** The last valid host LBR branch-to-IP stack range. */
347 uint32_t idLbrToIpMsrLast;
348
349 /** The first valid host LBR info stack range. */
350 uint32_t idLbrInfoMsrFirst;
351 /** The last valid host LBR info stack range. */
352 uint32_t idLbrInfoMsrLast;
353# endif
354
355 STAMCOUNTER StatMapPage;
356 STAMCOUNTER StatUnmapPage;
357 STAMCOUNTER StatMapPageFailed;
358 STAMCOUNTER StatUnmapPageFailed;
359#endif /* RT_OS_WINDOWS */
360} NEM;
361/** Pointer to NEM VM instance data. */
362typedef NEM *PNEM;
363
364/** NEM::u32Magic value. */
365#define NEM_MAGIC UINT32_C(0x004d454e)
366/** NEM::u32Magic value after termination. */
367#define NEM_MAGIC_DEAD UINT32_C(0xdead1111)
368
369
370/**
371 * NEM VMCPU Instance data.
372 */
373typedef struct NEMCPU
374{
375 /** NEMCPU_MAGIC. */
376 uint32_t u32Magic;
377 /** Whether \#UD needs to be intercepted and presented to GIM. */
378 bool fGIMTrapXcptUD : 1;
379 /** Whether \#GP needs to be intercept for mesa driver workaround. */
380 bool fTrapXcptGpForLovelyMesaDrv: 1;
381 /** Whether we should use the debug loop because of single stepping or special
382 * debug breakpoints / events are armed. */
383 bool fUseDebugLoop : 1;
384 /** Whether we're executing a single instruction. */
385 bool fSingleInstruction : 1;
386 /** Set if we using the debug loop and wish to intercept RDTSC. */
387 bool fDebugWantRdTscExit : 1;
388 /** Whether we are currently executing in the debug loop.
389 * Mainly for assertions. */
390 bool fUsingDebugLoop : 1;
391 /** Set if we need to clear the trap flag because of single stepping. */
392 bool fClearTrapFlag : 1;
393 /** Whether we're using the hyper DR7 or guest DR7. */
394 bool fUsingHyperDR7 : 1;
395 /** Whether \#DE needs to be intercepted for GIM. */
396 bool fGCMTrapXcptDE : 1;
397
398#if defined(RT_OS_LINUX)
399 uint8_t abPadding[3];
400 /** The KVM VCpu file descriptor. */
401 int32_t fdVCpu;
402 /** Pointer to the KVM_RUN data exchange region. */
403 R3PTRTYPE(struct kvm_run *) pRun;
404 /** The MSR_IA32_APICBASE value known to KVM. */
405 uint64_t uKvmApicBase;
406
407 /** @name Statistics
408 * @{ */
409 STAMCOUNTER StatExitTotal;
410 STAMCOUNTER StatExitIo;
411 STAMCOUNTER StatExitMmio;
412 STAMCOUNTER StatExitSetTpr;
413 STAMCOUNTER StatExitTprAccess;
414 STAMCOUNTER StatExitRdMsr;
415 STAMCOUNTER StatExitWrMsr;
416 STAMCOUNTER StatExitIrqWindowOpen;
417 STAMCOUNTER StatExitHalt;
418 STAMCOUNTER StatExitIntr;
419 STAMCOUNTER StatExitHypercall;
420 STAMCOUNTER StatExitDebug;
421 STAMCOUNTER StatExitBusLock;
422 STAMCOUNTER StatExitInternalErrorEmulation;
423 STAMCOUNTER StatExitInternalErrorFatal;
424# if 0
425 STAMCOUNTER StatExitCpuId;
426 STAMCOUNTER StatExitUnrecoverable;
427 STAMCOUNTER StatGetMsgTimeout;
428 STAMCOUNTER StatStopCpuSuccess;
429 STAMCOUNTER StatStopCpuPending;
430 STAMCOUNTER StatStopCpuPendingAlerts;
431 STAMCOUNTER StatStopCpuPendingOdd;
432 STAMCOUNTER StatCancelChangedState;
433 STAMCOUNTER StatCancelAlertedThread;
434# endif
435 STAMCOUNTER StatBreakOnCancel;
436 STAMCOUNTER StatBreakOnFFPre;
437 STAMCOUNTER StatBreakOnFFPost;
438 STAMCOUNTER StatBreakOnStatus;
439 STAMCOUNTER StatFlushExitOnReturn;
440 STAMCOUNTER StatFlushExitOnReturn1Loop;
441 STAMCOUNTER StatFlushExitOnReturn2Loops;
442 STAMCOUNTER StatFlushExitOnReturn3Loops;
443 STAMCOUNTER StatFlushExitOnReturn4PlusLoops;
444 STAMCOUNTER StatImportOnDemand;
445 STAMCOUNTER StatImportOnReturn;
446 STAMCOUNTER StatImportOnReturnSkipped;
447 STAMCOUNTER StatImportPendingInterrupt;
448 STAMCOUNTER StatExportPendingInterrupt;
449 STAMCOUNTER StatQueryCpuTick;
450 /** @} */
451
452
453#elif defined(RT_OS_WINDOWS)
454 /** The current state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
455 uint8_t fCurrentInterruptWindows;
456 /** The desired state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
457 uint8_t fDesiredInterruptWindows;
458 /** Last copy of HV_X64_VP_EXECUTION_STATE::InterruptShadow. */
459 bool fLastInterruptShadow : 1;
460 uint32_t uPadding;
461 /** The VID_MSHAGN_F_XXX flags.
462 * Either VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE or zero. */
463 uint32_t fHandleAndGetFlags;
464 /** What VidMessageSlotMap returns and is used for passing exit info. */
465 RTR3PTR pvMsgSlotMapping;
466 /** The windows thread handle. */
467 RTR3PTR hNativeThreadHandle;
468
469 /** @name Statistics
470 * @{ */
471 STAMCOUNTER StatExitPortIo;
472 STAMCOUNTER StatExitMemUnmapped;
473 STAMCOUNTER StatExitMemIntercept;
474 STAMCOUNTER StatExitHalt;
475 STAMCOUNTER StatExitInterruptWindow;
476 STAMCOUNTER StatExitCpuId;
477 STAMCOUNTER StatExitMsr;
478 STAMCOUNTER StatExitException;
479 STAMCOUNTER StatExitExceptionBp;
480 STAMCOUNTER StatExitExceptionDb;
481 STAMCOUNTER StatExitExceptionGp;
482 STAMCOUNTER StatExitExceptionGpMesa;
483 STAMCOUNTER StatExitExceptionUd;
484 STAMCOUNTER StatExitExceptionUdHandled;
485 STAMCOUNTER StatExitUnrecoverable;
486 STAMCOUNTER StatGetMsgTimeout;
487 STAMCOUNTER StatStopCpuSuccess;
488 STAMCOUNTER StatStopCpuPending;
489 STAMCOUNTER StatStopCpuPendingAlerts;
490 STAMCOUNTER StatStopCpuPendingOdd;
491 STAMCOUNTER StatCancelChangedState;
492 STAMCOUNTER StatCancelAlertedThread;
493 STAMCOUNTER StatBreakOnCancel;
494 STAMCOUNTER StatBreakOnFFPre;
495 STAMCOUNTER StatBreakOnFFPost;
496 STAMCOUNTER StatBreakOnStatus;
497 STAMCOUNTER StatImportOnDemand;
498 STAMCOUNTER StatImportOnReturn;
499 STAMCOUNTER StatImportOnReturnSkipped;
500 STAMCOUNTER StatQueryCpuTick;
501 /** @} */
502
503#elif defined(RT_OS_DARWIN)
504# if defined(VBOX_VMM_TARGET_ARMV8)
505 /** The vCPU handle associated with the EMT executing this vCPU. */
506 hv_vcpu_t hVCpu;
507 /** Pointer to the exit information structure. */
508 hv_vcpu_exit_t *pHvExit;
509 /** Flag whether an event is pending. */
510 bool fEventPending;
511 /** Flag whether the vTimer got activated and is masked. */
512 bool fVTimerActivated;
513 /** Flag whether to update the vTimer offset. */
514 bool fVTimerOffUpdate;
515# else
516 /** The vCPU handle associated with the EMT executing this vCPU. */
517 hv_vcpuid_t hVCpuId;
518
519 /** @name State shared with the VT-x code.
520 * @{ */
521 /** An additional error code used for some gurus. */
522 uint32_t u32HMError;
523 /** The last exit-to-ring-3 reason. */
524 int32_t rcLastExitToR3;
525 /** CPU-context changed flags (see HM_CHANGED_xxx). */
526 uint64_t fCtxChanged;
527
528 /** The guest VMCS information. */
529 VMXVMCSINFO VmcsInfo;
530
531 /** VT-x data. */
532 struct HMCPUVMX
533 {
534 /** @name Guest information.
535 * @{ */
536 /** Guest VMCS information shared with ring-3. */
537 VMXVMCSINFOSHARED VmcsInfo;
538 /** Nested-guest VMCS information shared with ring-3. */
539 VMXVMCSINFOSHARED VmcsInfoNstGst;
540 /** Whether the nested-guest VMCS was the last current VMCS (shadow copy for ring-3).
541 * @see HMR0PERVCPU::vmx.fSwitchedToNstGstVmcs */
542 bool fSwitchedToNstGstVmcsCopyForRing3;
543 /** Whether the static guest VMCS controls has been merged with the
544 * nested-guest VMCS controls. */
545 bool fMergedNstGstCtls;
546 /** Whether the nested-guest VMCS has been copied to the shadow VMCS. */
547 bool fCopiedNstGstToShadowVmcs;
548 /** Whether flushing the TLB is required due to switching to/from the
549 * nested-guest. */
550 bool fSwitchedNstGstFlushTlb;
551 /** Alignment. */
552 bool afAlignment0[4];
553 /** Cached guest APIC-base MSR for identifying when to map the APIC-access page. */
554 uint64_t u64GstMsrApicBase;
555 /** @} */
556
557 /** @name Error reporting and diagnostics.
558 * @{ */
559 /** VT-x error-reporting (mainly for ring-3 propagation). */
560 struct
561 {
562 RTCPUID idCurrentCpu;
563 RTCPUID idEnteredCpu;
564 RTHCPHYS HCPhysCurrentVmcs;
565 uint32_t u32VmcsRev;
566 uint32_t u32InstrError;
567 uint32_t u32ExitReason;
568 uint32_t u32GuestIntrState;
569 } LastError;
570 /** @} */
571 } vmx;
572
573 /** Event injection state. */
574 HMEVENT Event;
575
576 /** Current shadow paging mode for updating CR4.
577 * @todo move later (@bugref{9217}). */
578 PGMMODE enmShadowMode;
579 uint32_t u32TemporaryPadding;
580
581 /** The PAE PDPEs used with Nested Paging (only valid when
582 * VMCPU_FF_HM_UPDATE_PAE_PDPES is set). */
583 X86PDPE aPdpes[4];
584 /** Pointer to the VMX statistics. */
585 PVMXSTATISTICS pVmxStats;
586# endif
587
588 /** @name Statistics
589 * @{ */
590 STAMCOUNTER StatExitAll;
591 STAMCOUNTER StatBreakOnCancel;
592 STAMCOUNTER StatBreakOnFFPre;
593 STAMCOUNTER StatBreakOnFFPost;
594 STAMCOUNTER StatBreakOnStatus;
595 STAMCOUNTER StatImportOnDemand;
596 STAMCOUNTER StatImportOnReturn;
597 STAMCOUNTER StatImportOnReturnSkipped;
598 STAMCOUNTER StatQueryCpuTick;
599#ifdef VBOX_WITH_STATISTICS
600 STAMPROFILEADV StatProfGstStateImport;
601 STAMPROFILEADV StatProfGstStateExport;
602#endif
603 /** @} */
604
605 /** @} */
606#endif /* RT_OS_DARWIN */
607} NEMCPU;
608/** Pointer to NEM VMCPU instance data. */
609typedef NEMCPU *PNEMCPU;
610
611/** NEMCPU::u32Magic value. */
612#define NEMCPU_MAGIC UINT32_C(0x4d454e20)
613/** NEMCPU::u32Magic value after termination. */
614#define NEMCPU_MAGIC_DEAD UINT32_C(0xdead2222)
615
616
617#ifdef IN_RING0
618# ifdef RT_OS_WINDOWS
619/**
620 * Windows: Hypercall input/ouput page info.
621 */
622typedef struct NEMR0HYPERCALLDATA
623{
624 /** Host physical address of the hypercall input/output page. */
625 RTHCPHYS HCPhysPage;
626 /** Pointer to the hypercall input/output page. */
627 uint8_t *pbPage;
628 /** Handle to the memory object of the hypercall input/output page. */
629 RTR0MEMOBJ hMemObj;
630} NEMR0HYPERCALLDATA;
631/** Pointer to a Windows hypercall input/output page info. */
632typedef NEMR0HYPERCALLDATA *PNEMR0HYPERCALLDATA;
633# endif /* RT_OS_WINDOWS */
634
635/**
636 * NEM GVMCPU instance data.
637 */
638typedef struct NEMR0PERVCPU
639{
640 uint32_t uDummy;
641} NEMR0PERVCPU;
642
643/**
644 * NEM GVM instance data.
645 */
646typedef struct NEMR0PERVM
647{
648 uint32_t uDummy;
649} NEMR0PERVM;
650
651#endif /* IN_RING*/
652
653
654#ifdef IN_RING3
655
656int nemR3DisableCpuIsaExt(PVM pVM, const char *pszIsaExt);
657
658int nemR3NativeInit(PVM pVM, bool fFallback, bool fForced);
659int nemR3NativeInitAfterCPUM(PVM pVM);
660int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
661int nemR3NativeTerm(PVM pVM);
662void nemR3NativeReset(PVM pVM);
663void nemR3NativeResetCpu(PVMCPU pVCpu, bool fInitIpi);
664VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu);
665bool nemR3NativeCanExecuteGuest(PVM pVM, PVMCPU pVCpu);
666bool nemR3NativeSetSingleInstruction(PVM pVM, PVMCPU pVCpu, bool fEnable);
667
668/**
669 * Forced flag notification call from VMEmt.h.
670 *
671 * This is only called when pVCpu is in the VMCPUSTATE_STARTED_EXEC_NEM state.
672 *
673 * @param pVM The cross context VM structure.
674 * @param pVCpu The cross context virtual CPU structure of the CPU
675 * to be notified.
676 * @param fFlags Notification flags, VMNOTIFYFF_FLAGS_XXX.
677 */
678void nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags);
679
680/**
681 * Called by NEMR3NotifyDebugEventChanged() to let the native backend take the final decision
682 * on whether to switch to the debug loop.
683 *
684 * @returns Final flag whether to switch to the debug loop.
685 * @param pVM The VM cross context VM structure.
686 * @param fUseDebugLoop The current value determined by NEMR3NotifyDebugEventChanged().
687 * @thread EMT(0)
688 */
689DECLHIDDEN(bool) nemR3NativeNotifyDebugEventChanged(PVM pVM, bool fUseDebugLoop);
690
691
692/**
693 * Called by NEMR3NotifyDebugEventChangedPerCpu() to let the native backend take the final decision
694 * on whether to switch to the debug loop.
695 *
696 * @returns Final flag whether to switch to the debug loop.
697 * @param pVM The VM cross context VM structure.
698 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
699 * @param fUseDebugLoop The current value determined by NEMR3NotifyDebugEventChangedPerCpu().
700 */
701DECLHIDDEN(bool) nemR3NativeNotifyDebugEventChangedPerCpu(PVM pVM, PVMCPU pVCpu, bool fUseDebugLoop);
702
703#endif /* IN_RING3 */
704
705void nemHCNativeNotifyHandlerPhysicalRegister(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb);
706void nemHCNativeNotifyHandlerPhysicalModify(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld,
707 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM);
708int nemHCNativeNotifyPhysPageAllocated(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
709 PGMPAGETYPE enmType, uint8_t *pu2State);
710
711
712#ifdef RT_OS_WINDOWS
713/** Maximum number of pages we can map in a single NEMR0MapPages call. */
714# define NEM_MAX_MAP_PAGES ((HOST_PAGE_SIZE - RT_UOFFSETOF(HV_INPUT_MAP_GPA_PAGES, PageList)) / sizeof(HV_SPA_PAGE_NUMBER))
715/** Maximum number of pages we can unmap in a single NEMR0UnmapPages call. */
716# define NEM_MAX_UNMAP_PAGES 4095
717
718#endif
719/** @} */
720
721RT_C_DECLS_END
722
723#endif /* !VMM_INCLUDED_SRC_include_NEMInternal_h */
724
Note: See TracBrowser for help on using the repository browser.

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