VirtualBox

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

最後變更 在這個檔案從71222是 71222,由 vboxsync 提交於 7 年 前

NEM/win,VMM,PGM: Ported NEM runloop to ring-0. bugref:9044

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 11.1 KB
 
1/* $Id: NEMInternal.h 71222 2018-03-05 22:07:48Z vboxsync $ */
2/** @file
3 * NEM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2018 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.alldomusa.eu.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 ___NEMInternal_h
19#define ___NEMInternal_h
20
21#include <VBox/cdefs.h>
22#include <VBox/types.h>
23#include <VBox/vmm/nem.h>
24#include <VBox/vmm/cpum.h> /* For CPUMCPUVENDOR. */
25#include <VBox/vmm/stam.h>
26#include <VBox/vmm/vmapi.h>
27#ifdef RT_OS_WINDOWS
28#include <iprt/nt/hyperv.h>
29#endif
30
31RT_C_DECLS_BEGIN
32
33
34/** @defgroup grp_nem_int Internal
35 * @ingroup grp_nem
36 * @internal
37 * @{
38 */
39
40
41#ifdef RT_OS_WINDOWS
42/*
43 * Windows: Code configuration.
44 */
45# define NEM_WIN_USE_HYPERCALLS_FOR_PAGES
46# define NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
47# define NEM_WIN_USE_OUR_OWN_RUN_API
48# if defined(NEM_WIN_USE_OUR_OWN_RUN_API) && !defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS)
49# error "NEM_WIN_USE_OUR_OWN_RUN_API requires NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS"
50# endif
51
52/**
53 * Windows VID I/O control information.
54 */
55typedef struct NEMWINIOCTL
56{
57 /** The I/O control function number. */
58 uint32_t uFunction;
59 uint32_t cbInput;
60 uint32_t cbOutput;
61} NEMWINIOCTL;
62
63/** @name Windows: Our two-bit physical page state for PGMPAGE
64 * @{ */
65# define NEM_WIN_PAGE_STATE_NOT_SET 0
66# define NEM_WIN_PAGE_STATE_UNMAPPED 1
67# define NEM_WIN_PAGE_STATE_READABLE 2
68# define NEM_WIN_PAGE_STATE_WRITABLE 3
69/** @} */
70
71/** Windows: Checks if a_GCPhys is subject to the limited A20 gate emulation. */
72# define NEM_WIN_IS_SUBJECT_TO_A20(a_GCPhys) ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K)
73/** Windows: Checks if a_GCPhys is relevant to the limited A20 gate emulation. */
74# define NEM_WIN_IS_RELEVANT_TO_A20(a_GCPhys) \
75 ( ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K) || ((RTGCPHYS)(a_GCPhys) < (RTGCPHYS)_64K) )
76
77#endif /* RT_OS_WINDOWS */
78
79
80/** Trick to make slickedit see the static functions in the template. */
81#ifndef IN_SLICKEDIT
82# define NEM_TMPL_STATIC static
83#else
84# define NEM_TMPL_STATIC
85#endif
86
87
88/**
89 * NEM VM Instance data.
90 */
91typedef struct NEM
92{
93 /** NEM_MAGIC. */
94 uint32_t u32Magic;
95
96 /** Set if enabled. */
97 bool fEnabled;
98#ifdef RT_OS_WINDOWS
99 /** Set if we've created the EMTs. */
100 bool fCreatedEmts : 1;
101 /** WHvRunVpExitReasonX64Cpuid is supported. */
102 bool fExtendedMsrExit : 1;
103 /** WHvRunVpExitReasonX64MsrAccess is supported. */
104 bool fExtendedCpuIdExit : 1;
105 /** WHvRunVpExitReasonException is supported. */
106 bool fExtendedXcptExit : 1;
107 /** Set if we've started more than one CPU and cannot mess with A20. */
108 bool fA20Fixed : 1;
109 /** Set if A20 is enabled. */
110 bool fA20Enabled : 1;
111 /** The reported CPU vendor. */
112 CPUMCPUVENDOR enmCpuVendor;
113 /** Cache line flush size as a power of two. */
114 uint8_t cCacheLineFlushShift;
115 /** The result of WHvCapabilityCodeProcessorFeatures. */
116 union
117 {
118 /** 64-bit view. */
119 uint64_t u64;
120# ifdef _WINHVAPIDEFS_H_
121 /** Interpreed features. */
122 WHV_PROCESSOR_FEATURES u;
123# endif
124 } uCpuFeatures;
125
126 /** The partition handle. */
127# ifdef _WINHVAPIDEFS_H_
128 WHV_PARTITION_HANDLE
129# else
130 RTHCUINTPTR
131# endif
132 hPartition;
133 /** The device handle for the partition, for use with Vid APIs or direct I/O
134 * controls. */
135 RTR3PTR hPartitionDevice;
136 /** The Hyper-V partition ID. */
137 uint64_t idHvPartition;
138
139 /** Number of currently mapped pages. */
140 uint32_t volatile cMappedPages;
141
142 /** Info about the VidGetHvPartitionId I/O control interface. */
143 NEMWINIOCTL IoCtlGetHvPartitionId;
144 /** Info about the VidStartVirtualProcessor I/O control interface. */
145 NEMWINIOCTL IoCtlStartVirtualProcessor;
146 /** Info about the VidStopVirtualProcessor I/O control interface. */
147 NEMWINIOCTL IoCtlStopVirtualProcessor;
148 /** Info about the VidStopVirtualProcessor I/O control interface. */
149 NEMWINIOCTL IoCtlMessageSlotHandleAndGetNext;
150
151#endif /* RT_OS_WINDOWS */
152} NEM;
153/** Pointer to NEM VM instance data. */
154typedef NEM *PNEM;
155
156/** NEM::u32Magic value. */
157#define NEM_MAGIC UINT32_C(0x004d454e)
158/** NEM::u32Magic value after termination. */
159#define NEM_MAGIC_DEAD UINT32_C(0xdead1111)
160
161
162/**
163 * NEM VMCPU Instance data.
164 */
165typedef struct NEMCPU
166{
167 /** NEMCPU_MAGIC. */
168 uint32_t u32Magic;
169#ifdef RT_OS_WINDOWS
170# ifdef NEM_WIN_USE_OUR_OWN_RUN_API
171 /** Pending VERR_NEM_CHANGE_PGM_MODE or VERR_NEM_FLUSH_TLB. */
172 int32_t rcPgmPending;
173 /** The VID_MSHAGN_F_XXX flags.
174 * Either VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE or zero. */
175 uint32_t fHandleAndGetFlags;
176 /** What VidMessageSlotMap returns and is used for passing exit info. */
177 RTR3PTR pvMsgSlotMapping;
178# endif
179 /** The windows thread handle. */
180 RTR3PTR hNativeThreadHandle;
181 /** Parameters for making Hyper-V hypercalls. */
182 union
183 {
184 uint8_t ab[64];
185 /** Arguments for NEMR0MapPages (HvCallMapGpaPages). */
186 struct
187 {
188 RTGCPHYS GCPhysSrc;
189 RTGCPHYS GCPhysDst; /**< Same as GCPhysSrc except maybe when the A20 gate is disabled. */
190 uint32_t cPages;
191 HV_MAP_GPA_FLAGS fFlags;
192 } MapPages;
193 /** Arguments for NEMR0UnmapPages (HvCallUnmapGpaPages). */
194 struct
195 {
196 RTGCPHYS GCPhys;
197 uint32_t cPages;
198 } UnmapPages;
199 } Hypercall;
200 /** I/O control buffer, we always use this for I/O controls. */
201 union
202 {
203 uint8_t ab[64];
204 HV_PARTITION_ID idPartition;
205 HV_VP_INDEX idCpu;
206# ifdef VID_MSHAGN_F_GET_NEXT_MESSAGE
207 VID_IOCTL_INPUT_MESSAGE_SLOT_HANDLE_AND_GET_NEXT MsgSlotHandleAndGetNext;
208# endif
209 } uIoCtlBuf;
210#endif
211} NEMCPU;
212/** Pointer to NEM VMCPU instance data. */
213typedef NEMCPU *PNEMCPU;
214
215/** NEMCPU::u32Magic value. */
216#define NEMCPU_MAGIC UINT32_C(0x4d454e20)
217/** NEMCPU::u32Magic value after termination. */
218#define NEMCPU_MAGIC_DEAD UINT32_C(0xdead2222)
219
220
221#ifdef IN_RING0
222
223/**
224 * NEM GVMCPU instance data.
225 */
226typedef struct NEMR0PERVCPU
227{
228# ifdef RT_OS_WINDOWS
229 /** @name Hypercall input/ouput page.
230 * @{ */
231 /** Host physical address of the hypercall input/output page. */
232 RTHCPHYS HCPhysHypercallData;
233 /** Pointer to the hypercall input/output page. */
234 uint8_t *pbHypercallData;
235 /** Handle to the memory object of the hypercall input/output page. */
236 RTR0MEMOBJ hHypercallDataMemObj;
237 /** @} */
238# else
239 uint32_t uDummy;
240# endif
241} NEMR0PERVCPU;
242
243/**
244 * NEM GVM instance data.
245 */
246typedef struct NEMR0PERVM
247{
248# ifdef RT_OS_WINDOWS
249 /** The partition ID. */
250 uint64_t idHvPartition;
251 /** I/O control context. */
252 PSUPR0IOCTLCTX pIoCtlCtx;
253 /** Delta to add to convert a ring-0 pointer to a ring-3 one. */
254 uintptr_t offRing3ConversionDelta;
255 /** Info about the VidGetHvPartitionId I/O control interface. */
256 NEMWINIOCTL IoCtlGetHvPartitionId;
257 /** Info about the VidStartVirtualProcessor I/O control interface. */
258 NEMWINIOCTL IoCtlStartVirtualProcessor;
259 /** Info about the VidStopVirtualProcessor I/O control interface. */
260 NEMWINIOCTL IoCtlStopVirtualProcessor;
261 /** Info about the VidStopVirtualProcessor I/O control interface. */
262 NEMWINIOCTL IoCtlMessageSlotHandleAndGetNext;
263
264# else
265 uint32_t uDummy;
266# endif
267} NEMR0PERVM;
268
269#endif /* IN_RING*/
270
271
272#ifdef IN_RING3
273int nemR3NativeInit(PVM pVM, bool fFallback, bool fForced);
274int nemR3NativeInitAfterCPUM(PVM pVM);
275int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
276int nemR3NativeTerm(PVM pVM);
277void nemR3NativeReset(PVM pVM);
278void nemR3NativeResetCpu(PVMCPU pVCpu, bool fInitIpi);
279VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu);
280bool nemR3NativeCanExecuteGuest(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
281bool nemR3NativeSetSingleInstruction(PVM pVM, PVMCPU pVCpu, bool fEnable);
282void nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags);
283
284int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb);
285int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2);
286int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
287int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
288int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
289void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled);
290#endif
291
292void nemHCNativeNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb);
293void nemHCNativeNotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb,
294 int fRestoreAsRAM, bool fRestoreAsRAM2);
295void nemHCNativeNotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld,
296 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM);
297int nemHCNativeNotifyPhysPageAllocated(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
298 PGMPAGETYPE enmType, uint8_t *pu2State);
299void nemHCNativeNotifyPhysPageProtChanged(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
300 PGMPAGETYPE enmType, uint8_t *pu2State);
301void nemHCNativeNotifyPhysPageChanged(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhysPrev, RTHCPHYS HCPhysNew, uint32_t fPageProt,
302 PGMPAGETYPE enmType, uint8_t *pu2State);
303
304
305#ifdef RT_OS_WINDOWS
306/** Maximum number of pages we can map in a single NEMR0MapPages call. */
307# define NEM_MAX_MAP_PAGES ((PAGE_SIZE - RT_UOFFSETOF(HV_INPUT_MAP_GPA_PAGES, PageList)) / sizeof(HV_SPA_PAGE_NUMBER))
308/** Maximum number of pages we can unmap in a single NEMR0UnmapPages call. */
309# define NEM_MAX_UNMAP_PAGES 4095
310
311#endif
312/** @} */
313
314RT_C_DECLS_END
315
316#endif
317
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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