VirtualBox

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

Last change on this file since 100708 was 100708, checked in by vboxsync, 16 months ago

VMM/NEMR3Native-darwin-armv8.cpp: Query ID registers and put them in a struct for passing it down to CPUM later on (ID registers are privileged and only accessible from EL1 popposed to the CPUID mechanism on x86, so they need support from the hypervisor interface), bugref:10390

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 27.1 KB
Line 
1/* $Id: NEMInternal.h 100708 2023-07-26 13:16:19Z vboxsync $ */
2/** @file
3 * NEM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2018-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28#ifndef VMM_INCLUDED_SRC_include_NEMInternal_h
29#define VMM_INCLUDED_SRC_include_NEMInternal_h
30#ifndef RT_WITHOUT_PRAGMA_ONCE
31# pragma once
32#endif
33
34#include <VBox/cdefs.h>
35#include <VBox/types.h>
36#include <VBox/vmm/nem.h>
37#include <VBox/vmm/cpum.h> /* For CPUMCPUVENDOR. */
38#include <VBox/vmm/stam.h>
39#include <VBox/vmm/vmapi.h>
40#ifdef RT_OS_WINDOWS
41#include <iprt/nt/hyperv.h>
42#include <iprt/critsect.h>
43#elif defined(RT_OS_DARWIN)
44# if defined(VBOX_VMM_TARGET_ARMV8)
45# include <Hypervisor/Hypervisor.h>
46# else
47# include "VMXInternal.h"
48# endif
49#endif
50
51RT_C_DECLS_BEGIN
52
53
54/** @defgroup grp_nem_int Internal
55 * @ingroup grp_nem
56 * @internal
57 * @{
58 */
59
60#if defined(VBOX_WITH_NATIVE_NEM) && !defined(VBOX_WITH_PGM_NEM_MODE)
61# error "VBOX_WITH_NATIVE_NEM requires VBOX_WITH_PGM_NEM_MODE to be defined"
62#endif
63
64
65#ifdef RT_OS_WINDOWS
66/*
67 * Windows: Code configuration.
68 */
69/* nothing at the moment */
70
71/**
72 * Windows VID I/O control information.
73 */
74typedef struct NEMWINIOCTL
75{
76 /** The I/O control function number. */
77 uint32_t uFunction;
78 uint32_t cbInput;
79 uint32_t cbOutput;
80} NEMWINIOCTL;
81
82/** @name Windows: Our two-bit physical page state for PGMPAGE
83 * @{ */
84# define NEM_WIN_PAGE_STATE_NOT_SET 0
85# define NEM_WIN_PAGE_STATE_UNMAPPED 1
86# define NEM_WIN_PAGE_STATE_READABLE 2
87# define NEM_WIN_PAGE_STATE_WRITABLE 3
88/** @} */
89
90/** Windows: Checks if a_GCPhys is subject to the limited A20 gate emulation. */
91# define NEM_WIN_IS_SUBJECT_TO_A20(a_GCPhys) ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K)
92/** Windows: Checks if a_GCPhys is relevant to the limited A20 gate emulation. */
93# define NEM_WIN_IS_RELEVANT_TO_A20(a_GCPhys) \
94 ( ((RTGCPHYS)((a_GCPhys) - _1M) < (RTGCPHYS)_64K) || ((RTGCPHYS)(a_GCPhys) < (RTGCPHYS)_64K) )
95
96/** The CPUMCTX_EXTRN_XXX mask for IEM. */
97# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM ( IEM_CPUMCTX_EXTRN_MUST_MASK | CPUMCTX_EXTRN_INHIBIT_INT \
98 | CPUMCTX_EXTRN_INHIBIT_NMI )
99/** The CPUMCTX_EXTRN_XXX mask for IEM when raising exceptions. */
100# define NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT (IEM_CPUMCTX_EXTRN_XCPT_MASK | NEM_WIN_CPUMCTX_EXTRN_MASK_FOR_IEM)
101
102/** @name Windows: Interrupt window flags (NEM_WIN_INTW_F_XXX).
103 * @{ */
104# define NEM_WIN_INTW_F_NMI UINT8_C(0x01)
105# define NEM_WIN_INTW_F_REGULAR UINT8_C(0x02)
106# define NEM_WIN_INTW_F_PRIO_MASK UINT8_C(0x3c)
107# define NEM_WIN_INTW_F_PRIO_SHIFT 2
108/** @} */
109
110#endif /* RT_OS_WINDOWS */
111
112
113#ifdef RT_OS_DARWIN
114# if !defined(VBOX_VMM_TARGET_ARMV8)
115/** vCPU ID declaration to avoid dragging in HV headers here. */
116typedef unsigned hv_vcpuid_t;
117/** The HV VM memory space ID (ASID). */
118typedef unsigned hv_vm_space_t;
119# endif
120
121
122/** @name Darwin: Our two-bit physical page state for PGMPAGE
123 * @{ */
124# define NEM_DARWIN_PAGE_STATE_UNMAPPED 0
125# define NEM_DARWIN_PAGE_STATE_RX 1
126# define NEM_DARWIN_PAGE_STATE_RW 2
127# define NEM_DARWIN_PAGE_STATE_RWX 3
128/** @} */
129
130# if defined(VBOX_VMM_TARGET_ARMV8)
131/** The CPUMCTX_EXTRN_XXX mask for IEM. */
132# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM ( IEM_CPUMCTX_EXTRN_MUST_MASK )
133# else
134/** The CPUMCTX_EXTRN_XXX mask for IEM. */
135# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM ( IEM_CPUMCTX_EXTRN_MUST_MASK | CPUMCTX_EXTRN_INHIBIT_INT \
136 | CPUMCTX_EXTRN_INHIBIT_NMI )
137#endif
138
139/** The CPUMCTX_EXTRN_XXX mask for IEM when raising exceptions. */
140# define NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM_XCPT (IEM_CPUMCTX_EXTRN_XCPT_MASK | NEM_DARWIN_CPUMCTX_EXTRN_MASK_FOR_IEM)
141
142
143# if defined(VBOX_VMM_TARGET_ARMV8)
144/**
145 * MMIO2 tracking region.
146 */
147typedef struct
148{
149 /* Start of the region. */
150 RTGCPHYS GCPhysStart;
151 /** End of the region. */
152 RTGCPHYS GCPhysLast;
153 /** Whether the region was accessed since last time. */
154 bool fDirty;
155} NEMHVMMIO2REGION;
156/** Pointer to a MMIO2 tracking region. */
157typedef NEMHVMMIO2REGION *PNEMHVMMIO2REGION;
158
159/**
160 * Hypervisor.framework ARMv8 ID registers.
161 */
162typedef struct HVIDREGS
163{
164 uint64_t u64IdDfReg0El1;
165 uint64_t u64IdDfReg1El1;
166 uint64_t u64IdIsaReg0El1;
167 uint64_t u64IdIsaReg1El1;
168 uint64_t u64IdMmfReg0El1;
169 uint64_t u64IdMmfReg1El1;
170 uint64_t u64IdPfReg0El1;
171 uint64_t u64IdPfReg1El1;
172 uint64_t u64ClidrEl1;
173 uint64_t u64CtrEl0;
174 uint64_t u64DczidEl1;
175} HVIDREGS;
176/** Pointer to the ID registers struct. */
177typedef HVIDREGS *PHVIDREGS;
178/** Pointer to the const ID registers struct. */
179typedef const HVIDREGS *PCHVIDREGS;
180# endif
181
182#endif
183
184
185/** Trick to make slickedit see the static functions in the template. */
186#ifndef IN_SLICKEDIT
187# define NEM_TMPL_STATIC static
188#else
189# define NEM_TMPL_STATIC
190#endif
191
192
193/**
194 * Generic NEM exit type enumeration for use with EMHistoryAddExit.
195 *
196 * On windows we've got two different set of exit types and they are both jumping
197 * around the place value wise, so EM can use their values.
198 *
199 * @note We only have exit types for exits not covered by EM here.
200 */
201typedef enum NEMEXITTYPE
202{
203 NEMEXITTYPE_INVALID = 0,
204
205 /* Common: */
206 NEMEXITTYPE_INTTERRUPT_WINDOW,
207 NEMEXITTYPE_HALT,
208
209 /* Windows: */
210 NEMEXITTYPE_UNRECOVERABLE_EXCEPTION,
211 NEMEXITTYPE_INVALID_VP_REGISTER_VALUE,
212 NEMEXITTYPE_XCPT_UD,
213 NEMEXITTYPE_XCPT_DB,
214 NEMEXITTYPE_XCPT_BP,
215 NEMEXITTYPE_CANCELED,
216 NEMEXITTYPE_MEMORY_ACCESS,
217
218 /* Linux: */
219 NEMEXITTYPE_INTERNAL_ERROR_EMULATION,
220 NEMEXITTYPE_INTERNAL_ERROR_FATAL,
221 NEMEXITTYPE_INTERRUPTED,
222 NEMEXITTYPE_FAILED_ENTRY,
223
224 /* End of valid types. */
225 NEMEXITTYPE_END
226} NEMEXITTYPE;
227
228
229/**
230 * NEM VM Instance data.
231 */
232typedef struct NEM
233{
234 /** NEM_MAGIC. */
235 uint32_t u32Magic;
236
237 /** Set if enabled. */
238 bool fEnabled;
239 /** Set if long mode guests are allowed. */
240 bool fAllow64BitGuests;
241 /** Set when the debug facility has breakpoints/events enabled that requires
242 * us to use the debug execution loop. */
243 bool fUseDebugLoop;
244
245#if defined(RT_OS_LINUX)
246 /** The '/dev/kvm' file descriptor. */
247 int32_t fdKvm;
248 /** The KVM_CREATE_VM file descriptor. */
249 int32_t fdVm;
250
251 /** KVM_GET_VCPU_MMAP_SIZE. */
252 uint32_t cbVCpuMmap;
253 /** KVM_CAP_NR_MEMSLOTS. */
254 uint32_t cMaxMemSlots;
255 /** KVM_CAP_X86_ROBUST_SINGLESTEP. */
256 bool fRobustSingleStep;
257
258 /** Hint where there might be a free slot. */
259 uint16_t idPrevSlot;
260 /** Memory slot ID allocation bitmap. */
261 uint64_t bmSlotIds[_32K / 8 / sizeof(uint64_t)];
262
263#elif defined(RT_OS_WINDOWS)
264 /** Set if we've created the EMTs. */
265 bool fCreatedEmts : 1;
266 /** WHvRunVpExitReasonX64Cpuid is supported. */
267 bool fExtendedMsrExit : 1;
268 /** WHvRunVpExitReasonX64MsrAccess is supported. */
269 bool fExtendedCpuIdExit : 1;
270 /** WHvRunVpExitReasonException is supported. */
271 bool fExtendedXcptExit : 1;
272# ifdef NEM_WIN_WITH_A20
273 /** Set if we've started more than one CPU and cannot mess with A20. */
274 bool fA20Fixed : 1;
275 /** Set if A20 is enabled. */
276 bool fA20Enabled : 1;
277# endif
278 /** The reported CPU vendor. */
279 CPUMCPUVENDOR enmCpuVendor;
280 /** Cache line flush size as a power of two. */
281 uint8_t cCacheLineFlushShift;
282 /** The result of WHvCapabilityCodeProcessorFeatures. */
283 union
284 {
285 /** 64-bit view. */
286 uint64_t u64;
287# ifdef _WINHVAPIDEFS_H_
288 /** Interpreed features. */
289 WHV_PROCESSOR_FEATURES u;
290# endif
291 } uCpuFeatures;
292
293 /** The partition handle. */
294# ifdef _WINHVAPIDEFS_H_
295 WHV_PARTITION_HANDLE
296# else
297 RTHCUINTPTR
298# endif
299 hPartition;
300 /** The device handle for the partition, for use with Vid APIs or direct I/O
301 * controls. */
302 RTR3PTR hPartitionDevice;
303
304 /** Number of currently mapped pages. */
305 uint32_t volatile cMappedPages;
306 uint32_t u32Padding;
307 STAMCOUNTER StatMapPage;
308 STAMCOUNTER StatUnmapPage;
309 STAMCOUNTER StatMapPageFailed;
310 STAMCOUNTER StatUnmapPageFailed;
311 STAMPROFILE StatProfMapGpaRange;
312 STAMPROFILE StatProfUnmapGpaRange;
313 STAMPROFILE StatProfMapGpaRangePage;
314 STAMPROFILE StatProfUnmapGpaRangePage;
315
316 /** Statistics updated by NEMR0UpdateStatistics. */
317 struct
318 {
319 uint64_t cPagesAvailable;
320 uint64_t cPagesInUse;
321 } R0Stats;
322
323#elif defined(RT_OS_DARWIN)
324 /** Set if we've created the EMTs. */
325 bool fCreatedEmts : 1;
326 /** Set if hv_vm_create() was called successfully. */
327 bool fCreatedVm : 1;
328# if defined(VBOX_VMM_TARGET_ARMV8)
329 /** @name vTimer related state.
330 * @{ */
331 /** The counter frequency in Hz as obtained from CNTFRQ_EL0. */
332 uint64_t u64CntFrqHz;
333 /** The vTimer offset programmed. */
334 uint64_t u64VTimerOff;
335 /** Dirty tracking slots. */
336 NEMHVMMIO2REGION aMmio2DirtyTracking[8];
337 /** The vCPU config. */
338 hv_vcpu_config_t hVCpuCfg;
339 /** The ID registers. */
340 HVIDREGS IdRegs;
341 /** @} */
342# else
343 /** Set if hv_vm_space_create() was called successfully. */
344 bool fCreatedAsid : 1;
345 /** Set if Last Branch Record (LBR) is enabled. */
346 bool fLbr;
347 /** The ASID for this VM (only valid if fCreatedAsid is true). */
348 hv_vm_space_t uVmAsid;
349 /** Number of mach time units per NS, for hv_vcpu_run_until(). */
350 uint64_t cMachTimePerNs;
351 /** Pause-loop exiting (PLE) gap in ticks. */
352 uint32_t cPleGapTicks;
353 /** Pause-loop exiting (PLE) window in ticks. */
354 uint32_t cPleWindowTicks;
355
356 /** The host LBR TOS (top-of-stack) MSR id. */
357 uint32_t idLbrTosMsr;
358 /** The host LBR select MSR id. */
359 uint32_t idLbrSelectMsr;
360 /** The host last event record from IP MSR id. */
361 uint32_t idLerFromIpMsr;
362 /** The host last event record to IP MSR id. */
363 uint32_t idLerToIpMsr;
364
365 /** The first valid host LBR branch-from-IP stack range. */
366 uint32_t idLbrFromIpMsrFirst;
367 /** The last valid host LBR branch-from-IP stack range. */
368 uint32_t idLbrFromIpMsrLast;
369
370 /** The first valid host LBR branch-to-IP stack range. */
371 uint32_t idLbrToIpMsrFirst;
372 /** The last valid host LBR branch-to-IP stack range. */
373 uint32_t idLbrToIpMsrLast;
374
375 /** The first valid host LBR info stack range. */
376 uint32_t idLbrInfoMsrFirst;
377 /** The last valid host LBR info stack range. */
378 uint32_t idLbrInfoMsrLast;
379# endif
380
381 STAMCOUNTER StatMapPage;
382 STAMCOUNTER StatUnmapPage;
383 STAMCOUNTER StatMapPageFailed;
384 STAMCOUNTER StatUnmapPageFailed;
385#endif /* RT_OS_WINDOWS */
386} NEM;
387/** Pointer to NEM VM instance data. */
388typedef NEM *PNEM;
389
390/** NEM::u32Magic value. */
391#define NEM_MAGIC UINT32_C(0x004d454e)
392/** NEM::u32Magic value after termination. */
393#define NEM_MAGIC_DEAD UINT32_C(0xdead1111)
394
395
396/**
397 * NEM VMCPU Instance data.
398 */
399typedef struct NEMCPU
400{
401 /** NEMCPU_MAGIC. */
402 uint32_t u32Magic;
403 /** Whether \#UD needs to be intercepted and presented to GIM. */
404 bool fGIMTrapXcptUD : 1;
405 /** Whether \#GP needs to be intercept for mesa driver workaround. */
406 bool fTrapXcptGpForLovelyMesaDrv: 1;
407 /** Whether we should use the debug loop because of single stepping or special
408 * debug breakpoints / events are armed. */
409 bool fUseDebugLoop : 1;
410 /** Whether we're executing a single instruction. */
411 bool fSingleInstruction : 1;
412 /** Set if we using the debug loop and wish to intercept RDTSC. */
413 bool fDebugWantRdTscExit : 1;
414 /** Whether we are currently executing in the debug loop.
415 * Mainly for assertions. */
416 bool fUsingDebugLoop : 1;
417 /** Set if we need to clear the trap flag because of single stepping. */
418 bool fClearTrapFlag : 1;
419 /** Whether we're using the hyper DR7 or guest DR7. */
420 bool fUsingHyperDR7 : 1;
421 /** Whether \#DE needs to be intercepted for GIM. */
422 bool fGCMTrapXcptDE : 1;
423
424#if defined(RT_OS_LINUX)
425 uint8_t abPadding[3];
426 /** The KVM VCpu file descriptor. */
427 int32_t fdVCpu;
428 /** Pointer to the KVM_RUN data exchange region. */
429 R3PTRTYPE(struct kvm_run *) pRun;
430 /** The MSR_IA32_APICBASE value known to KVM. */
431 uint64_t uKvmApicBase;
432
433 /** @name Statistics
434 * @{ */
435 STAMCOUNTER StatExitTotal;
436 STAMCOUNTER StatExitIo;
437 STAMCOUNTER StatExitMmio;
438 STAMCOUNTER StatExitSetTpr;
439 STAMCOUNTER StatExitTprAccess;
440 STAMCOUNTER StatExitRdMsr;
441 STAMCOUNTER StatExitWrMsr;
442 STAMCOUNTER StatExitIrqWindowOpen;
443 STAMCOUNTER StatExitHalt;
444 STAMCOUNTER StatExitIntr;
445 STAMCOUNTER StatExitHypercall;
446 STAMCOUNTER StatExitDebug;
447 STAMCOUNTER StatExitBusLock;
448 STAMCOUNTER StatExitInternalErrorEmulation;
449 STAMCOUNTER StatExitInternalErrorFatal;
450# if 0
451 STAMCOUNTER StatExitCpuId;
452 STAMCOUNTER StatExitUnrecoverable;
453 STAMCOUNTER StatGetMsgTimeout;
454 STAMCOUNTER StatStopCpuSuccess;
455 STAMCOUNTER StatStopCpuPending;
456 STAMCOUNTER StatStopCpuPendingAlerts;
457 STAMCOUNTER StatStopCpuPendingOdd;
458 STAMCOUNTER StatCancelChangedState;
459 STAMCOUNTER StatCancelAlertedThread;
460# endif
461 STAMCOUNTER StatBreakOnCancel;
462 STAMCOUNTER StatBreakOnFFPre;
463 STAMCOUNTER StatBreakOnFFPost;
464 STAMCOUNTER StatBreakOnStatus;
465 STAMCOUNTER StatFlushExitOnReturn;
466 STAMCOUNTER StatFlushExitOnReturn1Loop;
467 STAMCOUNTER StatFlushExitOnReturn2Loops;
468 STAMCOUNTER StatFlushExitOnReturn3Loops;
469 STAMCOUNTER StatFlushExitOnReturn4PlusLoops;
470 STAMCOUNTER StatImportOnDemand;
471 STAMCOUNTER StatImportOnReturn;
472 STAMCOUNTER StatImportOnReturnSkipped;
473 STAMCOUNTER StatImportPendingInterrupt;
474 STAMCOUNTER StatExportPendingInterrupt;
475 STAMCOUNTER StatQueryCpuTick;
476 /** @} */
477
478
479#elif defined(RT_OS_WINDOWS)
480 /** The current state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
481 uint8_t fCurrentInterruptWindows;
482 /** The desired state of the interrupt windows (NEM_WIN_INTW_F_XXX). */
483 uint8_t fDesiredInterruptWindows;
484 /** Last copy of HV_X64_VP_EXECUTION_STATE::InterruptShadow. */
485 bool fLastInterruptShadow : 1;
486 uint32_t uPadding;
487 /** The VID_MSHAGN_F_XXX flags.
488 * Either VID_MSHAGN_F_HANDLE_MESSAGE | VID_MSHAGN_F_GET_NEXT_MESSAGE or zero. */
489 uint32_t fHandleAndGetFlags;
490 /** What VidMessageSlotMap returns and is used for passing exit info. */
491 RTR3PTR pvMsgSlotMapping;
492 /** The windows thread handle. */
493 RTR3PTR hNativeThreadHandle;
494
495 /** @name Statistics
496 * @{ */
497 STAMCOUNTER StatExitPortIo;
498 STAMCOUNTER StatExitMemUnmapped;
499 STAMCOUNTER StatExitMemIntercept;
500 STAMCOUNTER StatExitHalt;
501 STAMCOUNTER StatExitInterruptWindow;
502 STAMCOUNTER StatExitCpuId;
503 STAMCOUNTER StatExitMsr;
504 STAMCOUNTER StatExitException;
505 STAMCOUNTER StatExitExceptionBp;
506 STAMCOUNTER StatExitExceptionDb;
507 STAMCOUNTER StatExitExceptionGp;
508 STAMCOUNTER StatExitExceptionGpMesa;
509 STAMCOUNTER StatExitExceptionUd;
510 STAMCOUNTER StatExitExceptionUdHandled;
511 STAMCOUNTER StatExitUnrecoverable;
512 STAMCOUNTER StatGetMsgTimeout;
513 STAMCOUNTER StatStopCpuSuccess;
514 STAMCOUNTER StatStopCpuPending;
515 STAMCOUNTER StatStopCpuPendingAlerts;
516 STAMCOUNTER StatStopCpuPendingOdd;
517 STAMCOUNTER StatCancelChangedState;
518 STAMCOUNTER StatCancelAlertedThread;
519 STAMCOUNTER StatBreakOnCancel;
520 STAMCOUNTER StatBreakOnFFPre;
521 STAMCOUNTER StatBreakOnFFPost;
522 STAMCOUNTER StatBreakOnStatus;
523 STAMCOUNTER StatImportOnDemand;
524 STAMCOUNTER StatImportOnReturn;
525 STAMCOUNTER StatImportOnReturnSkipped;
526 STAMCOUNTER StatQueryCpuTick;
527 /** @} */
528
529#elif defined(RT_OS_DARWIN)
530# if defined(VBOX_VMM_TARGET_ARMV8)
531 /** The vCPU handle associated with the EMT executing this vCPU. */
532 hv_vcpu_t hVCpu;
533 /** Pointer to the exit information structure. */
534 hv_vcpu_exit_t *pHvExit;
535 /** Flag whether an event is pending. */
536 bool fEventPending;
537 /** Flag whether the vTimer got activated and is masked. */
538 bool fVTimerActivated;
539 /** Flag whether to update the vTimer offset. */
540 bool fVTimerOffUpdate;
541# else
542 /** The vCPU handle associated with the EMT executing this vCPU. */
543 hv_vcpuid_t hVCpuId;
544
545 /** @name State shared with the VT-x code.
546 * @{ */
547 /** An additional error code used for some gurus. */
548 uint32_t u32HMError;
549 /** The last exit-to-ring-3 reason. */
550 int32_t rcLastExitToR3;
551 /** CPU-context changed flags (see HM_CHANGED_xxx). */
552 uint64_t fCtxChanged;
553
554 /** The guest VMCS information. */
555 VMXVMCSINFO VmcsInfo;
556
557 /** VT-x data. */
558 struct HMCPUVMX
559 {
560 /** @name Guest information.
561 * @{ */
562 /** Guest VMCS information shared with ring-3. */
563 VMXVMCSINFOSHARED VmcsInfo;
564 /** Nested-guest VMCS information shared with ring-3. */
565 VMXVMCSINFOSHARED VmcsInfoNstGst;
566 /** Whether the nested-guest VMCS was the last current VMCS (shadow copy for ring-3).
567 * @see HMR0PERVCPU::vmx.fSwitchedToNstGstVmcs */
568 bool fSwitchedToNstGstVmcsCopyForRing3;
569 /** Whether the static guest VMCS controls has been merged with the
570 * nested-guest VMCS controls. */
571 bool fMergedNstGstCtls;
572 /** Whether the nested-guest VMCS has been copied to the shadow VMCS. */
573 bool fCopiedNstGstToShadowVmcs;
574 /** Whether flushing the TLB is required due to switching to/from the
575 * nested-guest. */
576 bool fSwitchedNstGstFlushTlb;
577 /** Alignment. */
578 bool afAlignment0[4];
579 /** Cached guest APIC-base MSR for identifying when to map the APIC-access page. */
580 uint64_t u64GstMsrApicBase;
581 /** @} */
582
583 /** @name Error reporting and diagnostics.
584 * @{ */
585 /** VT-x error-reporting (mainly for ring-3 propagation). */
586 struct
587 {
588 RTCPUID idCurrentCpu;
589 RTCPUID idEnteredCpu;
590 RTHCPHYS HCPhysCurrentVmcs;
591 uint32_t u32VmcsRev;
592 uint32_t u32InstrError;
593 uint32_t u32ExitReason;
594 uint32_t u32GuestIntrState;
595 } LastError;
596 /** @} */
597 } vmx;
598
599 /** Event injection state. */
600 HMEVENT Event;
601
602 /** Current shadow paging mode for updating CR4.
603 * @todo move later (@bugref{9217}). */
604 PGMMODE enmShadowMode;
605 uint32_t u32TemporaryPadding;
606
607 /** The PAE PDPEs used with Nested Paging (only valid when
608 * VMCPU_FF_HM_UPDATE_PAE_PDPES is set). */
609 X86PDPE aPdpes[4];
610 /** Pointer to the VMX statistics. */
611 PVMXSTATISTICS pVmxStats;
612# endif
613
614 /** @name Statistics
615 * @{ */
616 STAMCOUNTER StatExitAll;
617 STAMCOUNTER StatBreakOnCancel;
618 STAMCOUNTER StatBreakOnFFPre;
619 STAMCOUNTER StatBreakOnFFPost;
620 STAMCOUNTER StatBreakOnStatus;
621 STAMCOUNTER StatImportOnDemand;
622 STAMCOUNTER StatImportOnReturn;
623 STAMCOUNTER StatImportOnReturnSkipped;
624 STAMCOUNTER StatQueryCpuTick;
625#ifdef VBOX_WITH_STATISTICS
626 STAMPROFILEADV StatProfGstStateImport;
627 STAMPROFILEADV StatProfGstStateExport;
628#endif
629 /** @} */
630
631 /** @} */
632#endif /* RT_OS_DARWIN */
633} NEMCPU;
634/** Pointer to NEM VMCPU instance data. */
635typedef NEMCPU *PNEMCPU;
636
637/** NEMCPU::u32Magic value. */
638#define NEMCPU_MAGIC UINT32_C(0x4d454e20)
639/** NEMCPU::u32Magic value after termination. */
640#define NEMCPU_MAGIC_DEAD UINT32_C(0xdead2222)
641
642
643#ifdef IN_RING0
644# ifdef RT_OS_WINDOWS
645/**
646 * Windows: Hypercall input/ouput page info.
647 */
648typedef struct NEMR0HYPERCALLDATA
649{
650 /** Host physical address of the hypercall input/output page. */
651 RTHCPHYS HCPhysPage;
652 /** Pointer to the hypercall input/output page. */
653 uint8_t *pbPage;
654 /** Handle to the memory object of the hypercall input/output page. */
655 RTR0MEMOBJ hMemObj;
656} NEMR0HYPERCALLDATA;
657/** Pointer to a Windows hypercall input/output page info. */
658typedef NEMR0HYPERCALLDATA *PNEMR0HYPERCALLDATA;
659# endif /* RT_OS_WINDOWS */
660
661/**
662 * NEM GVMCPU instance data.
663 */
664typedef struct NEMR0PERVCPU
665{
666 uint32_t uDummy;
667} NEMR0PERVCPU;
668
669/**
670 * NEM GVM instance data.
671 */
672typedef struct NEMR0PERVM
673{
674 uint32_t uDummy;
675} NEMR0PERVM;
676
677#endif /* IN_RING*/
678
679
680#ifdef IN_RING3
681
682int nemR3DisableCpuIsaExt(PVM pVM, const char *pszIsaExt);
683
684int nemR3NativeInit(PVM pVM, bool fFallback, bool fForced);
685int nemR3NativeInitAfterCPUM(PVM pVM);
686int nemR3NativeInitCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
687int nemR3NativeTerm(PVM pVM);
688void nemR3NativeReset(PVM pVM);
689void nemR3NativeResetCpu(PVMCPU pVCpu, bool fInitIpi);
690VBOXSTRICTRC nemR3NativeRunGC(PVM pVM, PVMCPU pVCpu);
691bool nemR3NativeCanExecuteGuest(PVM pVM, PVMCPU pVCpu);
692bool nemR3NativeSetSingleInstruction(PVM pVM, PVMCPU pVCpu, bool fEnable);
693
694/**
695 * Forced flag notification call from VMEmt.h.
696 *
697 * This is only called when pVCpu is in the VMCPUSTATE_STARTED_EXEC_NEM state.
698 *
699 * @param pVM The cross context VM structure.
700 * @param pVCpu The cross context virtual CPU structure of the CPU
701 * to be notified.
702 * @param fFlags Notification flags, VMNOTIFYFF_FLAGS_XXX.
703 */
704void nemR3NativeNotifyFF(PVM pVM, PVMCPU pVCpu, uint32_t fFlags);
705
706/**
707 * Called by NEMR3NotifyDebugEventChanged() to let the native backend take the final decision
708 * on whether to switch to the debug loop.
709 *
710 * @returns Final flag whether to switch to the debug loop.
711 * @param pVM The VM cross context VM structure.
712 * @param fUseDebugLoop The current value determined by NEMR3NotifyDebugEventChanged().
713 * @thread EMT(0)
714 */
715DECLHIDDEN(bool) nemR3NativeNotifyDebugEventChanged(PVM pVM, bool fUseDebugLoop);
716
717
718/**
719 * Called by NEMR3NotifyDebugEventChangedPerCpu() to let the native backend take the final decision
720 * on whether to switch to the debug loop.
721 *
722 * @returns Final flag whether to switch to the debug loop.
723 * @param pVM The VM cross context VM structure.
724 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
725 * @param fUseDebugLoop The current value determined by NEMR3NotifyDebugEventChangedPerCpu().
726 */
727DECLHIDDEN(bool) nemR3NativeNotifyDebugEventChangedPerCpu(PVM pVM, PVMCPU pVCpu, bool fUseDebugLoop);
728
729#endif /* IN_RING3 */
730
731void nemHCNativeNotifyHandlerPhysicalRegister(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhys, RTGCPHYS cb);
732void nemHCNativeNotifyHandlerPhysicalModify(PVMCC pVM, PGMPHYSHANDLERKIND enmKind, RTGCPHYS GCPhysOld,
733 RTGCPHYS GCPhysNew, RTGCPHYS cb, bool fRestoreAsRAM);
734int nemHCNativeNotifyPhysPageAllocated(PVMCC pVM, RTGCPHYS GCPhys, RTHCPHYS HCPhys, uint32_t fPageProt,
735 PGMPAGETYPE enmType, uint8_t *pu2State);
736
737
738#ifdef RT_OS_WINDOWS
739/** Maximum number of pages we can map in a single NEMR0MapPages call. */
740# define NEM_MAX_MAP_PAGES ((HOST_PAGE_SIZE - RT_UOFFSETOF(HV_INPUT_MAP_GPA_PAGES, PageList)) / sizeof(HV_SPA_PAGE_NUMBER))
741/** Maximum number of pages we can unmap in a single NEMR0UnmapPages call. */
742# define NEM_MAX_UNMAP_PAGES 4095
743
744#endif
745/** @} */
746
747RT_C_DECLS_END
748
749#endif /* !VMM_INCLUDED_SRC_include_NEMInternal_h */
750
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