Index: /trunk/include/VBox/vmm/mm.h
===================================================================
--- /trunk/include/VBox/vmm/mm.h	(revision 51270)
+++ /trunk/include/VBox/vmm/mm.h	(revision 51271)
@@ -265,4 +265,5 @@
 VMMR3DECL(int)      MMR3HyperAllocOnceNoRel(PVM pVM, size_t cb, uint32_t uAlignment, MMTAG enmTag, void **ppv);
 VMMR3DECL(int)      MMR3HyperAllocOnceNoRelEx(PVM pVM, size_t cb, uint32_t uAlignment, MMTAG enmTag, uint32_t fFlags, void **ppv);
+VMMR3DECL(int)      MMR3HyperRealloc(PVM pVM, void *pv, size_t cb, unsigned uAlignmentNew, MMTAG enmTagNew, size_t cbNew, void **ppv);
 /** @name  MMR3HyperAllocOnceNoRelEx flags
  * @{ */
Index: /trunk/src/VBox/VMM/VMMAll/MMAllHyper.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/MMAllHyper.cpp	(revision 51270)
+++ /trunk/src/VBox/VMM/VMMAll/MMAllHyper.cpp	(revision 51271)
@@ -342,4 +342,15 @@
 /**
  * Duplicates a block of memory.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   pvSrc       The source memory block to copy from.
+ * @param   cb          Size of the source memory block.
+ * @param   uAlignment  Required memory alignment in bytes.
+ *                      Values are 0,8,16,32,64 and PAGE_SIZE.
+ *                      0 -> default alignment, i.e. 8 bytes.
+ * @param   enmTag      The statistics tag.
+ * @param   ppv         Where to store the address to the allocated
+ *                      memory.
  */
 VMMDECL(int) MMHyperDupMem(PVM pVM, const void *pvSrc, size_t cb, unsigned uAlignment, MMTAG enmTag, void **ppv)
Index: /trunk/src/VBox/VMM/VMMR3/CPUM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 51270)
+++ /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 51271)
@@ -776,5 +776,6 @@
          * MSR ranges).
          */
-        rc = cpumR3MsrRangesInsert(&pVM->cpum.s.GuestInfo.paMsrRangesR3, &pVM->cpum.s.GuestInfo.cMsrRanges, &MsrRange);
+        rc = cpumR3MsrRangesInsert(NULL /* pVM */, &pVM->cpum.s.GuestInfo.paMsrRangesR3, &pVM->cpum.s.GuestInfo.cMsrRanges,
+                                   &MsrRange);
         if (RT_FAILURE(rc))
             return VMSetError(pVM, rc, RT_SRC_POS, "Error adding MSR entry '%s': %Rrc\n", MsrRange.szName, rc);
@@ -870,5 +871,6 @@
          * Insert the leaf into the table (replaces existing ones).
          */
-        rc = cpumR3CpuIdInsert(&pVM->cpum.s.GuestInfo.paCpuIdLeavesR3, &pVM->cpum.s.GuestInfo.cCpuIdLeaves, &Leaf);
+        rc = cpumR3CpuIdInsert(NULL /* pVM */, &pVM->cpum.s.GuestInfo.paCpuIdLeavesR3, &pVM->cpum.s.GuestInfo.cCpuIdLeaves,
+                               &Leaf);
         if (RT_FAILURE(rc))
             return VMSetError(pVM, rc, RT_SRC_POS, "Error adding CPUID leaf entry '%s': %Rrc\n", szName, rc);
@@ -976,4 +978,5 @@
 
     AssertLogRelRCReturn(rc, rc);
+
 
     pCPUM->GuestInfo.paCpuIdLeavesR0 = MMHyperR3ToR0(pVM, pCPUM->GuestInfo.paCpuIdLeavesR3);
@@ -1467,5 +1470,5 @@
         }
 #endif
-        rc = cpumR3CpuIdInsert(&pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves, &NewLeaf);
+        rc = cpumR3CpuIdInsert(NULL /* pVM */, &pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves, &NewLeaf);
         AssertLogRelRCReturn(rc, rc);
     }
@@ -1668,5 +1671,5 @@
     NewLeaf.uEdx         = 0x786f4256 /* 'VBox' */;
     NewLeaf.fFlags       = 0;
-    rc = cpumR3CpuIdInsert(&pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves, &NewLeaf);
+    rc = cpumR3CpuIdInsert(NULL /* pVM */, &pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves, &NewLeaf);
     AssertLogRelRCReturn(rc, rc);
 
@@ -1677,5 +1680,5 @@
     NewLeaf.uEdx         = 0;
     NewLeaf.fFlags       = 0;
-    rc = cpumR3CpuIdInsert(&pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves, &NewLeaf);
+    rc = cpumR3CpuIdInsert(NULL /* pVM */, &pCPUM->GuestInfo.paCpuIdLeavesR3, &pCPUM->GuestInfo.cCpuIdLeaves, &NewLeaf);
     AssertLogRelRCReturn(rc, rc);
 
@@ -2068,5 +2071,5 @@
                 NewLeaf.uEdx            = CpuId.edx;
                 NewLeaf.fFlags          = 0;
-                rc = cpumR3CpuIdInsert(ppaLeaves, pcLeaves, &NewLeaf);
+                rc = cpumR3CpuIdInsert(NULL /* pVM */, ppaLeaves, pcLeaves, &NewLeaf);
             }
         }
@@ -4717,2 +4720,3 @@
     LogRel(("******************** End of CPUID dump **********************\n"));
 }
+
Index: /trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp	(revision 51270)
+++ /trunk/src/VBox/VMM/VMMR3/CPUMR3CpuId.cpp	(revision 51271)
@@ -23,4 +23,5 @@
 #include "CPUMInternal.h"
 #include <VBox/vmm/vm.h>
+#include <VBox/vmm/mm.h>
 
 #include <VBox/err.h>
@@ -553,19 +554,52 @@
  * @returns Pointer to the CPUID leaf array (*ppaLeaves) on success.  NULL on
  *          failure.
- * @param   ppaLeaves           Pointer to the variable holding the array
- *                              pointer (input/output).
- * @param   cLeaves             The current array size.
- */
-static PCPUMCPUIDLEAF cpumR3CpuIdEnsureSpace(PCPUMCPUIDLEAF *ppaLeaves, uint32_t cLeaves)
+ * @param   pVM         Pointer to the VM, used as the heap selector. Passing
+ *                      NULL uses the host-context heap, otherwise the VM's
+ *                      hyper heap is used.
+ * @param   ppaLeaves   Pointer to the variable holding the array pointer
+ *                      (input/output).
+ * @param   cLeaves     The current array size.
+ *
+ * @remarks This function will automatically update the R0 and RC pointers when
+ *          using the hyper heap, which means @a ppaLeaves and @a cLeaves must
+ *          be the corresponding VM's CPUID arrays (which is asserted).
+ */
+static PCPUMCPUIDLEAF cpumR3CpuIdEnsureSpace(PVM pVM, PCPUMCPUIDLEAF *ppaLeaves, uint32_t cLeaves)
 {
     uint32_t cAllocated = RT_ALIGN(cLeaves, 16);
     if (cLeaves + 1 > cAllocated)
     {
-        void *pvNew = RTMemRealloc(*ppaLeaves, (cAllocated + 16) * sizeof(**ppaLeaves));
-        if (!pvNew)
-        {
-            RTMemFree(*ppaLeaves);
-            *ppaLeaves = NULL;
-            return NULL;
+        void *pvNew;
+#ifndef IN_VBOX_CPU_REPORT
+        if (pVM)
+        {
+            Assert(ppaLeaves == &pVM->cpum.s.GuestInfo.paCpuIdLeavesR3);
+            Assert(cLeaves == pVM->cpum.s.GuestInfo.cCpuIdLeaves);
+
+            size_t cb    = cAllocated * sizeof(**ppaLeaves);
+            size_t cbNew = (cAllocated + 16) * sizeof(**ppaLeaves);
+            int rc = MMR3HyperRealloc(pVM, *ppaLeaves, cb, 32, MM_TAG_CPUM_CPUID, cbNew, &pvNew);
+            if (RT_FAILURE(rc))
+            {
+                *ppaLeaves = NULL;
+                pVM->cpum.s.GuestInfo.paCpuIdLeavesR0 = NIL_RTR0PTR;
+                pVM->cpum.s.GuestInfo.paCpuIdLeavesRC = NIL_RTRCPTR;
+                return NULL;
+            }
+
+            /* Update the R0 and RC pointers. */
+            pVM->cpum.s.GuestInfo.paCpuIdLeavesR0 = MMHyperR3ToR0(pVM, *ppaLeaves);
+            pVM->cpum.s.GuestInfo.paCpuIdLeavesRC = MMHyperR3ToRC(pVM, *ppaLeaves);
+        }
+        else
+#endif
+        {
+            pvNew = RTMemRealloc(*ppaLeaves, (cAllocated + 16) * sizeof(**ppaLeaves));
+            if (!pvNew)
+            {
+                RTMemFree(*ppaLeaves);
+                *ppaLeaves = NULL;
+                return NULL;
+            }
         }
         *ppaLeaves   = (PCPUMCPUIDLEAF)pvNew;
@@ -579,5 +613,5 @@
  *
  * ASSUMES linear insertion order, so we'll won't need to do any searching or
- * replace anything.  Use cpumR3CpuIdInsert for those cases.
+ * replace anything.  Use cpumR3CpuIdInsert() for those cases.
  *
  * @returns VINF_SUCCESS or VERR_NO_MEMORY.  On error, *ppaLeaves is freed, so
@@ -599,5 +633,5 @@
                                         uint32_t uEax, uint32_t uEbx, uint32_t uEcx, uint32_t uEdx, uint32_t fFlags)
 {
-    if (!cpumR3CpuIdEnsureSpace(ppaLeaves, *pcLeaves))
+    if (!cpumR3CpuIdEnsureSpace(NULL /* pVM */, ppaLeaves, *pcLeaves))
         return VERR_NO_MEMORY;
 
@@ -627,18 +661,36 @@
  * the same leaf number (eax), the simple leaf will replace the whole series.
  *
- * This ASSUMES that the leave array is still on the normal heap and has only
- * been allocated/reallocated by the cpumR3CpuIdEnsureSpace function.
+ * When pVM is NULL, this ASSUMES that the leaves array is still on the normal
+ * host-context heap and has only been allocated/reallocated by the
+ * cpumR3CpuIdEnsureSpace function.
  *
  * @returns VBox status code.
+ * @param   pVM             Pointer to the VM, used as the heap selector.
+ *                          Passing NULL uses the host-context heap, otherwise
+ *                          the VM's hyper heap is used.
  * @param   ppaLeaves       Pointer to the the pointer to the array of sorted
- *                          CPUID leaves and sub-leaves.
- * @param   pcLeaves        Where we keep the leaf count for *ppaLeaves.
+ *                          CPUID leaves and sub-leaves. Must be NULL if using
+ *                          the hyper heap.
+ * @param   pcLeaves        Where we keep the leaf count for *ppaLeaves. Must be
+ *                          NULL if using the hyper heap.
  * @param   pNewLeaf        Pointer to the data of the new leaf we're about to
  *                          insert.
  */
-int cpumR3CpuIdInsert(PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves, PCPUMCPUIDLEAF pNewLeaf)
+int cpumR3CpuIdInsert(PVM pVM, PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves, PCPUMCPUIDLEAF pNewLeaf)
 {
     PCPUMCPUIDLEAF  paLeaves = *ppaLeaves;
     uint32_t        cLeaves  = *pcLeaves;
+
+    /*
+     * Validate input parameters if we are using the hyper heap and use the VM's CPUID arrays.
+     */
+    if (pVM)
+    {
+        AssertReturn(!ppaLeaves, VERR_INVALID_PARAMETER);
+        AssertReturn(!pcLeaves, VERR_INVALID_PARAMETER);
+
+        ppaLeaves = &pVM->cpum.s.GuestInfo.paCpuIdLeavesR3;
+        pcLeaves  = &pVM->cpum.s.GuestInfo.cCpuIdLeaves;
+    }
 
     /*
@@ -649,5 +701,4 @@
     AssertReturn(RT_IS_POWER_OF_TWO(pNewLeaf->fSubLeafMask + 1), VERR_INVALID_PARAMETER);
     AssertReturn((pNewLeaf->fSubLeafMask & pNewLeaf->uSubLeaf) == pNewLeaf->uSubLeaf, VERR_INVALID_PARAMETER);
-
 
     /*
@@ -701,5 +752,5 @@
      * Adding a new leaf at 'i'.
      */
-    paLeaves = cpumR3CpuIdEnsureSpace(ppaLeaves, cLeaves);
+    paLeaves = cpumR3CpuIdEnsureSpace(pVM, ppaLeaves, cLeaves);
     if (!paLeaves)
         return VERR_NO_MEMORY;
@@ -864,4 +915,21 @@
     return true;
 }
+
+
+#if 0
+/**
+ * Inserts a CPU ID leaf, replacing any existing ones.
+ *
+ * @returns VBox status code.
+ * @param   pVM         Pointer to the VM.
+ * @param   pNewLeaf    Pointer to the leaf being inserted.
+ */
+VMMR3DECL(int) CPUMR3CpuIdInsert(PVM pVM, PCPUMCPUIDLEAF pNewLeaf)
+{
+    /** @todo Should we disallow here inserting/replacing the standard leaves that
+     *        PATM relies on? See @bugref{7270}. */
+    return cpumR3CpuIdInsert(pVM, NULL /* ppaLeaves */, NULL /* pcLeaves */, pNewLeaf);
+}
+#endif
 
 
Index: /trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp	(revision 51270)
+++ /trunk/src/VBox/VMM/VMMR3/CPUMR3Db.cpp	(revision 51271)
@@ -23,4 +23,5 @@
 #include "CPUMInternal.h"
 #include <VBox/vmm/vm.h>
+#include <VBox/vmm/mm.h>
 
 #include <VBox/err.h>
@@ -297,20 +298,47 @@
  * @returns Pointer to the MSR ranges on success, NULL on failure.  On failure
  *          @a *ppaMsrRanges is freed and set to NULL.
+ * @param   pVM             Pointer to the VM, used as the heap selector.
+ *                          Passing NULL uses the host-context heap, otherwise
+ *                          the VM's hyper heap is used.
  * @param   ppaMsrRanges    The variable pointing to the ranges (input/output).
  * @param   cMsrRanges      The current number of ranges.
  * @param   cNewRanges      The number of ranges to be added.
  */
-static PCPUMMSRRANGE cpumR3MsrRangesEnsureSpace(PCPUMMSRRANGE *ppaMsrRanges, uint32_t cMsrRanges, uint32_t cNewRanges)
+static PCPUMMSRRANGE cpumR3MsrRangesEnsureSpace(PVM pVM, PCPUMMSRRANGE *ppaMsrRanges, uint32_t cMsrRanges, uint32_t cNewRanges)
 {
     uint32_t cMsrRangesAllocated = RT_ALIGN_32(cMsrRanges, 16);
     if (cMsrRangesAllocated < cMsrRanges + cNewRanges)
     {
+        void    *pvNew;
         uint32_t cNew = RT_ALIGN_32(cMsrRanges + cNewRanges, 16);
-        void *pvNew = RTMemRealloc(*ppaMsrRanges, cNew * sizeof(**ppaMsrRanges));
-        if (!pvNew)
-        {
-            RTMemFree(*ppaMsrRanges);
-            *ppaMsrRanges = NULL;
-            return NULL;
+        if (pVM)
+        {
+            Assert(ppaMsrRanges == &pVM->cpum.s.GuestInfo.paMsrRangesR3);
+            Assert(cMsrRanges   == pVM->cpum.s.GuestInfo.cMsrRanges);
+
+            size_t cb    = cMsrRangesAllocated * sizeof(**ppaMsrRanges);
+            size_t cbNew = cNew * sizeof(**ppaMsrRanges);
+            int rc = MMR3HyperRealloc(pVM, *ppaMsrRanges, cb, 32, MM_TAG_CPUM_MSRS, cbNew, &pvNew);
+            if (RT_FAILURE(rc))
+            {
+                *ppaMsrRanges = NULL;
+                pVM->cpum.s.GuestInfo.paMsrRangesR0 = NIL_RTR0PTR;
+                pVM->cpum.s.GuestInfo.paMsrRangesRC = NIL_RTRCPTR;
+                return NULL;
+            }
+
+            pVM->cpum.s.GuestInfo.paMsrRangesR0 = MMHyperR3ToR0(pVM, *ppaMsrRanges);
+            pVM->cpum.s.GuestInfo.paMsrRangesR0 = MMHyperR3ToRC(pVM, *ppaMsrRanges);
+            /** @todo Update R0 and RC pointers here?  */
+        }
+        else
+        {
+            pvNew = RTMemRealloc(*ppaMsrRanges, cNew * sizeof(**ppaMsrRanges));
+            if (!pvNew)
+            {
+                RTMemFree(*ppaMsrRanges);
+                *ppaMsrRanges = NULL;
+                return NULL;
+            }
         }
         *ppaMsrRanges = (PCPUMMSRRANGE)pvNew;
@@ -330,9 +358,14 @@
  * @retval  VERR_NO_MEMORY
  *
+ * @param   pVM             Pointer to the VM, used as the heap selector.
+ *                          Passing NULL uses the host-context heap, otherwise
+ *                          the hyper heap.
  * @param   ppaMsrRanges    The variable pointing to the ranges (input/output).
- * @param   pcMsrRanges     The variable holding number of ranges.
+ *                          Must be NULL if using the hyper heap.
+ * @param   pcMsrRanges     The variable holding number of ranges. Must be NULL
+ *                          if using the hyper heap.
  * @param   pNewRange       The new range.
  */
-int cpumR3MsrRangesInsert(PCPUMMSRRANGE *ppaMsrRanges, uint32_t *pcMsrRanges, PCCPUMMSRRANGE pNewRange)
+int cpumR3MsrRangesInsert(PVM pVM, PCPUMMSRRANGE *ppaMsrRanges, uint32_t *pcMsrRanges, PCCPUMMSRRANGE pNewRange)
 {
     uint32_t        cMsrRanges  = *pcMsrRanges;
@@ -342,4 +375,16 @@
     Assert(pNewRange->enmRdFn > kCpumMsrRdFn_Invalid && pNewRange->enmRdFn < kCpumMsrRdFn_End);
     Assert(pNewRange->enmWrFn > kCpumMsrWrFn_Invalid && pNewRange->enmWrFn < kCpumMsrWrFn_End);
+
+    /*
+     * Validate and use the VM's MSR ranges array if we are using the hyper heap.
+     */
+    if (pVM)
+    {
+        AssertReturn(!ppaMsrRanges, VERR_INVALID_PARAMETER);
+        AssertReturn(!pcMsrRanges,  VERR_INVALID_PARAMETER);
+
+        ppaMsrRanges = &pVM->cpum.s.GuestInfo.paMsrRangesR3;
+        pcMsrRanges  = &pVM->cpum.s.GuestInfo.cMsrRanges;
+    }
 
     /*
@@ -349,5 +394,5 @@
         && paMsrRanges[cMsrRanges - 1].uLast < pNewRange->uFirst)
     {
-        paMsrRanges = cpumR3MsrRangesEnsureSpace(ppaMsrRanges, cMsrRanges, 1);
+        paMsrRanges = cpumR3MsrRangesEnsureSpace(pVM, ppaMsrRanges, cMsrRanges, 1);
         if (!paMsrRanges)
             return VERR_NO_MEMORY;
@@ -367,5 +412,5 @@
             || pNewRange->uLast < paMsrRanges[i].uFirst)
         {
-            paMsrRanges = cpumR3MsrRangesEnsureSpace(ppaMsrRanges, cMsrRanges, 1);
+            paMsrRanges = cpumR3MsrRangesEnsureSpace(pVM, ppaMsrRanges, cMsrRanges, 1);
             if (!paMsrRanges)
                 return VERR_NO_MEMORY;
@@ -387,5 +432,5 @@
                  && pNewRange->uLast  < paMsrRanges[i].uLast)
         {
-            paMsrRanges = cpumR3MsrRangesEnsureSpace(ppaMsrRanges, cMsrRanges, 2);
+            paMsrRanges = cpumR3MsrRangesEnsureSpace(pVM, ppaMsrRanges, cMsrRanges, 2);
             if (!paMsrRanges)
                 return VERR_NO_MEMORY;
@@ -447,5 +492,5 @@
 
             /* Now, perform a normal insertion. */
-            paMsrRanges = cpumR3MsrRangesEnsureSpace(ppaMsrRanges, cMsrRanges, 1);
+            paMsrRanges = cpumR3MsrRangesEnsureSpace(pVM, ppaMsrRanges, cMsrRanges, 1);
             if (!paMsrRanges)
                 return VERR_NO_MEMORY;
@@ -475,5 +520,5 @@
         {
             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,
+            int rc = cpumR3MsrRangesInsert(pVM, &pVM->cpum.s.GuestInfo.paMsrRangesR3, &pVM->cpum.s.GuestInfo.cMsrRanges,
                                            &paRanges[i]);
             if (RT_FAILURE(rc))
@@ -694,5 +739,5 @@
     while (cLeft-- > 0)
     {
-        rc = cpumR3MsrRangesInsert(&paMsrs, &cMsrs, pCurMsr);
+        rc = cpumR3MsrRangesInsert(NULL /* pVM */, &paMsrs, &cMsrs, pCurMsr);
         if (RT_FAILURE(rc))
         {
@@ -709,4 +754,22 @@
     return VINF_SUCCESS;
 }
+
+
+#if 0
+/**
+ * Insert an MSR range into the VM.
+ *
+ * If the new MSR range overlaps existing ranges, the existing ones will be
+ * adjusted/removed to fit in the new one.
+ *
+ * @returns VBox status code.
+ * @param   pVM                 Pointer to the cross context VM structure.
+ * @param   pNewRange           Pointer to the MSR range being inserted.
+ */
+VMMR3DECL(int) CPUMR3MsrRangesInsert(PVM pVM, PCCPUMMSRRANGE pNewRange)
+{
+    return cpumR3MsrRangesInsert(pVM, NULL /* ppaMsrRanges */, NULL /* pcMsrRanges */, pNewRange);
+}
+#endif
 
 
Index: /trunk/src/VBox/VMM/VMMR3/MMHyper.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/MMHyper.cpp	(revision 51270)
+++ /trunk/src/VBox/VMM/VMMR3/MMHyper.cpp	(revision 51271)
@@ -1437,2 +1437,63 @@
 }
 
+
+/**
+ * Re-allocates memory from the hyper heap.
+ *
+ * @returns VBox status code.
+ * @param   pVM             Pointer to the VM.
+ * @param   pvOld           The existing block of memory in the
+ *                          hyper heap to re-allocate (can be
+ *                          NULL).
+ * @param   cbOld           Size of the existing block.
+ * @param   uAlignmentNew   Required memory alignment in bytes.
+ *                          Values are 0,8,16,32 and PAGE_SIZE.
+ *                          0 -> default alignment, i.e. 8 bytes.
+ * @param   enmTagNew       The statistics tag.
+ * @param   cbNew           The required size of the new block.
+ * @param   ppv             Where to store the address to the
+ *                          re-allocated block.
+ *
+ * @remarks This does not work like normal realloc()
+ *          on failure, the memory pointed to by @a pvOld is
+ *          lost if there isn't sufficient space on the hyper
+ *          heap for the re-allocation to succeed.
+*/
+VMMR3DECL(int) MMR3HyperRealloc(PVM pVM, void *pvOld, size_t cbOld, unsigned uAlignmentNew, MMTAG enmTagNew, size_t cbNew,
+                                void **ppv)
+{
+    if (!pvOld)
+        return MMHyperAlloc(pVM, cbNew, uAlignmentNew, enmTagNew, ppv);
+
+    if (!cbNew && pvOld)
+        return MMHyperFree(pVM, pvOld);
+
+    if (cbOld == cbNew)
+        return VINF_SUCCESS;
+
+    size_t cbData = RT_MIN(cbNew, cbOld);
+    void *pvTmp = RTMemTmpAlloc(cbData);
+    if (RT_UNLIKELY(!pvTmp))
+    {
+        MMHyperFree(pVM, pvOld);
+        return VERR_NO_TMP_MEMORY;
+    }
+    memcpy(pvTmp, pvOld, cbData);
+
+    int rc = MMHyperFree(pVM, pvOld);
+    if (RT_SUCCESS(rc))
+    {
+        rc = MMHyperAlloc(pVM, cbNew, uAlignmentNew, enmTagNew, ppv);
+        if (RT_SUCCESS(rc))
+        {
+            Assert(cbData <= cbNew);
+            memcpy(*ppv, pvTmp, cbData);
+        }
+    }
+    else
+        AssertMsgFailed(("Failed to free hyper heap block pvOld=%p cbOld=%u\n", pvOld, cbOld));
+
+    RTMemTmpFree(pvTmp);
+    return rc;
+}
+
Index: /trunk/src/VBox/VMM/include/CPUMInternal.h
===================================================================
--- /trunk/src/VBox/VMM/include/CPUMInternal.h	(revision 51270)
+++ /trunk/src/VBox/VMM/include/CPUMInternal.h	(revision 51271)
@@ -1115,9 +1115,9 @@
 bool                cpumR3CpuIdGetLeafLegacy(PCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, uint32_t uLeaf, uint32_t uSubLeaf,
                                              PCPUMCPUID pLeagcy);
-int                 cpumR3CpuIdInsert(PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves, PCPUMCPUIDLEAF pNewLeaf);
+int                 cpumR3CpuIdInsert(PVM pVM, PCPUMCPUIDLEAF *ppaLeaves, uint32_t *pcLeaves, PCPUMCPUIDLEAF pNewLeaf);
 void                cpumR3CpuIdRemoveRange(PCPUMCPUIDLEAF paLeaves, uint32_t *pcLeaves, uint32_t uFirst, uint32_t uLast);
 int                 cpumR3CpuIdExplodeFeatures(PCCPUMCPUIDLEAF paLeaves, uint32_t cLeaves, PCPUMFEATURES pFeatures);
 int                 cpumR3DbGetCpuInfo(const char *pszName, PCPUMINFO pInfo);
-int                 cpumR3MsrRangesInsert(PCPUMMSRRANGE *ppaMsrRanges, uint32_t *pcMsrRanges, PCCPUMMSRRANGE pNewRange);
+int                 cpumR3MsrRangesInsert(PVM pVM, PCPUMMSRRANGE *ppaMsrRanges, uint32_t *pcMsrRanges, PCCPUMMSRRANGE pNewRange);
 int                 cpumR3MsrApplyFudge(PVM pVM);
 int                 cpumR3MsrRegStats(PVM pVM);
