Index: /trunk/src/VBox/VMM/VMMAll/GIMAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/GIMAll.cpp	(revision 51366)
+++ /trunk/src/VBox/VMM/VMMAll/GIMAll.cpp	(revision 51367)
@@ -81,4 +81,5 @@
 VMM_INT_DECL(int) GIMReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
 {
+    Assert(pVCpu);
     PVM pVM = pVCpu->CTX_SUFF(pVM);
     Assert(GIMIsEnabled(pVM));
@@ -109,4 +110,5 @@
 VMM_INT_DECL(int) GIMWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uValue, uint64_t uRawValue)
 {
+    Assert(pVCpu);
     PVM pVM = pVCpu->CTX_SUFF(pVM);
     Assert(GIMIsEnabled(pVM));
Index: /trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp	(revision 51366)
+++ /trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp	(revision 51367)
@@ -23,5 +23,7 @@
 #include "GIMHvInternal.h"
 
-#include <iprt/err.h>
+#include <VBox/err.h>
+#include <VBox/vmm/tm.h>
+#include <VBox/vmm/vm.h>
 
 DECLEXPORT(int) GIMHvHypercall(PVMCPU pVCpu, PCPUMCTX pCtx)
@@ -33,5 +35,27 @@
 DECLEXPORT(int) GIMHvReadMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t *puValue)
 {
-    return VINF_SUCCESS;
+    NOREF(pRange);
+    switch (idMsr)
+    {
+        case MSR_GIM_HV_TIME_REF_COUNT:
+        {
+            /* Hyper-V reports the time in 100ns units. */
+            uint64_t u64Tsc      = TMCpuTickGet(pVCpu);
+            uint64_t u64TscHz    = TMCpuTicksPerSecond(pVCpu->CTX_SUFF(pVM));
+            uint64_t u64Tsc100Ns = u64TscHz / UINT64_C(10000000); /* 100 ns */
+            *puValue = (u64Tsc / u64Tsc100Ns);
+            return VINF_SUCCESS;
+        }
+
+        case MSR_GIM_HV_VP_INDEX:
+            *puValue = pVCpu->idCpu;
+            return VINF_SUCCESS;
+
+        default:
+            break;
+    }
+
+    LogRel(("GIMHvReadMsr: Unknown/invalid RdMsr %#RX32 -> #GP(0)\n", idMsr));
+    return VERR_CPUM_RAISE_GP_0;
 }
 
@@ -39,5 +63,6 @@
 DECLEXPORT(int) GIMHvWriteMsr(PVMCPU pVCpu, uint32_t idMsr, PCCPUMMSRRANGE pRange, uint64_t uValue, uint64_t uRawValue)
 {
-    return VINF_SUCCESS;
+    LogRel(("GIMHvWriteMsr: Unknown/invalid WrMsr %#RX32 -> #GP(0)\n", idMsr));
+    return VERR_CPUM_RAISE_GP_0;
 }
 
Index: /trunk/src/VBox/VMM/VMMR3/GIM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GIM.cpp	(revision 51366)
+++ /trunk/src/VBox/VMM/VMMR3/GIM.cpp	(revision 51367)
@@ -116,5 +116,5 @@
      * Setup the GIM provider for this VM.
      */
-    LogRel(("GIM: Using provider \"%s\" version %u\n", szProvider, uVersion));
+    LogRel(("GIM: Using provider \"%s\" (Implementation version: %u)\n", szProvider, uVersion));
     if (!RTStrCmp(szProvider, "None"))
     {
@@ -143,5 +143,4 @@
         }
     }
-
     return rc;
 }
Index: /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp	(revision 51366)
+++ /trunk/src/VBox/VMM/VMMR3/GIMHv.cpp	(revision 51367)
@@ -36,5 +36,32 @@
 *   Defined Constants And Macros                                               *
 *******************************************************************************/
-#define GIMHV_HYPERCALL                 "GIMHvHypercall"
+//#define GIMHV_HYPERCALL                 "GIMHvHypercall"
+#ifdef VBOX_WITH_STATISTICS
+# define GIMHV_MSRRANGE(a_uFirst, a_uLast, a_szName) \
+    { (a_uFirst), (a_uLast), kCpumMsrRdFn_Gim, kCpumMsrWrFn_Gim, 0, 0, 0, 0, 0, a_szName, { 0 }, { 0 }, { 0 }, { 0 } }
+#else
+# define GIMHV_MSRRANGE(a_uFirst, a_uLast, a_szName) \
+    { (a_uFirst), (a_uLast), kCpumMsrRdFn_Gim, kCpumMsrWrFn_Gim, 0, 0, 0, 0, 0, a_szName }
+#endif
+
+/**
+ * Array of MSR ranges supported by Hyper-V.
+ */
+static CPUMMSRRANGE const g_aMsrRanges_HyperV[] =
+{
+    GIMHV_MSRRANGE(MSR_GIM_HV_RANGE0_START,  MSR_GIM_HV_RANGE0_END,  "Hyper-V range 0"),
+    GIMHV_MSRRANGE(MSR_GIM_HV_RANGE1_START,  MSR_GIM_HV_RANGE1_END,  "Hyper-V range 1"),
+    GIMHV_MSRRANGE(MSR_GIM_HV_RANGE2_START,  MSR_GIM_HV_RANGE2_END,  "Hyper-V range 2"),
+    GIMHV_MSRRANGE(MSR_GIM_HV_RANGE3_START,  MSR_GIM_HV_RANGE3_END,  "Hyper-V range 3"),
+    GIMHV_MSRRANGE(MSR_GIM_HV_RANGE4_START,  MSR_GIM_HV_RANGE4_END,  "Hyper-V range 4"),
+    GIMHV_MSRRANGE(MSR_GIM_HV_RANGE5_START,  MSR_GIM_HV_RANGE5_END,  "Hyper-V range 5"),
+    GIMHV_MSRRANGE(MSR_GIM_HV_RANGE6_START,  MSR_GIM_HV_RANGE6_END,  "Hyper-V range 6"),
+    GIMHV_MSRRANGE(MSR_GIM_HV_RANGE7_START,  MSR_GIM_HV_RANGE7_END,  "Hyper-V range 7"),
+    GIMHV_MSRRANGE(MSR_GIM_HV_RANGE8_START,  MSR_GIM_HV_RANGE8_END,  "Hyper-V range 8"),
+    GIMHV_MSRRANGE(MSR_GIM_HV_RANGE9_START,  MSR_GIM_HV_RANGE9_END,  "Hyper-V range 9"),
+    GIMHV_MSRRANGE(MSR_GIM_HV_RANGE10_START, MSR_GIM_HV_RANGE10_END, "Hyper-V range 10"),
+    GIMHV_MSRRANGE(MSR_GIM_HV_RANGE11_START, MSR_GIM_HV_RANGE11_END, "Hyper-V range 11")
+};
+#undef GIMHV_MSR
 
 
@@ -73,5 +100,20 @@
     if (!pVM->gim.s.u32Version)
     {
-        uBaseFeat = GIM_HV_BASE_FEAT_PART_REF_COUNT_MSR;
+        uBaseFeat = 0
+                  //| GIM_HV_BASE_FEAT_VP_RUNTIME_MSR
+                  | GIM_HV_BASE_FEAT_PART_REF_COUNT_MSR
+                  //| GIM_HV_BASE_FEAT_BASIC_SYNTH_IC
+                  //| GIM_HV_BASE_FEAT_SYNTH_TIMER_MSRS
+                  //| GIM_HV_BASE_FEAT_APIC_ACCESS_MSRS
+                  //| GIM_HV_BASE_FEAT_HYPERCALL_MSRS
+                  | GIM_HV_BASE_FEAT_VP_ID_MSR
+                  //| GIM_HV_BASE_FEAT_VIRT_SYS_RESET_MSR
+                  //| GIM_HV_BASE_FEAT_STAT_PAGES_MSR
+                  //| GIM_HV_BASE_FEAT_PART_REF_TSC_MSR
+                  //| GIM_HV_BASE_FEAT_GUEST_IDLE_STATE_MSR
+                  //| GIM_HV_BASE_FEAT_TIMER_FREQ_MSRS
+                  //| GIM_HV_BASE_FEAT_DEBUG_MSRS
+                  ;
+
         pVM->gim.s.u.hv.u16HyperIdVersionMajor = VBOX_VERSION_MAJOR;
         pVM->gim.s.u.hv.u16HyperIdVersionMajor = VBOX_VERSION_MINOR;
@@ -108,5 +150,5 @@
      * Add Hyper-V specific leaves.
      */
-    HyperLeaf.uLeaf        = UINT32_C(0x40000002); /* MBZ until MSR_HV_GUEST_OS_ID is set by the guest. */
+    HyperLeaf.uLeaf        = UINT32_C(0x40000002); /* MBZ until MSR_GIM_HV_GUEST_OS_ID is set by the guest. */
     HyperLeaf.uEax         = 0;
     HyperLeaf.uEbx         = 0;
@@ -125,17 +167,11 @@
 
     /*
-     * Register the complete MSR range for Hyper-V.
+     * Insert all MSR ranges of Hyper-V.
      */
-    CPUMMSRRANGE MsrRange;
-    RT_ZERO(MsrRange);
-    MsrRange.uFirst     = UINT32_C(0x40000000);
-    MsrRange.uLast      = UINT32_C(0x40000105);
-    MsrRange.enmRdFn    = kCpumMsrRdFn_Gim;
-    MsrRange.enmWrFn    = kCpumMsrWrFn_Gim;
-    RTStrCopy(MsrRange.szName, sizeof(MsrRange.szName), "Hyper-V");
-    rc = CPUMR3MsrRangesInsert(pVM, &MsrRange);
-    AssertLogRelRCReturn(rc, rc);
-
-
+    for (uint32_t i = 0; i < RT_ELEMENTS(g_aMsrRanges_HyperV); i++)
+    {
+        rc = CPUMR3MsrRangesInsert(pVM, &g_aMsrRanges_HyperV[i]);
+        AssertLogRelRCReturn(rc, rc);
+    }
     return VINF_SUCCESS;
 }
@@ -144,6 +180,8 @@
 VMMR3_INT_DECL(void) GIMR3HvRelocate(PVM pVM, RTGCINTPTR offDelta)
 {
-//    int rc = PDMR3LdrGetSymbolRC(pVM, NULL /* pszModule */, GIMHV_HYPERCALL, &pVM->gim.s.pfnHypercallRC);
-//    AssertFatalRC(rc);
+#if 0
+    int rc = PDMR3LdrGetSymbolRC(pVM, NULL /* pszModule */, GIMHV_HYPERCALL, &pVM->gim.s.pfnHypercallRC);
+    AssertFatalRC(rc);
+#endif
 }
 
Index: /trunk/src/VBox/VMM/VMMR3/VM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/VM.cpp	(revision 51366)
+++ /trunk/src/VBox/VMM/VMMR3/VM.cpp	(revision 51367)
@@ -989,6 +989,6 @@
                                                                     if (RT_SUCCESS(rc))
                                                                     {
-                                                                        /* GIM must be init'd after PDM, relies on PDMR3 for
-                                                                           symbol resolution.*/
+                                                                        /* GIM must be init'd after PDM, may rely on PDMR3 for
+                                                                           symbol resolution. */
                                                                         rc = GIMR3Init(pVM);
                                                                         if (RT_SUCCESS(rc))
Index: /trunk/src/VBox/VMM/include/GIMHvInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/GIMHvInternal.h	(revision 51366)
+++ /trunk/src/VBox/VMM/include/GIMHvInternal.h	(revision 51367)
@@ -188,4 +188,6 @@
  * @{
  */
+/** Start of range 0. */
+#define MSR_GIM_HV_RANGE0_START                   UINT32_C(0x40000000)
 /** Guest OS identification (R/W) */
 #define MSR_GIM_HV_GUEST_OS_ID                    UINT32_C(0x40000000)
@@ -196,6 +198,16 @@
 /** Reset operation (R/W) */
 #define MSR_GIM_HV_RESET                          UINT32_C(0x40000003)
+/** End of range 0. */
+#define MSR_GIM_HV_RANGE0_END                     MSR_GIM_HV_RESET
+
+/** Start of range 1. */
+#define MSR_GIM_HV_RANGE1_START                   UINT32_C(0x40000010)
 /** Virtual processor's (VCPU) runtime (R) */
 #define MSR_GIM_HV_VP_RUNTIME                     UINT32_C(0x40000010)
+/** End of range 1. */
+#define MSR_GIM_HV_RANGE1_END                     MSR_GIM_HV_VP_RUNTIME
+
+/** Start of range 2. */
+#define MSR_GIM_HV_RANGE2_START                   UINT32_C(0x40000020)
 /** Per-VM reference counter (R) */
 #define MSR_GIM_HV_TIME_REF_COUNT                 UINT32_C(0x40000020)
@@ -206,4 +218,9 @@
 /** Frequency of LAPIC in Hz as reported by the hypervisor (R) */
 #define MSR_GIM_HV_APIC_FREQ                      UINT32_C(0x40000023)
+/** End of range 2. */
+#define MSR_GIM_HV_RANGE2_END                     MSR_GIM_HV_APIC_FREQ
+
+/** Start of range 3. */
+#define MSR_GIM_HV_RANGE3_START                   UINT32_C(0x40000070)
 /** Access to APIC EOI (End-Of-Interrupt) register (W) */
 #define MSR_GIM_HV_EOI                            UINT32_C(0x40000070)
@@ -214,4 +231,9 @@
 /** Enables lazy EOI processing (R/W) */
 #define MSR_GIM_HV_APIC_ASSIST_PAGE               UINT32_C(0x40000073)
+/** End of range 3. */
+#define MSR_GIM_HV_RANGE3_END                     MSR_GIM_HV_APIC_ASSIST_PAGE
+
+/** Start of range 4. */
+#define MSR_GIM_HV_RANGE4_START                   UINT32_C(0x40000080)
 /** Control behaviour of synthetic interrupt controller (R/W) */
 #define MSR_GIM_HV_SCONTROL                       UINT32_C(0x40000080)
@@ -224,4 +246,9 @@
 /** End-Of-Message in synthetic interrupt parameter page (W) */
 #define MSR_GIM_HV_EOM                            UINT32_C(0x40000084)
+/** End of range 4. */
+#define MSR_GIM_HV_RANGE4_END                     MSR_GIM_HV_EOM
+
+/** Start of range 5. */
+#define MSR_GIM_HV_RANGE5_START                   UINT32_C(0x40000090)
 /** Configures synthetic interrupt source 0 (R/W) */
 #define MSR_GIM_HV_SINT0                          UINT32_C(0x40000090)
@@ -256,4 +283,9 @@
 /** Configures synthetic interrupt source 15 (R/W) */
 #define MSR_GIM_HV_SINT15                         UINT32_C(0x4000009F)
+/** End of range 5. */
+#define MSR_GIM_HV_RANGE5_END                     MSR_GIM_HV_SINT15
+
+/** Start of range 6. */
+#define MSR_GIM_HV_RANGE6_START                   UINT32_C(0x400000B0)
 /** Configures register for synthetic timer 0 (R/W) */
 #define MSR_GIM_HV_STIMER0_CONFIG                 UINT32_C(0x400000B0)
@@ -272,4 +304,9 @@
 /** Expiration time or period for synthetic timer 3 (R/W) */
 #define MSR_GIM_HV_STIMER3_COUNT                  UINT32_C(0x400000B7)
+/** End of range 6. */
+#define MSR_GIM_HV_RANGE6_END                     MSR_GIM_HV_STIMER3_COUNT
+
+/** Start of range 7. */
+#define MSR_GIM_HV_RANGE7_START                   UINT32_C(0x400000C1)
 /** Trigger to transition to power state C1 (R) */
 #define MSR_GIM_HV_POWER_STATE_TRIGGER_C1         UINT32_C(0x400000C1)
@@ -278,4 +315,9 @@
 /** Trigger to transition to power state C3 (R) */
 #define MSR_GIM_HV_POWER_STATE_TRIGGER_C3         UINT32_C(0x400000C3)
+/** End of range 7. */
+#define MSR_GIM_HV_RANGE7_END                     MSR_GIM_HV_POWER_STATE_TRIGGER_C3
+
+/** Start of range 8. */
+#define MSR_GIM_HV_RANGE8_START                   UINT32_C(0x400000D1)
 /** Configure the recipe for power state transitions to C1 (R/W) */
 #define MSR_GIM_HV_POWER_STATE_CONFIG_C1          UINT32_C(0x400000D1)
@@ -284,4 +326,9 @@
 /** Configure the recipe for power state transitions to C3 (R/W) */
 #define MSR_GIM_HV_POWER_STATE_CONFIG_C3          UINT32_C(0x400000D3)
+/** End of range 8. */
+#define MSR_GIM_HV_RANGE8_END                     MSR_GIM_HV_POWER_STATE_CONFIG_C3
+
+/** Start of range 9. */
+#define MSR_GIM_HV_RANGE9_START                   UINT32_C(0x400000E0)
 /** Map the guest's retail partition stats page (R/W) */
 #define MSR_GIM_HV_STATS_PART_RETAIL_PAGE         UINT32_C(0x400000E0)
@@ -292,4 +339,9 @@
 /** Map the guest's internal VP stats page (R/W) */
 #define MSR_GIM_HV_STATS_VP_INTERNAL_PAGE         UINT32_C(0x400000E3)
+/** End of range 9. */
+#define MSR_GIM_HV_RANGE9_END                     MSR_GIM_HV_STATS_VP_INTERNAL_PAGE
+
+/** Start of range 10. */
+#define MSR_GIM_HV_RANGE10_START                  UINT32_C(0x400000F0)
 /** Trigger the guest's transition to idle power state (R) */
 #define MSR_GIM_HV_GUEST_IDLE                     UINT32_C(0x400000F0)
@@ -304,4 +356,9 @@
 /** Synthetic debug pending buffer. */
 #define MSR_GIM_HV_SYNTH_DEBUG_PENDING_BUFFER     UINT32_C(0x400000F5)
+/** End of range 10. */
+#define MSR_GIM_HV_RANGE10_END                    MSR_GIM_HV_SYNTH_DEBUG_PENDING_BUFFER
+
+/** Start of range 11. */
+#define MSR_GIM_HV_RANGE11_START                  UINT32_C(0x40000100)
 /** Guest crash MSR 0. */
 #define MSR_GIM_HV_CRASH_P0                       UINT32_C(0x40000100)
@@ -316,6 +373,20 @@
 /** Guest crash control. */
 #define MSR_GIM_HV_CRASH_CTL                      UINT32_C(0x40000105)
+/** End of range 11. */
+#define MSR_GIM_HV_RANGE11_END                    MSR_GIM_HV_CRASH_CTL
 /** @} */
 
+AssertCompile(MSR_GIM_HV_RANGE0_START  <= MSR_GIM_HV_RANGE0_END);
+AssertCompile(MSR_GIM_HV_RANGE1_START  <= MSR_GIM_HV_RANGE1_END);
+AssertCompile(MSR_GIM_HV_RANGE2_START  <= MSR_GIM_HV_RANGE2_END);
+AssertCompile(MSR_GIM_HV_RANGE3_START  <= MSR_GIM_HV_RANGE3_END);
+AssertCompile(MSR_GIM_HV_RANGE4_START  <= MSR_GIM_HV_RANGE4_END);
+AssertCompile(MSR_GIM_HV_RANGE5_START  <= MSR_GIM_HV_RANGE5_END);
+AssertCompile(MSR_GIM_HV_RANGE6_START  <= MSR_GIM_HV_RANGE6_END);
+AssertCompile(MSR_GIM_HV_RANGE7_START  <= MSR_GIM_HV_RANGE7_END);
+AssertCompile(MSR_GIM_HV_RANGE8_START  <= MSR_GIM_HV_RANGE8_END);
+AssertCompile(MSR_GIM_HV_RANGE9_START  <= MSR_GIM_HV_RANGE9_END);
+AssertCompile(MSR_GIM_HV_RANGE10_START <= MSR_GIM_HV_RANGE10_END);
+AssertCompile(MSR_GIM_HV_RANGE11_START <= MSR_GIM_HV_RANGE11_END);
 
 RT_C_DECLS_BEGIN
