VirtualBox

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

Last change on this file since 92465 was 92465, checked in by vboxsync, 3 years ago

VMM/NEM-linux: Some more code. Got far enough to log the BIOS version to the release log. bugref:9044

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.5 KB
Line 
1/* $Id: NEMInternal.h 92465 2021-11-17 03:01:09Z vboxsync $ */
2/** @file
3 * NEM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2018-2020 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 VMM_INCLUDED_SRC_include_NEMInternal_h
19#define VMM_INCLUDED_SRC_include_NEMInternal_h
20#ifndef RT_WITHOUT_PRAGMA_ONCE
21# pragma once
22#endif
23
24#include <VBox/cdefs.h>
25#include <VBox/types.h>
26#include <VBox/vmm/nem.h>
27#include <VBox/vmm/cpum.h> /* For CPUMCPUVENDOR. */
28#include <VBox/vmm/stam.h>
29#include <VBox/vmm/vmapi.h>
30#ifdef RT_OS_WINDOWS
31#include <iprt/nt/hyperv.h>
32#include <iprt/critsect.h>
33#elif defined(RT_OS_DARWIN)
34# include "VMXInternal.h"
35#endif
36
37RT_C_DECLS_BEGIN
38
39
40/** @defgroup grp_nem_int Internal
41 * @ingroup grp_nem
42 * @internal
43 * @{
44 */
45
46#if defined(VBOX_WITH_PGM_NEM_MODE) && !defined(VBOX_WITH_NATIVE_NEM)
47# error "VBOX_WITH_PGM_NEM_MODE requires VBOX_WITH_NATIVE_NEM to be defined"
48#endif
49
50
51#ifdef RT_OS_WINDOWS
52/*
53 * Windows: Code configuration.
54 */
55# ifndef VBOX_WITH_PGM_NEM_MODE
56# define NEM_WIN_USE_HYPERCALLS_FOR_PAGES
57#endif
58//# define NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS /**< Applies to ring-3 code only. Useful for testing VID API. */
59//# define NEM_WIN_USE_OUR_OWN_RUN_API /**< Applies to ring-3 code only. Useful for testing VID API. */
60//# define NEM_WIN_WITH_RING0_RUNLOOP /**< Enables the ring-0 runloop. */
61//# define NEM_WIN_USE_RING0_RUNLOOP_BY_DEFAULT /**< For quickly testing ring-3 API without messing with CFGM. */
62# if defined(NEM_WIN_USE_OUR_OWN_RUN_API) && !defined(NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS)
63# error "NEM_WIN_USE_OUR_OWN_RUN_API requires NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS"
64# endif
65# if defined(NEM_WIN_USE_OUR_OWN_RUN_API) && !defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES)
66# error "NEM_WIN_USE_OUR_OWN_RUN_API requires NEM_WIN_USE_HYPERCALLS_FOR_PAGES"
67# endif
68# if defined(NEM_WIN_WITH_RING0_RUNLOOP) && !defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES)
69# error "NEM_WIN_WITH_RING0_RUNLOOP requires NEM_WIN_USE_HYPERCALLS_FOR_PAGES"
70# endif
71# if defined(VBOX_WITH_PGM_NEM_MODE) && defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES)
72# error "VBOX_WITH_PGM_NEM_MODE cannot be used together with NEM_WIN_USE_HYPERCALLS_FOR_PAGES"
73# endif
74
75/**
76 * Windows VID I/O control information.
77 */
78typedef struct NEMWINIOCTL
79{
80 /** The I/O control function number. */
81 uint32_t uFunction;
82 uint32_t cbInput;
83 uint32_t cbOutput;
84} NEMWINIOCTL;
85
86/** @name Windows: Our two-bit physical page state for PGMPAGE
87 * @{ */
88# define NEM_WIN_PAGE_STATE_NOT_SET 0
89# define NEM_WIN_PAGE_STATE_UNMAPPED 1
90# define NEM_WIN_PAGE_STATE_READABLE 2
91# define NEM_WIN_PAGE_STATE_WRITABLE 3
92/** @} */
93
94/** Windows: Checks if a_GCPhys is subject to the limited A20 gate emulation. */
95# define NEM_WIN_IS_SUBJECT_TO_A20(a_GCPhys) ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K)
96/** Windows: Checks if a_GCPhys is relevant to the limited A20 gate emulation. */
97# define NEM_WIN_IS_RELEVANT_TO_A20(a_GCPhys) \
98 ( ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K) || ((RTGCPHYS)(a_GCPhys) < (RTGCPHYS)_64K) )
99
100/** The CPUMCTX_EXTRN_XXX mask for IEM. */
101# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM ( IEM_CPUMCTX_EXTRN_MUST_MASK | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_INT \
102 | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_NMI )
103/** The CPUMCTX_EXTRN_XXX mask for IEM when raising exceptions. */
104# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT (IEM_CPUMCTX_EXTRN_XCPT_MASK | NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM)
105
106/** @name Windows: Interrupt window flags (NEM_WIN_INTW_F_XXX).
107 * @{ */
108# define NEM_WIN_INTW_F_NMI UINT8_C(0x01)
109# define NEM_WIN_INTW_F_REGULAR UINT8_C(0x02)
110# define NEM_WIN_INTW_F_PRIO_MASK UINT8_C(0x3c)
111# define NEM_WIN_INTW_F_PRIO_SHIFT 2
112/** @} */
113
114#endif /* RT_OS_WINDOWS */
115
116
117#ifdef RT_OS_DARWIN
118/** vCPU ID declaration to avoid dragging in HV headers here. */
119typedef unsigned hv_vcpuid_t;
120/** The HV VM memory space ID (ASID). */
121typedef unsigned hv_vm_space_t;
122
123
124/** @name Darwin: Our two-bit physical page state for PGMPAGE
125 * @{ */
126# define NEM_DARWIN_PAGE_STATE_NOT_SET 0
127# define NEM_DARWIN_PAGE_STATE_UNMAPPED 1
128# define NEM_DARWIN_PAGE_STATE_READABLE 2
129# define NEM_DARWIN_PAGE_STATE_WRITABLE 3
130/** @} */
131
132/** The CPUMCTX_EXTRN_XXX mask for IEM. */
133# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM ( IEM_CPUMCTX_EXTRN_MUST_MASK | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_INT \
134 | CPUMCTX_EXTRN_NEM_WIN_INHIBIT_NMI )
135/** The CPUMCTX_EXTRN_XXX mask for IEM when raising exceptions. */
136# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT (IEM_CPUMCTX_EXTRN_XCPT_MASK | NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM)
137
138#endif
139
140
141/** Trick to make slickedit see the static functions in the template. */
142#ifndef IN_SLICKEDIT
143# define NEM_TMPL_STATIC static
144#else
145# define NEM_TMPL_STATIC
146#endif
147
148
149/**
150 * Generic NEM exit type enumeration for use with EMHistoryAddExit.
151 *
152 * On windows we've got two different set of exit types and they are both jumping
153 * around the place value wise, so EM can use their values.
154 *
155 * @note We only have exit types for exits not covered by EM here.
156 */
157typedef enum NEMEXITTYPE
158{
159 /* windows: */
160 NEMEXITTYPE_UNRECOVERABLE_EXCEPTION = 1,
161 NEMEXITTYPE_INVALID_VP_REGISTER_VALUE,
162 NEMEXITTYPE_INTTERRUPT_WINDOW,
163 NEMEXITTYPE_HALT,
164 NEMEXITTYPE_XCPT_UD,
165 NEMEXITTYPE_XCPT_DB,
166 NEMEXITTYPE_XCPT_BP,
167 NEMEXITTYPE_CANCELED,
168 NEMEXITTYPE_MEMORY_ACCESS
169} NEMEXITTYPE;
170
171
172/**
173 * NEM VM Instance data.
174 */
175typedef struct NEM
176{
177 /** NEM_MAGIC. */
178 uint32_t u32Magic;
179
180 /** Set if enabled. */
181 bool fEnabled;
182 /** Set if long mode guests are allowed. */
183 bool fAllow64BitGuests;
184
185#if defined(RT_OS_LINUX)
186 /** The '/dev/kvm' file descriptor. */
187 int32_t fdKvm;
188 /** The KVM_CREATE_VM file descriptor. */
189 int32_t fdVm;
190
191 /** KVM_GET_VCPU_MMAP_SIZE. */
192 uint32_t cbVCpuMmap;
193 /** KVM_CAP_NR_MEMSLOTS. */
194 uint32_t cMaxMemSlots;
195 /** KVM_CAP_X86_ROBUST_SINGLESTEP. */
196 bool fRobustSingleStep;
197
198 /** Hint where there might be a free slot. */
199 uint16_t idPrevSlot;
200 /** Memory slot ID allocation bitmap. */
201 uint64_t bmSlotIds[_32K / 8 / sizeof(uint64_t)];
202
203#elif defined(RT_OS_WINDOWS)
204 /** Set if we've created the EMTs. */
205 bool fCreatedEmts : 1;
206 /** WHvRunVpExitReasonX64Cpuid is supported. */
207 bool fExtendedMsrExit : 1;
208 /** WHvRunVpExitReasonX64MsrAccess is supported. */
209 bool fExtendedCpuIdExit : 1;
210 /** WHvRunVpExitReasonException is supported. */
211 bool fExtendedXcptExit : 1;
212 /** Set if we're using the ring-0 API to do the work. */
213 bool fUseRing0Runloop : 1;
214# ifdef NEM_WIN_WITH_A20
215 /** Set if we've started more than one CPU and cannot mess with A20. */
216 bool fA20Fixed : 1;
217 /** Set if A20 is enabled. */
218 bool fA20Enabled : 1;
219# endif
220 /** The reported CPU vendor. */
221 CPUMCPUVENDOR enmCpuVendor;
222 /** Cache line flush size as a power of two. */
223 uint8_t cCacheLineFlushShift;
224 /** The result of WHvCapabilityCodeProcessorFeatures. */
225 union
226 {
227 /** 64-bit view. */
228 uint64_t u64;
229# ifdef _WINHVAPIDEFS_H_
230 /** Interpreed features. */
231 WHV_PROCESSOR_FEATURES u;
232# endif
233 } uCpuFeatures;
234
235 /** The partition handle. */
236# ifdef _WINHVAPIDEFS_H_
237 WHV_PARTITION_HANDLE
238# else
239 RTHCUINTPTR
240# endif
241 hPartition;
242 /** The device handle for the partition, for use with Vid APIs or direct I/O
243 * controls. */
244 RTR3PTR hPartitionDevice;
245 /** The Hyper-V partition ID. */
246 uint64_t idHvPartition;
247
248 /** Number of currently mapped pages. */
249 uint32_t volatile cMappedPages;
250# ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
251 /** Max number of pages we dare map at once. */
252 uint32_t cMaxMappedPages;
253# endif
254 STAMCOUNTER StatMapPage;
255 STAMCOUNTER StatUnmapPage;
256# ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
257 STAMCOUNTER StatRemapPage;
258 STAMCOUNTER StatRemapPageFailed;
259# elif !defined(VBOX_WITH_PGM_NEM_MODE)
260 STAMCOUNTER StatUnmapAllPages;
261# endif
262 STAMCOUNTER StatMapPageFailed;
263 STAMCOUNTER StatUnmapPageFailed;
264# ifdef VBOX_WITH_PGM_NEM_MODE
265 STAMPROFILE StatProfMapGpaRange;
266 STAMPROFILE StatProfUnmapGpaRange;
267# endif
268# ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
269 STAMPROFILE StatProfMapGpaRangePage;
270 STAMPROFILE StatProfUnmapGpaRangePage;
271# endif
272
273# ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
274 /** Info about the VidGetHvPartitionId I/O control interface. */
275 NEMWINIOCTL IoCtlGetHvPartitionId;
276 /** Info about the VidGetPartitionProperty I/O control interface. */
277 NEMWINIOCTL IoCtlGetPartitionProperty;
278# endif
279# ifdef NEM_WIN_WITH_RING0_RUNLOOP
280 /** Info about the VidStartVirtualProcessor I/O control interface. */
281 NEMWINIOCTL IoCtlStartVirtualProcessor;
282 /** Info about the VidStopVirtualProcessor I/O control interface. */
283 NEMWINIOCTL IoCtlStopVirtualProcessor;
284 /** Info about the VidStopVirtualProcessor I/O control interface. */
285 NEMWINIOCTL IoCtlMessageSlotHandleAndGetNext;
286# endif
287
288 /** Statistics updated by NEMR0UpdateStatistics. */
289 struct
290 {
291 uint64_t cPagesAvailable;
292 uint64_t cPagesInUse;
293 } R0Stats;
294
295#elif defined(RT_OS_DARWIN)
296 /** Set if we've created the EMTs. */
297 bool fCreatedEmts : 1;
298 /** Set if hv_vm_create() was called successfully. */
299 bool fCreatedVm : 1;
300 /** Set if hv_vm_space_create() was called successfully. */
301 bool fCreatedAsid : 1;
302 /** The ASID for this VM (only valid if fCreatedAsid is true). */
303 hv_vm_space_t uVmAsid;
304 STAMCOUNTER StatMapPage;
305 STAMCOUNTER StatUnmapPage;
306 STAMCOUNTER StatMapPageFailed;
307 STAMCOUNTER StatUnmapPageFailed;
308#endif /* RT_OS_WINDOWS */
309} NEM;
310/** Pointer to NEM VM instance data. */
311typedef NEM *PNEM;
312
313/** NEM::u32Magic value. */
314#define NEM_MAGIC UINT32_C(0x004d454e)
315/** NEM::u32Magic value after termination. */
316#define NEM_MAGIC_DEAD UINT32_C(0xdead1111)
317
318
319/**
320 * NEM VMCPU Instance data.
321 */
322typedef struct NEMCPU
323{
324 /** NEMCPU_MAGIC. */
325 uint32_t u32Magic;
326 /** Whether \#UD needs to be intercepted and presented to GIM. */
327 bool fGIMTrapXcptUD : 1;
328 /** Whether \#GP needs to be intercept for mesa driver workaround. */
329 bool fTrapXcptGpForLovelyMesaDrv: 1;
330
331#if defined(RT_OS_LINUX)
332 uint8_t abPadding[3];
333 /** The KVM VCpu file descriptor. */
334 int32_t fdVCpu;
335 /** Pointer to the KVM_RUN data exchange region. */
336 R3PTRTYPE(struct kvm_run *) pRun;
337
338 /** @name Statistics
339 * @{ */
340# if 0
341 STAMCOUNTER StatExitPortIo;
342 STAMCOUNTER StatExitMemUnmapped;
343 STAMCOUNTER StatExitMemIntercept;
344 STAMCOUNTER StatExitHalt;
345 STAMCOUNTER StatExitInterruptWindow;
346 STAMCOUNTER StatExitCpuId;
347 STAMCOUNTER StatExitMsr;
348 STAMCOUNTER StatExitException;
349 STAMCOUNTER StatExitExceptionBp;
350 STAMCOUNTER StatExitExceptionDb;
351 STAMCOUNTER StatExitExceptionGp;
352 STAMCOUNTER StatExitExceptionGpMesa;
353 STAMCOUNTER StatExitExceptionUd;
354 STAMCOUNTER StatExitExceptionUdHandled;
355 STAMCOUNTER StatExitUnrecoverable;
356 STAMCOUNTER StatGetMsgTimeout;
357 STAMCOUNTER StatStopCpuSuccess;
358 STAMCOUNTER StatStopCpuPending;
359 STAMCOUNTER StatStopCpuPendingAlerts;
360 STAMCOUNTER StatStopCpuPendingOdd;
361 STAMCOUNTER StatCancelChangedState;
362 STAMCOUNTER StatCancelAlertedThread;
363# endif
364 STAMCOUNTER StatBreakOnCancel;
365 STAMCOUNTER StatBreakOnFFPre;
366 STAMCOUNTER StatBreakOnFFPost;
367 STAMCOUNTER StatBreakOnStatus;
368 STAMCOUNTER StatImportOnDemand;
369 STAMCOUNTER StatImportOnReturn;
370 STAMCOUNTER StatImportOnReturnSkipped;
371 STAMCOUNTER StatQueryCpuTick;
372 /** @} */
373
374
375#elif defined(RT_OS_WINDOWS)
376 /** The current state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
377 uint8_t fCurrentInterruptWindows;
378 /** The desired state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
379 uint8_t fDesiredInterruptWindows;
380 /** Last copy of HV_X64_VP_EXECUTION_STATE::InterruptShadow. */
381 bool fLastInterruptShadow : 1;
382# ifdef NEM_WIN_WITH_RING0_RUNLOOP
383 /** Pending VINF_NEM_FLUSH_TLB. */
384 int32_t rcPending;
385# else
386 uint32_t uPadding;
387# endif
388 /** The VID_MSHAGN_F_XXX flags.
389 * Either VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE or zero. */
390 uint32_t fHandleAndGetFlags;
391 /** What VidMessageSlotMap returns and is used for passing exit info. */
392 RTR3PTR pvMsgSlotMapping;
393 /** The windows thread handle. */
394 RTR3PTR hNativeThreadHandle;
395 /** Parameters for making Hyper-V hypercalls. */
396 union
397 {
398 uint8_t ab[64];
399 /** Arguments for NEMR0MapPages (HvCallMapGpaPages). */
400 struct
401 {
402 RTGCPHYS GCPhysSrc;
403 RTGCPHYS GCPhysDst; /**< Same as GCPhysSrc except maybe when the A20 gate is disabled. */
404 uint32_t cPages;
405 HV_MAP_GPA_FLAGS fFlags;
406 } MapPages;
407 /** Arguments for NEMR0UnmapPages (HvCallUnmapGpaPages). */
408 struct
409 {
410 RTGCPHYS GCPhys;
411 uint32_t cPages;
412 } UnmapPages;
413 /** Result from NEMR0QueryCpuTick. */
414 struct
415 {
416 uint64_t cTicks;
417 uint32_t uAux;
418 } QueryCpuTick;
419 /** Input and output for NEMR0DoExperiment. */
420 struct
421 {
422 uint32_t uItem;
423 bool fSuccess;
424 uint64_t uStatus;
425 uint64_t uLoValue;
426 uint64_t uHiValue;
427 } Experiment;
428 } Hypercall;
429 /** I/O control buffer, we always use this for I/O controls. */
430 union
431 {
432 uint8_t ab[64];
433 HV_PARTITION_ID idPartition;
434 HV_VP_INDEX idCpu;
435 struct
436 {
437 uint64_t enmProperty;
438 uint64_t uValue;
439 } GetProp;
440# ifdef VID_MSHAGN_F_GET_NEXT_MESSAGE
441 VID_IOCTL_INPUT_MESSAGE_SLOT_HANDLE_AND_GET_NEXT MsgSlotHandleAndGetNext;
442# endif
443 } uIoCtlBuf;
444
445 /** @name Statistics
446 * @{ */
447 STAMCOUNTER StatExitPortIo;
448 STAMCOUNTER StatExitMemUnmapped;
449 STAMCOUNTER StatExitMemIntercept;
450 STAMCOUNTER StatExitHalt;
451 STAMCOUNTER StatExitInterruptWindow;
452 STAMCOUNTER StatExitCpuId;
453 STAMCOUNTER StatExitMsr;
454 STAMCOUNTER StatExitException;
455 STAMCOUNTER StatExitExceptionBp;
456 STAMCOUNTER StatExitExceptionDb;
457 STAMCOUNTER StatExitExceptionGp;
458 STAMCOUNTER StatExitExceptionGpMesa;
459 STAMCOUNTER StatExitExceptionUd;
460 STAMCOUNTER StatExitExceptionUdHandled;
461 STAMCOUNTER StatExitUnrecoverable;
462 STAMCOUNTER StatGetMsgTimeout;
463 STAMCOUNTER StatStopCpuSuccess;
464 STAMCOUNTER StatStopCpuPending;
465 STAMCOUNTER StatStopCpuPendingAlerts;
466 STAMCOUNTER StatStopCpuPendingOdd;
467 STAMCOUNTER StatCancelChangedState;
468 STAMCOUNTER StatCancelAlertedThread;
469 STAMCOUNTER StatBreakOnCancel;
470 STAMCOUNTER StatBreakOnFFPre;
471 STAMCOUNTER StatBreakOnFFPost;
472 STAMCOUNTER StatBreakOnStatus;
473 STAMCOUNTER StatImportOnDemand;
474 STAMCOUNTER StatImportOnReturn;
475 STAMCOUNTER StatImportOnReturnSkipped;
476 STAMCOUNTER StatQueryCpuTick;
477 /** @} */
478
479#elif defined(RT_OS_DARWIN)
480 /** The vCPU handle associated with the EMT executing this vCPU. */
481 hv_vcpuid_t hVCpuId;
482
483 /** @name State shared with the VT-x code.
484 * @{ */
485 /** Whether we should use the debug loop because of single stepping or special
486 * debug breakpoints / events are armed. */
487 bool fUseDebugLoop;
488 /** Whether we're executing a single instruction. */
489 bool fSingleInstruction;
490
491 bool afAlignment0[2];
492
493 /** An additional error code used for some gurus. */
494 uint32_t u32HMError;
495 /** The last exit-to-ring-3 reason. */
496 int32_t rcLastExitToR3;
497 /** CPU-context changed flags (see HM_CHANGED_xxx). */
498 uint64_t fCtxChanged;
499
500 /** The guest VMCS information. */
501 VMXVMCSINFO VmcsInfo;
502
503 /** VT-x data. */
504 struct HMCPUVMX
505 {
506 /** @name Guest information.
507 * @{ */
508 /** Guest VMCS information shared with ring-3. */
509 VMXVMCSINFOSHARED VmcsInfo;
510 /** Nested-guest VMCS information shared with ring-3. */
511 VMXVMCSINFOSHARED VmcsInfoNstGst;
512 /** Whether the nested-guest VMCS was the last current VMCS (shadow copy for ring-3).
513 * @see HMR0PERVCPU::vmx.fSwitchedToNstGstVmcs */
514 bool fSwitchedToNstGstVmcsCopyForRing3;
515 /** Whether the static guest VMCS controls has been merged with the
516 * nested-guest VMCS controls. */
517 bool fMergedNstGstCtls;
518 /** Whether the nested-guest VMCS has been copied to the shadow VMCS. */
519 bool fCopiedNstGstToShadowVmcs;
520 /** Whether flushing the TLB is required due to switching to/from the
521 * nested-guest. */
522 bool fSwitchedNstGstFlushTlb;
523 /** Alignment. */
524 bool afAlignment0[4];
525 /** Cached guest APIC-base MSR for identifying when to map the APIC-access page. */
526 uint64_t u64GstMsrApicBase;
527 /** @} */
528
529 /** @name Error reporting and diagnostics.
530 * @{ */
531 /** VT-x error-reporting (mainly for ring-3 propagation). */
532 struct
533 {
534 RTCPUID idCurrentCpu;
535 RTCPUID idEnteredCpu;
536 RTHCPHYS HCPhysCurrentVmcs;
537 uint32_t u32VmcsRev;
538 uint32_t u32InstrError;
539 uint32_t u32ExitReason;
540 uint32_t u32GuestIntrState;
541 } LastError;
542 /** @} */
543 } vmx;
544
545 /** Event injection state. */
546 HMEVENT Event;
547
548 /** Current shadow paging mode for updating CR4.
549 * @todo move later (@bugref{9217}). */
550 PGMMODE enmShadowMode;
551 uint32_t u32TemporaryPadding;
552
553 /** The PAE PDPEs used with Nested Paging (only valid when
554 * VMCPU_FF_HM_UPDATE_PAE_PDPES is set). */
555 X86PDPE aPdpes[4];
556 /** Pointer to the VMX statistics. */
557 PVMXSTATISTICS pVmxStats;
558
559 /** @name Statistics
560 * @{ */
561 STAMCOUNTER StatBreakOnCancel;
562 STAMCOUNTER StatBreakOnFFPre;
563 STAMCOUNTER StatBreakOnFFPost;
564 STAMCOUNTER StatBreakOnStatus;
565 STAMCOUNTER StatImportOnDemand;
566 STAMCOUNTER StatImportOnReturn;
567 STAMCOUNTER StatImportOnReturnSkipped;
568 STAMCOUNTER StatQueryCpuTick;
569 /** @} */
570
571 /** @} */
572#endif /* RT_OS_DARWIN */
573} NEMCPU;
574/** Pointer to NEM VMCPU instance data. */
575typedef NEMCPU *PNEMCPU;
576
577/** NEMCPU::u32Magic value. */
578#define NEMCPU_MAGIC UINT32_C(0x4d454e20)
579/** NEMCPU::u32Magic value after termination. */
580#define NEMCPU_MAGIC_DEAD UINT32_C(0xdead2222)
581
582
583#ifdef IN_RING0
584# ifdef RT_OS_WINDOWS
585/**
586 * Windows: Hypercall input/ouput page info.
587 */
588typedef struct NEMR0HYPERCALLDATA
589{
590 /** Host physical address of the hypercall input/output page. */
591 RTHCPHYS HCPhysPage;
592 /** Pointer to the hypercall input/output page. */
593 uint8_t *pbPage;
594 /** Handle to the memory object of the hypercall input/output page. */
595 RTR0MEMOBJ hMemObj;
596} NEMR0HYPERCALLDATA;
597/** Pointer to a Windows hypercall input/output page info. */
598typedef NEMR0HYPERCALLDATA *PNEMR0HYPERCALLDATA;
599# endif /* RT_OS_WINDOWS */
600
601/**
602 * NEM GVMCPU instance data.
603 */
604typedef struct NEMR0PERVCPU
605{
606# if defined(RT_OS_WINDOWS) && defined(NEM_WIN_USE_HYPERCALLS_FOR_PAGES)
607 /** Hypercall input/ouput page. */
608 NEMR0HYPERCALLDATA HypercallData;
609 /** Delta to add to convert a ring-0 pointer to a ring-3 one. */
610 uintptr_t offRing3ConversionDelta;
611# else
612 uint32_t uDummy;
613# endif
614} NEMR0PERVCPU;
615
616/**
617 * NEM GVM instance data.
618 */
619typedef struct NEMR0PERVM
620{
621# ifdef RT_OS_WINDOWS
622# ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
623 /** The partition ID. */
624 uint64_t idHvPartition;
625 /** I/O control context. */
626 PSUPR0IOCTLCTX pIoCtlCtx;
627 /** Info about the VidGetHvPartitionId I/O control interface. */
628 NEMWINIOCTL IoCtlGetHvPartitionId;
629 /** Info about the VidGetPartitionProperty I/O control interface. */
630 NEMWINIOCTL IoCtlGetPartitionProperty;
631# endif
632# ifdef NEM_WIN_WITH_RING0_RUNLOOP
633 /** Info about the VidStartVirtualProcessor I/O control interface. */
634 NEMWINIOCTL IoCtlStartVirtualProcessor;
635 /** Info about the VidStopVirtualProcessor I/O control interface. */
636 NEMWINIOCTL IoCtlStopVirtualProcessor;
637 /** Info about the VidStopVirtualProcessor I/O control interface. */
638 NEMWINIOCTL IoCtlMessageSlotHandleAndGetNext;
639 /** Whether we may use the ring-0 runloop or not. */
640 bool fMayUseRing0Runloop;
641# endif
642
643# ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
644 /** Hypercall input/ouput page for non-EMT. */
645 NEMR0HYPERCALLDATA HypercallData;
646 /** Critical section protecting use of HypercallData. */
647 RTCRITSECT HypercallDataCritSect;
648# endif
649
650# else
651 uint32_t uDummy;
652# endif
653} NEMR0PERVM;
654
655#endif /* IN_RING*/
656
657
658#ifdef IN_RING3
659int nemR3NativeInit(PVM pVM, bool fFallback, bool fForced);
660int nemR3NativeInitAfterCPUM(PVM pVM);
661int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
662int nemR3NativeTerm(PVM pVM);
663void nemR3NativeReset(PVM pVM);
664void nemR3NativeResetCpu(PVMCPU pVCpu, bool fInitIpi);
665VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu);
666bool nemR3NativeCanExecuteGuest(PVM pVM, PVMCPU pVCpu);
667bool nemR3NativeSetSingleInstruction(PVM pVM, PVMCPU pVCpu, bool fEnable);
668void nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags);
669#endif
670
671void nemHCNativeNotifyHandlerPhysicalRegister(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb);
672void nemHCNativeNotifyHandlerPhysicalModify(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld,
673 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM);
674int nemHCNativeNotifyPhysPageAllocated(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
675 PGMPAGETYPE enmType, uint8_t *pu2State);
676
677
678#ifdef RT_OS_WINDOWS
679/** Maximum number of pages we can map in a single NEMR0MapPages call. */
680# define NEM_MAX_MAP_PAGES ((PAGE_SIZE - RT_UOFFSETOF(HV_INPUT_MAP_GPA_PAGES, PageList)) / sizeof(HV_SPA_PAGE_NUMBER))
681/** Maximum number of pages we can unmap in a single NEMR0UnmapPages call. */
682# define NEM_MAX_UNMAP_PAGES 4095
683
684#endif
685/** @} */
686
687RT_C_DECLS_END
688
689#endif /* !VMM_INCLUDED_SRC_include_NEMInternal_h */
690
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