Index: /trunk/include/VBox/vmapi.h
===================================================================
--- /trunk/include/VBox/vmapi.h	(revision 25837)
+++ /trunk/include/VBox/vmapi.h	(revision 25838)
@@ -407,7 +407,7 @@
 VMMR3DECL(RTNATIVETHREAD)   VMR3GetVMCPUNativeThread(PVM pVM);
 VMMR3DECL(RTNATIVETHREAD)   VMR3GetVMCPUNativeThreadU(PUVM pUVM);
-VMMR3DECL(int)              VMR3GetCPUCoreAndPackageIdFromCPUId(PVM pVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage);
-VMMR3DECL(int)              VMR3HotunplugCPU(PVM pVM, VMCPUID idCpu);
-VMMR3DECL(int)              VMR3HotplugCPU(PVM pVM, VMCPUID idCpu);
+VMMR3DECL(int)              VMR3GetCpuCoreAndPackageIdFromCpuId(PVM pVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage);
+VMMR3DECL(int)              VMR3HotUnplugCpu(PVM pVM, VMCPUID idCpu);
+VMMR3DECL(int)              VMR3HotPlugCpu(PVM pVM, VMCPUID idCpu);
 
 /** @} */
Index: /trunk/src/VBox/Devices/Makefile.kmk
===================================================================
--- /trunk/src/VBox/Devices/Makefile.kmk	(revision 25837)
+++ /trunk/src/VBox/Devices/Makefile.kmk	(revision 25838)
@@ -471,20 +471,4 @@
  vboxaml.hex:: $$(PATH_DevicesR3)/vboxaml.hex
 
- # CPU hot-plug version
- DevicesR3_CLEAN        += $(PATH_DevicesR3)/vboxaml-cpuhotplug.hex $(PATH_DevicesR3)/vboxaml-cpuhotplug.hex.tmp $(PATH_DevicesR3)/vboxaml-cpuhotplug.aml
- PC/ACPI/VBoxAcpi.cpp_DEPS += $(PATH_DevicesR3)/vboxaml-cpuhotplug.hex
-
- $$(PATH_DevicesR3)/vboxaml-cpuhotplug.hex: $(PATH_SUB_CURRENT)/PC/vbox-cpuhotplug.dsl | $$(dir $$@)
-	$(call MSG_TOOL,iasl,DevicesR3,$<,$@)
-	$(QUIET)$(RM) -f $@ $@.tmp
-	$(QUIET)$(VBOX_IASLCMD) -tc -vs -p $@ $<
-	$(QUIET)$(MV) -f $@ $@.tmp
-	$(QUIET)$(SED) -e 's/AmlCode/AmlCodeCpuHotplug/' \
-		--output $@ $@.tmp
-	$(QUIET)$(RM) -f $@.tmp
-
-
- vboxaml-cpuhotplug.hex:: $$(PATH_DevicesR3)/vboxaml-cpuhotplug.hex
-
 endif # !VBOX_WITH_DYNAMIC_DSDT
 PC/ACPI/VBoxAcpi.cpp_INCS = $(PATH_DevicesR3)
Index: /trunk/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp	(revision 25837)
+++ /trunk/src/VBox/Devices/PC/ACPI/VBoxAcpi.cpp	(revision 25838)
@@ -30,7 +30,9 @@
 #include <VBox/param.h>
 #include <VBox/cfgm.h>
+#include <VBox/mm.h>
 #include <iprt/assert.h>
 #include <iprt/alloc.h>
 #include <iprt/string.h>
+#include <iprt/file.h>
 
 #ifdef VBOX_WITH_DYNAMIC_DSDT
@@ -40,5 +42,4 @@
 /* Statically compiled AML */
 # include <vboxaml.hex>
-# include <vboxaml-cpuhotplug.hex>
 #endif
 
@@ -142,27 +143,80 @@
     return prepareDynamicDsdt(pDevIns, ppPtr, puDsdtLen);
 #else
-    unsigned char *pbAmlCode = NULL;
+    uint8_t *pbAmlCode = NULL;
     size_t cbAmlCode = 0;
-    bool fCpuHotPlug = false;
-    int rc = CFGMR3QueryBoolDef(pDevIns->pCfgHandle, "CpuHotplug", &fCpuHotPlug, false); /** @todo r=bird: Rename to CpuHotPlug. */
-    if (RT_FAILURE(rc))
+    char *pszAmlFilePath = NULL;
+    int rc = CFGMR3QueryStringAlloc(pDevIns->pCfgHandle, "AmlFilePath", &pszAmlFilePath);
+    if (RT_SUCCESS(rc))
+    {
+        /* Load from file. */
+        RTFILE FileAml = NIL_RTFILE;
+
+        rc = RTFileOpen(&FileAml, pszAmlFilePath, RTFILE_O_OPEN | RTFILE_O_READ | RTFILE_O_DENY_NONE);
+        if (RT_SUCCESS(rc))
+        {
+            /*
+             * An AML file contains the raw DSDT thus the size of the file
+             * is equal to the size of the DSDT.
+             */
+            uint64_t cbAmlFile = 0;
+            rc = RTFileGetSize(FileAml, &cbAmlFile);
+
+            cbAmlCode = (size_t)cbAmlFile;
+
+            /* Don't use AML files over 4GB ;) */
+            if (   RT_SUCCESS(rc)
+                && ((uint64_t)cbAmlCode == cbAmlFile))
+            {
+                pbAmlCode = (uint8_t *)RTMemAllocZ(cbAmlCode);
+                if (pbAmlCode)
+                {
+                    rc = RTFileReadAt(FileAml, 0, pbAmlCode, cbAmlCode, NULL);
+
+                    /*
+                     * We fail if reading failed or the identifier at the
+                     * beginning is wrong.
+                     */
+                    if (   RT_FAILURE(rc)
+                        || strncmp((const char *)pbAmlCode, "DSDT", 4))
+                    {
+                        RTMemFree(pbAmlCode);
+                        pbAmlCode = NULL;
+
+                        /* Return error if file header check failed */
+                        if (RT_SUCCESS(rc))
+                            rc = VERR_PARSE_ERROR;
+                    }
+                }
+                else
+                    rc = VERR_NO_MEMORY;
+            }
+
+            RTFileClose(FileAml);
+        }
+        MMR3HeapFree(pszAmlFilePath);
+    }
+    else if (rc == VERR_CFGM_VALUE_NOT_FOUND)
+    {
+        rc = VINF_SUCCESS;
+
+        /* Use the compiled in AML code */
+        cbAmlCode = sizeof(AmlCode);
+        pbAmlCode = (uint8_t *)RTMemAllocZ(cbAmlCode);
+        if (pbAmlCode)
+            memcpy(pbAmlCode, AmlCode, cbAmlCode);
+        else
+            rc = VERR_NO_MEMORY;
+    }
+    else if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
-                                N_("Configuration error: Failed to read \"CpuHotplug\""));
-
-    if (fCpuHotPlug)
-    {
-        pbAmlCode = AmlCodeCpuHotplug;
-        cbAmlCode = sizeof(AmlCodeCpuHotplug);
-    }
-    else
-    {
-        pbAmlCode = AmlCode;
-        cbAmlCode = sizeof(AmlCode);
-    }
-
-    patchAml(pDevIns, pbAmlCode, cbAmlCode);
-    *ppPtr = pbAmlCode;
-    *puDsdtLen = cbAmlCode;
-    return 0;
+                                N_("Configuration error: Failed to read \"AmlFilePath\""));
+
+    if (RT_SUCCESS(rc))
+    {
+        patchAml(pDevIns, pbAmlCode, cbAmlCode);
+        *ppPtr = pbAmlCode;
+        *puDsdtLen = cbAmlCode;
+    }
+    return rc;
 #endif
 }
@@ -173,7 +227,8 @@
     return cleanupDynamicDsdt(pDevIns, pPtr);
 #else
-    /* Do nothing */
-    return 0;
-#endif
-}
-
+    if (pPtr)
+        RTMemFree(pPtr);
+    return VINF_SUCCESS;
+#endif
+}
+
Index: /trunk/src/VBox/Devices/PC/DevACPI.cpp
===================================================================
--- /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 25837)
+++ /trunk/src/VBox/Devices/PC/DevACPI.cpp	(revision 25838)
@@ -150,7 +150,8 @@
     SYSTEM_INFO_INDEX_RTC_STATUS        = 10,
     SYSTEM_INFO_INDEX_CPU_LOCKED        = 11,
-    SYSTEM_INFO_INDEX_MADT_ADDR         = 12,
-    SYSTEM_INFO_INDEX_MADT_SIZE         = 13,
-    SYSTEM_INFO_INDEX_END               = 14,
+    SYSTEM_INFO_INDEX_CPU_LOCK_CHECK    = 12,
+    SYSTEM_INFO_INDEX_MADT_ADDR         = 13,
+    SYSTEM_INFO_INDEX_MADT_SIZE         = 14,
+    SYSTEM_INFO_INDEX_END               = 15,
     SYSTEM_INFO_INDEX_INVALID           = 0x80,
     SYSTEM_INFO_INDEX_VALID             = 0x200
@@ -238,7 +239,9 @@
     uint32_t            cbMADT;
     /** Array of flags of attached CPUs */
-    bool                afCpuAttached[VMM_MAX_CPU_COUNT]; /**< @todo use VMCPUSET.  */
+    VMCPUSET            CpuSetAttached;
+    /** Which CPU to check for the locked status. */
+    uint32_t            idCpuLockCheck;
     /** Mask of locked CPUs (used by the guest) */
-    uint32_t            uCpusLocked;                      /**< @todo use VMCPUSET. */
+    VMCPUSET            CpuSetLocked;
     /** Flag whether CPU hot plugging is enabled */
     bool                fCpuHotPlug;
@@ -847,5 +850,5 @@
         lapic->u8ProcId    = i;
         lapic->u8ApicId    = i;
-        lapic->u32Flags    = s->afCpuAttached[i] ? RT_H2LE_U32(LAPIC_ENABLED) : 0;
+        lapic->u32Flags    = VMCPUSET_IS_PRESENT(&s->CpuSetAttached, i) ? RT_H2LE_U32(LAPIC_ENABLED) : 0;
         lapic++;
     }
@@ -986,5 +989,5 @@
 {
     ACPIState *s = IACPIPORT_2_ACPISTATE(pInterface);
-    *pfLocked = (s->uCpusLocked & RT_BIT(uCpu)) != 0;
+    *pfLocked = VMCPUSET_IS_PRESENT(&s->CpuSetLocked, uCpu);
     return VINF_SUCCESS;
 }
@@ -1406,5 +1409,5 @@
                   *pu32 = s->fShowCpu
                     && s->uSystemInfoIndex - SYSTEM_INFO_INDEX_CPU0_STATUS < s->cCpus
-                    && s->afCpuAttached[s->uSystemInfoIndex - SYSTEM_INFO_INDEX_CPU0_STATUS]
+                    && VMCPUSET_IS_PRESENT(&s->CpuSetAttached, s->uSystemInfoIndex - SYSTEM_INFO_INDEX_CPU0_STATUS)
                     ?
                       STA_DEVICE_PRESENT_MASK
@@ -1424,5 +1427,15 @@
                 case SYSTEM_INFO_INDEX_CPU_LOCKED:
                 {
-                    *pu32 = s->uCpusLocked;
+                    if (s->idCpuLockCheck != UINT32_C(0xffffffff))
+                    {
+                        *pu32 = VMCPUSET_IS_PRESENT(&s->CpuSetLocked, s->idCpuLockCheck) ? 1 : 0;
+                        s->idCpuLockCheck = UINT32_C(0xffffffff); /* Make the entry invalid */
+                    }
+                    else
+                    {
+                        AssertMsgFailed(("ACPI: CPU lock check protocol violation\n"));
+                        /* Always return locked status just to be safe */
+                        *pu32 = 1;
+                    }
                     break;
                 }
@@ -1479,6 +1492,14 @@
                 break;
 
+            case SYSTEM_INFO_INDEX_CPU_LOCK_CHECK:
+                if (u32 < s->cCpus)
+                    s->idCpuLockCheck = u32;
+                else
+                    LogRel(("ACPI: CPU %u does not exist\n", u32));
             case SYSTEM_INFO_INDEX_CPU_LOCKED:
-                s->uCpusLocked &= ~u32; /* Unlock the CPU */
+                if (u32 < s->cCpus)
+                    VMCPUSET_DEL(&s->CpuSetLocked, u32); /* Unlock the CPU */
+                else
+                    LogRel(("ACPI: CPU %u does not exist\n", u32));
                 break;
 
@@ -2080,5 +2101,5 @@
 
     /* Check if it was already attached */
-    if (s->afCpuAttached[iLUN])
+    if (VMCPUSET_IS_PRESENT(&s->CpuSetAttached, iLUN))
         return VINF_SUCCESS;
 
@@ -2089,13 +2110,14 @@
     {
         /* Enable the CPU */
-        s->afCpuAttached[iLUN] = true;
-
-        /* Enable the lapic */
-        acpiSetupMADT(s, s->GCPhysMADTBase);
+        VMCPUSET_ADD(&s->CpuSetAttached, iLUN);
+
         /*
          * Lock the CPU because we don't know if the guest will use it or not.
          * Prevents ejection while the CPU is still used
          */
-        s->uCpusLocked |= RT_BIT(iLUN);
+        VMCPUSET_ADD(&s->CpuSetLocked, iLUN);
+
+        /* Enable the lapic */
+        acpiSetupMADT(s, s->GCPhysMADTBase);
 
         /* Notify the guest */
@@ -2119,10 +2141,10 @@
 
     /* Check if it was already detached */
-    if (s->afCpuAttached[iLUN])
-    {
+    if (VMCPUSET_IS_PRESENT(&s->CpuSetAttached, iLUN))
+    {
+        AssertMsgReturnVoid(!(VMCPUSET_IS_PRESENT(&s->CpuSetLocked, iLUN)), ("CPU is still locked by the guest\n"));
+
         /* Disable the CPU */
-        s->afCpuAttached[iLUN] = false;
-
-        AssertMsg(!(s->uCpusLocked & RT_BIT(iLUN)), ("CPU is still locked by the guest\n"));
+        VMCPUSET_DEL(&s->CpuSetAttached, iLUN);
 
         /* Update the lapic state */
@@ -2195,5 +2217,6 @@
                               "ShowRtc\0"
                               "ShowCpu\0"
-                              "CpuHotplug\0" /** @todo r=bird: Rename to CpuHotPlug. */
+                              "CpuHotPlug\0"
+                              "AmlFilePath\0"
                               ))
         return PDMDEV_SET_ERROR(pDevIns, VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES,
@@ -2243,8 +2266,8 @@
 
     /* query whether we are allow CPU hot plugging */
-    rc = CFGMR3QueryBoolDef(pCfgHandle, "CpuHotplug", &s->fCpuHotPlug, false); /** @todo r=bird: Rename to CpuHotPlug. */
+    rc = CFGMR3QueryBoolDef(pCfgHandle, "CpuHotPlug", &s->fCpuHotPlug, false);
     if (RT_FAILURE(rc))
         return PDMDEV_SET_ERROR(pDevIns, rc,
-                                N_("Configuration error: Failed to read \"CpuHotplug\""));
+                                N_("Configuration error: Failed to read \"CpuHotPlug\""));
 
     rc = CFGMR3QueryBool(pCfgHandle, "GCEnabled", &s->fGCEnabled);
@@ -2274,7 +2297,11 @@
     s->IACPIPort.pfnGetCpuStatus            = acpiGetCpuStatus;
 
+    VMCPUSET_EMPTY(&s->CpuSetAttached);
+    VMCPUSET_EMPTY(&s->CpuSetLocked);
+    s->idCpuLockCheck = UINT32_C(0xffffffff);
+
     /* The first CPU can't be attached/detached */
-    s->afCpuAttached[0] = true;
-    s->uCpusLocked |= RT_BIT(0);
+    VMCPUSET_ADD(&s->CpuSetAttached, 0);
+    VMCPUSET_ADD(&s->CpuSetLocked, 0);
 
     /* Try to attach the other CPUs */
@@ -2288,13 +2315,10 @@
             if (RT_SUCCESS(rc))
             {
-                s->afCpuAttached[i] = true;
-                s->uCpusLocked |= RT_BIT(i);
+                VMCPUSET_ADD(&s->CpuSetAttached, i);
+                VMCPUSET_ADD(&s->CpuSetLocked, i);
                 Log(("acpi: Attached CPU %u\n", i));
             }
             else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
-            {
                 Log(("acpi: CPU %u not attached yet\n", i));
-                s->afCpuAttached[i] = false;
-            }
             else
                 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Failed to attach CPU object\n"));
@@ -2303,6 +2327,6 @@
         {
             /* CPU is always attached if hot-plug is not enabled. */
-            s->afCpuAttached[i] = true;
-            s->uCpusLocked |= RT_BIT(i);
+            VMCPUSET_ADD(&s->CpuSetAttached, i);
+            VMCPUSET_ADD(&s->CpuSetLocked, i);
         }
     }
Index: /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp
===================================================================
--- /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp	(revision 25837)
+++ /trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp	(revision 25838)
@@ -466,6 +466,7 @@
     GEN_CHECK_OFF(ACPIState, fUseSmc);
     GEN_CHECK_OFF(ACPIState, GCPhysMADTBase);
-    GEN_CHECK_OFF(ACPIState, afCpuAttached);
-    GEN_CHECK_OFF(ACPIState, uCpusLocked);
+    GEN_CHECK_OFF(ACPIState, CpuSetAttached);
+    GEN_CHECK_OFF(ACPIState, idCpuLockCheck);
+    GEN_CHECK_OFF(ACPIState, CpuSetLocked);
     GEN_CHECK_OFF(ACPIState, fCpuHotPlug);
     GEN_CHECK_OFF(ACPIState, IBase);
Index: /trunk/src/VBox/VMM/VM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VM.cpp	(revision 25837)
+++ /trunk/src/VBox/VMM/VM.cpp	(revision 25838)
@@ -4052,9 +4052,6 @@
  * @param   pidCpuPackage    Where to store the package ID of the virtual CPU.
  *
- * @todo    r=bird: Rename to VMR3GetCpuCoreAndPackageIdFromCpuId. We currently
- *          try avoid holding down the shift key, so 'Cpu' is favored over 'CPU'
- *          now.
- */
-VMMR3DECL(int) VMR3GetCPUCoreAndPackageIdFromCPUId(PVM pVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage)
+ */
+VMMR3DECL(int) VMR3GetCpuCoreAndPackageIdFromCpuId(PVM pVM, VMCPUID idCpu, uint32_t *pidCpuCore, uint32_t *pidCpuPackage)
 {
     if (idCpu >= pVM->cCpus)
@@ -4109,11 +4106,9 @@
  * @param   pVM     The VM to operate on.
  * @param   idCpu   Virtual CPU to perform the hot unplugging operation on.
- * @todo r=bird:  Rename to VMR3HotUnplugCpu.
- */
-VMMR3DECL(int) VMR3HotunplugCPU(PVM pVM, VMCPUID idCpu)
+ */
+VMMR3DECL(int) VMR3HotUnplugCpu(PVM pVM, VMCPUID idCpu)
 {
     AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
 
-    /** @todo Destroy EMT and not needed resources. */
     /** @todo r=bird: Don't destroy the EMT, it'll break VMMR3EmtRendezvous and
      *        broadcast requests.  Just note down somewhere that the CPU is
@@ -4130,11 +4125,9 @@
  * @param   pVM     The VM to operate on.
  * @param   idCpu   Virtual CPU to perform the hot plugging operation on.
- * @todo r=bird: Rename to VMR3HotPlugCpu.
- */
-VMMR3DECL(int) VMR3HotplugCPU(PVM pVM, VMCPUID idCpu)
+ */
+VMMR3DECL(int) VMR3HotPlugCpu(PVM pVM, VMCPUID idCpu)
 {
     AssertReturn(idCpu < pVM->cCpus, VERR_INVALID_CPU_ID);
 
-    /** @todo start EMT and allocate needed resources. */
     /** @todo r-bird: Just mark it online and make sure it waits on SPIP. */
     return VINF_SUCCESS;
