VirtualBox

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

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

NEM: Inject interrupts from the inner NEM loop, use interrupt windows. bugref:9044

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.7 KB
Line 
1/* $Id: NEMInternal.h 72207 2018-05-14 19:16:43Z 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#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/** The CPUMCTX_EXTRN_XXX mask for IEM. */
78# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM (CPUMCTX_EXTRN_ALL | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_INT | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_NMI)
79
80/** @name Windows: Interrupt window flags (NEM_WIN_INTW_F_XXX).
81 * @{ */
82# define NEM_WIN_INTW_F_NMI UINT8_C(0x01)
83# define NEM_WIN_INTW_F_REGULAR UINT8_C(0x02)
84# define NEM_WIN_INTW_F_PRIO_MASK UINT8_C(0x3c)
85# define NEM_WIN_INTW_F_PRIO_SHIFT 2
86/** @} */
87
88#endif /* RT_OS_WINDOWS */
89
90
91/** Trick to make slickedit see the static functions in the template. */
92#ifndef IN_SLICKEDIT
93# define NEM_TMPL_STATIC static
94#else
95# define NEM_TMPL_STATIC
96#endif
97
98
99/**
100 * NEM VM Instance data.
101 */
102typedef struct NEM
103{
104 /** NEM_MAGIC. */
105 uint32_t u32Magic;
106
107 /** Set if enabled. */
108 bool fEnabled;
109#ifdef RT_OS_WINDOWS
110 /** Set if we've created the EMTs. */
111 bool fCreatedEmts : 1;
112 /** WHvRunVpExitReasonX64Cpuid is supported. */
113 bool fExtendedMsrExit : 1;
114 /** WHvRunVpExitReasonX64MsrAccess is supported. */
115 bool fExtendedCpuIdExit : 1;
116 /** WHvRunVpExitReasonException is supported. */
117 bool fExtendedXcptExit : 1;
118 /** Set if we've started more than one CPU and cannot mess with A20. */
119 bool fA20Fixed : 1;
120 /** Set if A20 is enabled. */
121 bool fA20Enabled : 1;
122 /** The reported CPU vendor. */
123 CPUMCPUVENDOR enmCpuVendor;
124 /** Cache line flush size as a power of two. */
125 uint8_t cCacheLineFlushShift;
126 /** The result of WHvCapabilityCodeProcessorFeatures. */
127 union
128 {
129 /** 64-bit view. */
130 uint64_t u64;
131# ifdef _WINHVAPIDEFS_H_
132 /** Interpreed features. */
133 WHV_PROCESSOR_FEATURES u;
134# endif
135 } uCpuFeatures;
136
137 /** The partition handle. */
138# ifdef _WINHVAPIDEFS_H_
139 WHV_PARTITION_HANDLE
140# else
141 RTHCUINTPTR
142# endif
143 hPartition;
144 /** The device handle for the partition, for use with Vid APIs or direct I/O
145 * controls. */
146 RTR3PTR hPartitionDevice;
147 /** The Hyper-V partition ID. */
148 uint64_t idHvPartition;
149
150 /** Number of currently mapped pages. */
151 uint32_t volatile cMappedPages;
152
153 /** Info about the VidGetHvPartitionId I/O control interface. */
154 NEMWINIOCTL IoCtlGetHvPartitionId;
155 /** Info about the VidStartVirtualProcessor I/O control interface. */
156 NEMWINIOCTL IoCtlStartVirtualProcessor;
157 /** Info about the VidStopVirtualProcessor I/O control interface. */
158 NEMWINIOCTL IoCtlStopVirtualProcessor;
159 /** Info about the VidStopVirtualProcessor I/O control interface. */
160 NEMWINIOCTL IoCtlMessageSlotHandleAndGetNext;
161
162#endif /* RT_OS_WINDOWS */
163} NEM;
164/** Pointer to NEM VM instance data. */
165typedef NEM *PNEM;
166
167/** NEM::u32Magic value. */
168#define NEM_MAGIC UINT32_C(0x004d454e)
169/** NEM::u32Magic value after termination. */
170#define NEM_MAGIC_DEAD UINT32_C(0xdead1111)
171
172
173/**
174 * NEM VMCPU Instance data.
175 */
176typedef struct NEMCPU
177{
178 /** NEMCPU_MAGIC. */
179 uint32_t u32Magic;
180#ifdef RT_OS_WINDOWS
181 /** The current state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
182 uint8_t fCurrentInterruptWindows;
183 /** The desired state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
184 uint8_t fDesiredInterruptWindows;
185 /** Last copy of HV_X64_VP_EXECUTION_STATE::InterruptShadow. */
186 bool fLastInterruptShadow : 1;
187 bool afPadding[1];
188# ifdef NEM_WIN_USE_OUR_OWN_RUN_API
189 /** Pending VERR_NEM_CHANGE_PGM_MODE or VERR_NEM_FLUSH_TLB. */
190 int32_t rcPgmPending;
191 /** The VID_MSHAGN_F_XXX flags.
192 * Either VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE or zero. */
193 uint32_t fHandleAndGetFlags;
194 /** What VidMessageSlotMap returns and is used for passing exit info. */
195 RTR3PTR pvMsgSlotMapping;
196# endif
197 /** The windows thread handle. */
198 RTR3PTR hNativeThreadHandle;
199 /** Parameters for making Hyper-V hypercalls. */
200 union
201 {
202 uint8_t ab[64];
203 /** Arguments for NEMR0MapPages (HvCallMapGpaPages). */
204 struct
205 {
206 RTGCPHYS GCPhysSrc;
207 RTGCPHYS GCPhysDst; /**< Same as GCPhysSrc except maybe when the A20 gate is disabled. */
208 uint32_t cPages;
209 HV_MAP_GPA_FLAGS fFlags;
210 } MapPages;
211 /** Arguments for NEMR0UnmapPages (HvCallUnmapGpaPages). */
212 struct
213 {
214 RTGCPHYS GCPhys;
215 uint32_t cPages;
216 } UnmapPages;
217 } Hypercall;
218 /** I/O control buffer, we always use this for I/O controls. */
219 union
220 {
221 uint8_t ab[64];
222 HV_PARTITION_ID idPartition;
223 HV_VP_INDEX idCpu;
224# ifdef VID_MSHAGN_F_GET_NEXT_MESSAGE
225 VID_IOCTL_INPUT_MESSAGE_SLOT_HANDLE_AND_GET_NEXT MsgSlotHandleAndGetNext;
226# endif
227 } uIoCtlBuf;
228
229 /** @name Statistics
230 * @{ */
231 STAMCOUNTER StatExitPortIo;
232 STAMCOUNTER StatExitMemUnmapped;
233 STAMCOUNTER StatExitMemIntercept;
234 STAMCOUNTER StatExitHalt;
235 STAMCOUNTER StatExitInterruptWindow;
236 STAMCOUNTER StatGetMsgTimeout;
237 STAMCOUNTER StatStopCpuSuccess;
238 STAMCOUNTER StatStopCpuPending;
239 STAMCOUNTER StatCancelChangedState;
240 STAMCOUNTER StatCancelAlertedThread;
241 STAMCOUNTER StatBreakOnCancel;
242 STAMCOUNTER StatBreakOnFFPre;
243 STAMCOUNTER StatBreakOnFFPost;
244 STAMCOUNTER StatBreakOnStatus;
245 /** @} */
246#endif
247} NEMCPU;
248/** Pointer to NEM VMCPU instance data. */
249typedef NEMCPU *PNEMCPU;
250
251/** NEMCPU::u32Magic value. */
252#define NEMCPU_MAGIC UINT32_C(0x4d454e20)
253/** NEMCPU::u32Magic value after termination. */
254#define NEMCPU_MAGIC_DEAD UINT32_C(0xdead2222)
255
256
257#ifdef IN_RING0
258
259/**
260 * NEM GVMCPU instance data.
261 */
262typedef struct NEMR0PERVCPU
263{
264# ifdef RT_OS_WINDOWS
265 /** @name Hypercall input/ouput page.
266 * @{ */
267 /** Host physical address of the hypercall input/output page. */
268 RTHCPHYS HCPhysHypercallData;
269 /** Pointer to the hypercall input/output page. */
270 uint8_t *pbHypercallData;
271 /** Handle to the memory object of the hypercall input/output page. */
272 RTR0MEMOBJ hHypercallDataMemObj;
273 /** @} */
274# else
275 uint32_t uDummy;
276# endif
277} NEMR0PERVCPU;
278
279/**
280 * NEM GVM instance data.
281 */
282typedef struct NEMR0PERVM
283{
284# ifdef RT_OS_WINDOWS
285 /** The partition ID. */
286 uint64_t idHvPartition;
287 /** I/O control context. */
288 PSUPR0IOCTLCTX pIoCtlCtx;
289 /** Delta to add to convert a ring-0 pointer to a ring-3 one. */
290 uintptr_t offRing3ConversionDelta;
291 /** Info about the VidGetHvPartitionId I/O control interface. */
292 NEMWINIOCTL IoCtlGetHvPartitionId;
293 /** Info about the VidStartVirtualProcessor I/O control interface. */
294 NEMWINIOCTL IoCtlStartVirtualProcessor;
295 /** Info about the VidStopVirtualProcessor I/O control interface. */
296 NEMWINIOCTL IoCtlStopVirtualProcessor;
297 /** Info about the VidStopVirtualProcessor I/O control interface. */
298 NEMWINIOCTL IoCtlMessageSlotHandleAndGetNext;
299
300# else
301 uint32_t uDummy;
302# endif
303} NEMR0PERVM;
304
305#endif /* IN_RING*/
306
307
308#ifdef IN_RING3
309int nemR3NativeInit(PVM pVM, bool fFallback, bool fForced);
310int nemR3NativeInitAfterCPUM(PVM pVM);
311int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
312int nemR3NativeTerm(PVM pVM);
313void nemR3NativeReset(PVM pVM);
314void nemR3NativeResetCpu(PVMCPU pVCpu, bool fInitIpi);
315VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu);
316bool nemR3NativeCanExecuteGuest(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx);
317bool nemR3NativeSetSingleInstruction(PVM pVM, PVMCPU pVCpu, bool fEnable);
318void nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags);
319
320int nemR3NativeNotifyPhysRamRegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb);
321int nemR3NativeNotifyPhysMmioExMap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags, void *pvMmio2);
322int nemR3NativeNotifyPhysMmioExUnmap(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
323int nemR3NativeNotifyPhysRomRegisterEarly(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
324int nemR3NativeNotifyPhysRomRegisterLate(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, uint32_t fFlags);
325void nemR3NativeNotifySetA20(PVMCPU pVCpu, bool fEnabled);
326#endif
327
328void nemHCNativeNotifyHandlerPhysicalRegister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb);
329void nemHCNativeNotifyHandlerPhysicalDeregister(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb,
330 int fRestoreAsRAM, bool fRestoreAsRAM2);
331void nemHCNativeNotifyHandlerPhysicalModify(PVM pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld,
332 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM);
333int nemHCNativeNotifyPhysPageAllocated(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
334 PGMPAGETYPE enmType, uint8_t *pu2State);
335void nemHCNativeNotifyPhysPageProtChanged(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
336 PGMPAGETYPE enmType, uint8_t *pu2State);
337void nemHCNativeNotifyPhysPageChanged(PVM pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhysPrev, RTHCPHYS HCPhysNew, uint32_t fPageProt,
338 PGMPAGETYPE enmType, uint8_t *pu2State);
339
340
341#ifdef RT_OS_WINDOWS
342/** Maximum number of pages we can map in a single NEMR0MapPages call. */
343# define NEM_MAX_MAP_PAGES ((PAGE_SIZE - RT_UOFFSETOF(HV_INPUT_MAP_GPA_PAGES, PageList)) / sizeof(HV_SPA_PAGE_NUMBER))
344/** Maximum number of pages we can unmap in a single NEMR0UnmapPages call. */
345# define NEM_MAX_UNMAP_PAGES 4095
346
347#endif
348/** @} */
349
350RT_C_DECLS_END
351
352#endif
353
Note: See TracBrowser for help on using the repository browser.

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