/** @file * Hyper-V related types and definitions. */ /* * Copyright (C) 2018 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. * * The contents of this file may alternatively be used under the terms * of the Common Development and Distribution License Version 1.0 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the * VirtualBox OSE distribution, in which case the provisions of the * CDDL are applicable instead of those of the GPL. * * You may elect to license modified versions of this file under the * terms and conditions of either the GPL or the CDDL or both. */ #ifndef ___iprt_nt_hyperv_h #define ___iprt_nt_hyperv_h #ifndef IN_IDA_PRO # include # include #else # define RT_FLEXIBLE_ARRAY # define AssertCompile(expr) # define AssertCompileSize(type, size) # define AssertCompileMemberOffset(type, member, off) #endif /** Hyper-V partition ID. */ typedef uint64_t HV_PARTITION_ID; /** Invalid Hyper-V partition ID. */ #define HV_PARTITION_ID_INVALID UINT64_C(0) /** Hyper-V virtual processor index (== VMCPUID). */ typedef uint32_t HV_VP_INDEX; /** Guest physical address (== RTGCPHYS). */ typedef uint64_t HV_GPA; /** Guest physical page number. */ typedef uint64_t HV_GPA_PAGE_NUMBER; /** System(/parent) physical page number. */ typedef uint64_t HV_SPA_PAGE_NUMBER; /** Hyper-V unsigned 128-bit integer type. */ typedef struct { uint64_t Low64, High64; } HV_UINT128; /** Hyper-V port ID. */ typedef union { uint32_t AsUINT32; struct { uint32_t Id : 24; uint32_t Reserved : 8; }; } HV_PORT_ID; /** Pointer to a Hyper-V port ID. */ typedef HV_PORT_ID *PHV_PORT_ID; /** * Hypercall IDs. */ typedef enum { HvCallReserved0000 = 0, HvCallSwitchVirtualAddressSpace, HvCallFlushVirtualAddressSpace, HvCallFlushVirtualAddressList, HvCallGetLogicalProcessorRunTime, /* 5, 6 & 7 are deprecated / reserved. */ HvCallNotifyLongSpinWait = 8, HvCallParkLogicalProcessors, /**< @since v2 */ HvCallInvokeHypervisorDebugger, /**< @since v2 - not mentioned in TLFS v5.0b */ HvCallSendSyntheticClusterIpi, /**< @since v? */ HvCallModifyVtlProtectionMask, /**< @since v? */ HvCallEnablePartitionVtl, /**< @since v? */ HvCallDisablePartitionVtl, /**< @since v? */ HvCallEnableVpVtl, /**< @since v? */ HvCallDisableVpVtl, /**< @since v? */ HvCallVtlCall, /**< @since v? */ HvCallVtlReturn, /**< @since v? */ HvCallFlushVirtualAddressSpaceEx, /**< @since v? */ HvCallFlushVirtualAddressListEx, /**< @since v? */ HvCallSendSyntheticClusterIpiEx, /**< @since v? */ /* Reserved: 0x16..0x3f */ HvCallCreatePartition = 0x40, HvCallInitializePartition, HvCallFinalizePartition, HvCallDeletePartition, HvCallGetPartitionProperty, HvCallSetPartitionProperty, HvCallGetPartitionId, HvCallGetNextChildPartition, HvCallDepositMemory, /**< 0x48 - Repeat call. */ HvCallWithdrawMemory, /**< 0x49 - Repeat call. */ HvCallGetMemoryBalance, HvCallMapGpaPages, /**< 0X4b - Repeat call. */ HvCallUnmapGpaPages, /**< 0X4c - Repeat call. */ HvCallInstallIntercept, HvCallCreateVp, HvCallDeleteVp, /**< 0x4f - Fast call. */ HvCallGetVpRegisters, /**< 0x50 - Repeat call. */ HvCallSetVpRegisters, /**< 0x51 - Repeat call. */ HvCallTranslateVirtualAddress, HvCallReadGpa, HvCallWriteGpa, HvCallAssertVirtualInterruptV1, HvCallClearVirtualInterrupt, /**< 0x56 - Fast call. */ HvCallCreatePortV1, HvCallDeletePort, /**< 0x58 - Fast call. */ HvCallConnectPortV1, HvCallGetPortProperty, HvCallDisconnectPort, HvCallPostMessage, HvCallSignalEvent, HvCallSavePartitionState, HvCallRestorePartitionState, HvCallInitializeEventLogBufferGroup, HvCallFinalizeEventLogBufferGroup, HvCallCreateEventLogBuffer, HvCallDeleteEventLogBuffer, HvCallMapEventLogBuffer, HvCallUnmapEventLogBuffer, HvCallSetEventLogGroupSources, HvCallReleaseEventLogBuffer, HvCallFlushEventLogBuffer, HvCallPostDebugData, HvCallRetrieveDebugData, HvCallResetDebugSession, HvCallMapStatsPage, HvCallUnmapStatsPage, HvCallMapSparseGpaPages, /**< @since v2 */ HvCallSetSystemProperty, /**< @since v2 */ HvCallSetPortProperty, /**< @since v2 */ /* 0x71..0x75 reserved/deprecated (was v2 test IDs). */ HvCallAddLogicalProcessor = 0x76, HvCallRemoveLogicalProcessor, HvCallQueryNumaDistance, HvCallSetLogicalProcessorProperty, HvCallGetLogicalProcessorProperty, HvCallGetSystemProperty, HvCallMapDeviceInterrupt, HvCallUnmapDeviceInterrupt, HvCallRetargetDeviceInterrupt, /* 0x7f is reserved. */ HvCallMapDevicePages = 0x80, HvCallUnmapDevicePages, HvCallAttachDevice, HvCallDetachDevice, HvCallNotifyStandbyTransition, HvCallPrepareForSleep, HvCallPrepareForHibernate, HvCallNotifyPartitionEvent, HvCallGetLogicalProcessorRegisters, HvCallSetLogicalProcessorRegisters, HvCallQueryAssociatedLpsforMca, HvCallNotifyRingEmpty, HvCallInjectSyntheticMachineCheck, HvCallScrubPartition, HvCallCollectLivedump, HvCallDisableHypervisor, HvCallModifySparseGpaPages, HvCallRegisterInterceptResult, HvCallUnregisterInterceptResult, /* 0x93 is reserved/undocumented. */ HvCallAssertVirtualInterrupt = 0x94, HvCallCreatePort, HvCallConnectPort, HvCallGetSpaPageList, /* 0x98 is reserved. */ HvCallStartVirtualProcessor = 0x99, HvCallGetVpIndexFromApicId, /* 0x9b..0xae are reserved/undocumented. 0xad: New version of HvCallGetVpRegisters? Perhaps on logical CPU or smth. */ HvCallFlushGuestPhysicalAddressSpace = 0xaf, HvCallFlushGuestPhysicalAddressList, /* 0xb1..0xb4 are unknown */ HvCallCreateCpuGroup = 0xb5, HvCallDeleteCpuGroup, HvCallGetCpuGroupProperty, HvCallSetCpuGroupProperty, HvCallGetCpuGroupAffinit, HvCallGetNextCpuGroup = 0xba, HvCallGetNextCpuGroupPartition, HvCallPrecommitGpaPages = 0xbe, HvCallUncommitGpaPages, /**< Happens when VidDestroyGpaRangeCheckSecure/WHvUnmapGpaRange is called. */ /* 0xc0..0xcb are unknown */ HvCallVpRunloopRelated = 0xc2, /**< Fast */ HvCallQueryVtlProtectionMaskRange = 0xcc, HvCallModifyVtlProtectionMaskRange, /* 0xce..0xd1 are unknown */ HvCallAcquireSparseGpaPageHostAccess = 0xd2, HvCallReleaseSparseGpaPageHostAccess, HvCallCheckSparseGpaPageVtlAccess, HvCallAcquireSparseSpaPageHostAccess = 0xd7, HvCallReleaseSparseSpaPageHostAccess, HvCallAcceptGpaPages, /**< 0x18 byte input, zero rep, no output. */ /** Number of defined hypercalls (varies with version). */ HvCallCount } HV_CALL_CODE; AssertCompile(HvCallSendSyntheticClusterIpiEx == 0x15); AssertCompile(HvCallMapGpaPages == 0x4b); AssertCompile(HvCallSetPortProperty == 0x70); AssertCompile(HvCallRetargetDeviceInterrupt == 0x7e); AssertCompile(HvCallUnregisterInterceptResult == 0x92); AssertCompile(HvCallGetSpaPageList == 0x97); AssertCompile(HvCallFlushGuestPhysicalAddressList == 0xb0); AssertCompile(HvCallUncommitGpaPages == 0xbf); AssertCompile(HvCallCount == 0xda); /** Makes the first parameter to a hypercall (rcx). */ #define HV_MAKE_CALL_INFO(a_enmCallCode, a_cReps) ( (uint64_t)(a_enmCallCode) | ((uint64_t)(a_cReps) << 32) ) /** Makes the return value (success) for a rep hypercall. */ #define HV_MAKE_CALL_REP_RET(a_cReps) ((uint64_t)(a_cReps) << 32) /** Hypercall status code. */ typedef uint16_t HV_STATUS; /** @name Hyper-V Hypercall status codes * @{ */ #define HV_STATUS_SUCCESS (0x0000) #define HV_STATUS_RESERVED_1 (0x0001) #define HV_STATUS_INVALID_HYPERCALL_CODE (0x0002) #define HV_STATUS_INVALID_HYPERCALL_INPUT (0x0003) #define HV_STATUS_INVALID_ALIGNMENT (0x0004) #define HV_STATUS_INVALID_PARAMETER (0x0005) #define HV_STATUS_ACCESS_DENIED (0x0006) #define HV_STATUS_INVALID_PARTITION_STATE (0x0007) #define HV_STATUS_OPERATION_DENIED (0x0008) #define HV_STATUS_UNKNOWN_PROPERTY (0x0009) #define HV_STATUS_PROPERTY_VALUE_OUT_OF_RANGE (0x000a) #define HV_STATUS_INSUFFICIENT_MEMORY (0x000b) #define HV_STATUS_PARTITION_TOO_DEEP (0x000c) #define HV_STATUS_INVALID_PARTITION_ID (0x000d) #define HV_STATUS_INVALID_VP_INDEX (0x000e) #define HV_STATUS_RESERVED_F (0x000f) #define HV_STATUS_NOT_FOUND (0x0010) #define HV_STATUS_INVALID_PORT_ID (0x0011) #define HV_STATUS_INVALID_CONNECTION_ID (0x0012) #define HV_STATUS_INSUFFICIENT_BUFFERS (0x0013) #define HV_STATUS_NOT_ACKNOWLEDGED (0x0014) #define HV_STATUS_INVALID_VP_STATE (0x0015) #define HV_STATUS_ACKNOWLEDGED (0x0016) #define HV_STATUS_INVALID_SAVE_RESTORE_STATE (0x0017) #define HV_STATUS_INVALID_SYNIC_STATE (0x0018) #define HV_STATUS_OBJECT_IN_USE (0x0019) #define HV_STATUS_INVALID_PROXIMITY_DOMAIN_INFO (0x001a) #define HV_STATUS_NO_DATA (0x001b) #define HV_STATUS_INACTIVE (0x001c) #define HV_STATUS_NO_RESOURCES (0x001d) #define HV_STATUS_FEATURE_UNAVAILABLE (0x001e) #define HV_STATUS_PARTIAL_PACKET (0x001f) #define HV_STATUS_PROCESSOR_FEATURE_SSE3_NOT_SUPPORTED (0x0020) #define HV_STATUS_PROCESSOR_FEATURE_LAHFSAHF_NOT_SUPPORTED (0x0021) #define HV_STATUS_PROCESSOR_FEATURE_SSSE3_NOT_SUPPORTED (0x0022) #define HV_STATUS_PROCESSOR_FEATURE_SSE4_1_NOT_SUPPORTED (0x0023) #define HV_STATUS_PROCESSOR_FEATURE_SSE4_2_NOT_SUPPORTED (0x0024) #define HV_STATUS_PROCESSOR_FEATURE_SSE4A_NOT_SUPPORTED (0x0025) #define HV_STATUS_PROCESSOR_FEATURE_XOP_NOT_SUPPORTED (0x0026) #define HV_STATUS_PROCESSOR_FEATURE_POPCNT_NOT_SUPPORTED (0x0027) #define HV_STATUS_PROCESSOR_FEATURE_CMPXCHG16B_NOT_SUPPORTED (0x0028) #define HV_STATUS_PROCESSOR_FEATURE_ALTMOVCR8_NOT_SUPPORTED (0x0029) #define HV_STATUS_PROCESSOR_FEATURE_LZCNT_NOT_SUPPORTED (0x002a) #define HV_STATUS_PROCESSOR_FEATURE_MISALIGNED_SSE_NOT_SUPPORTED (0x002b) #define HV_STATUS_PROCESSOR_FEATURE_MMX_EXT_NOT_SUPPORTED (0x002c) #define HV_STATUS_PROCESSOR_FEATURE_3DNOW_NOT_SUPPORTED (0x002d) #define HV_STATUS_PROCESSOR_FEATURE_EXTENDED_3DNOW_NOT_SUPPORTED (0x002e) #define HV_STATUS_PROCESSOR_FEATURE_PAGE_1GB_NOT_SUPPORTED (0x002f) #define HV_STATUS_PROCESSOR_CACHE_LINE_FLUSH_SIZE_INCOMPATIBLE (0x0030) #define HV_STATUS_PROCESSOR_FEATURE_XSAVE_NOT_SUPPORTED (0x0031) #define HV_STATUS_PROCESSOR_FEATURE_XSAVEOPT_NOT_SUPPORTED (0x0032) #define HV_STATUS_INSUFFICIENT_BUFFER (0x0033) #define HV_STATUS_PROCESSOR_FEATURE_XSAVE_AVX_NOT_SUPPORTED (0x0034) #define HV_STATUS_PROCESSOR_FEATURE_XSAVE_ FEATURE_NOT_SUPPORTED (0x0035) #define HV_STATUS_PROCESSOR_XSAVE_SAVE_AREA_INCOMPATIBLE (0x0036) #define HV_STATUS_INCOMPATIBLE_PROCESSOR (0x0037) #define HV_STATUS_INSUFFICIENT_DEVICE_DOMAINS (0x0038) #define HV_STATUS_PROCESSOR_FEATURE_AES_NOT_SUPPORTED (0x0039) #define HV_STATUS_PROCESSOR_FEATURE_PCLMULQDQ_NOT_SUPPORTED (0x003a) #define HV_STATUS_PROCESSOR_FEATURE_INCOMPATIBLE_XSAVE_FEATURES (0x003b) #define HV_STATUS_CPUID_FEATURE_VALIDATION_ERROR (0x003c) #define HV_STATUS_CPUID_XSAVE_FEATURE_VALIDATION_ERROR (0x003d) #define HV_STATUS_PROCESSOR_STARTUP_TIMEOUT (0x003e) #define HV_STATUS_SMX_ENABLED (0x003f) #define HV_STATUS_PROCESSOR_FEATURE_PCID_NOT_SUPPORTED (0x0040) #define HV_STATUS_INVALID_LP_INDEX (0x0041) #define HV_STATUS_FEATURE_FMA4_NOT_SUPPORTED (0x0042) #define HV_STATUS_FEATURE_F16C_NOT_SUPPORTED (0x0043) #define HV_STATUS_PROCESSOR_FEATURE_RDRAND_NOT_SUPPORTED (0x0044) #define HV_STATUS_PROCESSOR_FEATURE_RDWRFSGS_NOT_SUPPORTED (0x0045) #define HV_STATUS_PROCESSOR_FEATURE_SMEP_NOT_SUPPORTED (0x0046) #define HV_STATUS_PROCESSOR_FEATURE_ENHANCED_FAST_STRING_NOT_SUPPORTED (0x0047) #define HV_STATUS_PROCESSOR_FEATURE_MOVBE_NOT_SUPPORTED (0x0048) #define HV_STATUS_PROCESSOR_FEATURE_BMI1_NOT_SUPPORTED (0x0049) #define HV_STATUS_PROCESSOR_FEATURE_BMI2_NOT_SUPPORTED (0x004a) #define HV_STATUS_PROCESSOR_FEATURE_HLE_NOT_SUPPORTED (0x004b) #define HV_STATUS_PROCESSOR_FEATURE_RTM_NOT_SUPPORTED (0x004c) #define HV_STATUS_PROCESSOR_FEATURE_XSAVE_FMA_NOT_SUPPORTED (0x004d) #define HV_STATUS_PROCESSOR_FEATURE_XSAVE_AVX2_NOT_SUPPORTED (0x004e) #define HV_STATUS_PROCESSOR_FEATURE_NPIEP1_NOT_SUPPORTED (0x004f) #define HV_STATUS_INVALID_REGISTER_VALUE (0x0050) #define HV_STATUS_PROCESSOR_FEATURE_RDSEED_NOT_SUPPORTED (0x0052) #define HV_STATUS_PROCESSOR_FEATURE_ADX_NOT_SUPPORTED (0x0053) #define HV_STATUS_PROCESSOR_FEATURE_SMAP_NOT_SUPPORTED (0x0054) #define HV_STATUS_NX_NOT_DETECTED (0x0055) #define HV_STATUS_PROCESSOR_FEATURE_INTEL_PREFETCH_NOT_SUPPORTED (0x0056) #define HV_STATUS_INVALID_DEVICE_ID (0x0057) #define HV_STATUS_INVALID_DEVICE_STATE (0x0058) #define HV_STATUS_PENDING_PAGE_REQUESTS (0x0059) #define HV_STATUS_PAGE_REQUEST_INVALID (0x0060) #define HV_STATUS_OPERATION_FAILED (0x0071) #define HV_STATUS_NOT_ALLOWED_WITH_NESTED_VIRT_ACTIVE (0x0072) /** @} */ /** Hyper-V partition property value. */ typedef uint64_t HV_PARTITION_PROPERTY; /** Pointer to a partition property value. */ typedef HV_PARTITION_PROPERTY *PHV_PARTITION_PROPERTY; /** * Hyper-V partition property code. * This is documented in TLFS, except version 5.x. */ typedef enum { HvPartitionPropertyPrivilegeFlags = 0x00010000, HvPartitionPropertyCpuReserve = 0x00020001, HvPartitionPropertyCpuCap, HvPartitionPropertyCpuWeight, HvPartitionPropertyUnknown20004, /**< On exo partition (build 17134), initial value zero. */ HvPartitionPropertyEmulatedTimerPeriod = 0x00030000, /**< @note Fails on exo partition (build 17134). */ HvPartitionPropertyEmulatedTimerControl, /**< @note Fails on exo partition (build 17134). */ HvPartitionPropertyPmTimerAssist, /**< @note Fails on exo partition (build 17134). */ HvPartitionPropertyDebugChannelId = 0x00040000, /**< @note Hangs system on exo partition hangs (build 17134). */ HvPartitionPropertyVirtualTlbPageCount = 0x00050000, HvPartitionPropertyUnknown50001, /**< On exo partition (build 17134), initial value zero. */ HvPartitionPropertyUnknown50002, /**< On exo partition (build 17134), initial value zero. */ HvPartitionPropertyUnknown50003, /**< On exo partition (build 17134), initial value zero. */ HvPartitionPropertyUnknown50004, /**< On exo partition (build 17134), initial value zero. */ HvPartitionPropertyUnknown50005, /**< On exo partition (build 17134), initial value one. */ HvPartitionPropertyUnknown50006, /**< On exo partition (build 17134), initial value zero. */ HvPartitionPropertyProcessorVendor = 0x00060000, HvPartitionPropertyProcessorFeatures, /**< On exo/17134/threadripper: 0x6cb26f39fbf */ HvPartitionPropertyProcessorXsaveFeatures, HvPartitionPropertyProcessorCLFlushSize, /**< On exo/17134/threadripper: 8 */ HvPartitionPropertyUnknown60004, /**< On exo partition (build 17134), initial value zero. */ HvPartitionPropertyUnknown60005, /**< On exo partition (build 17134), initial value 0x603. */ HvPartitionPropertyUnknown60006, /**< On exo partition (build 17134), initial value 0x2c. */ HvPartitionPropertyGuestOsId = 0x00070000, /**< @since v4 */ HvPartitionPropertyUnknown800000 = 0x00080000 /**< On exo partition (build 17134), initial value zero. */ } HV_PARTITION_PROPERTY_CODE; AssertCompileSize(HV_PARTITION_PROPERTY_CODE, 4); /** Pointer to a partition property code. */ typedef HV_PARTITION_PROPERTY_CODE *PHV_PARTITION_PROPERTY_CODE; /** Input for HvCallGetPartitionProperty. */ typedef struct { HV_PARTITION_ID PartitionId; HV_PARTITION_PROPERTY_CODE PropertyCode; uint32_t uPadding; } HV_INPUT_GET_PARTITION_PROPERTY; AssertCompileSize(HV_INPUT_GET_PARTITION_PROPERTY, 16); /** Pointer to input for HvCallGetPartitionProperty. */ typedef HV_INPUT_GET_PARTITION_PROPERTY *PHV_INPUT_GET_PARTITION_PROPERTY; /** Output for HvCallGetPartitionProperty. */ typedef struct { HV_PARTITION_PROPERTY PropertyValue; } HV_OUTPUT_GET_PARTITION_PROPERTY; /** Pointer to output for HvCallGetPartitionProperty. */ typedef HV_OUTPUT_GET_PARTITION_PROPERTY *PHV_OUTPUT_GET_PARTITION_PROPERTY; /** Input for HvCallSetPartitionProperty. */ typedef struct { HV_PARTITION_ID PartitionId; HV_PARTITION_PROPERTY_CODE PropertyCode; uint32_t uPadding; HV_PARTITION_PROPERTY PropertyValue; } HV_INPUT_SET_PARTITION_PROPERTY; AssertCompileSize(HV_INPUT_SET_PARTITION_PROPERTY, 24); /** Pointer to input for HvCallSetPartitionProperty. */ typedef HV_INPUT_SET_PARTITION_PROPERTY *PHV_INPUT_SET_PARTITION_PROPERTY; /** Hyper-V NUMA node ID. * On systems without NUMA, i.e. a single node, it uses 0 as identifier. */ typedef uint32_t HV_PROXIMITY_DOMAIN_ID; /** Pointer to NUMA node ID. */ typedef HV_PROXIMITY_DOMAIN_ID *PHV_PROXIMITY_DOMAIN_ID; /** Hyper-V NUMA flags. */ typedef struct { uint32_t ProximityPreferred : 1; /**< When set, allocations may come from other NUMA nodes. */ uint32_t Reserved : 30; /**< Reserved for future (as of circa v2). */ uint32_t ProxyimityInfoValid : 1; /**< Set if the NUMA information is valid. */ } HV_PROXIMITY_DOMAIN_FLAGS; /** Pointer to Hyper-V NUMA flags. */ typedef HV_PROXIMITY_DOMAIN_FLAGS *PHV_PROXIMITY_DOMAIN_FLAGS; /** Hyper-V NUMA information. */ typedef struct { HV_PROXIMITY_DOMAIN_ID Id; /**< NUMA node identifier. */ HV_PROXIMITY_DOMAIN_FLAGS Flags; /**< NUMA flags. */ } HV_PROXIMITY_DOMAIN_INFO; /** Pointer to Hyper-V NUMA information. */ typedef HV_PROXIMITY_DOMAIN_INFO *PHV_PROXIMITY_DOMAIN_INFO; /** Input for HvCallGetMemoryBalance. */ typedef struct { HV_PARTITION_ID TargetPartitionId; HV_PROXIMITY_DOMAIN_INFO ProximityDomainInfo; } HV_INPUT_GET_MEMORY_BALANCE; AssertCompileSize(HV_INPUT_GET_MEMORY_BALANCE, 16); /** Pointer to the input for HvCallGetMemoryBalance. */ typedef HV_INPUT_GET_MEMORY_BALANCE *PHV_INPUT_GET_MEMORY_BALANCE; /** Output for HvCallGetMemoryBalance. */ typedef struct { uint64_t PagesAvailable; uint64_t PagesInUse; } HV_OUTPUT_GET_MEMORY_BALANCE; /** Pointer to the output for HvCallGetMemoryBalance. */ typedef HV_OUTPUT_GET_MEMORY_BALANCE *PHV_OUTPUT_GET_MEMORY_BALANCE; /** @name Flags used with HvCallMapGpaPages and HvCallMapSparseGpaPages. * @note There seems to be a more flags defined after v2. * @{ */ typedef uint32_t HV_MAP_GPA_FLAGS; #define HV_MAP_GPA_READABLE UINT32_C(0x0001) #define HV_MAP_GPA_WRITABLE UINT32_C(0x0002) #define HV_MAP_GPA_EXECUTABLE UINT32_C(0x0004) /** Seems this have to be set when HV_MAP_GPA_EXECUTABLE is (17101). */ #define HV_MAP_GPA_EXECUTABLE_AGAIN UINT32_C(0x0008) /** Dunno what this is yet, but it requires HV_MAP_GPA_DUNNO_1000. * The readable bit gets put here when both HV_MAP_GPA_DUNNO_1000 and * HV_MAP_GPA_DUNNO_MASK_0700 are clear. */ #define HV_MAP_GPA_DUNNO_ACCESS UINT32_C(0x0010) /** Guess work. */ #define HV_MAP_GPA_MAYBE_ACCESS_MASK UINT32_C(0x001f) /** Some kind of mask. */ #define HV_MAP_GPA_DUNNO_MASK_0700 UINT32_C(0x0700) /** Dunno what this is, but required for HV_MAP_GPA_DUNNO_ACCESS. */ #define HV_MAP_GPA_DUNNO_1000 UINT32_C(0x1000) /** Working with large 2MB pages. */ #define HV_MAP_GPA_LARGE UINT32_C(0x2000) /** Valid mask as per build 17101. */ #define HV_MAP_GPA_VALID_MASK UINT32_C(0x7f1f) /** @} */ /** Input for HvCallMapGpaPages. */ typedef struct { HV_PARTITION_ID TargetPartitionId; HV_GPA_PAGE_NUMBER TargetGpaBase; HV_MAP_GPA_FLAGS MapFlags; uint32_t u32ExplicitPadding; /* The repeating part: */ HV_SPA_PAGE_NUMBER PageList[RT_FLEXIBLE_ARRAY]; } HV_INPUT_MAP_GPA_PAGES; AssertCompileMemberOffset(HV_INPUT_MAP_GPA_PAGES, PageList, 24); /** Pointer to the input for HvCallMapGpaPages. */ typedef HV_INPUT_MAP_GPA_PAGES *PHV_INPUT_MAP_GPA_PAGES; /** A parent to guest mapping pair for HvCallMapSparseGpaPages. */ typedef struct { HV_GPA_PAGE_NUMBER TargetGpaPageNumber; HV_SPA_PAGE_NUMBER SourceSpaPageNumber; } HV_GPA_MAPPING; /** Pointer to a parent->guest mapping pair for HvCallMapSparseGpaPages. */ typedef HV_GPA_MAPPING *PHV_GPA_MAPPING; /** Input for HvCallMapSparseGpaPages. */ typedef struct { HV_PARTITION_ID TargetPartitionId; HV_MAP_GPA_FLAGS MapFlags; uint32_t u32ExplicitPadding; /* The repeating part: */ HV_GPA_MAPPING PageList[RT_FLEXIBLE_ARRAY]; } HV_INPUT_MAP_SPARSE_GPA_PAGES; AssertCompileMemberOffset(HV_INPUT_MAP_SPARSE_GPA_PAGES, PageList, 16); /** Pointer to the input for HvCallMapSparseGpaPages. */ typedef HV_INPUT_MAP_SPARSE_GPA_PAGES *PHV_INPUT_MAP_SPARSE_GPA_PAGES; /** Input for HvCallUnmapGpaPages. */ typedef struct { HV_PARTITION_ID TargetPartitionId; HV_GPA_PAGE_NUMBER TargetGpaBase; /** This field is either an omission in the 7600 WDK or a later additions. * Anyway, not quite sure what it does. Bit 2 seems to indicate 2MB pages. */ uint64_t fFlags; } HV_INPUT_UNMAP_GPA_PAGES; AssertCompileSize(HV_INPUT_UNMAP_GPA_PAGES, 24); /** Pointer to the input for HvCallUnmapGpaPages. */ typedef HV_INPUT_UNMAP_GPA_PAGES *PHV_INPUT_UNMAP_GPA_PAGES; /** Cache types used by HvCallReadGpa and HvCallWriteGpa. */ typedef enum { HvCacheTypeX64Uncached = 0, HvCacheTypeX64WriteCombining, /* 2 & 3 are undefined. */ HvCacheTypeX64WriteThrough = 4, HvCacheTypeX64WriteProtected, HvCacheTypeX64WriteBack } HV_CACHE_TYPE; /** Control flags for HvCallReadGpa and HvCallWriteGpa. */ typedef union { uint64_t AsUINT64; struct { uint64_t CacheType : 8; /**< HV_CACHE_TYPE */ uint64_t Reserved : 56; }; } HV_ACCESS_GPA_CONTROL_FLAGS; /** Results codes for HvCallReadGpa and HvCallWriteGpa. */ typedef enum { HvAccessGpaSuccess = 0, HvAccessGpaUnmapped, HvAccessGpaReadIntercept, HvAccessGpaWriteIntercept, HvAccessGpaIllegalOverlayAccess } HV_ACCESS_GPA_RESULT_CODE; /** The result of HvCallReadGpa and HvCallWriteGpa. */ typedef union { uint64_t AsUINT64; struct { HV_ACCESS_GPA_RESULT_CODE ResultCode; uint32_t Reserved; }; } HV_ACCESS_GPA_RESULT; /** Input for HvCallReadGpa. */ typedef struct { HV_PARTITION_ID PartitionId; HV_VP_INDEX VpIndex; uint32_t ByteCount; HV_GPA BaseGpa; HV_ACCESS_GPA_CONTROL_FLAGS ControlFlags; } HV_INPUT_READ_GPA; AssertCompileSize(HV_INPUT_READ_GPA, 32); /** Pointer to the input for HvCallReadGpa. */ typedef HV_INPUT_READ_GPA *PHV_INPUT_READ_GPA; /** Output for HvCallReadGpa. */ typedef struct { HV_ACCESS_GPA_RESULT AccessResult; uint8_t Data[16]; } HV_OUTPUT_READ_GPA; AssertCompileSize(HV_OUTPUT_READ_GPA, 24); /** Pointer to the output for HvCallReadGpa. */ typedef HV_OUTPUT_READ_GPA *PHV_OUTPUT_READ_GPA; /** Input for HvCallWriteGpa. */ typedef struct { HV_PARTITION_ID PartitionId; HV_VP_INDEX VpIndex; uint32_t ByteCount; HV_GPA BaseGpa; HV_ACCESS_GPA_CONTROL_FLAGS ControlFlags; uint8_t Data[16]; } HV_INPUT_WRITE_GPA; AssertCompileSize(HV_INPUT_READ_GPA, 32); /** Pointer to the input for HvCallWriteGpa. */ typedef HV_INPUT_READ_GPA *PHV_INPUT_READ_GPA; /** Output for HvCallWriteGpa. */ typedef struct { HV_ACCESS_GPA_RESULT AccessResult; } HV_OUTPUT_WRITE_GPA; AssertCompileSize(HV_OUTPUT_WRITE_GPA, 8); /** Pointer to the output for HvCallWriteGpa. */ typedef HV_OUTPUT_WRITE_GPA *PHV_OUTPUT_WRITE_GPA; /** * Register names used by HvCallGetVpRegisters and HvCallSetVpRegisters. */ typedef enum _HV_REGISTER_NAME { HvRegisterExplicitSuspend = 0x00000000, HvRegisterInterceptSuspend, HvRegisterUnknown02, /**< Reads as 0 initially on exo part. */ HvRegisterUnknown03, /**< Reads as 0 initially on exo part. */ HvRegisterHypervisorVersion = 0x00000100, /**< @since v5 @note Not readable on exo part. */ HvRegisterPrivilegesAndFeaturesInfo = 0x00000200, /**< @since v5 @note Not readable on exo part. */ HvRegisterFeaturesInfo, /**< @since v5 @note Not readable on exo part. */ HvRegisterImplementationLimitsInfo, /**< @since v5 @note Not readable on exo part. */ HvRegisterHardwareFeaturesInfo, /**< @since v5 @note Not readable on exo part. */ HvRegisterGuestCrashP0 = 0x00000210, /**< @since v5 @note Not readable on exo part. */ HvRegisterGuestCrashP1, /**< @since v5 @note Not readable on exo part. */ HvRegisterGuestCrashP2, /**< @since v5 @note Not readable on exo part. */ HvRegisterGuestCrashP3, /**< @since v5 @note Not readable on exo part. */ HvRegisterGuestCrashP4, /**< @since v5 @note Not readable on exo part. */ HvRegisterGuestCrashCtl, /**< @since v5 @note Not readable on exo part. */ HvRegisterPowerStateConfigC1 = 0x00000220, /**< @since v5 @note Not readable on exo part. */ HvRegisterPowerStateTriggerC1, /**< @since v5 @note Not readable on exo part. */ HvRegisterPowerStateConfigC2, /**< @since v5 @note Not readable on exo part. */ HvRegisterPowerStateTriggerC2, /**< @since v5 @note Not readable on exo part. */ HvRegisterPowerStateConfigC3, /**< @since v5 @note Not readable on exo part. */ HvRegisterPowerStateTriggerC3, /**< @since v5 @note Not readable on exo part. */ HvRegisterSystemReset = 0x00000230, /**< @since v5 @note Not readable on exo part. */ HvRegisterProcessorClockFrequency = 0x00000240, /**< @since v5 @note Not readable on exo part. */ HvRegisterInterruptClockFrequency, /**< @since v5 @note Not readable on exo part. */ HvRegisterGuestIdle = 0x00000250, /**< @since v5 @note Not readable on exo part. */ HvRegisterDebugDeviceOptions = 0x00000260, /**< @since v5 @note Not readable on exo part. */ HvRegisterPendingInterruption = 0x00010002, HvRegisterInterruptState, HvRegisterPendingEvent0, /**< @since v5 */ HvRegisterPendingEvent1, /**< @since v5 */ HvX64RegisterDeliverabilityNotifications, /**< @since v5c? Late 2017? */ HvX64RegisterRax = 0x00020000, HvX64RegisterRcx, HvX64RegisterRdx, HvX64RegisterRbx, HvX64RegisterRsp, HvX64RegisterRbp, HvX64RegisterRsi, HvX64RegisterRdi, HvX64RegisterR8, HvX64RegisterR9, HvX64RegisterR10, HvX64RegisterR11, HvX64RegisterR12, HvX64RegisterR13, HvX64RegisterR14, HvX64RegisterR15, HvX64RegisterRip, HvX64RegisterRflags, HvX64RegisterXmm0 = 0x00030000, HvX64RegisterXmm1, HvX64RegisterXmm2, HvX64RegisterXmm3, HvX64RegisterXmm4, HvX64RegisterXmm5, HvX64RegisterXmm6, HvX64RegisterXmm7, HvX64RegisterXmm8, HvX64RegisterXmm9, HvX64RegisterXmm10, HvX64RegisterXmm11, HvX64RegisterXmm12, HvX64RegisterXmm13, HvX64RegisterXmm14, HvX64RegisterXmm15, HvX64RegisterFpMmx0, HvX64RegisterFpMmx1, HvX64RegisterFpMmx2, HvX64RegisterFpMmx3, HvX64RegisterFpMmx4, HvX64RegisterFpMmx5, HvX64RegisterFpMmx6, HvX64RegisterFpMmx7, HvX64RegisterFpControlStatus, HvX64RegisterXmmControlStatus, HvX64RegisterCr0 = 0x00040000, HvX64RegisterCr2, HvX64RegisterCr3, HvX64RegisterCr4, HvX64RegisterCr8, HvX64RegisterXfem, HvX64RegisterIntermediateCr0 = 0x00041000, /**< @since v5 */ HvX64RegisterIntermediateCr4 = 0x00041003, /**< @since v5 */ HvX64RegisterIntermediateCr8, /**< @since v5 */ HvX64RegisterDr0 = 0x00050000, HvX64RegisterDr1, HvX64RegisterDr2, HvX64RegisterDr3, HvX64RegisterDr6, HvX64RegisterDr7, HvX64RegisterEs = 0x00060000, HvX64RegisterCs, HvX64RegisterSs, HvX64RegisterDs, HvX64RegisterFs, HvX64RegisterGs, HvX64RegisterLdtr, HvX64RegisterTr, HvX64RegisterIdtr = 0x00070000, HvX64RegisterGdtr, HvX64RegisterTsc = 0x00080000, HvX64RegisterEfer, HvX64RegisterKernelGsBase, HvX64RegisterApicBase, HvX64RegisterPat, HvX64RegisterSysenterCs, HvX64RegisterSysenterEip, HvX64RegisterSysenterEsp, HvX64RegisterStar, HvX64RegisterLstar, HvX64RegisterCstar, HvX64RegisterSfmask, HvX64RegisterInitialApicId, HvX64RegisterMtrrCap, /**< Not readable in exo partitions? */ HvX64RegisterMtrrDefType, HvX64RegisterMtrrPhysBase0 = 0x00080010, HvX64RegisterMtrrPhysBase1, HvX64RegisterMtrrPhysBase2, HvX64RegisterMtrrPhysBase3, HvX64RegisterMtrrPhysBase4, HvX64RegisterMtrrPhysBase5, HvX64RegisterMtrrPhysBase6, HvX64RegisterMtrrPhysBase7, HvX64RegisterMtrrPhysBase8, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysBase9, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysBaseA, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysBaseB, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysBaseC, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysBaseD, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysBaseE, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysBaseF, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysMask0 = 0x00080040, HvX64RegisterMtrrPhysMask1, HvX64RegisterMtrrPhysMask2, HvX64RegisterMtrrPhysMask3, HvX64RegisterMtrrPhysMask4, HvX64RegisterMtrrPhysMask5, HvX64RegisterMtrrPhysMask6, HvX64RegisterMtrrPhysMask7, HvX64RegisterMtrrPhysMask8, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysMask9, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysMaskA, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysMaskB, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysMaskC, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysMaskD, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysMaskE, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrPhysMaskF, /**< @since v4 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterMtrrFix64k00000 = 0x00080070, HvX64RegisterMtrrFix16k80000, HvX64RegisterMtrrFix16kA0000, HvX64RegisterMtrrFix4kC0000, HvX64RegisterMtrrFix4kC8000, HvX64RegisterMtrrFix4kD0000, HvX64RegisterMtrrFix4kD8000, HvX64RegisterMtrrFix4kE0000, HvX64RegisterMtrrFix4kE8000, HvX64RegisterMtrrFix4kF0000, HvX64RegisterMtrrFix4kF8000, HvX64RegisterTscAux, /**< @since v5c? late 2017? */ HvX64RegisterUnknown8007d = 0x0008007d, /**< Readable on exo partition (17134), initial value is zero. */ HvX64RegisterIa32MiscEnable = 0x000800a0, /**< @since v5 @note Appears not to be readable on exo partition (Threadripper). */ HvX64RegisterIa32FeatureControl, /**< @since v5 @note Appears not to be readable on exo partition (Threadripper). */ /** Uptime counter or some such thing. Unit is different than HvRegisterTimeRefCount or the accounting is different. */ HvX64RegisterVpRuntime = 0x00090000, HvX64RegisterHypercall, HvRegisterGuestOsId, HvRegisterVpIndex, HvRegisterTimeRefCount, /**< Time counter since partition creation, 100ns units. */ HvRegisterCpuManagementVersion = 0x00090007, /**< @since v5 @note Appears not to be readable on exo partition. */ HvX64RegisterEoi = 0x00090010, /**< @note Appears not to be readable on exo partition. */ HvX64RegisterIcr, /**< @note Appears not to be readable on exo partition. */ HvX64RegisterTpr, /**< @note Appears not to be readable on exo partition. */ HvRegisterVpAssistPage, /** Readable on exo partition (17134). Some kind of counter. */ HvRegisterUnknown90014, HvRegisterStatsPartitionRetail = 0x00090020, HvRegisterStatsPartitionInternal, HvRegisterStatsVpRetail, HvRegisterStatsVpInternal, HvRegisterSint0 = 0x000a0000, HvRegisterSint1, HvRegisterSint2, HvRegisterSint3, HvRegisterSint4, HvRegisterSint5, HvRegisterSint6, HvRegisterSint7, HvRegisterSint8, HvRegisterSint9, HvRegisterSint10, HvRegisterSint11, HvRegisterSint12, HvRegisterSint13, HvRegisterSint14, HvRegisterSint15, HvRegisterScontrol, HvRegisterSversion, HvRegisterSifp, HvRegisterSipp, HvRegisterEom, HvRegisterSirbp, /**< @since v4 */ HvRegisterStimer0Config = 0x000b0000, HvRegisterStimer0Count, HvRegisterStimer1Config, HvRegisterStimer1Count, HvRegisterStimer2Config, HvRegisterStimer2Count, HvRegisterStimer3Config, HvRegisterStimer3Count, HvRegisterUnknown0b0100 = 0x000b0100, /**< Readable on exo partition (17134), initial value is zero. */ HvRegisterUnknown0b0101, /**< Readable on exo partition (17134), initial value is zero. */ HvX64RegisterYmm0Low = 0x000c0000, /**< @note Not readable on exo partition. Need something enabled? */ HvX64RegisterYmm1Low, HvX64RegisterYmm2Low, HvX64RegisterYmm3Low, HvX64RegisterYmm4Low, HvX64RegisterYmm5Low, HvX64RegisterYmm6Low, HvX64RegisterYmm7Low, HvX64RegisterYmm8Low, HvX64RegisterYmm9Low, HvX64RegisterYmm10Low, HvX64RegisterYmm11Low, HvX64RegisterYmm12Low, HvX64RegisterYmm13Low, HvX64RegisterYmm14Low, HvX64RegisterYmm15Low, HvX64RegisterYmm0High, HvX64RegisterYmm1High, HvX64RegisterYmm2High, HvX64RegisterYmm3High, HvX64RegisterYmm4High, HvX64RegisterYmm5High, HvX64RegisterYmm6High, HvX64RegisterYmm7High, HvX64RegisterYmm8High, HvX64RegisterYmm9High, HvX64RegisterYmm10High, HvX64RegisterYmm11High, HvX64RegisterYmm12High, HvX64RegisterYmm13High, HvX64RegisterYmm14High, HvX64RegisterYmm15High, HvRegisterVsmVpVtlControl = 0x000d0000, /**< @note Not readable on exo partition. */ HvRegisterVsmCodePageOffsets = 0x000d0002, HvRegisterVsmVpStatus, HvRegisterVsmPartitionStatus, HvRegisterVsmVina, /**< @note Not readable on exo partition. */ HvRegisterVsmCapabilities, HvRegisterVsmPartitionConfig, /**< @note Not readable on exo partition. */ HvRegisterVsmVpSecureConfigVtl0 = 0x000d0010, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl1, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl2, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl3, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl4, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl5, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl6, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl7, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl8, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl9, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl10, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl11, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl12, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl13, /**< @since v5 */ HvRegisterVsmVpSecureConfigVtl14, /**< @since v5 */ HvRegisterUnknown0e0000 = 0x000e0000, /**< Readable on exo partition (17134), initial value zero. */ HvRegisterUnknown0e0001, /**< Readable on exo partition (17134), initial value zero. */ HvRegisterUnknown0e0002, /**< Readable on exo partition (17134), initial value zero. */ HvRegisterUnknown0e0003 /**< Readable on exo partition (17134), initial value zero. */ } HV_REGISTER_NAME; AssertCompile(HvRegisterInterceptSuspend == 0x00000001); AssertCompile(HvRegisterPendingEvent1 == 0x00010005); AssertCompile(HvX64RegisterDeliverabilityNotifications == 0x00010006); AssertCompile(HvX64RegisterRflags == 0x00020011); AssertCompile(HvX64RegisterXmmControlStatus == 0x00030019); AssertCompile(HvX64RegisterXfem == 0x00040005); AssertCompile(HvX64RegisterIntermediateCr0 == 0x00041000); AssertCompile(HvX64RegisterIntermediateCr4 == 0x00041003); AssertCompile(HvX64RegisterDr7 == 0x00050005); AssertCompile(HvX64RegisterTr == 0x00060007); AssertCompile(HvX64RegisterGdtr == 0x00070001); AssertCompile(HvX64RegisterInitialApicId == 0x0008000c); AssertCompile(HvX64RegisterMtrrCap == 0x0008000d); AssertCompile(HvX64RegisterMtrrDefType == 0x0008000e); AssertCompile(HvX64RegisterMtrrPhysBaseF == 0x0008001f); AssertCompile(HvX64RegisterMtrrPhysMaskF == 0x0008004f); AssertCompile(HvX64RegisterMtrrFix4kF8000 == 0x0008007a); AssertCompile(HvRegisterTimeRefCount == 0x00090004); AssertCompile(HvRegisterCpuManagementVersion == 0x00090007); AssertCompile(HvRegisterVpAssistPage == 0x00090013); AssertCompile(HvRegisterStatsVpInternal == 0x00090023); AssertCompile(HvRegisterSirbp == 0x000a0015); AssertCompile(HvRegisterStimer3Count == 0x000b0007); AssertCompile(HvX64RegisterYmm15High == 0x000c001f); AssertCompile(HvRegisterVsmVpSecureConfigVtl14 == 0x000d001e); AssertCompileSize(HV_REGISTER_NAME, 4); /** Value format for HvRegisterExplicitSuspend. */ typedef union { uint64_t AsUINT64; struct { uint64_t Suspended : 1; uint64_t Reserved : 63; }; } HV_EXPLICIT_SUSPEND_REGISTER; /** Pointer to a value of HvRegisterExplicitSuspend. */ typedef HV_EXPLICIT_SUSPEND_REGISTER *PHV_EXPLICIT_SUSPEND_REGISTER; /** Value format for HvRegisterInterceptSuspend. */ typedef union { uint64_t AsUINT64; struct { uint64_t Suspended : 1; uint64_t TlbLocked : 1; uint64_t Reserved : 62; }; } HV_INTERCEPT_SUSPEND_REGISTER; /** Pointer to a value of HvRegisterInterceptSuspend. */ typedef HV_INTERCEPT_SUSPEND_REGISTER *PHV_INTERCEPT_SUSPEND_REGISTER; /** Value format for HvRegisterInterruptState. * @sa WHV_X64_INTERRUPT_STATE_REGISTER */ typedef union { uint64_t AsUINT64; struct { uint64_t InterruptShadow : 1; uint64_t NmiMasked : 1; uint64_t Reserved : 62; }; } HV_X64_INTERRUPT_STATE_REGISTER; /** Pointer to a value of HvRegisterInterruptState. */ typedef HV_X64_INTERRUPT_STATE_REGISTER *PHV_X64_INTERRUPT_STATE_REGISTER; /** Pending exception type for HvRegisterPendingInterruption. * @sa WHV_X64_PENDING_INTERRUPTION_TYPE */ typedef enum { HvX64PendingInterrupt = 0, /* what is/was 1? */ HvX64PendingNmi = 2, HvX64PendingException /* any more? */ } HV_X64_PENDING_INTERRUPTION_TYPE; /** Value format for HvRegisterPendingInterruption. * @sa WHV_X64_PENDING_INTERRUPTION_REGISTER */ typedef union { uint64_t AsUINT64; struct { uint32_t InterruptionPending : 1; uint32_t InterruptionType : 3; /**< HV_X64_PENDING_INTERRUPTION_TYPE */ uint32_t DeliverErrorCode : 1; uint32_t InstructionLength : 4; /**< @since v5? Wasn't in 7600 WDK */ uint32_t NestedEvent : 1; /**< @since v5? Wasn't in 7600 WDK */ uint32_t Reserved : 6; uint32_t InterruptionVector : 16; uint32_t ErrorCode; }; } HV_X64_PENDING_INTERRUPTION_REGISTER; /** Pointer to a value of HvRegisterPendingInterruption. */ typedef HV_X64_PENDING_INTERRUPTION_REGISTER *PHV_X64_PENDING_INTERRUPTION_REGISTER; /** Value format for HvX64RegisterDeliverabilityNotifications. * Value format for HvRegisterPendingEvent0/1. * @sa WHV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER */ typedef union { uint64_t AsUINT64; struct { uint64_t NmiNotification : 1; uint64_t InterruptNotification : 1; uint64_t InterruptPriority : 4; uint64_t Reserved : 58; }; } HV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER; /** Pointer to a value of HvRegisterPendingEvent0/1. */ typedef HV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER *PHV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER; /** Value format for HvX64RegisterEs..Tr. * @sa WHV_X64_SEGMENT_REGISTER */ typedef struct _HV_X64_SEGMENT_REGISTER { uint64_t Base; uint32_t Limit; uint16_t Selector; union { struct { uint16_t SegmentType : 4; uint16_t NonSystemSegment : 1; uint16_t DescriptorPrivilegeLevel : 2; uint16_t Present : 1; uint16_t Reserved : 4; uint16_t Available : 1; uint16_t Long : 1; uint16_t Default : 1; uint16_t Granularity : 1; }; uint16_t Attributes; }; } HV_X64_SEGMENT_REGISTER; AssertCompileSize(HV_X64_SEGMENT_REGISTER, 16); /** Pointer to a value of HvX64RegisterEs..Tr. */ typedef HV_X64_SEGMENT_REGISTER *PHV_X64_SEGMENT_REGISTER; /** Value format for HvX64RegisterIdtr/Gdtr. * @sa WHV_X64_TABLE_REGISTER */ typedef struct { uint16_t Pad[3]; uint16_t Limit; uint64_t Base; } HV_X64_TABLE_REGISTER; AssertCompileSize(HV_X64_TABLE_REGISTER, 16); /** Pointer to a value of HvX64RegisterIdtr/Gdtrr. */ typedef HV_X64_TABLE_REGISTER *PHV_X64_TABLE_REGISTER; /** Value format for HvX64RegisterFpMmx0..7 in floating pointer mode. * @sa WHV_X64_FP_REGISTER, RTFLOAT80U2 */ typedef union { HV_UINT128 AsUINT128; struct { uint64_t Mantissa; uint64_t BiasedExponent : 15; uint64_t Sign : 1; uint64_t Reserved : 48; }; } HV_X64_FP_REGISTER; /** Pointer to a value of HvX64RegisterFpMmx0..7 in floating point mode. */ typedef HV_X64_FP_REGISTER *PHV_X64_FP_REGISTER; /** Value union for HvX64RegisterFpMmx0..7. */ typedef union { HV_UINT128 AsUINT128; HV_X64_FP_REGISTER Fp; uint64_t Mmx; } HV_X64_FP_MMX_REGISTER; /** Pointer to a value of HvX64RegisterFpMmx0..7. */ typedef HV_X64_FP_MMX_REGISTER *PHV_X64_FP_MMX_REGISTER; /** Value format for HvX64RegisterFpControlStatus. * @sa WHV_X64_FP_CONTROL_STATUS_REGISTER */ typedef union { HV_UINT128 AsUINT128; struct { uint16_t FpControl; uint16_t FpStatus; uint8_t FpTag; uint8_t IgnNe : 1; uint8_t Reserved : 7; uint16_t LastFpOp; union { uint64_t LastFpRip; struct { uint32_t LastFpEip; uint16_t LastFpCs; }; }; }; } HV_X64_FP_CONTROL_STATUS_REGISTER; /** Pointer to a value of HvX64RegisterFpControlStatus. */ typedef HV_X64_FP_CONTROL_STATUS_REGISTER *PHV_X64_FP_CONTROL_STATUS_REGISTER; /** Value format for HvX64RegisterXmmControlStatus. * @sa WHV_X64_XMM_CONTROL_STATUS_REGISTER */ typedef union { HV_UINT128 AsUINT128; struct { union { uint64_t LastFpRdp; struct { uint32_t LastFpDp; uint16_t LastFpDs; }; }; uint32_t XmmStatusControl; uint32_t XmmStatusControlMask; }; } HV_X64_XMM_CONTROL_STATUS_REGISTER; /** Pointer to a value of HvX64RegisterXmmControlStatus. */ typedef HV_X64_XMM_CONTROL_STATUS_REGISTER *PHV_X64_XMM_CONTROL_STATUS_REGISTER; /** Register value union. * @sa WHV_REGISTER_VALUE */ typedef union { HV_UINT128 Reg128; uint64_t Reg64; uint32_t Reg32; uint16_t Reg16; uint8_t Reg8; HV_EXPLICIT_SUSPEND_REGISTER ExplicitSuspend; HV_INTERCEPT_SUSPEND_REGISTER InterceptSuspend; HV_X64_INTERRUPT_STATE_REGISTER InterruptState; HV_X64_PENDING_INTERRUPTION_REGISTER PendingInterruption; HV_X64_DELIVERABILITY_NOTIFICATIONS_REGISTER DeliverabilityNotifications; HV_X64_TABLE_REGISTER Table; HV_X64_SEGMENT_REGISTER Segment; HV_X64_FP_REGISTER Fp; HV_X64_FP_CONTROL_STATUS_REGISTER FpControlStatus; HV_X64_XMM_CONTROL_STATUS_REGISTER XmmControlStatus; } HV_REGISTER_VALUE; AssertCompileSize(HV_REGISTER_VALUE, 16); /** Pointer to a Hyper-V register value union. */ typedef HV_REGISTER_VALUE *PHV_REGISTER_VALUE; /** Pointer to a const Hyper-V register value union. */ typedef HV_REGISTER_VALUE const *PCHV_REGISTER_VALUE; /** Input for HvCallGetVpRegisters. */ typedef struct { HV_PARTITION_ID PartitionId; HV_VP_INDEX VpIndex; /** Was this introduced after v2? Dunno what it it really is. */ uint32_t fFlags; /* The repeating part: */ HV_REGISTER_NAME Names[RT_FLEXIBLE_ARRAY]; } HV_INPUT_GET_VP_REGISTERS; AssertCompileMemberOffset(HV_INPUT_GET_VP_REGISTERS, Names, 16); /** Pointer to input for HvCallGetVpRegisters. */ typedef HV_INPUT_GET_VP_REGISTERS *PHV_INPUT_GET_VP_REGISTERS; /* Output for HvCallGetVpRegisters is an array of HV_REGISTER_VALUE parallel to HV_INPUT_GET_VP_REGISTERS::Names. */ /** Register and value pair for HvCallSetVpRegisters. */ typedef struct { HV_REGISTER_NAME Name; uint32_t Pad0; uint64_t Pad1; HV_REGISTER_VALUE Value; } HV_REGISTER_ASSOC; AssertCompileSize(HV_REGISTER_ASSOC, 32); AssertCompileMemberOffset(HV_REGISTER_ASSOC, Value, 16); /** Pointer to a register and value pair for HvCallSetVpRegisters. */ typedef HV_REGISTER_ASSOC *PHV_REGISTER_ASSOC; /** Helper for clearing the alignment padding members. */ #define HV_REGISTER_ASSOC_ZERO_PADDING(a_pRegAssoc) do { (a_pRegAssoc)->Pad0 = 0; (a_pRegAssoc)->Pad1 = 0; } while (0) /** Helper for clearing the alignment padding members and the high 64-bit * part of the value. */ #define HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(a_pRegAssoc) \ do { (a_pRegAssoc)->Pad0 = 0; (a_pRegAssoc)->Pad1 = 0; (a_pRegAssoc)->Value.Reg128.High64 = 0; } while (0) /** Input for HvCallSetVpRegisters. */ typedef struct { HV_PARTITION_ID PartitionId; HV_VP_INDEX VpIndex; uint32_t RsvdZ; /* The repeating part: */ HV_REGISTER_ASSOC Elements[RT_FLEXIBLE_ARRAY]; } HV_INPUT_SET_VP_REGISTERS; AssertCompileMemberOffset(HV_INPUT_SET_VP_REGISTERS, Elements, 16); /** Pointer to input for HvCallSetVpRegisters. */ typedef HV_INPUT_SET_VP_REGISTERS *PHV_INPUT_SET_VP_REGISTERS; /** * Hyper-V SyncIC message types. */ typedef enum { HvMessageTypeNone = 0x00000000, HvMessageTypeUnmappedGpa = 0x80000000, HvMessageTypeGpaIntercept, HvMessageTimerExpired = 0x80000010, HvMessageTypeInvalidVpRegisterValue = 0x80000020, HvMessageTypeUnrecoverableException, HvMessageTypeUnsupportedFeature, HvMessageTypeTlbPageSizeMismatch, /**< @since v5 */ /** @note Same as HvMessageTypeX64ApicEoi? Gone in 5.0. Missing from 7600 WDK * headers even if it's in the 2.0 docs. */ HvMessageTypeApicEoi = 0x80000030, /** @note Same as HvMessageTypeX64LegacyFpError? Gone in 5.0, whereas 4.0b * calls it HvMessageTypeX64LegacyFpError. Missing from 7600 WDK * headers even if it's in the 2.0 docs. */ HvMessageTypeFerrAsserted, HvMessageTypeEventLogBufferComplete = 0x80000040, HvMessageTypeX64IoPortIntercept = 0x80010000, HvMessageTypeX64MsrIntercept, HvMessageTypeX64CpuidIntercept, HvMessageTypeX64ExceptionIntercept, /** @note Appeared in 5.0 docs, but were here in 7600 WDK headers already. */ HvMessageTypeX64ApicEoi, /** @note Appeared in 5.0 docs, but were here in 7600 WDK headers already. */ HvMessageTypeX64LegacyFpError, /** @since v5 */ HvMessageTypeX64RegisterIntercept, /** @since WinHvPlatform? */ HvMessageTypeX64Halt, /** @since WinHvPlatform? */ HvMessageTypeX64InterruptWindow } HV_MESSAGE_TYPE; AssertCompileSize(HV_MESSAGE_TYPE, 4); AssertCompile(HvMessageTypeX64RegisterIntercept == 0x80010006); AssertCompile(HvMessageTypeX64Halt == 0x80010007); AssertCompile(HvMessageTypeX64InterruptWindow == 0x80010008); /** Pointer to a Hyper-V SyncIC message type. */ typedef HV_MESSAGE_TYPE *PHV_MESSAGE_TYPE; /** Flag set for hypervisor messages, guest cannot send messages with this * flag set. */ #define HV_MESSAGE_TYPE_HYPERVISOR_MASK UINT32_C(0x80000000) /** Hyper-V SynIC message size (they are fixed sized). */ #define HV_MESSAGE_SIZE 256 /** Maximum Hyper-V SynIC message payload size in bytes. */ #define HV_MESSAGE_MAX_PAYLOAD_BYTE_COUNT (HV_MESSAGE_SIZE - 16) /** Maximum Hyper-V SynIC message payload size in QWORDs (uint64_t). */ #define HV_MESSAGE_MAX_PAYLOAD_QWORD_COUNT (HV_MESSAGE_MAX_PAYLOAD_BYTE_COUNT / 8) /** SynIC message flags. */ typedef union { uint8_t AsUINT8; struct { /** Messages are pending in the queue. */ uint8_t MessagePending : 1; uint8_t Reserved : 7; }; } HV_MESSAGE_FLAGS; AssertCompileSize(HV_MESSAGE_FLAGS, 1); /** SynIC message header. */ typedef struct { HV_MESSAGE_TYPE MessageType; /** The 2.0-5.0b docs all have this incorrectly switched with 'Reserved', WDK 7600 got it right. */ uint8_t PayloadSize; HV_MESSAGE_FLAGS MessageFlags; uint16_t Reserved; union { uint64_t OriginationId; HV_PARTITION_ID Sender; HV_PORT_ID Port; }; } HV_MESSAGE_HEADER; AssertCompileSize(HV_MESSAGE_HEADER, 16); /** Pointer to a Hyper-V message header. */ typedef HV_MESSAGE_HEADER *PHV_MESSAGE_HEADER; /** Pointer to a const Hyper-V message header. */ typedef HV_MESSAGE_HEADER const *PCHV_MESSAGE_HEADER; /** @name Intercept access type. * @{ */ typedef uint8_t HV_INTERCEPT_ACCESS_TYPE; #define HV_INTERCEPT_ACCESS_READ 0 #define HV_INTERCEPT_ACCESS_WRITE 1 #define HV_INTERCEPT_ACCESS_EXECUTE 2 /** @} */ /** @name Intercept access type mask. * @{ */ typedef uint32_t HV_INTERCEPT_ACCESS_TYPE_MASK; #define HV_INTERCEPT_ACCESS_MASK_NONE 0 #define HV_INTERCEPT_ACCESS_MASK_READ 1 #define HV_INTERCEPT_ACCESS_MASK_WRITE 2 #define HV_INTERCEPT_ACCESS_MASK_EXECUTE 4 /** @} */ /** X64 intercept execution state. * @sa WHV_X64_VP_EXECUTION_STATE */ typedef union { uint16_t AsUINT16; struct { uint16_t Cpl : 2; uint16_t Cr0Pe : 1; uint16_t Cr0Am : 1; uint16_t EferLma : 1; uint16_t DebugActive : 1; uint16_t InterruptionPending : 1; uint16_t Reserved0 : 5; uint16_t InterruptShadow : 1; uint16_t Reserved1 : 3; }; } HV_X64_VP_EXECUTION_STATE; AssertCompileSize(HV_X64_VP_EXECUTION_STATE, 2); /** Pointer to X86 intercept execution state. */ typedef HV_X64_VP_EXECUTION_STATE *PHV_X64_VP_EXECUTION_STATE; /** Pointer to const X86 intercept execution state. */ typedef HV_X64_VP_EXECUTION_STATE const *PCHV_X64_VP_EXECUTION_STATE; /** X64 intercept message header. */ typedef struct { HV_VP_INDEX VpIndex; /**< 0x00 */ uint8_t InstructionLength : 4; /**< 0x04[3:0]: Zero if not available, instruction fetch exit, ... */ uint8_t Cr8 : 4; /**< 0x04[7:4]: Not sure since when, but after v2. */ HV_INTERCEPT_ACCESS_TYPE InterceptAccessType; /**< 0x05 */ HV_X64_VP_EXECUTION_STATE ExecutionState; /**< 0x06 */ HV_X64_SEGMENT_REGISTER CsSegment; /**< 0x08 */ uint64_t Rip; /**< 0x18 */ uint64_t Rflags; /**< 0x20 */ } HV_X64_INTERCEPT_MESSAGE_HEADER; AssertCompileSize(HV_X64_INTERCEPT_MESSAGE_HEADER, 40); /** Pointer to a x86 intercept message header. */ typedef HV_X64_INTERCEPT_MESSAGE_HEADER *PHV_X64_INTERCEPT_MESSAGE_HEADER; /** X64 memory access flags (HvMessageTypeGpaIntercept, HvMessageTypeUnmappedGpa). * @sa WHV_MEMORY_ACCESS_INFO */ typedef union { uint8_t AsUINT8; struct { uint8_t GvaValid : 1; uint8_t Reserved : 7; }; } HV_X64_MEMORY_ACCESS_INFO; AssertCompileSize(HV_X64_MEMORY_ACCESS_INFO, 1); /** The payload format for HvMessageTypeGpaIntercept and HvMessageTypeUnmappedGpa. * @sa WHV_MEMORY_ACCESS_CONTEXT * @note max message size. */ typedef struct { HV_X64_INTERCEPT_MESSAGE_HEADER Header; /**< 0x00 */ HV_CACHE_TYPE CacheType; /**< 0x28 */ uint8_t InstructionByteCount; /**< 0x2c */ HV_X64_MEMORY_ACCESS_INFO MemoryAccessInfo; /**< 0x2d */ uint16_t Reserved1; /**< 0x2e */ uint64_t GuestVirtualAddress; /**< 0x30 */ uint64_t GuestPhysicalAddress; /**< 0x38 */ uint8_t InstructionBytes[16]; /**< 0x40 */ /* We don't the following (v5 / WinHvPlatform): */ HV_X64_SEGMENT_REGISTER DsSegment; /**< 0x50 */ HV_X64_SEGMENT_REGISTER SsSegment; /**< 0x60 */ uint64_t Rax; /**< 0x70 */ uint64_t Rcx; /**< 0x78 */ uint64_t Rdx; /**< 0x80 */ uint64_t Rbx; /**< 0x88 */ uint64_t Rsp; /**< 0x90 */ uint64_t Rbp; /**< 0x98 */ uint64_t Rsi; /**< 0xa0 */ uint64_t Rdi; /**< 0xa8 */ uint64_t R8; /**< 0xb0 */ uint64_t R9; /**< 0xb8 */ uint64_t R10; /**< 0xc0 */ uint64_t R11; /**< 0xc8 */ uint64_t R12; /**< 0xd0 */ uint64_t R13; /**< 0xd8 */ uint64_t R14; /**< 0xe0 */ uint64_t R15; /**< 0xe8 */ } HV_X64_MEMORY_INTERCEPT_MESSAGE; AssertCompileSize(HV_X64_MEMORY_INTERCEPT_MESSAGE, 0xf0); AssertCompileMemberOffset(HV_X64_MEMORY_INTERCEPT_MESSAGE, DsSegment, 0x50); /** Pointer to a HvMessageTypeGpaIntercept or HvMessageTypeUnmappedGpa payload. */ typedef HV_X64_MEMORY_INTERCEPT_MESSAGE *PHV_X64_MEMORY_INTERCEPT_MESSAGE; /** Pointer to a const HvMessageTypeGpaIntercept or HvMessageTypeUnmappedGpa payload. */ typedef HV_X64_MEMORY_INTERCEPT_MESSAGE const *PCHV_X64_MEMORY_INTERCEPT_MESSAGE; /** The payload format for HvMessageTypeX64MsrIntercept. */ typedef struct _HV_X64_MSR_INTERCEPT_MESSAGE { HV_X64_INTERCEPT_MESSAGE_HEADER Header; /**< 0x00 */ uint32_t MsrNumber; /**< 0x28 (ecx) */ uint32_t Reserved; /**< 0x2c */ uint64_t Rdx; /**< 0x30 */ uint64_t Rax; /**< 0x38 */ } HV_X64_MSR_INTERCEPT_MESSAGE; AssertCompileSize(HV_X64_MSR_INTERCEPT_MESSAGE, 0x40); /** Pointer to a HvMessageTypeX64MsrIntercept payload. */ typedef HV_X64_MSR_INTERCEPT_MESSAGE *PHV_X64_MSR_INTERCEPT_MESSAGE; /** Pointer to a const HvMessageTypeX64MsrIntercept payload. */ typedef HV_X64_MSR_INTERCEPT_MESSAGE const *PCHV_X64_MSR_INTERCEPT_MESSAGE; /** Full MSR message. */ typedef struct { HV_MESSAGE_HEADER MsgHdr; HV_X64_MSR_INTERCEPT_MESSAGE Payload; } HV_X64_MSR_INTERCEPT_MESSAGE_FULL; /** X64 I/O port access information (HvMessageTypeX64IoPortIntercept). */ typedef union HV_X64_IO_PORT_ACCESS_INFO { uint8_t AsUINT8; struct { uint8_t AccessSize : 3; uint8_t StringOp : 1; uint8_t RepPrefix : 1; uint8_t Reserved : 3; }; } HV_X64_IO_PORT_ACCESS_INFO; AssertCompileSize(HV_X64_IO_PORT_ACCESS_INFO, 1); /** The payload format for HvMessageTypeX64IoPortIntercept. */ typedef struct _HV_X64_IO_PORT_INTERCEPT_MESSAGE { HV_X64_INTERCEPT_MESSAGE_HEADER Header; /**< 0x00 */ uint16_t PortNumber; /**< 0x28 */ HV_X64_IO_PORT_ACCESS_INFO AccessInfo; /**< 0x2a */ uint8_t InstructionByteCount; /**< 0x2b */ uint32_t Reserved; /**< 0x2c */ uint64_t Rax; /**< 0x30 */ uint8_t InstructionBytes[16]; /**< 0x38 */ HV_X64_SEGMENT_REGISTER DsSegment; /**< 0x48 */ HV_X64_SEGMENT_REGISTER EsSegment; /**< 0x58 */ uint64_t Rcx; /**< 0x68 */ uint64_t Rsi; /**< 0x70 */ uint64_t Rdi; /**< 0x78 */ } HV_X64_IO_PORT_INTERCEPT_MESSAGE; AssertCompileSize(HV_X64_IO_PORT_INTERCEPT_MESSAGE, 128); /** Pointer to a HvMessageTypeX64IoPortIntercept payload. */ typedef HV_X64_IO_PORT_INTERCEPT_MESSAGE *PHV_X64_IO_PORT_INTERCEPT_MESSAGE; /** Pointer to a const HvMessageTypeX64IoPortIntercept payload. */ typedef HV_X64_IO_PORT_INTERCEPT_MESSAGE const *PCHV_X64_IO_PORT_INTERCEPT_MESSAGE; /** Full I/O port message. */ typedef struct { HV_MESSAGE_HEADER MsgHdr; HV_X64_IO_PORT_INTERCEPT_MESSAGE Payload; } HV_X64_IO_PORT_INTERCEPT_MESSAGE_FULL; /** * The payload format for HvMessageTypeX64CpuidIntercept, * * @note This message does not include HV_X64_INTERCEPT_MESSAGE_HEADER! */ typedef struct { HV_X64_INTERCEPT_MESSAGE_HEADER Header; /**< 0x00: The usual intercept header. */ uint64_t Rax; /**< 0x28: Input RAX. */ uint64_t Rcx; /**< 0x30: Input RCX. */ uint64_t Rdx; /**< 0x38: Input RDX. */ uint64_t Rbx; /**< 0x40: Input RBX. */ uint64_t DefaultResultRax; /**< 0x48: Default result RAX. */ uint64_t DefaultResultRcx; /**< 0x50: Default result RCX. */ uint64_t DefaultResultRdx; /**< 0x58: Default result RDX. */ uint64_t DefaultResultRbx; /**< 0x60: Default result RBX. */ } HV_X64_CPUID_INTERCEPT_MESSAGE; AssertCompileSize(HV_X64_CPUID_INTERCEPT_MESSAGE, 0x68); /** Pointer to a HvMessageTypeX64CpuidIntercept payload. */ typedef HV_X64_CPUID_INTERCEPT_MESSAGE *PHV_X64_CPUID_INTERCEPT_MESSAGE; /** Pointer to a const HvMessageTypeX64CpuidIntercept payload. */ typedef HV_X64_CPUID_INTERCEPT_MESSAGE const *PCHV_X64_CPUID_INTERCEPT_MESSAGE; /** Full HvMessageTypeX64CpuidIntercept message. */ typedef struct { HV_MESSAGE_HEADER MsgHdr; HV_X64_CPUID_INTERCEPT_MESSAGE Payload; } HV_X64_CPUID_INTERCEPT_MESSAGE_FULL; /** X64 exception information (HvMessageTypeX64ExceptionIntercept). * @sa WHV_VP_EXCEPTION_INFO */ typedef union { uint8_t AsUINT8; struct { uint8_t ErrorCodeValid : 1; /** @todo WHV_VP_EXCEPTION_INFO::SoftwareException */ uint8_t Reserved : 7; }; } HV_X64_EXCEPTION_INFO; AssertCompileSize(HV_X64_EXCEPTION_INFO, 1); /** The payload format for HvMessageTypeX64ExceptionIntercept. * @sa WHV_VP_EXCEPTION_CONTEXT * @note max message size. */ typedef struct { HV_X64_INTERCEPT_MESSAGE_HEADER Header; /**< 0x00 */ uint16_t ExceptionVector; /**< 0x28 */ HV_X64_EXCEPTION_INFO ExceptionInfo; /**< 0x2a */ uint8_t InstructionByteCount; /**< 0x2b */ uint32_t ErrorCode; /**< 0x2c */ uint64_t ExceptionParameter; /**< 0x30 */ uint64_t Reserved; /**< 0x38 */ uint8_t InstructionBytes[16]; /**< 0x40 */ HV_X64_SEGMENT_REGISTER DsSegment; /**< 0x50 */ HV_X64_SEGMENT_REGISTER SsSegment; /**< 0x60 */ uint64_t Rax; /**< 0x70 */ uint64_t Rcx; /**< 0x78 */ uint64_t Rdx; /**< 0x80 */ uint64_t Rbx; /**< 0x88 */ uint64_t Rsp; /**< 0x90 */ uint64_t Rbp; /**< 0x98 */ uint64_t Rsi; /**< 0xa0 */ uint64_t Rdi; /**< 0xa8 */ uint64_t R8; /**< 0xb0 */ uint64_t R9; /**< 0xb8 */ uint64_t R10; /**< 0xc0 */ uint64_t R11; /**< 0xc8 */ uint64_t R12; /**< 0xd0 */ uint64_t R13; /**< 0xd8 */ uint64_t R14; /**< 0xe0 */ uint64_t R15; /**< 0xe8 */ } HV_X64_EXCEPTION_INTERCEPT_MESSAGE; AssertCompileSize(HV_X64_EXCEPTION_INTERCEPT_MESSAGE, 0xf0); /** Pointer to a HvMessageTypeX64ExceptionIntercept payload. */ typedef HV_X64_EXCEPTION_INTERCEPT_MESSAGE *PHV_X64_EXCEPTION_INTERCEPT_MESSAGE; /** Pointer to a ocnst HvMessageTypeX64ExceptionIntercept payload. */ typedef HV_X64_EXCEPTION_INTERCEPT_MESSAGE const *PCHV_X64_EXCEPTION_INTERCEPT_MESSAGE; /** * The payload format for HvMessageTypeX64Halt, * * @note This message does not include HV_X64_INTERCEPT_MESSAGE_HEADER! */ typedef struct { /** Seems to be a zero 64-bit field here. */ uint64_t u64Reserved; } HV_X64_HALT_MESSAGE; /** Pointer to a HvMessageTypeX64Halt payload. */ typedef HV_X64_HALT_MESSAGE *PHV_X64_HALT_MESSAGE; /** Pointer to a const HvMessageTypeX64Halt payload. */ typedef HV_X64_HALT_MESSAGE const *PCHV_X64_HALT_MESSAGE; /** Full HvMessageTypeX64Halt message. */ typedef struct { HV_MESSAGE_HEADER MsgHdr; HV_X64_HALT_MESSAGE Payload; } HV_X64_HALT_MESSAGE_FULL; /** * The payload format for HvMessageTypeX64InterruptWindow, * * @note This message does not include HV_X64_INTERCEPT_MESSAGE_HEADER! */ typedef struct { /** 0x00: The usual intercept header. */ HV_X64_INTERCEPT_MESSAGE_HEADER Header; /** 0x28: What's pending. */ HV_X64_PENDING_INTERRUPTION_TYPE Type; /** 0x2c: Explicit structure alignment padding. */ uint32_t u32ExplicitPadding; } HV_X64_INTERRUPT_WINDOW_MESSAGE; AssertCompileSize(HV_X64_INTERRUPT_WINDOW_MESSAGE, 0x30); /** Pointer to a HvMessageTypeX64InterruptWindow payload. */ typedef HV_X64_INTERRUPT_WINDOW_MESSAGE *PHV_X64_INTERRUPT_WINDOW_MESSAGE; /** Pointer to a const HvMessageTypeX64InterruptWindow payload. */ typedef HV_X64_INTERRUPT_WINDOW_MESSAGE const *PCHV_X64_INTERRUPT_WINDOW_MESSAGE; /** Full HvMessageTypeX64InterruptWindow message. */ typedef struct { /** Payload size is 0x30. */ HV_MESSAGE_HEADER MsgHdr; HV_X64_INTERRUPT_WINDOW_MESSAGE Payload; } HV_X64_INTERRUPT_WINDOW_MESSAGE_FULL; /** Hyper-V SynIC message. */ typedef struct { HV_MESSAGE_HEADER Header; /** 0x10 */ union { uint64_t Payload[HV_MESSAGE_MAX_PAYLOAD_QWORD_COUNT]; /** Common header for X64 intercept messages. * The HvMessageTypeUnrecoverableException message only has this. */ HV_X64_INTERCEPT_MESSAGE_HEADER X64InterceptHeader; /** HvMessageTypeGpaIntercept, HvMessageTypeUnmappedGpa. */ HV_X64_MEMORY_INTERCEPT_MESSAGE X64MemoryIntercept; /** HvMessageTypeX64IoPortIntercept */ HV_X64_IO_PORT_INTERCEPT_MESSAGE X64IoPortIntercept; /** HvMessageTypeX64MsrIntercept */ HV_X64_MSR_INTERCEPT_MESSAGE X64MsrIntercept; /** HvMessageTypeX64CpuidIntercept */ HV_X64_CPUID_INTERCEPT_MESSAGE X64CpuIdIntercept; /** HvMessageTypeX64ExceptionIntercept */ HV_X64_EXCEPTION_INTERCEPT_MESSAGE X64ExceptionIntercept; /** HvMessageTypeX64Halt. * @note No intercept header? */ HV_X64_HALT_MESSAGE X64Halt; /** HvMessageTypeX64InterruptWindow. */ HV_X64_INTERRUPT_WINDOW_MESSAGE X64InterruptWindow; }; } HV_MESSAGE; AssertCompileSize(HV_MESSAGE, HV_MESSAGE_SIZE); /** Pointer to a Hyper-V SynIC message. */ typedef HV_MESSAGE *PHV_MESSAGE; /** Pointer to const a Hyper-V SynIC message. */ typedef HV_MESSAGE const *PCHV_MESSAGE; #endif