Index: /trunk/include/iprt/x86.h
===================================================================
--- /trunk/include/iprt/x86.h	(revision 48367)
+++ /trunk/include/iprt/x86.h	(revision 48368)
@@ -973,4 +973,7 @@
 /** Get FSB clock status (Intel-specific). */
 #define MSR_IA32_FSB_CLOCK_STS              0xCD
+
+/** C-State configuration control. Intel specific: Nehalem, Sandy Bridge. */
+#define MSR_PKG_CST_CONFIG_CONTROL          UINT32_C(0x000000e2)
 
 /** C0 Maximum Frequency Clock Count */
Index: /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 48367)
+++ /trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp	(revision 48368)
@@ -872,20 +872,13 @@
 
 /**
- * Query an MSR.
- *
- * The caller is responsible for checking privilege if the call is the result
- * of a RDMSR instruction. We'll do the rest.
- *
- * @retval  VINF_SUCCESS on success.
- * @retval  VERR_CPUM_RAISE_GP_0 on failure (invalid MSR), the caller is
- *          expected to take the appropriate actions. @a *puValue is set to 0.
- * @param   pVCpu               Pointer to the VMCPU.
- * @param   idMsr               The MSR.
- * @param   puValue             Where to return the value.
- *
- * @remarks This will always return the right values, even when we're in the
- *          recompiler.
- */
-VMMDECL(int) CPUMQueryGuestMsr(PVMCPU pVCpu, uint32_t idMsr, uint64_t *puValue)
+ * Worker for CPUMQueryGuestMsr().
+ *
+ * @retval  VINF_SUCCESS
+ * @retval  VERR_CPUM_RAISE_GP_0
+ * @param   pVCpu               The cross context CPU structure.
+ * @param   idMsr               The MSR to read.
+ * @param   puValue             Where to store the return value.
+ */
+static int cpumQueryGuestMsrInt(PVMCPU pVCpu, uint32_t idMsr, uint64_t *puValue)
 {
     /*
@@ -1149,4 +1142,5 @@
         case MSR_RAPL_POWER_UNIT:
         case MSR_BBL_CR_CTL3:               /* ca. core arch? */
+        case MSR_PKG_CST_CONFIG_CONTROL:   /* Nahalem, Sandy Bridge */
             *puValue = 0;
             if (CPUMGetGuestCpuVendor(pVCpu->CTX_SUFF(pVM)) != CPUMCPUVENDOR_INTEL)
@@ -1171,4 +1165,7 @@
                                                    0, /* bit 23 - L2 Not Present (RO). */
                                                    0);
+                    break;
+                case MSR_PKG_CST_CONFIG_CONTROL:
+                    *puValue = pVCpu->cpum.s.GuestMsrs.msr.PkgCStateCfgCtrl;
                     break;
             }
@@ -1231,4 +1228,28 @@
 
 /**
+ * Query an MSR.
+ *
+ * The caller is responsible for checking privilege if the call is the result
+ * of a RDMSR instruction. We'll do the rest.
+ *
+ * @retval  VINF_SUCCESS on success.
+ * @retval  VERR_CPUM_RAISE_GP_0 on failure (invalid MSR), the caller is
+ *          expected to take the appropriate actions. @a *puValue is set to 0.
+ * @param   pVCpu               Pointer to the VMCPU.
+ * @param   idMsr               The MSR.
+ * @param   puValue             Where to return the value.
+ *
+ * @remarks This will always return the right values, even when we're in the
+ *          recompiler.
+ */
+VMMDECL(int) CPUMQueryGuestMsr(PVMCPU pVCpu, uint32_t idMsr, uint64_t *puValue)
+{
+    int rc = cpumQueryGuestMsrInt(pVCpu, idMsr, puValue);
+    LogFlow(("CPUMQueryGuestMsr: %#x -> %llx rc=%d\n", idMsr, *puValue, rc));
+    return rc;
+}
+
+
+/**
  * Sets the MSR.
  *
@@ -1250,4 +1271,6 @@
 VMMDECL(int) CPUMSetGuestMsr(PVMCPU pVCpu, uint32_t idMsr, uint64_t uValue)
 {
+    LogFlow(("CPUSetGuestMsr: %#x <- %#llx\n", idMsr, uValue));
+
     /*
      * If we don't indicate MSR support in the CPUID feature bits, indicate
@@ -1457,8 +1480,31 @@
         /*case MSR_IA32_MC0_CTL:     - read-only? */
         /*case MSR_IA32_MC0_STATUS:  - read-only? */
+        case MSR_PKG_CST_CONFIG_CONTROL:
             if (CPUMGetGuestCpuVendor(pVCpu->CTX_SUFF(pVM)) != CPUMCPUVENDOR_INTEL)
             {
                 Log(("CPUM: MSR %#x is Intel, the virtual CPU isn't an Intel one -> #GP\n", idMsr));
                 return VERR_CPUM_RAISE_GP_0;
+            }
+
+            switch (idMsr)
+            {
+                case MSR_PKG_CST_CONFIG_CONTROL:
+                {
+                    if (pVCpu->cpum.s.GuestMsrs.msr.PkgCStateCfgCtrl & RT_BIT_64(15))
+                    {
+                        Log(("MSR_PKG_CST_CONFIG_CONTROL: Write protected -> #GP\n"));
+                        return VERR_CPUM_RAISE_GP_0;
+                    }
+                    static uint64_t s_fMask = UINT64_C(0x01f08407); /** @todo Only Nehalem has 24; Only Sandy has 27 and 28. */
+                    static uint64_t s_fGpInvalid = UINT64_C(0xffffffff00ff0000); /** @todo figure out exactly what's off limits. */
+                    if ((uValue & s_fGpInvalid) || (uValue & 7) >= 5)
+                    {
+                        Log(("MSR_PKG_CST_CONFIG_CONTROL: Invalid value %#llx -> #GP\n", uValue));
+                        return VERR_CPUM_RAISE_GP_0;
+                    }
+                    pVCpu->cpum.s.GuestMsrs.msr.PkgCStateCfgCtrl = uValue & s_fMask;
+                    break;
+                }
+
             }
             /* ignored */
Index: /trunk/src/VBox/VMM/VMMR3/CPUM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 48367)
+++ /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 48368)
@@ -1572,4 +1572,9 @@
 #endif
 
+
+    /* C-state control. Guesses. */
+    pVCpu->cpum.s.GuestMsrs.msr.PkgCStateCfgCtrl = 1 /*C1*/ | RT_BIT_32(25) | RT_BIT_32(26) | RT_BIT_32(27) | RT_BIT_32(28);
+
+
     /*
      * Get the APIC base MSR from the APIC device. For historical reasons (saved state), the APIC base
