Index: /trunk/include/VBox/err.h
===================================================================
--- /trunk/include/VBox/err.h	(revision 71086)
+++ /trunk/include/VBox/err.h	(revision 71087)
@@ -2823,4 +2823,12 @@
 /** NEM failed to unmap page(s) into the VM. */
 #define VERR_NEM_UNMAP_PAGES_FAILED                 (-6806)
+/** NEM failed to get registers. */
+#define VERR_NEM_GET_REGISTERS_FAILED               (-6807)
+/** NEM failed to set registers. */
+#define VERR_NEM_SET_REGISTERS_FAILED               (-6808)
+/** Get register caller must flush the TLB (not an error). */
+#define VERR_NEM_FLUSH_TLB                          (-6809)
+/** Get register caller must change the CPU mode (not an error). */
+#define VERR_NEM_CHANGE_PGM_MODE                    (-6810)
 /** @} */
 
Index: /trunk/include/VBox/vmm/nem.h
===================================================================
--- /trunk/include/VBox/vmm/nem.h	(revision 71086)
+++ /trunk/include/VBox/vmm/nem.h	(revision 71087)
@@ -87,4 +87,6 @@
 VMMR0_INT_DECL(int)  NEMR0MapPages(PGVM pGVM, PVM pVM, VMCPUID idCpu);
 VMMR0_INT_DECL(int)  NEMR0UnmapPages(PGVM pGVM, PVM pVM, VMCPUID idCpu);
+VMMR0_INT_DECL(int)  NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat);
+VMMR0_INT_DECL(int)  NEMR0ImportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat);
 /** @} */
 
Index: /trunk/include/VBox/vmm/vmm.h
===================================================================
--- /trunk/include/VBox/vmm/vmm.h	(revision 71086)
+++ /trunk/include/VBox/vmm/vmm.h	(revision 71087)
@@ -436,4 +436,8 @@
     /** Call NEMR0UnmapPages() (host specific). */
     VMMR0_DO_NEM_UNMAP_PAGES,
+    /** Call NEMR0ExportState() (host specific). */
+    VMMR0_DO_NEM_EXPORT_STATE,
+    /** Call NEMR0ImportState() (host specific). */
+    VMMR0_DO_NEM_IMPORT_STATE,
 
     /** Official call we use for testing Ring-0 APIs. */
Index: /trunk/include/iprt/nt/hyperv.h
===================================================================
--- /trunk/include/iprt/nt/hyperv.h	(revision 71086)
+++ /trunk/include/iprt/nt/hyperv.h	(revision 71087)
@@ -28,6 +28,13 @@
 #define ___iprt_nt_hyperv_h
 
-#include <iprt/types.h>
-#include <iprt/assertcompile.h>
+#ifndef IN_IDA_PRO
+# include <iprt/types.h>
+# include <iprt/assertcompile.h>
+#else
+# define RT_FLEXIBLE_ARRAY
+# define AssertCompile(expr)
+# define AssertCompileSize(type, size)
+# define AssertCompileMemberOffset(type, member, off)
+#endif
 
 
@@ -44,8 +51,11 @@
 /** System(/parent) physical page number. */
 typedef uint64_t HV_SPA_PAGE_NUMBER;
-
-
-
-/** Hypercall IDs.   */
+/** Hyper-V unsigned 128-bit integer type.   */
+typedef struct { uint64_t Low64, High64; } HV_UINT128;
+
+
+/**
+ * Hypercall IDs.
+ */
 typedef enum
 {
@@ -160,5 +170,6 @@
     HvCallStartVirtualProcessor = 0x99,
     HvCallGetVpIndexFromApicId,
-    /* 0x9b.. are reserved/undocumented. */
+    /* 0x9b..0xae are reserved/undocumented.
+       0xad: New version of HvCallGetVpRegisters? Perhaps on logical CPU or smth. */
     HvCallFlushGuestPhysicalAddressSpace = 0xaf,
     HvCallFlushGuestPhysicalAddressList,
@@ -197,4 +208,8 @@
 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. */
@@ -468,4 +483,604 @@
 
 
+/**
+ * Register names used by HvCallGetVpRegisters and HvCallSetVpRegisters.
+ */
+typedef enum _HV_REGISTER_NAME
+{
+    HvRegisterExplicitSuspend = 0x00000000,
+    HvRegisterInterceptSuspend,
+
+    HvRegisterHypervisorVersion = 0x00000100,           /**< @since v5 */
+
+    HvRegisterPrivilegesAndFeaturesInfo = 0x00000200,   /**< @since v5 */
+    HvRegisterFeaturesInfo,                             /**< @since v5 */
+    HvRegisterImplementationLimitsInfo,                 /**< @since v5 */
+    HvRegisterHardwareFeaturesInfo,                     /**< @since v5 */
+
+    HvRegisterGuestCrashP0 = 0x00000210,                /**< @since v5 */
+    HvRegisterGuestCrashP1,                             /**< @since v5 */
+    HvRegisterGuestCrashP2,                             /**< @since v5 */
+    HvRegisterGuestCrashP3,                             /**< @since v5 */
+    HvRegisterGuestCrashP4,                             /**< @since v5 */
+    HvRegisterGuestCrashCtl,                            /**< @since v5 */
+
+    HvRegisterPowerStateConfigC1 = 0x00000220,          /**< @since v5 */
+    HvRegisterPowerStateTriggerC1,                      /**< @since v5 */
+    HvRegisterPowerStateConfigC2,                       /**< @since v5 */
+    HvRegisterPowerStateTriggerC2,                      /**< @since v5 */
+    HvRegisterPowerStateConfigC3,                       /**< @since v5 */
+    HvRegisterPowerStateTriggerC3,                      /**< @since v5 */
+
+    HvRegisterSystemReset = 0x00000230,                 /**< @since v5 */
+
+    HvRegisterProcessorClockFrequency = 0x00000240,     /**< @since v5 */
+    HvRegisterInterruptClockFrequency,                  /**< @since v5 */
+
+    HvRegisterGuestIdle = 0x00000250,                   /**< @since v5 */
+
+    HvRegisterDebugDeviceOptions = 0x00000260,          /**< @since v5 */
+
+    HvRegisterPendingInterruption = 0x00010002,
+    HvRegisterInterruptState,
+    HvRegisterPendingEvent0,                            /**< @since v5 */
+    HvRegisterPendingEvent1,                            /**< @since v5 */
+
+    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,
+    HvX64RegisterMtrrDefType,
+
+    HvX64RegisterMtrrPhysBase0 = 0x00080010,
+    HvX64RegisterMtrrPhysBase1,
+    HvX64RegisterMtrrPhysBase2,
+    HvX64RegisterMtrrPhysBase3,
+    HvX64RegisterMtrrPhysBase4,
+    HvX64RegisterMtrrPhysBase5,
+    HvX64RegisterMtrrPhysBase6,
+    HvX64RegisterMtrrPhysBase7,
+    HvX64RegisterMtrrPhysBase8,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysBase9,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysBaseA,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysBaseB,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysBaseC,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysBaseD,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysBaseE,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysBaseF,                     /**< @since v4 */
+
+    HvX64RegisterMtrrPhysMask0 = 0x00080040,
+    HvX64RegisterMtrrPhysMask1,
+    HvX64RegisterMtrrPhysMask2,
+    HvX64RegisterMtrrPhysMask3,
+    HvX64RegisterMtrrPhysMask4,
+    HvX64RegisterMtrrPhysMask5,
+    HvX64RegisterMtrrPhysMask6,
+    HvX64RegisterMtrrPhysMask7,
+    HvX64RegisterMtrrPhysMask8,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysMask9,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysMaskA,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysMaskB,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysMaskC,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysMaskD,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysMaskE,                     /**< @since v4 */
+    HvX64RegisterMtrrPhysMaskF,                     /**< @since v4 */
+
+    HvX64RegisterMtrrFix64k00000 = 0x00080070,
+    HvX64RegisterMtrrFix16k80000,
+    HvX64RegisterMtrrFix16kA0000,
+    HvX64RegisterMtrrFix4kC0000,
+    HvX64RegisterMtrrFix4kC8000,
+    HvX64RegisterMtrrFix4kD0000,
+    HvX64RegisterMtrrFix4kD8000,
+    HvX64RegisterMtrrFix4kE0000,
+    HvX64RegisterMtrrFix4kE8000,
+    HvX64RegisterMtrrFix4kF0000,
+    HvX64RegisterMtrrFix4kF8000,
+
+    HvX64RegisterIa32MiscEnable = 0x000800a0,       /**< @since v5 */
+    HvX64RegisterIa32FeatureControl,                /**< @since v5 */
+
+    HvX64RegisterVpRuntime = 0x00090000,
+    HvX64RegisterHypercall,
+    HvRegisterGuestOsId,
+    HvRegisterVpIndex,
+    HvRegisterTimeRefCount,
+
+    HvRegisterCpuManagementVersion = 0x00090007,    /**< @since v5 */
+
+    HvX64RegisterEoi = 0x00090010,
+    HvX64RegisterIcr,
+    HvX64RegisterTpr,
+    HvRegisterVpAssistPage,
+
+    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,
+
+    HvX64RegisterYmm0Low = 0x000c0000,
+    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,
+
+    HvRegisterVsmCodePageOffsets = 0x000d0002,
+    HvRegisterVsmVpStatus,
+    HvRegisterVsmPartitionStatus,
+    HvRegisterVsmVina,
+    HvRegisterVsmCapabilities,
+    HvRegisterVsmPartitionConfig,
+
+    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 */
+
+} HV_REGISTER_NAME;
+AssertCompile(HvRegisterInterceptSuspend == 0x00000001);
+AssertCompile(HvRegisterPendingEvent1 == 0x00010005);
+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(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 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;
+/** 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;
+/** 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 HvCallGetVpRegister. */
+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 HvCallGetVpRegister. */
+typedef HV_INPUT_GET_VP_REGISTERS *PHV_INPUT_GET_VP_REGISTERS;
+/* Output for HvCallGetVpRegister is an array of HV_REGISTER_VALUE parallel to HV_INPUT_GET_VP_REGISTERS::Names. */
+
+
+/** Register and value pair for HvCallSetVpRegister. */
+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 HvCallSetVpRegister. */
+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 HvCallSetVpRegister. */
+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 HvCallSetVpRegister. */
+typedef HV_INPUT_SET_VP_REGISTERS *PHV_INPUT_SET_VP_REGISTERS;
+
+
 #endif
 
Index: /trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp	(revision 71086)
+++ /trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp	(revision 71087)
@@ -50,5 +50,5 @@
 *   Global Variables                                                                                                             *
 *********************************************************************************************************************************/
-static uint64_t (* g_pfnHvlInvokeHypercall)(uint64_t uCallInfo, uint64_t GCPhysInput, uint64_t GCPhysOutput);
+static uint64_t (* g_pfnHvlInvokeHypercall)(uint64_t uCallInfo, uint64_t HCPhysInput, uint64_t HCPhysOutput);
 
 
@@ -327,2 +327,833 @@
 
 
+/**
+ * Worker for NEMR0ExportState.
+ *
+ * Intention is to use it internally later.
+ *
+ * @returns VBox status code.
+ * @param   pGVM        The ring-0 VM handle.
+ * @param   pGVCpu      The irng-0 VCPU handle.
+ * @param   pCtx        The CPU context structure to import into.
+ * @param   fWhat       What to export. To be defined, UINT64_MAX for now.
+ */
+static int nemR0WinExportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat)
+{
+    PVMCPU                     pVCpu  = &pGVM->pVM->aCpus[pGVCpu->idCpu];
+    HV_INPUT_SET_VP_REGISTERS *pInput = (HV_INPUT_SET_VP_REGISTERS *)pGVCpu->nem.s.pbHypercallData;
+    AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3);
+
+    pInput->PartitionId = pGVM->nem.s.idHvPartition;
+    pInput->VpIndex     = pGVCpu->idCpu;
+    pInput->RsvdZ       = 0;
+
+    RT_NOREF_PV(fWhat); /** @todo group selection. */
+
+    /* GPRs */
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[0]);
+    pInput->Elements[0].Name                = HvX64RegisterRax;
+    pInput->Elements[0].Value.Reg64         = pCtx->rax;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[1]);
+    pInput->Elements[1].Name                = HvX64RegisterRcx;
+    pInput->Elements[1].Value.Reg64         = pCtx->rcx;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[2]);
+    pInput->Elements[2].Name                = HvX64RegisterRdx;
+    pInput->Elements[2].Value.Reg64         = pCtx->rdx;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[3]);
+    pInput->Elements[3].Name                = HvX64RegisterRbx;
+    pInput->Elements[3].Value.Reg64         = pCtx->rbx;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[4]);
+    pInput->Elements[4].Name                = HvX64RegisterRsp;
+    pInput->Elements[4].Value.Reg64         = pCtx->rsp;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[5]);
+    pInput->Elements[5].Name                = HvX64RegisterRbp;
+    pInput->Elements[5].Value.Reg64         = pCtx->rbp;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[6]);
+    pInput->Elements[6].Name                = HvX64RegisterRsi;
+    pInput->Elements[6].Value.Reg64         = pCtx->rsi;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[7]);
+    pInput->Elements[7].Name                = HvX64RegisterRdi;
+    pInput->Elements[7].Value.Reg64         = pCtx->rdi;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[8]);
+    pInput->Elements[8].Name                = HvX64RegisterR8;
+    pInput->Elements[8].Value.Reg64         = pCtx->r8;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[9]);
+    pInput->Elements[9].Name                = HvX64RegisterR9;
+    pInput->Elements[9].Value.Reg64         = pCtx->r9;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[10]);
+    pInput->Elements[10].Name                = HvX64RegisterR10;
+    pInput->Elements[10].Value.Reg64         = pCtx->r10;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[11]);
+    pInput->Elements[11].Name                = HvX64RegisterR11;
+    pInput->Elements[11].Value.Reg64         = pCtx->r11;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[12]);
+    pInput->Elements[12].Name                = HvX64RegisterR12;
+    pInput->Elements[12].Value.Reg64         = pCtx->r12;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[13]);
+    pInput->Elements[13].Name                = HvX64RegisterR13;
+    pInput->Elements[13].Value.Reg64         = pCtx->r13;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[14]);
+    pInput->Elements[14].Name                = HvX64RegisterR14;
+    pInput->Elements[14].Value.Reg64         = pCtx->r14;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[15]);
+    pInput->Elements[15].Name                = HvX64RegisterR15;
+    pInput->Elements[15].Value.Reg64         = pCtx->r15;
+
+    /* RIP & Flags */
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[16]);
+    pInput->Elements[16].Name                = HvX64RegisterRip;
+    pInput->Elements[16].Value.Reg64         = pCtx->rip;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[17]);
+    pInput->Elements[17].Name                = HvX64RegisterRflags;
+    pInput->Elements[17].Value.Reg64         = pCtx->rflags.u;
+
+    /* Segments */
+#define COPY_OUT_SEG(a_idx, a_enmName, a_SReg) \
+        do { \
+            HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[a_idx]); \
+            pInput->Elements[a_idx].Name                     = a_enmName; \
+            pInput->Elements[a_idx].Value.Segment.Base       = (a_SReg).u64Base; \
+            pInput->Elements[a_idx].Value.Segment.Limit      = (a_SReg).u32Limit; \
+            pInput->Elements[a_idx].Value.Segment.Selector   = (a_SReg).Sel; \
+            pInput->Elements[a_idx].Value.Segment.Attributes = (a_SReg).Attr.u; \
+        } while (0)
+    COPY_OUT_SEG(18, HvX64RegisterEs,   pCtx->es);
+    COPY_OUT_SEG(19, HvX64RegisterCs,   pCtx->cs);
+    COPY_OUT_SEG(20, HvX64RegisterSs,   pCtx->ss);
+    COPY_OUT_SEG(21, HvX64RegisterDs,   pCtx->ds);
+    COPY_OUT_SEG(22, HvX64RegisterFs,   pCtx->fs);
+    COPY_OUT_SEG(23, HvX64RegisterGs,   pCtx->gs);
+    COPY_OUT_SEG(24, HvX64RegisterLdtr, pCtx->ldtr);
+    COPY_OUT_SEG(25, HvX64RegisterTr,   pCtx->tr);
+
+    uintptr_t iReg = 26;
+    /* Descriptor tables. */
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Value.Table.Pad[0]   = 0;
+    pInput->Elements[iReg].Value.Table.Pad[1]   = 0;
+    pInput->Elements[iReg].Value.Table.Pad[2]   = 0;
+    pInput->Elements[iReg].Name                 = HvX64RegisterIdtr;
+    pInput->Elements[iReg].Value.Table.Limit    = pCtx->idtr.cbIdt;
+    pInput->Elements[iReg].Value.Table.Base     = pCtx->idtr.pIdt;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Value.Table.Pad[0]   = 0;
+    pInput->Elements[iReg].Value.Table.Pad[1]   = 0;
+    pInput->Elements[iReg].Value.Table.Pad[2]   = 0;
+    pInput->Elements[iReg].Name                 = HvX64RegisterGdtr;
+    pInput->Elements[iReg].Value.Table.Limit    = pCtx->gdtr.cbGdt;
+    pInput->Elements[iReg].Value.Table.Base     = pCtx->gdtr.pGdt;
+    iReg++;
+
+    /* Control registers. */
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterCr0;
+    pInput->Elements[iReg].Value.Reg64          = pCtx->cr0;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterCr2;
+    pInput->Elements[iReg].Value.Reg64          = pCtx->cr2;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterCr3;
+    pInput->Elements[iReg].Value.Reg64          = pCtx->cr3;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterCr4;
+    pInput->Elements[iReg].Value.Reg64          = pCtx->cr4;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterCr8;
+    pInput->Elements[iReg].Value.Reg64          = CPUMGetGuestCR8(pVCpu);
+    iReg++;
+
+    /* Debug registers. */
+/** @todo fixme. Figure out what the hyper-v version of KVM_SET_GUEST_DEBUG would be. */
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterDr0;
+    //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR0(pVCpu);
+    pInput->Elements[iReg].Value.Reg64          = pCtx->dr[0];
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterDr1;
+    //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR1(pVCpu);
+    pInput->Elements[iReg].Value.Reg64          = pCtx->dr[1];
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterDr2;
+    //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR2(pVCpu);
+    pInput->Elements[iReg].Value.Reg64          = pCtx->dr[2];
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterDr3;
+    //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR3(pVCpu);
+    pInput->Elements[iReg].Value.Reg64          = pCtx->dr[3];
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterDr6;
+    //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR6(pVCpu);
+    pInput->Elements[iReg].Value.Reg64          = pCtx->dr[6];
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterDr7;
+    //pInput->Elements[iReg].Value.Reg64        = CPUMGetHyperDR7(pVCpu);
+    pInput->Elements[iReg].Value.Reg64          = pCtx->dr[7];
+    iReg++;
+
+    /* Vector state. */
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm0;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm1;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm2;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm3;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm4;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm5;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm6;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm7;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm8;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm9;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm10;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm11;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm12;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm13;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm14;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterXmm15;
+    pInput->Elements[iReg].Value.Reg128.Low64   = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo;
+    pInput->Elements[iReg].Value.Reg128.High64  = pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi;
+    iReg++;
+
+    /* Floating point state. */
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx0;
+    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[0].au64[0];
+    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[0].au64[1];
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx1;
+    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[1].au64[0];
+    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[1].au64[1];
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx2;
+    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[2].au64[0];
+    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[2].au64[1];
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx3;
+    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[3].au64[0];
+    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[3].au64[1];
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx4;
+    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[4].au64[0];
+    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[4].au64[1];
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx5;
+    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[5].au64[0];
+    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[5].au64[1];
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx6;
+    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[6].au64[0];
+    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[6].au64[1];
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                      = HvX64RegisterFpMmx7;
+    pInput->Elements[iReg].Value.Fp.AsUINT128.Low64  = pCtx->pXStateR0->x87.aRegs[7].au64[0];
+    pInput->Elements[iReg].Value.Fp.AsUINT128.High64 = pCtx->pXStateR0->x87.aRegs[7].au64[1];
+    iReg++;
+
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                            = HvX64RegisterFpControlStatus;
+    pInput->Elements[iReg].Value.FpControlStatus.FpControl = pCtx->pXStateR0->x87.FCW;
+    pInput->Elements[iReg].Value.FpControlStatus.FpStatus  = pCtx->pXStateR0->x87.FSW;
+    pInput->Elements[iReg].Value.FpControlStatus.FpTag     = pCtx->pXStateR0->x87.FTW;
+    pInput->Elements[iReg].Value.FpControlStatus.Reserved  = pCtx->pXStateR0->x87.FTW >> 8;
+    pInput->Elements[iReg].Value.FpControlStatus.LastFpOp  = pCtx->pXStateR0->x87.FOP;
+    pInput->Elements[iReg].Value.FpControlStatus.LastFpRip = (pCtx->pXStateR0->x87.FPUIP)
+                                                           | ((uint64_t)pCtx->pXStateR0->x87.CS << 32)
+                                                           | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd1 << 48);
+    iReg++;
+
+    HV_REGISTER_ASSOC_ZERO_PADDING(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                                        = HvX64RegisterXmmControlStatus;
+    pInput->Elements[iReg].Value.XmmControlStatus.LastFpRdp            = (pCtx->pXStateR0->x87.FPUDP)
+                                                                       | ((uint64_t)pCtx->pXStateR0->x87.DS << 32)
+                                                                       | ((uint64_t)pCtx->pXStateR0->x87.Rsrvd2 << 48);
+    pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControl     = pCtx->pXStateR0->x87.MXCSR;
+    pInput->Elements[iReg].Value.XmmControlStatus.XmmStatusControlMask = pCtx->pXStateR0->x87.MXCSR_MASK; /** @todo ??? (Isn't this an output field?) */
+    iReg++;
+
+    /* MSRs */
+    // HvX64RegisterTsc - don't touch
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterEfer;
+    pInput->Elements[iReg].Value.Reg64          = pCtx->msrEFER;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterKernelGsBase;
+    pInput->Elements[iReg].Value.Reg64          = pCtx->msrKERNELGSBASE;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterApicBase;
+    pInput->Elements[iReg].Value.Reg64          = APICGetBaseMsrNoCheck(pVCpu);
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterPat;
+    pInput->Elements[iReg].Value.Reg64          = pCtx->msrPAT;
+    iReg++;
+    /// @todo HvX64RegisterSysenterCs
+    /// @todo HvX64RegisterSysenterEip
+    /// @todo HvX64RegisterSysenterEsp
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterStar;
+    pInput->Elements[iReg].Value.Reg64          = pCtx->msrSTAR;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterLstar;
+    pInput->Elements[iReg].Value.Reg64          = pCtx->msrLSTAR;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterCstar;
+    pInput->Elements[iReg].Value.Reg64          = pCtx->msrCSTAR;
+    iReg++;
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvX64RegisterSfmask;
+    pInput->Elements[iReg].Value.Reg64          = pCtx->msrSFMASK;
+    iReg++;
+
+    /* event injection (always clear it). */
+    HV_REGISTER_ASSOC_ZERO_PADDING_AND_HI64(&pInput->Elements[iReg]);
+    pInput->Elements[iReg].Name                 = HvRegisterPendingInterruption;
+    pInput->Elements[iReg].Value.Reg64          = 0;
+    iReg++;
+    /// @todo HvRegisterInterruptState
+    /// @todo HvRegisterPendingEvent0
+    /// @todo HvRegisterPendingEvent1
+
+    /*
+     * Set the registers.
+     */
+    Assert((uintptr_t)&pInput->Elements[iReg] - (uintptr_t)pGVCpu->nem.s.pbHypercallData < PAGE_SIZE); /* max is 127 */
+
+    /*
+     * Make the hypercall.
+     */
+    uint64_t uResult = g_pfnHvlInvokeHypercall(HV_MAKE_CALL_INFO(HvCallSetVpRegisters, iReg),
+                                               pGVCpu->nem.s.HCPhysHypercallData, 0 /*GCPhysOutput*/);
+    AssertLogRelMsgReturn(uResult == HV_MAKE_CALL_REP_RET(iReg),
+                          ("uResult=%RX64 iRegs=%#x\n", uResult, iReg),
+                          VERR_NEM_SET_REGISTERS_FAILED);
+    return VINF_SUCCESS;
+}
+
+
+/**
+ * Export the state to the native API (out of CPUMCTX).
+ *
+ * @returns VBox status code
+ * @param   pGVM        The ring-0 VM handle.
+ * @param   pVM         The cross context VM handle.
+ * @param   idCpu       The calling EMT.  Necessary for getting the
+ *                      hypercall page and arguments.
+ * @param   fWhat       What to export. To be defined, UINT64_MAX for now.
+ */
+VMMR0_INT_DECL(int)  NEMR0ExportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat)
+{
+    /*
+     * Validate the call.
+     */
+    int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, idCpu);
+    if (RT_SUCCESS(rc))
+    {
+        PVMCPU  pVCpu  = &pVM->aCpus[idCpu];
+        PGVMCPU pGVCpu = &pGVM->aCpus[idCpu];
+        AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API);
+
+        /** @todo fix pGVM->nem.s.idHvPartition init. */
+        if (pGVM->nem.s.idHvPartition == 0)
+            pGVM->nem.s.idHvPartition = pVM->nem.s.idHvPartition;
+
+        /*
+         * Call worker.
+         */
+        rc = nemR0WinExportState(pGVM, pGVCpu, CPUMQueryGuestCtxPtr(pVCpu), fWhat);
+    }
+    return rc;
+}
+
+
+/**
+ * Worker for NEMR0ImportState.
+ *
+ * Intention is to use it internally later.
+ *
+ * @returns VBox status code.
+ * @param   pGVM        The ring-0 VM handle.
+ * @param   pGVCpu      The irng-0 VCPU handle.
+ * @param   pCtx        The CPU context structure to import into.
+ * @param   fWhat       What to import. To be defined, UINT64_MAX for now.
+ */
+static int nemR0WinImportState(PGVM pGVM, PGVMCPU pGVCpu, PCPUMCTX pCtx, uint64_t fWhat)
+{
+    HV_INPUT_GET_VP_REGISTERS *pInput = (HV_INPUT_GET_VP_REGISTERS *)pGVCpu->nem.s.pbHypercallData;
+    AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3);
+
+    pInput->PartitionId = pGVM->nem.s.idHvPartition;
+    pInput->VpIndex     = pGVCpu->idCpu;
+    pInput->fFlags      = 0;
+
+    RT_NOREF_PV(fWhat); /** @todo group selection. */
+
+    /* GPRs */
+    pInput->Names[0]  = HvX64RegisterRax;
+    pInput->Names[1]  = HvX64RegisterRcx;
+    pInput->Names[2]  = HvX64RegisterRdx;
+    pInput->Names[3]  = HvX64RegisterRbx;
+    pInput->Names[4]  = HvX64RegisterRsp;
+    pInput->Names[5]  = HvX64RegisterRbp;
+    pInput->Names[6]  = HvX64RegisterRsi;
+    pInput->Names[7]  = HvX64RegisterRdi;
+    pInput->Names[8]  = HvX64RegisterR8;
+    pInput->Names[9]  = HvX64RegisterR9;
+    pInput->Names[10] = HvX64RegisterR10;
+    pInput->Names[11] = HvX64RegisterR11;
+    pInput->Names[12] = HvX64RegisterR12;
+    pInput->Names[13] = HvX64RegisterR13;
+    pInput->Names[14] = HvX64RegisterR14;
+    pInput->Names[15] = HvX64RegisterR15;
+
+    /* RIP & Flags */
+    pInput->Names[16] = HvX64RegisterRip;
+    pInput->Names[17] = HvX64RegisterRflags;
+
+    /* Segments */
+    pInput->Names[18] = HvX64RegisterEs;
+    pInput->Names[19] = HvX64RegisterCs;
+    pInput->Names[20] = HvX64RegisterSs;
+    pInput->Names[21] = HvX64RegisterDs;
+    pInput->Names[22] = HvX64RegisterFs;
+    pInput->Names[23] = HvX64RegisterGs;
+    pInput->Names[24] = HvX64RegisterLdtr;
+    pInput->Names[25] = HvX64RegisterTr;
+
+    /* Descriptor tables. */
+    pInput->Names[26] = HvX64RegisterIdtr;
+    pInput->Names[27] = HvX64RegisterGdtr;
+
+    /* Control registers. */
+    pInput->Names[28] = HvX64RegisterCr0;
+    pInput->Names[29] = HvX64RegisterCr2;
+    pInput->Names[30] = HvX64RegisterCr3;
+    pInput->Names[31] = HvX64RegisterCr4;
+    pInput->Names[32] = HvX64RegisterCr8;
+
+    /* Debug registers. */
+    pInput->Names[33] = HvX64RegisterDr0;
+    pInput->Names[34] = HvX64RegisterDr1;
+    pInput->Names[35] = HvX64RegisterDr2;
+    pInput->Names[36] = HvX64RegisterDr3;
+    pInput->Names[37] = HvX64RegisterDr6;
+    pInput->Names[38] = HvX64RegisterDr7;
+
+    /* Vector state. */
+    pInput->Names[39] = HvX64RegisterXmm0;
+    pInput->Names[40] = HvX64RegisterXmm1;
+    pInput->Names[41] = HvX64RegisterXmm2;
+    pInput->Names[42] = HvX64RegisterXmm3;
+    pInput->Names[43] = HvX64RegisterXmm4;
+    pInput->Names[44] = HvX64RegisterXmm5;
+    pInput->Names[45] = HvX64RegisterXmm6;
+    pInput->Names[46] = HvX64RegisterXmm7;
+    pInput->Names[47] = HvX64RegisterXmm8;
+    pInput->Names[48] = HvX64RegisterXmm9;
+    pInput->Names[49] = HvX64RegisterXmm10;
+    pInput->Names[50] = HvX64RegisterXmm11;
+    pInput->Names[51] = HvX64RegisterXmm12;
+    pInput->Names[52] = HvX64RegisterXmm13;
+    pInput->Names[53] = HvX64RegisterXmm14;
+    pInput->Names[54] = HvX64RegisterXmm15;
+
+    /* Floating point state. */
+    pInput->Names[55] = HvX64RegisterFpMmx0;
+    pInput->Names[56] = HvX64RegisterFpMmx1;
+    pInput->Names[57] = HvX64RegisterFpMmx2;
+    pInput->Names[58] = HvX64RegisterFpMmx3;
+    pInput->Names[59] = HvX64RegisterFpMmx4;
+    pInput->Names[60] = HvX64RegisterFpMmx5;
+    pInput->Names[61] = HvX64RegisterFpMmx6;
+    pInput->Names[62] = HvX64RegisterFpMmx7;
+    pInput->Names[63] = HvX64RegisterFpControlStatus;
+    pInput->Names[64] = HvX64RegisterXmmControlStatus;
+
+    /* MSRs */
+    // HvX64RegisterTsc - don't touch
+    pInput->Names[65] = HvX64RegisterEfer;
+    pInput->Names[66] = HvX64RegisterKernelGsBase;
+    pInput->Names[67] = HvX64RegisterApicBase;
+    pInput->Names[68] = HvX64RegisterPat;
+    pInput->Names[69] = HvX64RegisterSysenterCs;
+    pInput->Names[70] = HvX64RegisterSysenterEip;
+    pInput->Names[71] = HvX64RegisterSysenterEsp;
+    pInput->Names[72] = HvX64RegisterStar;
+    pInput->Names[73] = HvX64RegisterLstar;
+    pInput->Names[74] = HvX64RegisterCstar;
+    pInput->Names[75] = HvX64RegisterSfmask;
+
+    /* event injection */
+    pInput->Names[76] = HvRegisterPendingInterruption;
+    pInput->Names[77] = HvRegisterInterruptState;
+    pInput->Names[78] = HvRegisterInterruptState;
+    pInput->Names[79] = HvRegisterPendingEvent0;
+    pInput->Names[80] = HvRegisterPendingEvent1;
+    unsigned const cRegs   = 81;
+    size_t const   cbInput = RT_ALIGN_Z(RT_OFFSETOF(HV_INPUT_GET_VP_REGISTERS, Names[cRegs]), 32);
+
+    HV_REGISTER_VALUE *paValues = (HV_REGISTER_VALUE *)((uint8_t *)pInput + cbInput);
+    Assert((uintptr_t)&paValues[cRegs] - (uintptr_t)pGVCpu->nem.s.pbHypercallData < PAGE_SIZE); /* (max is around 168 registers) */
+    RT_BZERO(paValues, cRegs * sizeof(paValues[0]));
+
+    /*
+     * Make the hypercall.
+     */
+    uint64_t uResult = g_pfnHvlInvokeHypercall(HV_MAKE_CALL_INFO(HvCallGetVpRegisters, cRegs),
+                                               pGVCpu->nem.s.HCPhysHypercallData,
+                                               pGVCpu->nem.s.HCPhysHypercallData + cbInput);
+    AssertLogRelMsgReturn(uResult == HV_MAKE_CALL_REP_RET(cRegs),
+                          ("uResult=%RX64 cRegs=%#x\n", uResult, cRegs),
+                          VERR_NEM_GET_REGISTERS_FAILED);
+
+    /*
+     * Copy information to the CPUM context.
+     */
+    PVMCPU pVCpu = &pGVM->pVM->aCpus[pGVCpu->idCpu];
+
+    /* GPRs */
+    Assert(pInput->Names[0]  == HvX64RegisterRax);
+    Assert(pInput->Names[15] == HvX64RegisterR15);
+    pCtx->rax = paValues[0].Reg64;
+    pCtx->rcx = paValues[1].Reg64;
+    pCtx->rdx = paValues[2].Reg64;
+    pCtx->rbx = paValues[3].Reg64;
+    pCtx->rsp = paValues[4].Reg64;
+    pCtx->rbp = paValues[5].Reg64;
+    pCtx->rsi = paValues[6].Reg64;
+    pCtx->rdi = paValues[7].Reg64;
+    pCtx->r8  = paValues[8].Reg64;
+    pCtx->r9  = paValues[9].Reg64;
+    pCtx->r10 = paValues[10].Reg64;
+    pCtx->r11 = paValues[11].Reg64;
+    pCtx->r12 = paValues[12].Reg64;
+    pCtx->r13 = paValues[13].Reg64;
+    pCtx->r14 = paValues[14].Reg64;
+    pCtx->r15 = paValues[15].Reg64;
+
+    /* RIP & Flags */
+    Assert(pInput->Names[16] == HvX64RegisterRip);
+    pCtx->rip      = paValues[16].Reg64;
+    pCtx->rflags.u = paValues[17].Reg64;
+
+    /* Segments */
+#define COPY_BACK_SEG(a_idx, a_enmName, a_SReg) \
+        do { \
+            Assert(pInput->Names[a_idx] == a_enmName); \
+            (a_SReg).u64Base  = paValues[a_idx].Segment.Base; \
+            (a_SReg).u32Limit = paValues[a_idx].Segment.Limit; \
+            (a_SReg).ValidSel = (a_SReg).Sel = paValues[a_idx].Segment.Selector; \
+            (a_SReg).Attr.u   = paValues[a_idx].Segment.Attributes; \
+            (a_SReg).fFlags   = CPUMSELREG_FLAGS_VALID; \
+        } while (0)
+    COPY_BACK_SEG(18, HvX64RegisterEs,   pCtx->es);
+    COPY_BACK_SEG(19, HvX64RegisterCs,   pCtx->cs);
+    COPY_BACK_SEG(20, HvX64RegisterSs,   pCtx->ss);
+    COPY_BACK_SEG(21, HvX64RegisterDs,   pCtx->ds);
+    COPY_BACK_SEG(22, HvX64RegisterFs,   pCtx->fs);
+    COPY_BACK_SEG(23, HvX64RegisterGs,   pCtx->gs);
+    COPY_BACK_SEG(24, HvX64RegisterLdtr, pCtx->ldtr);
+    COPY_BACK_SEG(25, HvX64RegisterTr,   pCtx->tr);
+
+    /* Descriptor tables. */
+    Assert(pInput->Names[26] == HvX64RegisterIdtr);
+    pCtx->idtr.cbIdt = paValues[26].Table.Limit;
+    pCtx->idtr.pIdt  = paValues[26].Table.Base;
+    Assert(pInput->Names[27] == HvX64RegisterGdtr);
+    pCtx->gdtr.cbGdt = paValues[27].Table.Limit;
+    pCtx->gdtr.pGdt  = paValues[27].Table.Base;
+
+    /* Control registers. */
+    Assert(pInput->Names[28] == HvX64RegisterCr0);
+    bool fMaybeChangedMode = false;
+    bool fFlushTlb         = false;
+    bool fFlushGlobalTlb   = false;
+    if (pCtx->cr0 != paValues[28].Reg64)
+    {
+        CPUMSetGuestCR0(pVCpu, paValues[28].Reg64);
+        fMaybeChangedMode = true;
+        fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this
+    }
+    Assert(pInput->Names[29] == HvX64RegisterCr2);
+    pCtx->cr2 = paValues[29].Reg64;
+    if (pCtx->cr3 != paValues[30].Reg64)
+    {
+        CPUMSetGuestCR3(pVCpu, paValues[30].Reg64);
+        fFlushTlb = true;
+    }
+    if (pCtx->cr4 != paValues[31].Reg64)
+    {
+        CPUMSetGuestCR4(pVCpu, paValues[31].Reg64);
+        fMaybeChangedMode = true;
+        fFlushTlb = fFlushGlobalTlb = true; /// @todo fix this
+    }
+    APICSetTpr(pVCpu, (uint8_t)paValues[32].Reg64 << 4);
+
+    /* Debug registers. */
+    Assert(pInput->Names[33] == HvX64RegisterDr0);
+/** @todo fixme */
+    if (pCtx->dr[0] != paValues[33].Reg64)
+        CPUMSetGuestDR0(pVCpu, paValues[33].Reg64);
+    if (pCtx->dr[1] != paValues[34].Reg64)
+        CPUMSetGuestDR1(pVCpu, paValues[34].Reg64);
+    if (pCtx->dr[2] != paValues[35].Reg64)
+        CPUMSetGuestDR2(pVCpu, paValues[35].Reg64);
+    if (pCtx->dr[3] != paValues[36].Reg64)
+        CPUMSetGuestDR3(pVCpu, paValues[36].Reg64);
+    Assert(pInput->Names[37] == HvX64RegisterDr6);
+    Assert(pInput->Names[38] == HvX64RegisterDr7);
+    if (pCtx->dr[6] != paValues[37].Reg64)
+        CPUMSetGuestDR6(pVCpu, paValues[37].Reg64);
+    if (pCtx->dr[7] != paValues[38].Reg64)
+        CPUMSetGuestDR6(pVCpu, paValues[38].Reg64);
+
+    /* Vector state. */
+    Assert(pInput->Names[39] == HvX64RegisterXmm0);
+    Assert(pInput->Names[54] == HvX64RegisterXmm15);
+    pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Lo  = paValues[39].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[0].uXmm.s.Hi  = paValues[39].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Lo  = paValues[40].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[1].uXmm.s.Hi  = paValues[40].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Lo  = paValues[41].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[2].uXmm.s.Hi  = paValues[41].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Lo  = paValues[42].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[3].uXmm.s.Hi  = paValues[42].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Lo  = paValues[43].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[4].uXmm.s.Hi  = paValues[43].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Lo  = paValues[44].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[5].uXmm.s.Hi  = paValues[44].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Lo  = paValues[45].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[6].uXmm.s.Hi  = paValues[45].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Lo  = paValues[46].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[7].uXmm.s.Hi  = paValues[46].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Lo  = paValues[47].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[8].uXmm.s.Hi  = paValues[47].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Lo  = paValues[48].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[9].uXmm.s.Hi  = paValues[48].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Lo = paValues[49].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[10].uXmm.s.Hi = paValues[49].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Lo = paValues[50].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[11].uXmm.s.Hi = paValues[50].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Lo = paValues[51].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[12].uXmm.s.Hi = paValues[51].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Lo = paValues[52].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[13].uXmm.s.Hi = paValues[52].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Lo = paValues[53].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[14].uXmm.s.Hi = paValues[53].Reg128.High64;
+    pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Lo = paValues[54].Reg128.Low64;
+    pCtx->pXStateR0->x87.aXMM[15].uXmm.s.Hi = paValues[54].Reg128.High64;
+
+    /* Floating point state. */
+    Assert(pInput->Names[55] == HvX64RegisterFpMmx0);
+    Assert(pInput->Names[62] == HvX64RegisterFpMmx7);
+    pCtx->pXStateR0->x87.aRegs[0].au64[0] = paValues[55].Fp.AsUINT128.Low64;
+    pCtx->pXStateR0->x87.aRegs[0].au64[1] = paValues[55].Fp.AsUINT128.High64;
+    pCtx->pXStateR0->x87.aRegs[1].au64[0] = paValues[56].Fp.AsUINT128.Low64;
+    pCtx->pXStateR0->x87.aRegs[1].au64[1] = paValues[56].Fp.AsUINT128.High64;
+    pCtx->pXStateR0->x87.aRegs[2].au64[0] = paValues[57].Fp.AsUINT128.Low64;
+    pCtx->pXStateR0->x87.aRegs[2].au64[1] = paValues[57].Fp.AsUINT128.High64;
+    pCtx->pXStateR0->x87.aRegs[3].au64[0] = paValues[58].Fp.AsUINT128.Low64;
+    pCtx->pXStateR0->x87.aRegs[3].au64[1] = paValues[58].Fp.AsUINT128.High64;
+    pCtx->pXStateR0->x87.aRegs[4].au64[0] = paValues[59].Fp.AsUINT128.Low64;
+    pCtx->pXStateR0->x87.aRegs[4].au64[1] = paValues[59].Fp.AsUINT128.High64;
+    pCtx->pXStateR0->x87.aRegs[5].au64[0] = paValues[60].Fp.AsUINT128.Low64;
+    pCtx->pXStateR0->x87.aRegs[5].au64[1] = paValues[60].Fp.AsUINT128.High64;
+    pCtx->pXStateR0->x87.aRegs[6].au64[0] = paValues[61].Fp.AsUINT128.Low64;
+    pCtx->pXStateR0->x87.aRegs[6].au64[1] = paValues[61].Fp.AsUINT128.High64;
+    pCtx->pXStateR0->x87.aRegs[7].au64[0] = paValues[62].Fp.AsUINT128.Low64;
+    pCtx->pXStateR0->x87.aRegs[7].au64[1] = paValues[62].Fp.AsUINT128.High64;
+
+    Assert(pInput->Names[63] == HvX64RegisterFpControlStatus);
+    pCtx->pXStateR0->x87.FCW        = paValues[63].FpControlStatus.FpControl;
+    pCtx->pXStateR0->x87.FSW        = paValues[63].FpControlStatus.FpStatus;
+    pCtx->pXStateR0->x87.FTW        = paValues[63].FpControlStatus.FpTag
+                                    /*| (paValues[63].FpControlStatus.Reserved << 8)*/;
+    pCtx->pXStateR0->x87.FOP        = paValues[63].FpControlStatus.LastFpOp;
+    pCtx->pXStateR0->x87.FPUIP      = (uint32_t)paValues[63].FpControlStatus.LastFpRip;
+    pCtx->pXStateR0->x87.CS         = (uint16_t)(paValues[63].FpControlStatus.LastFpRip >> 32);
+    pCtx->pXStateR0->x87.Rsrvd1     = (uint16_t)(paValues[63].FpControlStatus.LastFpRip >> 48);
+
+    Assert(pInput->Names[64] == HvX64RegisterXmmControlStatus);
+    pCtx->pXStateR0->x87.FPUDP      = (uint32_t)paValues[64].XmmControlStatus.LastFpRdp;
+    pCtx->pXStateR0->x87.DS         = (uint16_t)(paValues[64].XmmControlStatus.LastFpRdp >> 32);
+    pCtx->pXStateR0->x87.Rsrvd2     = (uint16_t)(paValues[64].XmmControlStatus.LastFpRdp >> 48);
+    pCtx->pXStateR0->x87.MXCSR      = paValues[64].XmmControlStatus.XmmStatusControl;
+    pCtx->pXStateR0->x87.MXCSR_MASK = paValues[64].XmmControlStatus.XmmStatusControlMask; /** @todo ??? (Isn't this an output field?) */
+
+    /* MSRs */
+    // HvX64RegisterTsc - don't touch
+    Assert(pInput->Names[65] == HvX64RegisterEfer);
+    if (paValues[65].Reg64 != pCtx->msrEFER)
+    {
+        pCtx->msrEFER = paValues[65].Reg64;
+        fMaybeChangedMode = true;
+    }
+
+    Assert(pInput->Names[66] == HvX64RegisterKernelGsBase);
+    pCtx->msrKERNELGSBASE = paValues[66].Reg64;
+
+    Assert(pInput->Names[67] == HvX64RegisterApicBase);
+    if (paValues[67].Reg64 != APICGetBaseMsrNoCheck(pVCpu))
+    {
+        VBOXSTRICTRC rc2 = APICSetBaseMsr(pVCpu, paValues[67].Reg64);
+        Assert(rc2 == VINF_SUCCESS); NOREF(rc2);
+    }
+
+    Assert(pInput->Names[68] == HvX64RegisterPat);
+    pCtx->msrPAT    = paValues[68].Reg64;
+    /// @todo HvX64RegisterSysenterCs
+    /// @todo HvX64RegisterSysenterEip
+    /// @todo HvX64RegisterSysenterEsp
+    Assert(pInput->Names[72] == HvX64RegisterStar);
+    pCtx->msrSTAR   = paValues[72].Reg64;
+    Assert(pInput->Names[73] == HvX64RegisterLstar);
+    pCtx->msrLSTAR  = paValues[73].Reg64;
+    Assert(pInput->Names[74] == HvX64RegisterCstar);
+    pCtx->msrCSTAR  = paValues[74].Reg64;
+    Assert(pInput->Names[75] == HvX64RegisterSfmask);
+    pCtx->msrSFMASK = paValues[75].Reg64;
+
+    /// @todo HvRegisterPendingInterruption
+    Assert(pInput->Names[76] == HvRegisterPendingInterruption);
+    if (paValues[76].PendingInterruption.InterruptionPending)
+    {
+        Log7(("PendingInterruption: type=%u vector=%#x errcd=%RTbool/%#x instr-len=%u nested=%u\n",
+              paValues[76].PendingInterruption.InterruptionType, paValues[76].PendingInterruption.InterruptionVector,
+              paValues[76].PendingInterruption.DeliverErrorCode, paValues[76].PendingInterruption.ErrorCode,
+              paValues[76].PendingInterruption.InstructionLength, paValues[76].PendingInterruption.NestedEvent));
+        AssertMsg((paValues[76].PendingInterruption.AsUINT64 & UINT64_C(0xfc00)) == 0,
+                  ("%#RX64\n", paValues[76].PendingInterruption.AsUINT64));
+    }
+
+    /// @todo HvRegisterInterruptState
+    /// @todo HvRegisterPendingEvent0
+    /// @todo HvRegisterPendingEvent1
+
+    int rc = VINF_SUCCESS;
+    if (fMaybeChangedMode)
+    {
+        rc = PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
+        if (rc == VINF_PGM_CHANGE_MODE)
+            rc = VERR_NEM_CHANGE_PGM_MODE;
+        else
+            AssertRC(rc);
+    }
+    if (fFlushTlb && rc == VINF_SUCCESS)
+        rc = VERR_NEM_FLUSH_TLB; /* Calling PGMFlushTLB w/o long jump setup doesn't work, ring-3 does it. */
+
+    return rc;
+}
+
+
+/**
+ * Import the state from the native API (back to CPUMCTX).
+ *
+ * @returns VBox status code
+ * @param   pGVM        The ring-0 VM handle.
+ * @param   pVM         The cross context VM handle.
+ * @param   idCpu       The calling EMT.  Necessary for getting the
+ *                      hypercall page and arguments.
+ * @param   fWhat       What to import. To be defined, UINT64_MAX for now.
+ */
+VMMR0_INT_DECL(int)  NEMR0ImportState(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t fWhat)
+{
+    /*
+     * Validate the call.
+     */
+    int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, idCpu);
+    if (RT_SUCCESS(rc))
+    {
+        PVMCPU  pVCpu  = &pVM->aCpus[idCpu];
+        PGVMCPU pGVCpu = &pGVM->aCpus[idCpu];
+        AssertReturn(g_pfnHvlInvokeHypercall, VERR_NEM_MISSING_KERNEL_API);
+
+        /** @todo fix pGVM->nem.s.idHvPartition init. */
+        if (pGVM->nem.s.idHvPartition == 0)
+            pGVM->nem.s.idHvPartition = pVM->nem.s.idHvPartition;
+
+        /*
+         * Call worker.
+         */
+        rc = nemR0WinImportState(pGVM, pGVCpu, CPUMQueryGuestCtxPtr(pVCpu), fWhat);
+    }
+    return rc;
+}
+
Index: /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 71086)
+++ /trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 71087)
@@ -1988,4 +1988,18 @@
             VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
             break;
+
+        case VMMR0_DO_NEM_EXPORT_STATE:
+            if (pReqHdr || idCpu == NIL_VMCPUID)
+                return VERR_INVALID_PARAMETER;
+            rc = NEMR0ExportState(pGVM, pVM, idCpu, u64Arg);
+            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
+            break;
+
+        case VMMR0_DO_NEM_IMPORT_STATE:
+            if (pReqHdr || idCpu == NIL_VMCPUID)
+                return VERR_INVALID_PARAMETER;
+            rc = NEMR0ImportState(pGVM, pVM, idCpu, u64Arg);
+            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
+            break;
 # endif
 #endif
Index: /trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp	(revision 71086)
+++ /trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp	(revision 71087)
@@ -78,5 +78,6 @@
 
 
-#define NEM_WIN_USE_HYPERCALLS
+#define NEM_WIN_USE_HYPERCALLS_FOR_PAGES
+#define NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
 
 
@@ -99,33 +100,4 @@
 AssertCompileSize(MISSINGINTERUPTSTATEREG, 16);
 
-/** Used by MISSINGPENDINGINTERRUPTIONREG. */
-typedef enum MISSINGPENDINGINTERRUPTIONTYPE
-{
-    kPendingIntType_Interrupt = 0,
-    kPendingIntType_Nmi,
-    kPendingIntType_Xcpt,
-    kPendingIntType_Dunno,
-    kPendingIntType_SoftwareInterrupt
-} MISSINGPENDINGINTERRUPTIONTYPE;
-
-/** WHvRegisterPendingInterruption layout, reconstructed from the v7.1 DDK. */
-typedef union MISSINGPENDINGINTERRUPTIONREG
-{
-    /** 64-bit view. */
-    uint64_t au64[2];
-    struct /* unamed */
-    {
-        uint32_t fInterruptionPending : 1;
-        uint32_t enmInterruptionType : 3; /**< MISSINGPENDINGINTERRUPTIONTYPE */
-        uint32_t fDeliverErrCd : 1;
-        uint32_t fUnknown0 : 1;
-        uint32_t fUnknown1 : 1; /**< Observed set when software interrupt was issued. */
-        uint32_t uReserved0 : 9;
-        uint32_t InterruptionVector : 16;
-        uint32_t uErrCd;
-        uint64_t uReserved1;
-    };
-} MISSINGPENDINGINTERRUPTIONREG;
-AssertCompileSize(MISSINGPENDINGINTERRUPTIONREG, 16);
 
 
@@ -985,5 +957,5 @@
 
 
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
 
 /**
@@ -1023,8 +995,15 @@
 }
 
-#endif /* NEM_WIN_USE_HYPERCALLS */
+#endif /* NEM_WIN_USE_HYPERCALLS_FOR_PAGES */
 
 static int nemR3WinCopyStateToHyperV(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 {
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
+    NOREF(pCtx);
+    int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_EXPORT_STATE, UINT64_MAX, NULL);
+    AssertLogRelRCReturn(rc, rc);
+    return rc;
+
+#else
     WHV_REGISTER_NAME  aenmNames[128];
     WHV_REGISTER_VALUE aValues[128];
@@ -1293,7 +1272,4 @@
 
     /* event injection (always clear it). */
-    /** @todo Someone at microsoft please explain why HV_X64_PENDING_INTERRUPTION_REGISTER
-     * and HV_X64_INTERRUPT_STATE_REGISTER are missing from the headers.  Ditto for
-     * wathever structures WHvRegisterPendingEvent0/1 uses.   */
     aenmNames[iReg]     = WHvRegisterPendingInterruption;
     aValues[iReg].Reg64 = 0;
@@ -1319,8 +1295,22 @@
                            hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));
     return VERR_INTERNAL_ERROR;
+#endif /* !NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */
 }
 
 static int nemR3WinCopyStateFromHyperV(PVM pVM, PVMCPU pVCpu, PCPUMCTX pCtx)
 {
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS
+    NOREF(pCtx);
+    int rc = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_IMPORT_STATE, UINT64_MAX, NULL);
+    if (RT_SUCCESS(rc))
+        return rc;
+    if (rc == VERR_NEM_FLUSH_TLB)
+        return PGMFlushTLB(pVCpu, pCtx->cr3, true /*fGlobal*/);
+    if (rc == VERR_NEM_CHANGE_PGM_MODE)
+        return PGMChangeMode(pVCpu, pCtx->cr0, pCtx->cr4, pCtx->msrEFER);
+    AssertLogRelRCReturn(rc, rc);
+    return rc;
+
+#else
     WHV_REGISTER_NAME  aenmNames[128];
 
@@ -1646,15 +1636,11 @@
         /// @todo WHvRegisterPendingInterruption
         Assert(aenmNames[76] == WHvRegisterPendingInterruption);
-        /** @todo Someone at microsoft please explain why HV_X64_PENDING_INTERRUPTION_REGISTER
-         * and HV_X64_INTERRUPT_STATE_REGISTER are missing from the headers.  Ditto for
-         * wathever structures WHvRegisterPendingEvent0/1 uses.   */
-        MISSINGPENDINGINTERRUPTIONREG const * pPendingInt = (MISSINGPENDINGINTERRUPTIONREG const *)&aValues[76];
-        if (pPendingInt->fInterruptionPending)
-        {
-            Log7(("PendingInterruption: type=%u vector=%#x errcd=%RTbool/%#x unk0=%u unk1=%u\n",
-                  pPendingInt->enmInterruptionType, pPendingInt->InterruptionVector, pPendingInt->fDeliverErrCd,
-                  pPendingInt->uErrCd, pPendingInt->fUnknown0, pPendingInt->fUnknown1));
-            AssertMsg(pPendingInt->uReserved0 == 0 && pPendingInt->uReserved1 == 0,
-                      ("%#RX64 %#RX64\n", pPendingInt->au64[0], pPendingInt->au64[1]));
+        WHV_X64_PENDING_INTERRUPTION_REGISTER const * pPendingInt = (WHV_X64_PENDING_INTERRUPTION_REGISTER const *)&aValues[76];
+        if (pPendingInt->InterruptionPending)
+        {
+            Log7(("PendingInterruption: type=%u vector=%#x errcd=%RTbool/%#x instr-len=%u nested=%u\n",
+                  pPendingInt->InterruptionType, pPendingInt->InterruptionVector, pPendingInt->DeliverErrorCode,
+                  pPendingInt->ErrorCode, pPendingInt->InstructionLength, pPendingInt->NestedEvent));
+            AssertMsg((pPendingInt->AsUINT64 & UINT64_C(0xfc00)) == 0, ("%#RX64\n", pPendingInt->AsUINT64));
         }
 
@@ -1682,4 +1668,5 @@
                            hrc, RTNtCurrentTeb()->LastStatusValue, RTNtCurrentTeb()->LastErrorValue));
     return VERR_INTERNAL_ERROR;
+#endif /* !NEM_WIN_USE_HYPERCALLS_FOR_REGISTERS */
 }
 
@@ -1884,5 +1871,5 @@
 {
     RT_NOREF_PV(pvUser);
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
     int rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhys);
     AssertRC(rc);
@@ -1899,5 +1886,5 @@
     else
     {
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
         LogRel(("nemR3WinUnmapOnePageCallback: GCPhys=%RGp rc=%Rrc\n", GCPhys, rc));
 #else
@@ -1962,5 +1949,5 @@
      * We don't really consider downgrades here, as they shouldn't happen.
      */
-#ifndef NEM_WIN_USE_HYPERCALLS
+#ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
     /** @todo Someone at microsoft please explain:
      * I'm not sure WTF was going on, but I ended up in a loop if I remapped a
@@ -2014,5 +2001,5 @@
             }
 
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
             /* Upgrade page to writable. */
 /** @todo test this*/
@@ -2050,5 +2037,5 @@
                 return VINF_SUCCESS;
             }
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
             AssertFailed(); /* There should be no downgrades. */
 #endif
@@ -2063,5 +2050,5 @@
      * If this fails, which it does every so often, just unmap everything for now.
      */
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
     rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhys);
     AssertRC(rc);
@@ -2080,5 +2067,5 @@
         return VINF_SUCCESS;
     }
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
     LogRel(("nemR3WinHandleMemoryAccessPageCheckerCallback/unmap: GCPhysDst=%RGp rc=%Rrc\n", GCPhys, rc));
     return rc;
@@ -2455,5 +2442,5 @@
         }
 
-#ifndef NEM_WIN_USE_HYPERCALLS
+#ifndef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
         /* Hack alert! */
         uint32_t const cMappedPages = pVM->nem.s.cMappedPages;
@@ -2637,5 +2624,5 @@
     if (pInfo->u2NemState > NEM_WIN_PAGE_STATE_UNMAPPED)
     {
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
         int rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhys);
         AssertRC(rc);
@@ -2652,5 +2639,5 @@
         else
         {
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
             LogRel(("nemR3WinUnsetForA20CheckerCallback/unmap: GCPhys=%RGp rc=%Rrc\n", GCPhys, rc));
             return rc;
@@ -2752,5 +2739,5 @@
                                   uint8_t *pu2State, bool fBackingChanged)
 {
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
     /*
      * When using the hypercalls instead of the ring-3 APIs, we don't need to
@@ -2836,5 +2823,5 @@
         if (u2OldState > NEM_WIN_PAGE_STATE_UNMAPPED)
         {
-# ifdef NEM_WIN_USE_HYPERCALLS
+# ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
             int rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhysDst);
             AssertRC(rc);
@@ -2883,5 +2870,5 @@
     if (fPageProt & NEM_PAGE_PROT_WRITE)
     {
-# ifdef NEM_WIN_USE_HYPERCALLS
+# ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
         int rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhysDst,
                                             HV_MAP_GPA_READABLE   | HV_MAP_GPA_WRITABLE
@@ -2924,5 +2911,5 @@
     if (fPageProt & NEM_PAGE_PROT_READ)
     {
-# ifdef NEM_WIN_USE_HYPERCALLS
+# ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
         int rc = nemR3WinHypercallMapPage(pVM, pVCpu, GCPhysSrc, GCPhysDst,
                                           HV_MAP_GPA_READABLE | HV_MAP_GPA_EXECUTABLE | HV_MAP_GPA_EXECUTABLE_AGAIN);
@@ -2965,5 +2952,5 @@
     *pu2State = NEM_WIN_PAGE_STATE_UNMAPPED;
     return VINF_SUCCESS;
-#endif /* !NEM_WIN_USE_HYPERCALLS */
+#endif /* !NEM_WIN_USE_HYPERCALLS_FOR_PAGES */
 }
 
@@ -2978,5 +2965,5 @@
     }
 
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
     PVMCPU pVCpu = VMMGetCpu(pVM);
     int rc = nemR3WinHypercallUnmapPage(pVM, pVCpu, GCPhysDst);
@@ -3015,5 +3002,5 @@
 
     int rc;
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (   pVM->nem.s.fA20Enabled
@@ -3049,5 +3036,5 @@
     RT_NOREF_PV(HCPhys); RT_NOREF_PV(enmType);
 
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (   pVM->nem.s.fA20Enabled
@@ -3080,5 +3067,5 @@
     RT_NOREF_PV(HCPhysPrev); RT_NOREF_PV(HCPhysNew); RT_NOREF_PV(enmType);
 
-#ifdef NEM_WIN_USE_HYPERCALLS
+#ifdef NEM_WIN_USE_HYPERCALLS_FOR_PAGES
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (   pVM->nem.s.fA20Enabled
