VirtualBox

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

Last change on this file since 72456 was 72446, checked in by vboxsync, 7 years ago

NEM/win: Working on intercepting VMMCALL and VMCALL. bugref:9044

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 14.0 KB
Line 
1/* $Id: NEMInternal.h 72446 2018-06-05 08:53:01Z 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.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 ___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#include <iprt/critsect.h>
30#endif
31
32RT_C_DECLS_BEGIN
33
34
35/** @defgroup grp_nem_int Internal
36 * @ingroup grp_nem
37 * @internal
38 * @{
39 */
40
41
42#ifdef RT_OS_WINDOWS
43/*
44 * Windows: Code configuration.
45 */
46# define NEM_WIN_USE_HYPERCALLS_FOR_PAGES
47# define NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
48# define NEM_WIN_USE_OUR_OWN_RUN_API
49# if defined(NEM_WIN_USE_OUR_OWN_RUN_API) && !defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS)
50# error "NEM_WIN_USE_OUR_OWN_RUN_API requires NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS"
51# endif
52# if defined(NEM_WIN_USE_OUR_OWN_RUN_API) && !defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES)
53# error "NEM_WIN_USE_OUR_OWN_RUN_API requires NEM_WIN_USE_HYPERCALLS_FOR_PAGES"
54# endif
55
56/**
57 * Windows VID I/O control information.
58 */
59typedef struct NEMWINIOCTL
60{
61 /** The I/O control function number. */
62 uint32_t uFunction;
63 uint32_t cbInput;
64 uint32_t cbOutput;
65} NEMWINIOCTL;
66
67/** @name Windows: Our two-bit physical page state for PGMPAGE
68 * @{ */
69# define NEM_WIN_PAGE_STATE_NOT_SET 0
70# define NEM_WIN_PAGE_STATE_UNMAPPED 1
71# define NEM_WIN_PAGE_STATE_READABLE 2
72# define NEM_WIN_PAGE_STATE_WRITABLE 3
73/** @} */
74
75/** Windows: Checks if a_GCPhys is subject to the limited A20 gate emulation. */
76# define NEM_WIN_IS_SUBJECT_TO_A20(a_GCPhys) ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K)
77/** Windows: Checks if a_GCPhys is relevant to the limited A20 gate emulation. */
78# define NEM_WIN_IS_RELEVANT_TO_A20(a_GCPhys) \
79 ( ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K) || ((RTGCPHYS)(a_GCPhys) < (RTGCPHYS)_64K) )
80
81/** The CPUMCTX_EXTRN_XXX mask for IEM. */
82# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_INT | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_NMI)
83
84/** @name Windows: Interrupt window flags (NEM_WIN_INTW_F_XXX).
85 * @{ */
86# define NEM_WIN_INTW_F_NMI UINT8_C(0x01)
87# define NEM_WIN_INTW_F_REGULAR UINT8_C(0x02)
88# define NEM_WIN_INTW_F_PRIO_MASK UINT8_C(0x3c)
89# define NEM_WIN_INTW_F_PRIO_SHIFT 2
90/** @} */
91
92#endif /* RT_OS_WINDOWS */
93
94
95/** Trick to make slickedit see the static functions in the template. */
96#ifndef IN_SLICKEDIT
97# define NEM_TMPL_STATIC static
98#else
99# define NEM_TMPL_STATIC
100#endif
101
102
103/**
104 * NEM VM Instance data.
105 */
106typedef struct NEM
107{
108 /** NEM_MAGIC. */
109 uint32_t u32Magic;
110
111 /** Set if enabled. */
112 bool fEnabled;
113 /** Set if long mode guests are allowed. */
114 bool fAllow64BitGuests;
115#ifdef RT_OS_WINDOWS
116 /** Set if we've created the EMTs. */
117 bool fCreatedEmts : 1;
118 /** WHvRunVpExitReasonX64Cpuid is supported. */
119 bool fExtendedMsrExit : 1;
120 /** WHvRunVpExitReasonX64MsrAccess is supported. */
121 bool fExtendedCpuIdExit : 1;
122 /** WHvRunVpExitReasonException is supported. */
123 bool fExtendedXcptExit : 1;
124 /** Set if we've started more than one CPU and cannot mess with A20. */
125 bool fA20Fixed : 1;
126 /** Set if A20 is enabled. */
127 bool fA20Enabled : 1;
128 /** The reported CPU vendor. */
129 CPUMCPUVENDOR enmCpuVendor;
130 /** Cache line flush size as a power of two. */
131 uint8_t cCacheLineFlushShift;
132 /** The result of WHvCapabilityCodeProcessorFeatures. */
133 union
134 {
135 /** 64-bit view. */
136 uint64_t u64;
137# ifdef _WINHVAPIDEFS_H_
138 /** Interpreed features. */
139 WHV_PROCESSOR_FEATURES u;
140# endif
141 } uCpuFeatures;
142
143 /** The partition handle. */
144# ifdef _WINHVAPIDEFS_H_
145 WHV_PARTITION_HANDLE
146# else
147 RTHCUINTPTR
148# endif
149 hPartition;
150 /** The device handle for the partition, for use with Vid APIs or direct I/O
151 * controls. */
152 RTR3PTR hPartitionDevice;
153 /** The Hyper-V partition ID. */
154 uint64_t idHvPartition;
155
156 /** Number of currently mapped pages. */
157 uint32_t volatile cMappedPages;
158
159 /** Info about the VidGetHvPartitionId I/O control interface. */
160 NEMWINIOCTL IoCtlGetHvPartitionId;
161 /** Info about the VidStartVirtualProcessor I/O control interface. */
162 NEMWINIOCTL IoCtlStartVirtualProcessor;
163 /** Info about the VidStopVirtualProcessor I/O control interface. */
164 NEMWINIOCTL IoCtlStopVirtualProcessor;
165 /** Info about the VidStopVirtualProcessor I/O control interface. */
166 NEMWINIOCTL IoCtlMessageSlotHandleAndGetNext;
167
168 /** Statistics updated by NEMR0UpdateStatistics. */
169 struct
170 {
171 uint64_t cPagesAvailable;
172 uint64_t cPagesInUse;
173 } R0Stats;
174#endif /* RT_OS_WINDOWS */
175} NEM;
176/** Pointer to NEM VM instance data. */
177typedef NEM *PNEM;
178
179/** NEM::u32Magic value. */
180#define NEM_MAGIC UINT32_C(0x004d454e)
181/** NEM::u32Magic value after termination. */
182#define NEM_MAGIC_DEAD UINT32_C(0xdead1111)
183
184
185/**
186 * NEM VMCPU Instance data.
187 */
188typedef struct NEMCPU
189{
190 /** NEMCPU_MAGIC. */
191 uint32_t u32Magic;
192#ifdef RT_OS_WINDOWS
193 /** The current state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
194 uint8_t fCurrentInterruptWindows;
195 /** The desired state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
196 uint8_t fDesiredInterruptWindows;
197 /** Last copy of HV_X64_VP_EXECUTION_STATE::InterruptShadow. */
198 bool fLastInterruptShadow : 1;
199 bool afPadding[1];
200 /** Pending APIC base value.
201 * This is set to UINT64_MAX when not pending */
202 uint64_t uPendingApicBase;
203# ifdef NEM_WIN_USE_OUR_OWN_RUN_API
204 /** Pending VINF_NEM_CHANGE_PGM_MODE, VINF_NEM_FLUSH_TLB or VINF_NEM_UPDATE_APIC_BASE. */
205 int32_t rcPending;
206 /** The VID_MSHAGN_F_XXX flags.
207 * Either VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE or zero. */
208 uint32_t fHandleAndGetFlags;
209 /** What VidMessageSlotMap returns and is used for passing exit info. */
210 RTR3PTR pvMsgSlotMapping;
211# endif
212 /** The windows thread handle. */
213 RTR3PTR hNativeThreadHandle;
214 /** Parameters for making Hyper-V hypercalls. */
215 union
216 {
217 uint8_t ab[64];
218 /** Arguments for NEMR0MapPages (HvCallMapGpaPages). */
219 struct
220 {
221 RTGCPHYS GCPhysSrc;
222 RTGCPHYS GCPhysDst; /**< Same as GCPhysSrc except maybe when the A20 gate is disabled. */
223 uint32_t cPages;
224 HV_MAP_GPA_FLAGS fFlags;
225 } MapPages;
226 /** Arguments for NEMR0UnmapPages (HvCallUnmapGpaPages). */
227 struct
228 {
229 RTGCPHYS GCPhys;
230 uint32_t cPages;
231 } UnmapPages;
232 } Hypercall;
233 /** I/O control buffer, we always use this for I/O controls. */
234 union
235 {
236 uint8_t ab[64];
237 HV_PARTITION_ID idPartition;
238 HV_VP_INDEX idCpu;
239# ifdef VID_MSHAGN_F_GET_NEXT_MESSAGE
240 VID_IOCTL_INPUT_MESSAGE_SLOT_HANDLE_AND_GET_NEXT MsgSlotHandleAndGetNext;
241# endif
242 } uIoCtlBuf;
243
244 /** @name Statistics
245 * @{ */
246 STAMCOUNTER StatExitPortIo;
247 STAMCOUNTER StatExitMemUnmapped;
248 STAMCOUNTER StatExitMemIntercept;
249 STAMCOUNTER StatExitHalt;
250 STAMCOUNTER StatExitInterruptWindow;
251 STAMCOUNTER StatExitCpuId;
252 STAMCOUNTER StatExitMsr;
253 STAMCOUNTER StatExitException;
254 STAMCOUNTER StatExitUnrecoverable;
255 STAMCOUNTER StatGetMsgTimeout;
256 STAMCOUNTER StatStopCpuSuccess;
257 STAMCOUNTER StatStopCpuPending;
258 STAMCOUNTER StatCancelChangedState;
259 STAMCOUNTER StatCancelAlertedThread;
260 STAMCOUNTER StatBreakOnCancel;
261 STAMCOUNTER StatBreakOnFFPre;
262 STAMCOUNTER StatBreakOnFFPost;
263 STAMCOUNTER StatBreakOnStatus;
264 /** @} */
265#endif /* RT_OS_WINDOWS */
266} NEMCPU;
267/** Pointer to NEM VMCPU instance data. */
268typedef NEMCPU *PNEMCPU;
269
270/** NEMCPU::u32Magic value. */
271#define NEMCPU_MAGIC UINT32_C(0x4d454e20)
272/** NEMCPU::u32Magic value after termination. */
273#define NEMCPU_MAGIC_DEAD UINT32_C(0xdead2222)
274
275
276#ifdef IN_RING0
277# ifdef RT_OS_WINDOWS
278/**
279 * Windows: Hypercall input/ouput page info.
280 */
281typedef struct NEMR0HYPERCALLDATA
282{
283 /** Host physical address of the hypercall input/output page. */
284 RTHCPHYS HCPhysPage;
285 /** Pointer to the hypercall input/output page. */
286 uint8_t *pbPage;
287 /** Handle to the memory object of the hypercall input/output page. */
288 RTR0MEMOBJ hMemObj;
289} NEMR0HYPERCALLDATA;
290/** Pointer to a Windows hypercall input/output page info. */
291typedef NEMR0HYPERCALLDATA *PNEMR0HYPERCALLDATA;
292# endif /* RT_OS_WINDOWS */
293
294/**
295 * NEM GVMCPU instance data.
296 */
297typedef struct NEMR0PERVCPU
298{
299# ifdef RT_OS_WINDOWS
300 /** Hypercall input/ouput page. */
301 NEMR0HYPERCALLDATA HypercallData;
302# else
303 uint32_t uDummy;
304# endif
305} NEMR0PERVCPU;
306
307/**
308 * NEM GVM instance data.
309 */
310typedef struct NEMR0PERVM
311{
312# ifdef RT_OS_WINDOWS
313 /** The partition ID. */
314 uint64_t idHvPartition;
315 /** I/O control context. */
316 PSUPR0IOCTLCTX pIoCtlCtx;
317 /** Delta to add to convert a ring-0 pointer to a ring-3 one. */
318 uintptr_t offRing3ConversionDelta;
319 /** Info about the VidGetHvPartitionId I/O control interface. */
320 NEMWINIOCTL IoCtlGetHvPartitionId;
321 /** Info about the VidStartVirtualProcessor I/O control interface. */
322 NEMWINIOCTL IoCtlStartVirtualProcessor;
323 /** Info about the VidStopVirtualProcessor I/O control interface. */
324 NEMWINIOCTL IoCtlStopVirtualProcessor;
325 /** Info about the VidStopVirtualProcessor I/O control interface. */
326 NEMWINIOCTL IoCtlMessageSlotHandleAndGetNext;
327
328 /** Hypercall input/ouput page for non-EMT. */
329 NEMR0HYPERCALLDATA HypercallData;
330 /** Critical section protecting use of HypercallData. */
331 RTCRITSECT HypercallDataCritSect;
332
333# else
334 uint32_t uDummy;
335# endif
336} NEMR0PERVM;
337
338#endif /* IN_RING*/
339
340
341#ifdef IN_RING3
342int nemR3NativeInit(PVM pVM, bool fFallback, bool fForced);
343int nemR3NativeInitAfterCPUM(PVM pVM);
344int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
345int nemR3NativeTerm(PVM pVM);
346void nemR3NativeReset(PVM pVM);
347void nemR3NativeResetCpu(PVMCPU pVCpu, bool fInitIpi);
348VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu);
349bool nemR3NativeCanExecuteGuest(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
350bool nemR3NativeSetSingleInstruction(PVM pVM, PVMCPU pVCpu, bool fEnable);
351void nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags);
352
353int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb);
354int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2);
355int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
356int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
357int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
358void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled);
359#endif
360
361void nemHCNativeNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb);
362void nemHCNativeNotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb,
363 int fRestoreAsRAM, bool fRestoreAsRAM2);
364void nemHCNativeNotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld,
365 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM);
366int nemHCNativeNotifyPhysPageAllocated(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
367 PGMPAGETYPE enmType, uint8_t *pu2State);
368void nemHCNativeNotifyPhysPageProtChanged(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
369 PGMPAGETYPE enmType, uint8_t *pu2State);
370void nemHCNativeNotifyPhysPageChanged(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhysPrev, RTHCPHYS HCPhysNew, uint32_t fPageProt,
371 PGMPAGETYPE enmType, uint8_t *pu2State);
372
373
374#ifdef RT_OS_WINDOWS
375/** Maximum number of pages we can map in a single NEMR0MapPages call. */
376# define NEM_MAX_MAP_PAGES ((PAGE_SIZE - RT_UOFFSETOF(HV_INPUT_MAP_GPA_PAGES, PageList)) / sizeof(HV_SPA_PAGE_NUMBER))
377/** Maximum number of pages we can unmap in a single NEMR0UnmapPages call. */
378# define NEM_MAX_UNMAP_PAGES 4095
379
380#endif
381/** @} */
382
383RT_C_DECLS_END
384
385#endif
386
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