Index: /trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp	(revision 49977)
+++ /trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp	(revision 49978)
@@ -440,4 +440,27 @@
 
 /**
+ * Worker for cpumR3MsrApplyFudge that applies one table.
+ *
+ * @returns VBox status code.
+ * @param   pVM                 Pointer to the cross context VM structure.
+ * @param   paRanges            Array of MSRs to fudge.
+ * @param   cRanges             Number of MSRs in the array.
+ */
+static int cpumR3MsrApplyFudgeTable(PVM pVM, PCCPUMMSRRANGE paRanges, size_t cRanges)
+{
+    for (uint32_t i = 0; i < cRanges; i++)
+        if (!cpumLookupMsrRange(pVM, paRanges[i].uFirst))
+        {
+            LogRel(("CPUM: MSR fudge: %#010x %s\n", paRanges[i].uFirst, paRanges[i].szName));
+            int rc = cpumR3MsrRangesInsert(&pVM->cpum.s.GuestInfo.paMsrRangesR3, &pVM->cpum.s.GuestInfo.cMsrRanges,
+                                           &paRanges[i]);
+            if (RT_FAILURE(rc))
+                return rc;
+        }
+    return VINF_SUCCESS;
+}
+
+
+/**
  * Fudges the MSRs that guest are known to access in some odd cases.
  *
@@ -450,7 +473,10 @@
 int cpumR3MsrApplyFudge(PVM pVM)
 {
+    /*
+     * Basic.
+     */
     static CPUMMSRRANGE const s_aFudgeMsrs[] =
     {
-        MFO(0x00000099, "IA32_P5_MC_ADDR",          Ia32P5McAddr),
+        MFO(0x00000000, "IA32_P5_MC_ADDR",          Ia32P5McAddr),
         MFX(0x00000001, "IA32_P5_MC_TYPE",          Ia32P5McType,   Ia32P5McType,   0, 0, UINT64_MAX),
         MVO(0x00000017, "IA32_PLATFORM_ID",         0),
@@ -470,16 +496,21 @@
         MFN(0x00000400, "IA32_MCi_CTL_STATUS_ADDR_MISC", Ia32McCtlStatusAddrMiscN, Ia32McCtlStatusAddrMiscN),
     };
-
-    for (uint32_t i = 0; i < RT_ELEMENTS(s_aFudgeMsrs); i++)
-        if (!cpumLookupMsrRange(pVM, s_aFudgeMsrs[i].uFirst))
-        {
-            LogRel(("CPUM: MSR fudge: %#010x %s\n", s_aFudgeMsrs[i].uFirst, s_aFudgeMsrs[i].szName));
-            int rc = cpumR3MsrRangesInsert(&pVM->cpum.s.GuestInfo.paMsrRangesR3, &pVM->cpum.s.GuestInfo.cMsrRanges,
-                                           &s_aFudgeMsrs[i]);
-            if (RT_FAILURE(rc))
-                return rc;
-        }
-
-    return VINF_SUCCESS;
+    int rc = cpumR3MsrApplyFudgeTable(pVM, &s_aFudgeMsrs[0], RT_ELEMENTS(s_aFudgeMsrs));
+    AssertLogRelRCReturn(rc, rc);
+
+    /*
+     * XP might mistake opterons and other newer CPUs for P4s.
+     */
+    if (pVM->cpum.s.GuestFeatures.uFamily >= 0xf)
+    {
+        static CPUMMSRRANGE const s_aP4FudgeMsrs[] =
+        {
+            MFX(0x0000002c, "P4_EBC_FREQUENCY_ID", IntelP4EbcFrequencyId, IntelP4EbcFrequencyId, 0xf12010f, UINT64_MAX, 0),
+        };
+        int rc = cpumR3MsrApplyFudgeTable(pVM, &s_aP4FudgeMsrs[0], RT_ELEMENTS(s_aP4FudgeMsrs));
+        AssertLogRelRCReturn(rc, rc);
+    }
+
+    return rc;
 }
 
