Index: /trunk/include/VBox/gmm.h
===================================================================
--- /trunk/include/VBox/gmm.h	(revision 29619)
+++ /trunk/include/VBox/gmm.h	(revision 29620)
@@ -419,4 +419,6 @@
     /** The number of ballooned pages (out). */
     uint64_t            cBalloonedPages;
+    /** The number of shared pages (out). */
+    uint64_t            cSharedPages;
     /** Maximum nr of pages (out). */
     uint64_t            cMaxPages;
@@ -607,5 +609,5 @@
 GMMR3DECL(int)  GMMR3MapUnmapChunk(PVM pVM, uint32_t idChunkMap, uint32_t idChunkUnmap, PRTR3PTR ppvR3);
 GMMR3DECL(int)  GMMR3SeedChunk(PVM pVM, RTR3PTR pvR3);
-GMMR3DECL(int)  GMMR3QueryHypervisorMemoryStats(PVM pVM, uint64_t *pcTotalAllocPages, uint64_t *pcTotalFreePages, uint64_t *pcTotalBalloonPages);
+GMMR3DECL(int)  GMMR3QueryHypervisorMemoryStats(PVM pVM, uint64_t *pcTotalAllocPages, uint64_t *pcTotalFreePages, uint64_t *pcTotalBalloonPages, uint64_t *puTotalBalloonSize);
 GMMR3DECL(int)  GMMR3QueryMemoryStats(PVM pVM, uint64_t *pcAllocPages, uint64_t *pcMaxPages, uint64_t *pcBalloonPages);
 GMMR3DECL(int)  GMMR3BalloonedPages(PVM pVM, GMMBALLOONACTION enmAction, uint32_t cBalloonedPages);
Index: /trunk/include/VBox/pgm.h
===================================================================
--- /trunk/include/VBox/pgm.h	(revision 29619)
+++ /trunk/include/VBox/pgm.h	(revision 29620)
@@ -467,5 +467,6 @@
 VMMR3DECL(int)      PGMR3PhysRegisterRam(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb, const char *pszDesc);
 VMMR3DECL(int)      PGMR3PhysChangeMemBalloon(PVM pVM, bool fInflate, unsigned cPages, RTGCPHYS *paPhysPage);
-VMMR3DECL(int)      PGMR3QueryVMMMemoryStats(PVM pVM, uint64_t *puTotalAllocSize, uint64_t *puTotalFreeSize, uint64_t *puTotalBalloonSize);
+VMMR3DECL(int)      PGMR3QueryVMMMemoryStats(PVM pVM, uint64_t *puTotalAllocSize, uint64_t *puTotalFreeSize, uint64_t *puTotalBalloonSize, uint64_t *puTotalSharedSize);
+VMMR3DECL(int)      PGMR3QueryMemoryStats(PVM pVM, uint64_t *pulTotalMem, uint64_t *pulPrivateMem, uint64_t *puTotalSharedMem, uint64_t *puTotalZeroMem);
 VMMR3DECL(int)      PGMR3PhysMMIORegister(PVM pVM, RTGCPHYS GCPhys, RTGCPHYS cb,
                                           R3PTRTYPE(PFNPGMR3PHYSHANDLER) pfnHandlerR3, RTR3PTR pvUserR3,
Index: /trunk/src/VBox/Main/GuestImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/GuestImpl.cpp	(revision 29619)
+++ /trunk/src/VBox/Main/GuestImpl.cpp	(revision 29620)
@@ -338,12 +338,11 @@
     *aMemCache   = mCurrentGuestStat[GUESTSTATTYPE_MEMCACHE] * (_4K/_1K);     /* page (4K) -> 1KB units */
     *aPageTotal  = mCurrentGuestStat[GUESTSTATTYPE_PAGETOTAL] * (_4K/_1K);   /* page (4K) -> 1KB units */
-    *aMemShared  = 0; /** todo */
 
     Console::SafeVMPtr pVM (mParent);
     if (pVM.isOk())
     {
-        uint64_t uFreeTotal, uAllocTotal, uBalloonedTotal;
+        uint64_t uFreeTotal, uAllocTotal, uBalloonedTotal, uSharedTotal;
         *aMemFreeTotal = 0;
-        int rc = PGMR3QueryVMMMemoryStats(pVM.raw(), &uAllocTotal, &uFreeTotal, &uBalloonedTotal);
+        int rc = PGMR3QueryVMMMemoryStats(pVM.raw(), &uAllocTotal, &uFreeTotal, &uBalloonedTotal, &uSharedTotal);
         AssertRC(rc);
         if (rc == VINF_SUCCESS)
@@ -352,9 +351,21 @@
             *aMemFreeTotal    = (ULONG)(uFreeTotal / _1K);
             *aMemBalloonTotal = (ULONG)(uBalloonedTotal / _1K);
-            *aMemSharedTotal  = 0; /** todo */
+            *aMemSharedTotal  = (ULONG)(uSharedTotal / _1K);
+        }
+
+        /* Query the missing per-VM memory statistics. */
+        *aMemShared  = 0;
+        uint64_t uTotalMem, uPrivateMem, uSharedMem, uZeroMem;
+        rc = PGMR3QueryMemoryStats(pVM.raw(), &uTotalMem, &uPrivateMem, &uSharedMem, &uZeroMem);
+        if (rc == VINF_SUCCESS)
+        {
+            *aMemShared = (ULONG)(uSharedMem / _1K);
         }
     }
     else
+    {
         *aMemFreeTotal = 0;
+        *aMemShared  = 0;
+    }
 
     return S_OK;
Index: /trunk/src/VBox/Main/HostImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/HostImpl.cpp	(revision 29619)
+++ /trunk/src/VBox/Main/HostImpl.cpp	(revision 29620)
@@ -2356,4 +2356,6 @@
     pm::SubMetric *ramVMMBallooned  = new pm::SubMetric("RAM/VMM/Ballooned",
         "Total physical memory ballooned by the hypervisor.");
+    pm::SubMetric *ramVMMShared = new pm::SubMetric("RAM/VMM/Shared",
+        "Total physical memory shared between VMs.");
 
 
@@ -2368,5 +2370,5 @@
     aCollector->registerBaseMetric (cpuMhz);
     pm::BaseMetric *ramUsage = new pm::HostRamUsage(hal, objptr, ramUsageTotal, ramUsageUsed,
-                                           ramUsageFree, ramVMMUsed, ramVMMFree, ramVMMBallooned);
+                                           ramUsageFree, ramVMMUsed, ramVMMFree, ramVMMBallooned, ramVMMShared);
     aCollector->registerBaseMetric (ramUsage);
 
@@ -2450,4 +2452,12 @@
     aCollector->registerMetric(new pm::Metric(ramUsage, ramVMMBallooned,
                                               new pm::AggregateMax()));
+
+    aCollector->registerMetric(new pm::Metric(ramUsage, ramVMMShared, 0));
+    aCollector->registerMetric(new pm::Metric(ramUsage, ramVMMShared,
+                                              new pm::AggregateAvg()));
+    aCollector->registerMetric(new pm::Metric(ramUsage, ramVMMShared,
+                                              new pm::AggregateMin()));
+    aCollector->registerMetric(new pm::Metric(ramUsage, ramVMMShared,
+                                              new pm::AggregateMax()));
 }
 
Index: /trunk/src/VBox/Main/MachineImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/MachineImpl.cpp	(revision 29619)
+++ /trunk/src/VBox/Main/MachineImpl.cpp	(revision 29620)
@@ -9221,4 +9221,5 @@
     pm::SubMetric *guestMemFree = new pm::SubMetric("Guest/RAM/Usage/Free",        "Free amount of physical guest RAM.");
     pm::SubMetric *guestMemBalloon = new pm::SubMetric("Guest/RAM/Usage/Balloon",  "Amount of ballooned physical guest RAM.");
+    pm::SubMetric *guestMemShared = new pm::SubMetric("Guest/RAM/Usage/Shared",  "Amount of shared physical guest RAM.");
     pm::SubMetric *guestMemCache = new pm::SubMetric("Guest/RAM/Usage/Cache",        "Total amount of guest (disk) cache memory.");
 
@@ -9229,5 +9230,5 @@
     aCollector->registerBaseMetric(guestCpuLoad);
 
-    pm::BaseMetric *guestCpuMem = new pm::GuestRamUsage(mGuestHAL, aMachine, guestMemTotal, guestMemFree, guestMemBalloon,
+    pm::BaseMetric *guestCpuMem = new pm::GuestRamUsage(mGuestHAL, aMachine, guestMemTotal, guestMemFree, guestMemBalloon, guestMemShared,
                                                         guestMemCache, guestPagedTotal);
     aCollector->registerBaseMetric(guestCpuMem);
@@ -9262,4 +9263,9 @@
     aCollector->registerMetric(new pm::Metric(guestCpuMem, guestMemBalloon, new pm::AggregateMin()));
     aCollector->registerMetric(new pm::Metric(guestCpuMem, guestMemBalloon, new pm::AggregateMax()));
+
+    aCollector->registerMetric(new pm::Metric(guestCpuMem, guestMemShared, 0));
+    aCollector->registerMetric(new pm::Metric(guestCpuMem, guestMemShared, new pm::AggregateAvg()));
+    aCollector->registerMetric(new pm::Metric(guestCpuMem, guestMemShared, new pm::AggregateMin()));
+    aCollector->registerMetric(new pm::Metric(guestCpuMem, guestMemShared, new pm::AggregateMax()));
 
     aCollector->registerMetric(new pm::Metric(guestCpuMem, guestMemCache, 0));
Index: /trunk/src/VBox/Main/Performance.cpp
===================================================================
--- /trunk/src/VBox/Main/Performance.cpp	(revision 29619)
+++ /trunk/src/VBox/Main/Performance.cpp	(revision 29620)
@@ -164,13 +164,13 @@
         &&  iTick != mLastTick)
     {
-        ULONG ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemSharedTotal, uMemShared;
+        ULONG ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemSharedTotal, ulMemShared;
 
         /** todo shared stats. */
         mGuest->InternalGetStatistics(&mCpuUser, &mCpuKernel, &mCpuIdle,
-                                      &mMemTotal, &mMemFree, &mMemBalloon, &mMemCache, &uMemShared,
+                                      &mMemTotal, &mMemFree, &mMemBalloon, &ulMemShared, &mMemCache,
                                       &mPageTotal, &ulMemAllocTotal, &ulMemFreeTotal, &ulMemBalloonTotal, &ulMemSharedTotal);
 
         if (mHostHAL)
-            mHostHAL->setMemHypervisorStats(ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal);
+            mHostHAL->setMemHypervisorStats(ulMemAllocTotal, ulMemFreeTotal, ulMemBalloonTotal, ulMemShared);
 
         mLastTick = iTick;
@@ -288,4 +288,5 @@
     mFreeVMM->init(mLength);
     mBalloonVMM->init(mLength);
+    mSharedVMM->init(mLength);
 }
 
@@ -306,10 +307,11 @@
 
     }
-    ULONG allocVMM, freeVMM, balloonVMM;
-
-    mHAL->getMemHypervisorStats(&allocVMM, &freeVMM, &balloonVMM);
+    ULONG allocVMM, freeVMM, balloonVMM, sharedVMM;
+
+    mHAL->getMemHypervisorStats(&allocVMM, &freeVMM, &balloonVMM, &sharedVMM);
     mAllocVMM->put(allocVMM);
     mFreeVMM->put(freeVMM);
     mBalloonVMM->put(balloonVMM);
+    mSharedVMM->put(sharedVMM);
 }
 
@@ -419,4 +421,5 @@
     mFree->init(mLength);
     mBallooned->init(mLength);
+    mShared->init(mLength);
     mCache->init(mLength);
     mPagedTotal->init(mLength);
@@ -430,10 +433,11 @@
 void GuestRamUsage::collect()
 {
-    ULONG ulMemTotal = 0, ulMemFree = 0, ulMemBalloon = 0, ulMemCache = 0, ulPageTotal = 0;
-
-    mGuestHAL->getGuestMemLoad(&ulMemTotal, &ulMemFree, &ulMemBalloon, &ulMemCache, &ulPageTotal);
+    ULONG ulMemTotal = 0, ulMemFree = 0, ulMemBalloon = 0, ulMemShared = 0, ulMemCache = 0, ulPageTotal = 0;
+
+    mGuestHAL->getGuestMemLoad(&ulMemTotal, &ulMemFree, &ulMemBalloon, &ulMemShared, &ulMemCache, &ulPageTotal);
     mTotal->put(ulMemTotal);
     mFree->put(ulMemFree);
     mBallooned->put(ulMemBalloon);
+    mShared->put(ulMemShared);
     mCache->put(ulMemCache);
     mPagedTotal->put(ulPageTotal);
Index: /trunk/src/VBox/Main/PerformanceImpl.cpp
===================================================================
--- /trunk/src/VBox/Main/PerformanceImpl.cpp	(revision 29619)
+++ /trunk/src/VBox/Main/PerformanceImpl.cpp	(revision 29620)
@@ -76,4 +76,8 @@
     "RAM/VMM/Ballooned:min",
     "RAM/VMM/Ballooned:max",
+    "RAM/VMM/Shared",
+    "RAM/VMM/Shared:avg",
+    "RAM/VMM/Shared:min",
+    "RAM/VMM/Shared:max",
     "Guest/CPU/Load/User",
     "Guest/CPU/Load/User:avg",
@@ -100,4 +104,8 @@
     "Guest/RAM/Usage/Balloon:min",
     "Guest/RAM/Usage/Balloon:max",
+    "Guest/RAM/Usage/Shared",
+    "Guest/RAM/Usage/Shared:avg",
+    "Guest/RAM/Usage/Shared:min",
+    "Guest/RAM/Usage/Shared:max",
     "Guest/RAM/Usage/Cache",
     "Guest/RAM/Usage/Cache:avg",
Index: /trunk/src/VBox/Main/include/Performance.h
===================================================================
--- /trunk/src/VBox/Main/include/Performance.h	(revision 29619)
+++ /trunk/src/VBox/Main/include/Performance.h	(revision 29620)
@@ -159,17 +159,19 @@
         virtual int disable();
 
-        virtual int setMemHypervisorStats(ULONG memAlloc, ULONG memFree, ULONG memBallooned)
+        virtual int setMemHypervisorStats(ULONG memAlloc, ULONG memFree, ULONG memBallooned, ULONG memShared)
         {
             mMemAllocVMM     = memAlloc;
             mMemFreeVMM      = memFree;
             mMemBalloonedVMM = memBallooned;
+            mMemSharedVMM    = memShared;
             return S_OK;
         }
 
-        virtual void getMemHypervisorStats(ULONG *pMemAlloc, ULONG *pMemFree, ULONG *pMemBallooned)
+        virtual void getMemHypervisorStats(ULONG *pMemAlloc, ULONG *pMemFree, ULONG *pMemBallooned, ULONG *pMemShared)
         {
             *pMemAlloc     = mMemAllocVMM;
             *pMemFree      = mMemFreeVMM;
             *pMemBallooned = mMemBalloonedVMM;
+            *pMemShared    = mMemSharedVMM;
         }
 
@@ -178,4 +180,5 @@
         ULONG       mMemFreeVMM;
         ULONG       mMemBalloonedVMM;
+        ULONG       mMemSharedVMM;
     };
 
@@ -185,5 +188,5 @@
         CollectorGuestHAL(Machine *machine, CollectorHAL *hostHAL) : CollectorHAL(), cEnabled(0), mMachine(machine), mConsole(NULL), mGuest(NULL),
                                               mLastTick(0), mHostHAL(hostHAL), mCpuUser(0), mCpuKernel(0), mCpuIdle(0), mMemTotal(0), mMemFree(0),
-                                              mMemBalloon(0), mMemCache(0), mPageTotal(0) {};
+                                              mMemBalloon(0), mMemShared(0), mMemCache(0), mPageTotal(0) {};
         ~CollectorGuestHAL();
 
@@ -204,9 +207,10 @@
 
         /** Return guest memory information in KB. */
-        void getGuestMemLoad(ULONG *pulMemTotal, ULONG *pulMemFree, ULONG *pulMemBalloon, ULONG *pulMemCache, ULONG *pulPageTotal)
+        void getGuestMemLoad(ULONG *pulMemTotal, ULONG *pulMemFree, ULONG *pulMemBalloon, ULONG *pulMemShared, ULONG *pulMemCache, ULONG *pulPageTotal)
         {
             *pulMemTotal        = mMemTotal;
             *pulMemFree         = mMemFree;
             *pulMemBalloon      = mMemBalloon;
+            *pulMemShared       = mMemShared;
             *pulMemCache        = mMemCache;
             *pulPageTotal       = mPageTotal;
@@ -229,4 +233,5 @@
         ULONG                mMemFree;
         ULONG                mMemBalloon;
+        ULONG                mMemShared;
         ULONG                mMemCache;
         ULONG                mPageTotal;
@@ -337,7 +342,7 @@
     {
     public:
-        HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM)
-        : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available), mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM) {};
-        ~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; };
+        HostRamUsage(CollectorHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *used, SubMetric *available, SubMetric *allocVMM, SubMetric *freeVMM, SubMetric *balloonVMM, SubMetric *sharedVMM)
+        : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mUsed(used), mAvailable(available), mAllocVMM(allocVMM), mFreeVMM(freeVMM), mBalloonVMM(balloonVMM), mSharedVMM(sharedVMM) {};
+        ~HostRamUsage() { delete mTotal; delete mUsed; delete mAvailable; delete mAllocVMM; delete mFreeVMM; delete mBalloonVMM; delete mSharedVMM; };
 
         void init(ULONG period, ULONG length);
@@ -355,4 +360,5 @@
         SubMetric *mFreeVMM;
         SubMetric *mBalloonVMM;
+        SubMetric *mSharedVMM;
     };
 
@@ -434,7 +440,7 @@
     {
     public:
-        GuestRamUsage(CollectorGuestHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *cache, SubMetric *pagedtotal)
-        : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mCache(cache), mPagedTotal(pagedtotal), mGuestHAL(hal) {};
-        ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mCache; delete mPagedTotal; };
+        GuestRamUsage(CollectorGuestHAL *hal, ComPtr<IUnknown> object, SubMetric *total, SubMetric *free, SubMetric *balloon, SubMetric *shared, SubMetric *cache, SubMetric *pagedtotal)
+        : BaseMetric(hal, "RAM/Usage", object), mTotal(total), mFree(free), mBallooned(balloon), mShared(shared), mCache(cache), mPagedTotal(pagedtotal), mGuestHAL(hal) {};
+        ~GuestRamUsage() { delete mTotal; delete mFree; delete mBallooned; delete mShared; delete mCache; delete mPagedTotal; };
 
         void init(ULONG period, ULONG length);
@@ -446,5 +452,5 @@
         ULONG getScale() { return 1; }
     private:
-        SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal;
+        SubMetric *mTotal, *mFree, *mBallooned, *mCache, *mPagedTotal, *mShared;
         CollectorGuestHAL *mGuestHAL;
     };
Index: /trunk/src/VBox/VMM/GMM.cpp
===================================================================
--- /trunk/src/VBox/VMM/GMM.cpp	(revision 29619)
+++ /trunk/src/VBox/VMM/GMM.cpp	(revision 29620)
@@ -290,5 +290,5 @@
  * @see GMMR0QueryVMMMemoryStatsReq
  */
-GMMR3DECL(int)  GMMR3QueryHypervisorMemoryStats(PVM pVM, uint64_t *pcTotalAllocPages, uint64_t *pcTotalFreePages, uint64_t *pcTotalBalloonPages)
+GMMR3DECL(int)  GMMR3QueryHypervisorMemoryStats(PVM pVM, uint64_t *pcTotalAllocPages, uint64_t *pcTotalFreePages, uint64_t *pcTotalBalloonPages, uint64_t *puTotalBalloonSize)
 {
     GMMMEMSTATSREQ Req;
@@ -298,8 +298,10 @@
     Req.cFreePages       = 0;
     Req.cBalloonedPages  = 0;
+    Req.cSharedPages     = 0;
 
     *pcTotalAllocPages   = 0;
     *pcTotalFreePages    = 0;
     *pcTotalBalloonPages = 0;
+    *puTotalBalloonSize  = 0;
 
     /* Must be callable from any thread, so can't use VMMR3CallR0. */
@@ -310,4 +312,5 @@
         *pcTotalFreePages    = Req.cFreePages;
         *pcTotalBalloonPages = Req.cBalloonedPages;
+        *puTotalBalloonSize  = Req.cSharedPages;
     }
     return rc;
Index: /trunk/src/VBox/VMM/PGMPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/PGMPhys.cpp	(revision 29619)
+++ /trunk/src/VBox/VMM/PGMPhys.cpp	(revision 29620)
@@ -967,11 +967,12 @@
  * @param   puTotalFreeSize     Pointer to total free (allocated but not used yet) memory inside VMMR0 (in bytes)
  * @param   puTotalBalloonSize  Pointer to total ballooned memory inside VMMR0 (in bytes)
- */
-VMMR3DECL(int) PGMR3QueryVMMMemoryStats(PVM pVM, uint64_t *puTotalAllocSize, uint64_t *puTotalFreeSize, uint64_t *puTotalBalloonSize)
+ * @param   puTotalSharedSize   Pointer to total shared memory inside VMMR0 (in bytes)
+ */
+VMMR3DECL(int) PGMR3QueryVMMMemoryStats(PVM pVM, uint64_t *puTotalAllocSize, uint64_t *puTotalFreeSize, uint64_t *puTotalBalloonSize, uint64_t *puTotalSharedSize)
 {
     int rc;
 
-    uint64_t cAllocPages = 0, cFreePages = 0, cBalloonPages = 0;
-    rc = GMMR3QueryHypervisorMemoryStats(pVM, &cAllocPages, &cFreePages, &cBalloonPages);
+    uint64_t cAllocPages = 0, cFreePages = 0, cBalloonPages = 0, cSharedPages = 0;
+    rc = GMMR3QueryHypervisorMemoryStats(pVM, &cAllocPages, &cFreePages, &cBalloonPages, &cSharedPages);
     AssertRCReturn(rc, rc);
 
@@ -984,4 +985,34 @@
     if (puTotalBalloonSize)
         *puTotalBalloonSize = cBalloonPages * _4K;
+
+    if (puTotalSharedSize)
+        *puTotalSharedSize = cSharedPages * _4K;
+
+    return VINF_SUCCESS;
+}
+
+/**
+ * Query memory stats for the VM
+ *
+ * @returns VBox status code.
+ * @param   pVM                 The VM handle.
+ * @param   puTotalAllocSize    Pointer to total allocated  memory inside the VM (in bytes)
+ * @param   puTotalFreeSize     Pointer to total free (allocated but not used yet) memory inside the VM (in bytes)
+ * @param   puTotalBalloonSize  Pointer to total ballooned memory inside the VM (in bytes)
+ * @param   puTotalSharedSize   Pointer to total shared memory inside the VM (in bytes)
+ */
+VMMR3DECL(int) PGMR3QueryMemoryStats(PVM pVM, uint64_t *pulTotalMem, uint64_t *pulPrivateMem, uint64_t *puTotalSharedMem, uint64_t *puTotalZeroMem)
+{
+    if (pulTotalMem)
+        *pulTotalMem = pVM->pgm.s.cAllPages * _4K;
+
+    if (pulPrivateMem)
+        *pulPrivateMem = pVM->pgm.s.cPrivatePages * _4K;
+
+    if (puTotalSharedMem)
+        *puTotalSharedMem = pVM->pgm.s.cReusedSharedPages * _4K;
+
+    if (puTotalZeroMem)
+        *puTotalZeroMem = pVM->pgm.s.cZeroPages * _4K;
 
     return VINF_SUCCESS;
Index: /trunk/src/VBox/VMM/VMMR0/GMMR0.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR0/GMMR0.cpp	(revision 29619)
+++ /trunk/src/VBox/VMM/VMMR0/GMMR0.cpp	(revision 29620)
@@ -505,4 +505,6 @@
     /** The number of pages that are shared. A subset of cAllocatedPages. */
     uint64_t            cSharedPages;
+    /** The number of pages that are actually shared between VMs. */
+    uint64_t            cDuplicatePages;
     /** The number of pages that are shared that has been left behind by
      * VMs not doing proper cleanups. */
@@ -852,4 +854,5 @@
             pGMM->cAllocatedPages = 0;
             pGMM->cSharedPages = 0;
+            pGMM->cDuplicatePages = 0;
             pGMM->cLeftBehindSharedPages = 0;
             pGMM->cChunks = 0;
@@ -2127,5 +2130,12 @@
                             pGVM->gmm.s.Allocated.cBasePages--;
                             if (!--pPage->Shared.cRefs)
+                            {
                                 gmmR0FreeSharedPage(pGMM, paPages[iPage].idSharedPage, pPage);
+                            }
+                            else
+                            {
+                                Assert(pGMM->cDuplicatePages);
+                                pGMM->cDuplicatePages--;
+                            }
 
                             paPages[iPage].idSharedPage = NIL_GMM_PAGEID;
@@ -2667,4 +2677,6 @@
     Assert(pGMM->cSharedPages > 0);
     Assert(pGMM->cAllocatedPages > 0);
+
+    pGMM->cDuplicatePages++;
 
     pPage->Shared.cRefs++;
@@ -3078,4 +3090,5 @@
     pReq->cBalloonedPages = pGMM->cBalloonedPages;
     pReq->cMaxPages       = pGMM->cMaxPages;
+    pReq->cSharedPages    = pGMM->cDuplicatePages;
     GMM_CHECK_SANITY_UPON_LEAVING(pGMM);
 
