Index: /trunk/src/VBox/VMM/VMMAll/APICAll.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 60653)
+++ /trunk/src/VBox/VMM/VMMAll/APICAll.cpp	(revision 60654)
@@ -2016,7 +2016,13 @@
                  *
                  * See Intel spec. 10.4.3 "Enabling or Disabling the Local APIC".
+                 *
+                 * We'll also manually manage the APIC base MSR here. We want a single-point of commit
+                 * at the end of this function rather than touching it in APICR3Reset. This means we also
+                 * need to update the CPUID leaf ourselves.
                  */
                 APICR3Reset(pVCpu, false /* fResetApicBaseMsr */);
                 uBaseMsr &= ~(MSR_APICBASE_XAPIC_ENABLE_BIT | MSR_APICBASE_X2APIC_ENABLE_BIT);
+
+                APICUpdateCpuIdForMode(pVCpu->CTX_SUFF(pVM), APICMODE_DISABLED);
                 Log2(("APIC%u: Switched mode to disabled\n", pVCpu->idCpu));
                 break;
@@ -2030,5 +2036,7 @@
                     return apicMsrAccessError(pVCpu, MSR_IA32_APICBASE, APICMSRACCESS_WRITE_INVALID);
                 }
+
                 uBaseMsr |= MSR_APICBASE_XAPIC_ENABLE_BIT;
+                APICUpdateCpuIdForMode(pVCpu->CTX_SUFF(pVM), APICMODE_XAPIC);
                 Log2(("APIC%u: Switched mode to xApic\n", pVCpu->idCpu));
                 break;
@@ -2037,4 +2045,10 @@
             case APICMODE_X2APIC:
             {
+                if (enmOldMode != APICMODE_XAPIC)
+                {
+                    Log(("APIC%u: Can only transition to x2APIC state from xAPIC state\n", pVCpu->idCpu));
+                    return apicMsrAccessError(pVCpu, MSR_IA32_APICBASE, APICMSRACCESS_WRITE_INVALID);
+                }
+
                 uBaseMsr |= MSR_APICBASE_XAPIC_ENABLE_BIT | MSR_APICBASE_X2APIC_ENABLE_BIT;
 
@@ -2056,4 +2070,5 @@
                 pX2ApicPage->ldr.u32LogicalApicId = ((pX2ApicPage->id.u32ApicId & UINT32_C(0xffff0)) << 16)
                                                   | (UINT32_C(1) << pX2ApicPage->id.u32ApicId & UINT32_C(0xf));
+
                 Log2(("APIC%u: Switched mode to x2Apic\n", pVCpu->idCpu));
                 break;
@@ -2544,4 +2559,6 @@
 VMM_INT_DECL(void) APICUpdateCpuIdForMode(PVM pVM, APICMODE enmMode)
 {
+    LogFlow(("APIC: APICUpdateCpuIdForMode: enmMode=%d (%s)\n", enmMode, apicGetModeName(enmMode)));
+
     /* The CPUID bits being updated to reflect the current state is a bit vague. See @bugref{8245#c32}. */
     /** @todo This needs to be done on a per-VCPU basis! */
Index: /trunk/src/VBox/VMM/VMMR3/APIC.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 60653)
+++ /trunk/src/VBox/VMM/VMMR3/APIC.cpp	(revision 60654)
@@ -241,9 +241,17 @@
      */
     VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
+
+    /* Construct. */
     PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
-    pApicCpu->uApicBaseMsr = XAPIC_APICBASE_PHYSADDR
-                           | MSR_APICBASE_XAPIC_ENABLE_BIT;
+    uint64_t uApicBaseMsr = XAPIC_APICBASE_PHYSADDR
+                          | MSR_APICBASE_XAPIC_ENABLE_BIT;
     if (pVCpu->idCpu == 0)
-        pApicCpu->uApicBaseMsr |= MSR_APICBASE_BOOTSTRAP_CPU_BIT;
+        uApicBaseMsr |= MSR_APICBASE_BOOTSTRAP_CPU_BIT;
+
+    /* Update CPUID. */
+    APICUpdateCpuIdForMode(pVCpu->CTX_SUFF(pVM), APICMODE_XAPIC);
+
+    /* Commit. */
+    ASMAtomicWriteU64(&pApicCpu->uApicBaseMsr, uApicBaseMsr);
 }
 
