Index: trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp	(revision 72539)
+++ trunk/src/VBox/VMM/VMMR0/NEMR0Native-win.cpp	(revision 72541)
@@ -333,5 +333,4 @@
                           VERR_NEM_INIT_FAILED);
 
-
     return rc;
 }
@@ -2285,4 +2284,5 @@
 }
 
+
 VMMR0_INT_DECL(VBOXSTRICTRC) NEMR0RunGuestCode(PGVM pGVM, VMCPUID idCpu)
 {
@@ -2369,2 +2369,80 @@
 }
 
+
+#if 1 && defined(DEBUG_bird)
+/**
+ * Debug only interface for poking around and exploring Hyper-V stuff.
+ *
+ * @param   pGVM        The ring-0 VM handle.
+ * @param   pVM         The cross context VM handle.
+ * @param   idCpu       The calling EMT.
+ * @param   u64Arg      What to query.  0 == registers.
+ */
+VMMR0_INT_DECL(int) NEMR0DoExperiment(PGVM pGVM, PVM pVM, VMCPUID idCpu, uint64_t u64Arg)
+{
+    /*
+     * Resolve CPU structures.
+     */
+    int rc = GVMMR0ValidateGVMandVMandEMT(pGVM, pVM, idCpu);
+    if (RT_SUCCESS(rc))
+    {
+        PGVMCPU pGVCpu = &pGVM->aCpus[idCpu];
+        PVMCPU  pVCpu  = &pVM->aCpus[idCpu];
+        if (u64Arg == 0)
+        {
+            /*
+             * Query register.
+             */
+            HV_INPUT_GET_VP_REGISTERS *pInput = (HV_INPUT_GET_VP_REGISTERS *)pGVCpu->nem.s.HypercallData.pbPage;
+            AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3);
+
+            size_t const cbInput = RT_ALIGN_Z(RT_OFFSETOF(HV_INPUT_GET_VP_REGISTERS, Names[1]), 32);
+            HV_REGISTER_VALUE *paValues = (HV_REGISTER_VALUE *)((uint8_t *)pInput + cbInput);
+            RT_BZERO(paValues, sizeof(paValues[0]) * 1);
+
+            pInput->PartitionId = pGVM->nem.s.idHvPartition;
+            pInput->VpIndex     = pGVCpu->idCpu;
+            pInput->fFlags      = 0;
+            pInput->Names[0]    = (HV_REGISTER_NAME)pVCpu->nem.s.Hypercall.Experiment.uItem;
+
+            uint64_t uResult = g_pfnHvlInvokeHypercall(HV_MAKE_CALL_INFO(HvCallGetVpRegisters, 1),
+                                                       pGVCpu->nem.s.HypercallData.HCPhysPage,
+                                                       pGVCpu->nem.s.HypercallData.HCPhysPage + cbInput);
+            pVCpu->nem.s.Hypercall.Experiment.fSuccess = uResult == HV_MAKE_CALL_REP_RET(1);
+            pVCpu->nem.s.Hypercall.Experiment.uStatus  = uResult;
+            pVCpu->nem.s.Hypercall.Experiment.uLoValue = paValues[0].Reg128.Low64;
+            pVCpu->nem.s.Hypercall.Experiment.uHiValue = paValues[0].Reg128.High64;
+            rc = VINF_SUCCESS;
+        }
+        else if (u64Arg == 1)
+        {
+            /*
+             * Query partition property.
+             */
+            HV_INPUT_GET_PARTITION_PROPERTY *pInput = (HV_INPUT_GET_PARTITION_PROPERTY *)pGVCpu->nem.s.HypercallData.pbPage;
+            AssertPtrReturn(pInput, VERR_INTERNAL_ERROR_3);
+
+            size_t const cbInput = RT_ALIGN_Z(sizeof(*pInput), 32);
+            HV_OUTPUT_GET_PARTITION_PROPERTY *pOutput = (HV_OUTPUT_GET_PARTITION_PROPERTY *)((uint8_t *)pInput + cbInput);
+            pOutput->PropertyValue = 0;
+
+            pInput->PartitionId  = pGVM->nem.s.idHvPartition;
+            pInput->PropertyCode = (HV_PARTITION_PROPERTY_CODE)pVCpu->nem.s.Hypercall.Experiment.uItem;
+            pInput->uPadding     = 0;
+
+            uint64_t uResult = g_pfnHvlInvokeHypercall(HvCallGetPartitionProperty,
+                                                       pGVCpu->nem.s.HypercallData.HCPhysPage,
+                                                       pGVCpu->nem.s.HypercallData.HCPhysPage + cbInput);
+            pVCpu->nem.s.Hypercall.Experiment.fSuccess = uResult == HV_STATUS_SUCCESS;
+            pVCpu->nem.s.Hypercall.Experiment.uStatus  = uResult;
+            pVCpu->nem.s.Hypercall.Experiment.uLoValue = pOutput->PropertyValue;
+            pVCpu->nem.s.Hypercall.Experiment.uHiValue = 0;
+            rc = VINF_SUCCESS;
+        }
+        else
+            rc = VERR_INVALID_FUNCTION;
+    }
+    return rc;
+}
+#endif /* DEBUG_bird */
+
Index: trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 72539)
+++ trunk/src/VBox/VMM/VMMR0/VMMR0.cpp	(revision 72541)
@@ -2076,4 +2076,13 @@
             VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
             break;
+
+#   if 1 && defined(DEBUG_bird)
+        case VMMR0_DO_NEM_EXPERIMENT:
+            if (pReqHdr)
+                return VERR_INVALID_PARAMETER;
+            rc = NEMR0DoExperiment(pGVM, pVM, idCpu, u64Arg);
+            VMM_CHECK_SMAP_CHECK2(pVM, RT_NOTHING);
+            break;
+#   endif
 # endif
 #endif
Index: trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp	(revision 72539)
+++ trunk/src/VBox/VMM/VMMR3/NEMR3Native-win.cpp	(revision 72541)
@@ -1444,4 +1444,41 @@
          * Note! We've already disabled X2APIC via CFGM during the first init call.
          */
+
+#if 1 && defined(DEBUG_bird)
+        /*
+         * Poke and probe a little.
+         */
+        for (uint32_t iReg = 0; iReg < 0x001101ff; iReg++)
+        {
+            PVMCPU pVCpu = &pVM->aCpus[0];
+            RT_ZERO(pVCpu->nem.s.Hypercall.Experiment);
+            pVCpu->nem.s.Hypercall.Experiment.uItem = iReg;
+            int rc2 = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_EXPERIMENT, 0, NULL);
+            AssertLogRelRCBreak(rc2);
+            if (pVCpu->nem.s.Hypercall.Experiment.fSuccess)
+            {
+                LogRel(("Register %#010x = %#18RX64, %#18RX64\n", iReg,
+                        pVCpu->nem.s.Hypercall.Experiment.uLoValue, pVCpu->nem.s.Hypercall.Experiment.uHiValue));
+                if (iReg == HvX64RegisterTsc)
+                {
+                    uint64_t uTsc = ASMReadTSC();
+                    LogRel(("TSC = %#18RX64; Delta %#18RX64 or %#18RX64\n",
+                            uTsc, pVCpu->nem.s.Hypercall.Experiment.uLoValue - uTsc, uTsc - pVCpu->nem.s.Hypercall.Experiment.uLoValue));
+                }
+            }
+        }
+        for (uint32_t iProp = 0; iProp < _1M; iProp++)
+        {
+            if (iProp == HvPartitionPropertyDebugChannelId /* hangs host */)
+                continue;
+            PVMCPU pVCpu = &pVM->aCpus[0];
+            RT_ZERO(pVCpu->nem.s.Hypercall.Experiment);
+            pVCpu->nem.s.Hypercall.Experiment.uItem = iProp;
+            int rc2 = VMMR3CallR0Emt(pVM, pVCpu, VMMR0_DO_NEM_EXPERIMENT, 1, NULL);
+            AssertLogRelRCBreak(rc2);
+            if (pVCpu->nem.s.Hypercall.Experiment.fSuccess)
+                LogRel(("Property %#010x = %#18RX64\n", iProp, pVCpu->nem.s.Hypercall.Experiment.uLoValue));
+        }
+#endif
         return VINF_SUCCESS;
     }
@@ -2507,5 +2544,11 @@
  *
  *
- * - Unable to access WHvX64RegisterMsrMtrrCap on AMD Ryzen (build 17134).
+ * - How do we modify the TSC offset (or bias if you like).
+ *
+ *   This is a show stopper as it breaks both pausing the VM and restoring
+ *   of saved state.
+ *
+ *
+ * - Unable to access WHvX64RegisterMsrMtrrCap (build 17134).
  *
  *
@@ -2689,6 +2732,10 @@
  *
  *
- * - Query WHvCapabilityCodeExceptionExitBitmap returns zero even when
+ * - Querying WHvCapabilityCodeExceptionExitBitmap returns zero even when
  *   intercepts demonstrably works (17134).
+ *
+ *
+ * - Querying HvPartitionPropertyDebugChannelId via HvCallGetPartitionProperty
+ *   (hypercall) hangs the host (17134).
  *
  *
Index: trunk/src/VBox/VMM/include/NEMInternal.h
===================================================================
--- trunk/src/VBox/VMM/include/NEMInternal.h	(revision 72539)
+++ trunk/src/VBox/VMM/include/NEMInternal.h	(revision 72541)
@@ -240,4 +240,13 @@
             uint32_t            uAux;
         }                       QueryCpuTick;
+        /** Input and output for NEMR0DoExperiment. */
+        struct
+        {
+            uint32_t            uItem;
+            bool                fSuccess;
+            uint64_t            uStatus;
+            uint64_t            uLoValue;
+            uint64_t            uHiValue;
+        }                       Experiment;
     } Hypercall;
     /** I/O control buffer, we always use this for I/O controls. */
