diff options
Diffstat (limited to 'src/VBox/VMM/include/NEMInternal.h')
-rw-r--r-- | src/VBox/VMM/include/NEMInternal.h | 669 |
1 files changed, 669 insertions, 0 deletions
diff --git a/src/VBox/VMM/include/NEMInternal.h b/src/VBox/VMM/include/NEMInternal.h new file mode 100644 index 00000000..e0817e21 --- /dev/null +++ b/src/VBox/VMM/include/NEMInternal.h @@ -0,0 +1,669 @@ +/* $Id: NEMInternal.h $ */ +/** @file + * NEM - Internal header file. + */ + +/* + * Copyright (C) 2018-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <https://www.gnu.org/licenses>. + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#ifndef VMM_INCLUDED_SRC_include_NEMInternal_h +#define VMM_INCLUDED_SRC_include_NEMInternal_h +#ifndef RT_WITHOUT_PRAGMA_ONCE +# pragma once +#endif + +#include <VBox/cdefs.h> +#include <VBox/types.h> +#include <VBox/vmm/nem.h> +#include <VBox/vmm/cpum.h> /* For CPUMCPUVENDOR. */ +#include <VBox/vmm/stam.h> +#include <VBox/vmm/vmapi.h> +#ifdef RT_OS_WINDOWS +#include <iprt/nt/hyperv.h> +#include <iprt/critsect.h> +#elif defined(RT_OS_DARWIN) +# include "VMXInternal.h" +#endif + +RT_C_DECLS_BEGIN + + +/** @defgroup grp_nem_int Internal + * @ingroup grp_nem + * @internal + * @{ + */ + +#if defined(VBOX_WITH_NATIVE_NEM) && !defined(VBOX_WITH_PGM_NEM_MODE) +# error "VBOX_WITH_NATIVE_NEM requires VBOX_WITH_PGM_NEM_MODE to be defined" +#endif + + +#ifdef RT_OS_WINDOWS +/* + * Windows: Code configuration. + */ +/* nothing at the moment */ + +/** + * Windows VID I/O control information. + */ +typedef struct NEMWINIOCTL +{ + /** The I/O control function number. */ + uint32_t uFunction; + uint32_t cbInput; + uint32_t cbOutput; +} NEMWINIOCTL; + +/** @name Windows: Our two-bit physical page state for PGMPAGE + * @{ */ +# define NEM_WIN_PAGE_STATE_NOT_SET 0 +# define NEM_WIN_PAGE_STATE_UNMAPPED 1 +# define NEM_WIN_PAGE_STATE_READABLE 2 +# define NEM_WIN_PAGE_STATE_WRITABLE 3 +/** @} */ + +/** Windows: Checks if a_GCPhys is subject to the limited A20 gate emulation. */ +# define NEM_WIN_IS_SUBJECT_TO_A20(a_GCPhys) ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K) +/** Windows: Checks if a_GCPhys is relevant to the limited A20 gate emulation. */ +# define NEM_WIN_IS_RELEVANT_TO_A20(a_GCPhys) \ + ( ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K) || ((RTGCPHYS)(a_GCPhys) < (RTGCPHYS)_64K) ) + +/** The CPUMCTX_EXTRN_XXX mask for IEM. */ +# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM ( IEM_CPUMCTX_EXTRN_MUST_MASK | CPUMCTX_EXTRN_INHIBIT_INT \ + | CPUMCTX_EXTRN_INHIBIT_NMI ) +/** The CPUMCTX_EXTRN_XXX mask for IEM when raising exceptions. */ +# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT (IEM_CPUMCTX_EXTRN_XCPT_MASK | NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM) + +/** @name Windows: Interrupt window flags (NEM_WIN_INTW_F_XXX). + * @{ */ +# define NEM_WIN_INTW_F_NMI UINT8_C(0x01) +# define NEM_WIN_INTW_F_REGULAR UINT8_C(0x02) +# define NEM_WIN_INTW_F_PRIO_MASK UINT8_C(0x3c) +# define NEM_WIN_INTW_F_PRIO_SHIFT 2 +/** @} */ + +#endif /* RT_OS_WINDOWS */ + + +#ifdef RT_OS_DARWIN +/** vCPU ID declaration to avoid dragging in HV headers here. */ +typedef unsigned hv_vcpuid_t; +/** The HV VM memory space ID (ASID). */ +typedef unsigned hv_vm_space_t; + + +/** @name Darwin: Our two-bit physical page state for PGMPAGE + * @{ */ +# define NEM_DARWIN_PAGE_STATE_UNMAPPED 0 +# define NEM_DARWIN_PAGE_STATE_RX 1 +# define NEM_DARWIN_PAGE_STATE_RW 2 +# define NEM_DARWIN_PAGE_STATE_RWX 3 +/** @} */ + +/** The CPUMCTX_EXTRN_XXX mask for IEM. */ +# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM ( IEM_CPUMCTX_EXTRN_MUST_MASK | CPUMCTX_EXTRN_INHIBIT_INT \ + | CPUMCTX_EXTRN_INHIBIT_NMI ) +/** The CPUMCTX_EXTRN_XXX mask for IEM when raising exceptions. */ +# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT (IEM_CPUMCTX_EXTRN_XCPT_MASK | NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM) + +#endif + + +/** Trick to make slickedit see the static functions in the template. */ +#ifndef IN_SLICKEDIT +# define NEM_TMPL_STATIC static +#else +# define NEM_TMPL_STATIC +#endif + + +/** + * Generic NEM exit type enumeration for use with EMHistoryAddExit. + * + * On windows we've got two different set of exit types and they are both jumping + * around the place value wise, so EM can use their values. + * + * @note We only have exit types for exits not covered by EM here. + */ +typedef enum NEMEXITTYPE +{ + NEMEXITTYPE_INVALID = 0, + + /* Common: */ + NEMEXITTYPE_INTTERRUPT_WINDOW, + NEMEXITTYPE_HALT, + + /* Windows: */ + NEMEXITTYPE_UNRECOVERABLE_EXCEPTION, + NEMEXITTYPE_INVALID_VP_REGISTER_VALUE, + NEMEXITTYPE_XCPT_UD, + NEMEXITTYPE_XCPT_DB, + NEMEXITTYPE_XCPT_BP, + NEMEXITTYPE_CANCELED, + NEMEXITTYPE_MEMORY_ACCESS, + + /* Linux: */ + NEMEXITTYPE_INTERNAL_ERROR_EMULATION, + NEMEXITTYPE_INTERNAL_ERROR_FATAL, + NEMEXITTYPE_INTERRUPTED, + NEMEXITTYPE_FAILED_ENTRY, + + /* End of valid types. */ + NEMEXITTYPE_END +} NEMEXITTYPE; + + +/** + * NEM VM Instance data. + */ +typedef struct NEM +{ + /** NEM_MAGIC. */ + uint32_t u32Magic; + + /** Set if enabled. */ + bool fEnabled; + /** Set if long mode guests are allowed. */ + bool fAllow64BitGuests; + /** Set when the debug facility has breakpoints/events enabled that requires + * us to use the debug execution loop. */ + bool fUseDebugLoop; + +#if defined(RT_OS_LINUX) + /** The '/dev/kvm' file descriptor. */ + int32_t fdKvm; + /** The KVM_CREATE_VM file descriptor. */ + int32_t fdVm; + + /** KVM_GET_VCPU_MMAP_SIZE. */ + uint32_t cbVCpuMmap; + /** KVM_CAP_NR_MEMSLOTS. */ + uint32_t cMaxMemSlots; + /** KVM_CAP_X86_ROBUST_SINGLESTEP. */ + bool fRobustSingleStep; + + /** Hint where there might be a free slot. */ + uint16_t idPrevSlot; + /** Memory slot ID allocation bitmap. */ + uint64_t bmSlotIds[_32K / 8 / sizeof(uint64_t)]; + +#elif defined(RT_OS_WINDOWS) + /** Set if we've created the EMTs. */ + bool fCreatedEmts : 1; + /** WHvRunVpExitReasonX64Cpuid is supported. */ + bool fExtendedMsrExit : 1; + /** WHvRunVpExitReasonX64MsrAccess is supported. */ + bool fExtendedCpuIdExit : 1; + /** WHvRunVpExitReasonException is supported. */ + bool fExtendedXcptExit : 1; +# ifdef NEM_WIN_WITH_A20 + /** Set if we've started more than one CPU and cannot mess with A20. */ + bool fA20Fixed : 1; + /** Set if A20 is enabled. */ + bool fA20Enabled : 1; +# endif + /** The reported CPU vendor. */ + CPUMCPUVENDOR enmCpuVendor; + /** Cache line flush size as a power of two. */ + uint8_t cCacheLineFlushShift; + /** The result of WHvCapabilityCodeProcessorFeatures. */ + union + { + /** 64-bit view. */ + uint64_t u64; +# ifdef _WINHVAPIDEFS_H_ + /** Interpreed features. */ + WHV_PROCESSOR_FEATURES u; +# endif + } uCpuFeatures; + + /** The partition handle. */ +# ifdef _WINHVAPIDEFS_H_ + WHV_PARTITION_HANDLE +# else + RTHCUINTPTR +# endif + hPartition; + /** The device handle for the partition, for use with Vid APIs or direct I/O + * controls. */ + RTR3PTR hPartitionDevice; + + /** Number of currently mapped pages. */ + uint32_t volatile cMappedPages; + uint32_t u32Padding; + STAMCOUNTER StatMapPage; + STAMCOUNTER StatUnmapPage; + STAMCOUNTER StatMapPageFailed; + STAMCOUNTER StatUnmapPageFailed; + STAMPROFILE StatProfMapGpaRange; + STAMPROFILE StatProfUnmapGpaRange; + STAMPROFILE StatProfMapGpaRangePage; + STAMPROFILE StatProfUnmapGpaRangePage; + + /** Statistics updated by NEMR0UpdateStatistics. */ + struct + { + uint64_t cPagesAvailable; + uint64_t cPagesInUse; + } R0Stats; + +#elif defined(RT_OS_DARWIN) + /** Set if we've created the EMTs. */ + bool fCreatedEmts : 1; + /** Set if hv_vm_create() was called successfully. */ + bool fCreatedVm : 1; + /** Set if hv_vm_space_create() was called successfully. */ + bool fCreatedAsid : 1; + /** Set if Last Branch Record (LBR) is enabled. */ + bool fLbr; + /** The ASID for this VM (only valid if fCreatedAsid is true). */ + hv_vm_space_t uVmAsid; + /** Number of mach time units per NS, for hv_vcpu_run_until(). */ + uint64_t cMachTimePerNs; + /** Pause-loop exiting (PLE) gap in ticks. */ + uint32_t cPleGapTicks; + /** Pause-loop exiting (PLE) window in ticks. */ + uint32_t cPleWindowTicks; + + /** The host LBR TOS (top-of-stack) MSR id. */ + uint32_t idLbrTosMsr; + /** The host LBR select MSR id. */ + uint32_t idLbrSelectMsr; + /** The host last event record from IP MSR id. */ + uint32_t idLerFromIpMsr; + /** The host last event record to IP MSR id. */ + uint32_t idLerToIpMsr; + + /** The first valid host LBR branch-from-IP stack range. */ + uint32_t idLbrFromIpMsrFirst; + /** The last valid host LBR branch-from-IP stack range. */ + uint32_t idLbrFromIpMsrLast; + + /** The first valid host LBR branch-to-IP stack range. */ + uint32_t idLbrToIpMsrFirst; + /** The last valid host LBR branch-to-IP stack range. */ + uint32_t idLbrToIpMsrLast; + + /** The first valid host LBR info stack range. */ + uint32_t idLbrInfoMsrFirst; + /** The last valid host LBR info stack range. */ + uint32_t idLbrInfoMsrLast; + + STAMCOUNTER StatMapPage; + STAMCOUNTER StatUnmapPage; + STAMCOUNTER StatMapPageFailed; + STAMCOUNTER StatUnmapPageFailed; +#endif /* RT_OS_WINDOWS */ +} NEM; +/** Pointer to NEM VM instance data. */ +typedef NEM *PNEM; + +/** NEM::u32Magic value. */ +#define NEM_MAGIC UINT32_C(0x004d454e) +/** NEM::u32Magic value after termination. */ +#define NEM_MAGIC_DEAD UINT32_C(0xdead1111) + + +/** + * NEM VMCPU Instance data. + */ +typedef struct NEMCPU +{ + /** NEMCPU_MAGIC. */ + uint32_t u32Magic; + /** Whether \#UD needs to be intercepted and presented to GIM. */ + bool fGIMTrapXcptUD : 1; + /** Whether \#GP needs to be intercept for mesa driver workaround. */ + bool fTrapXcptGpForLovelyMesaDrv: 1; + /** Whether we should use the debug loop because of single stepping or special + * debug breakpoints / events are armed. */ + bool fUseDebugLoop : 1; + /** Whether we're executing a single instruction. */ + bool fSingleInstruction : 1; + /** Set if we using the debug loop and wish to intercept RDTSC. */ + bool fDebugWantRdTscExit : 1; + /** Whether we are currently executing in the debug loop. + * Mainly for assertions. */ + bool fUsingDebugLoop : 1; + /** Set if we need to clear the trap flag because of single stepping. */ + bool fClearTrapFlag : 1; + /** Whether we're using the hyper DR7 or guest DR7. */ + bool fUsingHyperDR7 : 1; + /** Whether \#DE needs to be intercepted for GIM. */ + bool fGCMTrapXcptDE : 1; + +#if defined(RT_OS_LINUX) + uint8_t abPadding[3]; + /** The KVM VCpu file descriptor. */ + int32_t fdVCpu; + /** Pointer to the KVM_RUN data exchange region. */ + R3PTRTYPE(struct kvm_run *) pRun; + /** The MSR_IA32_APICBASE value known to KVM. */ + uint64_t uKvmApicBase; + + /** @name Statistics + * @{ */ + STAMCOUNTER StatExitTotal; + STAMCOUNTER StatExitIo; + STAMCOUNTER StatExitMmio; + STAMCOUNTER StatExitSetTpr; + STAMCOUNTER StatExitTprAccess; + STAMCOUNTER StatExitRdMsr; + STAMCOUNTER StatExitWrMsr; + STAMCOUNTER StatExitIrqWindowOpen; + STAMCOUNTER StatExitHalt; + STAMCOUNTER StatExitIntr; + STAMCOUNTER StatExitHypercall; + STAMCOUNTER StatExitDebug; + STAMCOUNTER StatExitBusLock; + STAMCOUNTER StatExitInternalErrorEmulation; + STAMCOUNTER StatExitInternalErrorFatal; +# if 0 + STAMCOUNTER StatExitCpuId; + STAMCOUNTER StatExitUnrecoverable; + STAMCOUNTER StatGetMsgTimeout; + STAMCOUNTER StatStopCpuSuccess; + STAMCOUNTER StatStopCpuPending; + STAMCOUNTER StatStopCpuPendingAlerts; + STAMCOUNTER StatStopCpuPendingOdd; + STAMCOUNTER StatCancelChangedState; + STAMCOUNTER StatCancelAlertedThread; +# endif + STAMCOUNTER StatBreakOnCancel; + STAMCOUNTER StatBreakOnFFPre; + STAMCOUNTER StatBreakOnFFPost; + STAMCOUNTER StatBreakOnStatus; + STAMCOUNTER StatFlushExitOnReturn; + STAMCOUNTER StatFlushExitOnReturn1Loop; + STAMCOUNTER StatFlushExitOnReturn2Loops; + STAMCOUNTER StatFlushExitOnReturn3Loops; + STAMCOUNTER StatFlushExitOnReturn4PlusLoops; + STAMCOUNTER StatImportOnDemand; + STAMCOUNTER StatImportOnReturn; + STAMCOUNTER StatImportOnReturnSkipped; + STAMCOUNTER StatImportPendingInterrupt; + STAMCOUNTER StatExportPendingInterrupt; + STAMCOUNTER StatQueryCpuTick; + /** @} */ + + +#elif defined(RT_OS_WINDOWS) + /** The current state of the interrupt windows (NEM_WIN_INTW_F_XXX). */ + uint8_t fCurrentInterruptWindows; + /** The desired state of the interrupt windows (NEM_WIN_INTW_F_XXX). */ + uint8_t fDesiredInterruptWindows; + /** Last copy of HV_X64_VP_EXECUTION_STATE::InterruptShadow. */ + bool fLastInterruptShadow : 1; + uint32_t uPadding; + /** The VID_MSHAGN_F_XXX flags. + * Either VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE or zero. */ + uint32_t fHandleAndGetFlags; + /** What VidMessageSlotMap returns and is used for passing exit info. */ + RTR3PTR pvMsgSlotMapping; + /** The windows thread handle. */ + RTR3PTR hNativeThreadHandle; + + /** @name Statistics + * @{ */ + STAMCOUNTER StatExitPortIo; + STAMCOUNTER StatExitMemUnmapped; + STAMCOUNTER StatExitMemIntercept; + STAMCOUNTER StatExitHalt; + STAMCOUNTER StatExitInterruptWindow; + STAMCOUNTER StatExitCpuId; + STAMCOUNTER StatExitMsr; + STAMCOUNTER StatExitException; + STAMCOUNTER StatExitExceptionBp; + STAMCOUNTER StatExitExceptionDb; + STAMCOUNTER StatExitExceptionGp; + STAMCOUNTER StatExitExceptionGpMesa; + STAMCOUNTER StatExitExceptionUd; + STAMCOUNTER StatExitExceptionUdHandled; + STAMCOUNTER StatExitUnrecoverable; + STAMCOUNTER StatGetMsgTimeout; + STAMCOUNTER StatStopCpuSuccess; + STAMCOUNTER StatStopCpuPending; + STAMCOUNTER StatStopCpuPendingAlerts; + STAMCOUNTER StatStopCpuPendingOdd; + STAMCOUNTER StatCancelChangedState; + STAMCOUNTER StatCancelAlertedThread; + STAMCOUNTER StatBreakOnCancel; + STAMCOUNTER StatBreakOnFFPre; + STAMCOUNTER StatBreakOnFFPost; + STAMCOUNTER StatBreakOnStatus; + STAMCOUNTER StatImportOnDemand; + STAMCOUNTER StatImportOnReturn; + STAMCOUNTER StatImportOnReturnSkipped; + STAMCOUNTER StatQueryCpuTick; + /** @} */ + +#elif defined(RT_OS_DARWIN) + /** The vCPU handle associated with the EMT executing this vCPU. */ + hv_vcpuid_t hVCpuId; + + /** @name State shared with the VT-x code. + * @{ */ + /** An additional error code used for some gurus. */ + uint32_t u32HMError; + /** The last exit-to-ring-3 reason. */ + int32_t rcLastExitToR3; + /** CPU-context changed flags (see HM_CHANGED_xxx). */ + uint64_t fCtxChanged; + + /** The guest VMCS information. */ + VMXVMCSINFO VmcsInfo; + + /** VT-x data. */ + struct HMCPUVMX + { + /** @name Guest information. + * @{ */ + /** Guest VMCS information shared with ring-3. */ + VMXVMCSINFOSHARED VmcsInfo; + /** Nested-guest VMCS information shared with ring-3. */ + VMXVMCSINFOSHARED VmcsInfoNstGst; + /** Whether the nested-guest VMCS was the last current VMCS (shadow copy for ring-3). + * @see HMR0PERVCPU::vmx.fSwitchedToNstGstVmcs */ + bool fSwitchedToNstGstVmcsCopyForRing3; + /** Whether the static guest VMCS controls has been merged with the + * nested-guest VMCS controls. */ + bool fMergedNstGstCtls; + /** Whether the nested-guest VMCS has been copied to the shadow VMCS. */ + bool fCopiedNstGstToShadowVmcs; + /** Whether flushing the TLB is required due to switching to/from the + * nested-guest. */ + bool fSwitchedNstGstFlushTlb; + /** Alignment. */ + bool afAlignment0[4]; + /** Cached guest APIC-base MSR for identifying when to map the APIC-access page. */ + uint64_t u64GstMsrApicBase; + /** @} */ + + /** @name Error reporting and diagnostics. + * @{ */ + /** VT-x error-reporting (mainly for ring-3 propagation). */ + struct + { + RTCPUID idCurrentCpu; + RTCPUID idEnteredCpu; + RTHCPHYS HCPhysCurrentVmcs; + uint32_t u32VmcsRev; + uint32_t u32InstrError; + uint32_t u32ExitReason; + uint32_t u32GuestIntrState; + } LastError; + /** @} */ + } vmx; + + /** Event injection state. */ + HMEVENT Event; + + /** Current shadow paging mode for updating CR4. + * @todo move later (@bugref{9217}). */ + PGMMODE enmShadowMode; + uint32_t u32TemporaryPadding; + + /** The PAE PDPEs used with Nested Paging (only valid when + * VMCPU_FF_HM_UPDATE_PAE_PDPES is set). */ + X86PDPE aPdpes[4]; + /** Pointer to the VMX statistics. */ + PVMXSTATISTICS pVmxStats; + + /** @name Statistics + * @{ */ + STAMCOUNTER StatExitAll; + STAMCOUNTER StatBreakOnCancel; + STAMCOUNTER StatBreakOnFFPre; + STAMCOUNTER StatBreakOnFFPost; + STAMCOUNTER StatBreakOnStatus; + STAMCOUNTER StatImportOnDemand; + STAMCOUNTER StatImportOnReturn; + STAMCOUNTER StatImportOnReturnSkipped; + STAMCOUNTER StatQueryCpuTick; +#ifdef VBOX_WITH_STATISTICS + STAMPROFILEADV StatProfGstStateImport; + STAMPROFILEADV StatProfGstStateExport; +#endif + /** @} */ + + /** @} */ +#endif /* RT_OS_DARWIN */ +} NEMCPU; +/** Pointer to NEM VMCPU instance data. */ +typedef NEMCPU *PNEMCPU; + +/** NEMCPU::u32Magic value. */ +#define NEMCPU_MAGIC UINT32_C(0x4d454e20) +/** NEMCPU::u32Magic value after termination. */ +#define NEMCPU_MAGIC_DEAD UINT32_C(0xdead2222) + + +#ifdef IN_RING0 +# ifdef RT_OS_WINDOWS +/** + * Windows: Hypercall input/ouput page info. + */ +typedef struct NEMR0HYPERCALLDATA +{ + /** Host physical address of the hypercall input/output page. */ + RTHCPHYS HCPhysPage; + /** Pointer to the hypercall input/output page. */ + uint8_t *pbPage; + /** Handle to the memory object of the hypercall input/output page. */ + RTR0MEMOBJ hMemObj; +} NEMR0HYPERCALLDATA; +/** Pointer to a Windows hypercall input/output page info. */ +typedef NEMR0HYPERCALLDATA *PNEMR0HYPERCALLDATA; +# endif /* RT_OS_WINDOWS */ + +/** + * NEM GVMCPU instance data. + */ +typedef struct NEMR0PERVCPU +{ + uint32_t uDummy; +} NEMR0PERVCPU; + +/** + * NEM GVM instance data. + */ +typedef struct NEMR0PERVM +{ + uint32_t uDummy; +} NEMR0PERVM; + +#endif /* IN_RING*/ + + +#ifdef IN_RING3 + +int nemR3DisableCpuIsaExt(PVM pVM, const char *pszIsaExt); + +int nemR3NativeInit(PVM pVM, bool fFallback, bool fForced); +int nemR3NativeInitAfterCPUM(PVM pVM); +int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat); +int nemR3NativeTerm(PVM pVM); +void nemR3NativeReset(PVM pVM); +void nemR3NativeResetCpu(PVMCPU pVCpu, bool fInitIpi); +VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu); +bool nemR3NativeCanExecuteGuest(PVM pVM, PVMCPU pVCpu); +bool nemR3NativeSetSingleInstruction(PVM pVM, PVMCPU pVCpu, bool fEnable); + +/** + * Forced flag notification call from VMEmt.h. + * + * This is only called when pVCpu is in the VMCPUSTATE_STARTED_EXEC_NEM state. + * + * @param pVM The cross context VM structure. + * @param pVCpu The cross context virtual CPU structure of the CPU + * to be notified. + * @param fFlags Notification flags, VMNOTIFYFF_FLAGS_XXX. + */ +void nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags); + +/** + * Called by NEMR3NotifyDebugEventChanged() to let the native backend take the final decision + * on whether to switch to the debug loop. + * + * @returns Final flag whether to switch to the debug loop. + * @param pVM The VM cross context VM structure. + * @param fUseDebugLoop The current value determined by NEMR3NotifyDebugEventChanged(). + * @thread EMT(0) + */ +DECLHIDDEN(bool) nemR3NativeNotifyDebugEventChanged(PVM pVM, bool fUseDebugLoop); + + +/** + * Called by NEMR3NotifyDebugEventChangedPerCpu() to let the native backend take the final decision + * on whether to switch to the debug loop. + * + * @returns Final flag whether to switch to the debug loop. + * @param pVM The VM cross context VM structure. + * @param pVCpu The cross context virtual CPU structure of the calling EMT. + * @param fUseDebugLoop The current value determined by NEMR3NotifyDebugEventChangedPerCpu(). + */ +DECLHIDDEN(bool) nemR3NativeNotifyDebugEventChangedPerCpu(PVM pVM, PVMCPU pVCpu, bool fUseDebugLoop); + +#endif /* IN_RING3 */ + +void nemHCNativeNotifyHandlerPhysicalRegister(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb); +void nemHCNativeNotifyHandlerPhysicalModify(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld, + RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM); +int nemHCNativeNotifyPhysPageAllocated(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt, + PGMPAGETYPE enmType, uint8_t *pu2State); + + +#ifdef RT_OS_WINDOWS +/** Maximum number of pages we can map in a single NEMR0MapPages call. */ +# define NEM_MAX_MAP_PAGES ((HOST_PAGE_SIZE - RT_UOFFSETOF(HV_INPUT_MAP_GPA_PAGES, PageList)) / sizeof(HV_SPA_PAGE_NUMBER)) +/** Maximum number of pages we can unmap in a single NEMR0UnmapPages call. */ +# define NEM_MAX_UNMAP_PAGES 4095 + +#endif +/** @} */ + +RT_C_DECLS_END + +#endif /* !VMM_INCLUDED_SRC_include_NEMInternal_h */ + |