Index: /trunk/include/iprt/mangling.h
===================================================================
--- /trunk/include/iprt/mangling.h	(revision 104847)
+++ /trunk/include/iprt/mangling.h	(revision 104848)
@@ -1917,4 +1917,5 @@
 # define RTR0MemObjSize                                 RT_MANGLER(RTR0MemObjSize)             /* r0drv */
 # define RTR0MemObjWasZeroInitialized                   RT_MANGLER(RTR0MemObjWasZeroInitialized)/* r0drv */
+# define RTR0MemObjZeroInitialize                       RT_MANGLER(RTR0MemObjZeroInitialize)   /* r0drv */
 # define RTR0MemUserCopyFrom                            RT_MANGLER(RTR0MemUserCopyFrom)        /* r0drv */
 # define RTR0MemUserCopyTo                              RT_MANGLER(RTR0MemUserCopyTo)          /* r0drv */
Index: /trunk/include/iprt/memobj.h
===================================================================
--- /trunk/include/iprt/memobj.h	(revision 104847)
+++ /trunk/include/iprt/memobj.h	(revision 104848)
@@ -128,5 +128,5 @@
  * @returns true if the allocation was initialized to zero at allocation time,
  *          false if not or query not meaningful to the object type.
- * @param   hMemObj             The ring-0 memory object to be freed.
+ * @param   hMemObj             The ring-0 memory object.
  *
  * @remarks It can be expected that memory allocated in the same fashion will
@@ -136,4 +136,19 @@
  */
 RTR0DECL(bool) RTR0MemObjWasZeroInitialized(RTR0MEMOBJ hMemObj);
+
+/**
+ * Initializes the allocation to zero.
+ *
+ * This only works on allocations, locked ring-0 memory and ring-0 mappings.  It
+ * will return VERR_WRONG_TYPE if applied to any memory reservation,
+ * ring-3 mapping or ring-3 locking object.
+ *
+ * @returns IPRT status code.
+ * @param   hMemObj         The ring-0 memory object.
+ * @param   fForce          If @c true, always zero the allocation, if @c false
+ *                          it is only done when RTR0MemObjWasZeroInitialized()
+ *                          would return false.
+ */
+RTR0DECL(int) RTR0MemObjZeroInitialize(RTR0MEMOBJ hMemObj, bool fForce);
 
 /**
Index: /trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp	(revision 104847)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDrv.cpp	(revision 104848)
@@ -474,4 +474,5 @@
     SUPEXP_STK_OKAY(    1,  RTR0MemObjSize),
     SUPEXP_STK_OKAY(    1,  RTR0MemObjWasZeroInitialized),
+    SUPEXP_STK_OKAY(    2,  RTR0MemObjZeroInitialize),
     SUPEXP_STK_BACK(    3,  RTR0MemUserCopyFrom),
     SUPEXP_STK_BACK(    3,  RTR0MemUserCopyTo),
Index: /trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h	(revision 104847)
+++ /trunk/src/VBox/HostDrivers/Support/SUPDrvIOC.h	(revision 104848)
@@ -233,5 +233,5 @@
  *          - nothing
  */
-#define SUPDRV_IOC_VERSION                              0x00340000
+#define SUPDRV_IOC_VERSION                              0x00340001
 
 /** SUP_IOCTL_COOKIE. */
Index: /trunk/src/VBox/HostDrivers/Support/SUPLib.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPLib.cpp	(revision 104847)
+++ /trunk/src/VBox/HostDrivers/Support/SUPLib.cpp	(revision 104848)
@@ -298,7 +298,7 @@
         strcpy(CookieReq.u.In.szMagic, SUPCOOKIE_MAGIC);
         CookieReq.u.In.u32ReqVersion = SUPDRV_IOC_VERSION;
-        const uint32_t uMinVersion = /*(SUPDRV_IOC_VERSION & 0xffff0000) == 0x00340000
-                                   ? 0x00340000
-                                   : */ SUPDRV_IOC_VERSION & 0xffff0000;
+        const uint32_t uMinVersion = (SUPDRV_IOC_VERSION & 0xffff0000) == 0x00340000
+                                   ? 0x00340001
+                                   : SUPDRV_IOC_VERSION & 0xffff0000;
         CookieReq.u.In.u32MinVersion = uMinVersion;
         rc = suplibOsIOCtl(&g_supLibData, SUP_IOCTL_COOKIE, &CookieReq, SUP_IOCTL_COOKIE_SIZE);
Index: /trunk/src/VBox/Runtime/include/internal/memobj.h
===================================================================
--- /trunk/src/VBox/Runtime/include/internal/memobj.h	(revision 104847)
+++ /trunk/src/VBox/Runtime/include/internal/memobj.h	(revision 104848)
@@ -538,4 +538,12 @@
 DECLHIDDEN(RTHCPHYS) rtR0MemObjNativeGetPagePhysAddr(PRTR0MEMOBJINTERNAL pMem, size_t iPage);
 
+/**
+ * Zero initialize an object without a ring-0 mapping.
+ *
+ * @returns IPRT status code.
+ * @param   pMem            The ring-0 memory object handle.
+ */
+DECLHIDDEN(int) rtR0MemObjNativeZeroInitWithoutMapping(PRTR0MEMOBJINTERNAL pMem);
+
 DECLHIDDEN(PRTR0MEMOBJINTERNAL) rtR0MemObjNew(size_t cbSelf, RTR0MEMOBJTYPE enmType, void *pv, size_t cb, const char *pszTag);
 DECLHIDDEN(void) rtR0MemObjDelete(PRTR0MEMOBJINTERNAL pMem);
Index: /trunk/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp	(revision 104847)
+++ /trunk/src/VBox/Runtime/r0drv/darwin/memobj-r0drv-darwin.cpp	(revision 104848)
@@ -1580,2 +1580,9 @@
 }
 
+
+DECLHIDDEN(int) rtR0MemObjNativeZeroInitWithoutMapping(PRTR0MEMOBJINTERNAL pMem)
+{
+    RT_NOREF(pMem);
+    return VERR_NOT_IMPLEMENTED;
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c	(revision 104847)
+++ /trunk/src/VBox/Runtime/r0drv/freebsd/memobj-r0drv-freebsd.c	(revision 104848)
@@ -77,4 +77,5 @@
 #include <iprt/param.h>
 #include <iprt/process.h>
+#include <iprt/string.h>
 #include "internal/memobj.h"
 
@@ -906,2 +907,27 @@
 }
 
+
+DECLHIDDEN(int) rtR0MemObjNativeZeroInitWithoutMapping(PRTR0MEMOBJINTERNAL pMem)
+{
+    PRTR0MEMOBJFREEBSD const pMemFreeBsd = (PRTR0MEMOBJFREEBSD)pMem;
+    size_t const             cPages      = pMemSolaris->Core.cb >> PAGE_SHIFT;
+    size_t                   iPage;
+    for (iPage = 0; iPage < cPages; iPage++)
+    {
+        void          *pvPage;
+
+        /* Get the physical address of the page. */
+        RTHCPHYS const HCPhys = rtR0MemObjNativeGetPagePhysAddr(&pMemFreeBsd->Core, iPage);
+        AssertReturn(HCPhys != NIL_RTHCPHYS, VERR_INTERNAL_ERROR_3);
+        Assert(!(HCPhys & PAGE_OFFSET_MASK));
+
+        /* Map it. */
+        pvPage = (void *)(uintptr_t)pmap_map(NULL, HCPhys, (HCPhys | PAGE_OFFSET_MASK) + 1, VM_PROT_WRITE | VM_PROT_READ);
+        AssertPtrReturn(pvPage, VERR_INTERNAL_ERROR_3);
+
+        /* Zero it. */
+        RT_BZERO(pvPage, PAGE_SIZE);
+    }
+    return VINF_SUCCESS;
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/haiku/memobj-r0drv-haiku.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/haiku/memobj-r0drv-haiku.c	(revision 104847)
+++ /trunk/src/VBox/Runtime/r0drv/haiku/memobj-r0drv-haiku.c	(revision 104848)
@@ -685,2 +685,9 @@
 }
 
+
+DECLHIDDEN(int) rtR0MemObjNativeZeroInitWithoutMapping(PRTR0MEMOBJINTERNAL pMem)
+{
+    RT_NOREF(pMem);
+    return VERR_NOT_IMPLEMENTED;
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c	(revision 104847)
+++ /trunk/src/VBox/Runtime/r0drv/linux/memobj-r0drv-linux.c	(revision 104848)
@@ -2181,2 +2181,31 @@
 }
 
+
+DECLHIDDEN(int) rtR0MemObjNativeZeroInitWithoutMapping(PRTR0MEMOBJINTERNAL pMem)
+{
+    PRTR0MEMOBJLNX const pMemLnx = (PRTR0MEMOBJLNX)pMem;
+    size_t const         cPages  = pMemLnx->Core.cb >> PAGE_SHIFT;
+    size_t               iPage;
+    /** @todo optimize this. */
+    for (iPage = 0; iPage < cPages; iPage++)
+    {
+        void          *pvPage;
+
+        /* Get the physical address of the page. */
+        RTHCPHYS const HCPhys = rtR0MemObjNativeGetPagePhysAddr(&pMemLnx->Core, iPage);
+        AssertReturn(HCPhys != NIL_RTHCPHYS, VERR_INTERNAL_ERROR_3);
+        Assert(!(HCPhys & PAGE_OFFSET_MASK));
+
+        /* Would've like to use valid_phys_addr_range for this test, but it isn't exported. */
+        AssertReturn((HCPhys | PAGE_OFFSET_MASK) < __pa(high_memory), VERR_INTERNAL_ERROR_3);
+
+        /* Map it. */
+        pvPage = phys_to_virt(HCPhys);
+        AssertPtrReturn(pvPage, VERR_INTERNAL_ERROR_3);
+
+        /* Zero it. */
+        RT_BZERO(pvPage, PAGE_SIZE);
+    }
+    return VINF_SUCCESS;
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/memobj-r0drv.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/memobj-r0drv.cpp	(revision 104847)
+++ /trunk/src/VBox/Runtime/r0drv/memobj-r0drv.cpp	(revision 104848)
@@ -52,4 +52,5 @@
 #include <iprt/param.h>
 #include <iprt/process.h>
+#include <iprt/string.h>
 #include <iprt/thread.h>
 
@@ -296,4 +297,39 @@
 
 
+RTR0DECL(int) RTR0MemObjZeroInitialize(RTR0MEMOBJ hMemObj, bool fForce)
+{
+    PRTR0MEMOBJINTERNAL pMem;
+
+    /* Validate the object handle. */
+    AssertReturn(hMemObj != NIL_RTR0MEMOBJ, VERR_INVALID_HANDLE);
+    AssertPtrReturn(hMemObj, VERR_INVALID_HANDLE);
+    pMem = (PRTR0MEMOBJINTERNAL)hMemObj;
+    AssertMsgReturn(pMem->u32Magic == RTR0MEMOBJ_MAGIC, ("%p: %#x\n", pMem, pMem->u32Magic), VERR_INVALID_HANDLE);
+    AssertMsgReturn(pMem->enmType > RTR0MEMOBJTYPE_INVALID && pMem->enmType < RTR0MEMOBJTYPE_END, ("%p: %d\n", pMem, pMem->enmType), VERR_INVALID_HANDLE);
+    AssertReturn(   (pMem->enmType != RTR0MEMOBJTYPE_MAPPING || pMem->u.Mapping.R0Process == NIL_RTR0PROCESS)
+                 && (pMem->enmType != RTR0MEMOBJTYPE_LOCK    || pMem->u.Lock.R0Process    == NIL_RTR0PROCESS)
+                 && pMem->enmType != RTR0MEMOBJTYPE_RES_VIRT
+                 , VERR_WRONG_TYPE);
+    Assert(   (pMem->fFlags & (RTR0MEMOBJ_FLAGS_ZERO_AT_ALLOC | RTR0MEMOBJ_FLAGS_UNINITIALIZED_AT_ALLOC))
+           !=                 (RTR0MEMOBJ_FLAGS_ZERO_AT_ALLOC | RTR0MEMOBJ_FLAGS_UNINITIALIZED_AT_ALLOC));
+
+    /*
+     * Do we need to do anything?
+     */
+    if (   fForce
+        ||    (pMem->fFlags & (RTR0MEMOBJ_FLAGS_ZERO_AT_ALLOC | RTR0MEMOBJ_FLAGS_UNINITIALIZED_AT_ALLOC))
+           !=                  RTR0MEMOBJ_FLAGS_ZERO_AT_ALLOC)
+    {
+        /* This is easy if there is a ring-0 mapping: */
+        if (pMem->pv)
+            RT_BZERO(pMem->pv, pMem->cb);
+        else
+            return rtR0MemObjNativeZeroInitWithoutMapping(pMem);
+    }
+    return VINF_SUCCESS;
+}
+RT_EXPORT_SYMBOL(RTR0MemObjWasZeroInitialized);
+
+
 RTR0DECL(int) RTR0MemObjFree(RTR0MEMOBJ MemObj, bool fFreeMappings)
 {
Index: /trunk/src/VBox/Runtime/r0drv/netbsd/memobj-r0drv-netbsd.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/netbsd/memobj-r0drv-netbsd.c	(revision 104847)
+++ /trunk/src/VBox/Runtime/r0drv/netbsd/memobj-r0drv-netbsd.c	(revision 104848)
@@ -586,2 +586,9 @@
 }
 
+
+DECLHIDDEN(int) rtR0MemObjNativeZeroInitWithoutMapping(PRTR0MEMOBJINTERNAL pMem)
+{
+    RT_NOREF(pMem);
+    return VERR_NOT_IMPLEMENTED;
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp	(revision 104847)
+++ /trunk/src/VBox/Runtime/r0drv/nt/memobj-r0drv-nt.cpp	(revision 104848)
@@ -1301,2 +1301,9 @@
 }
 
+
+DECLHIDDEN(int) rtR0MemObjNativeZeroInitWithoutMapping(PRTR0MEMOBJINTERNAL pMem)
+{
+    RT_NOREF(pMem);
+    return VERR_NOT_IMPLEMENTED;
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/os2/memobj-r0drv-os2.cpp
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/os2/memobj-r0drv-os2.cpp	(revision 104847)
+++ /trunk/src/VBox/Runtime/r0drv/os2/memobj-r0drv-os2.cpp	(revision 104848)
@@ -635,2 +635,9 @@
 }
 
+
+DECLHIDDEN(int) rtR0MemObjNativeZeroInitWithoutMapping(PRTR0MEMOBJINTERNAL pMem)
+{
+    RT_NOREF(pMem);
+    return VERR_NOT_IMPLEMENTED;
+}
+
Index: /trunk/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c
===================================================================
--- /trunk/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c	(revision 104847)
+++ /trunk/src/VBox/Runtime/r0drv/solaris/memobj-r0drv-solaris.c	(revision 104848)
@@ -50,4 +50,5 @@
 #include <iprt/param.h>
 #include <iprt/process.h>
+#include <iprt/string.h>
 #include "internal/memobj.h"
 #include "memobj-r0drv-solaris.h"
@@ -1213,2 +1214,29 @@
 }
 
+
+DECLHIDDEN(int) rtR0MemObjNativeZeroInitWithoutMapping(PRTR0MEMOBJINTERNAL pMem)
+{
+    PRTR0MEMOBJSOL const pMemSolaris = (PRTR0MEMOBJSOL)pMem;
+    size_t const         cPages      = pMemSolaris->Core.cb >> PAGE_SHIFT;
+    size_t               iPage;
+    for (iPage = 0; iPage < cPages; iPage++)
+    {
+        void          *pvPage;
+
+        /* Get the physical address of the page. */
+        RTHCPHYS const HCPhys = rtR0MemObjNativeGetPagePhysAddr(&pMemSolaris->Core, iPage);
+        AssertReturn(HCPhys != NIL_RTHCPHYS, VERR_INTERNAL_ERROR_3);
+        Assert(!(HCPhys & PAGE_OFFSET_MASK));
+
+        /* Map it. */
+        HCPhys >>= PAGE_SHIFT;
+        AssertReturn(HCPhys <= physmax, VERR_INTERNAL_ERROR_3);
+        pvPage = hat_kpm_pfn2va(HCPhys);
+        AssertPtrReturn(pvPage, VERR_INTERNAL_ERROR_3);
+
+        /* Zero it. */
+        RT_BZERO(pvPage, PAGE_SIZE);
+    }
+    return VINF_SUCCESS;
+}
+
Index: /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 104847)
+++ /trunk/src/VBox/VMM/VMMAll/PGMAllPhys.cpp	(revision 104848)
@@ -1194,10 +1194,6 @@
         AssertPtr(pbMmio2BackingR0);
 # endif
-        if (!RTR0MemObjWasZeroInitialized(hMemObj))
-        {
-            void *pv = RTR0MemObjAddress(hMemObj);
-            AssertReturnStmt(pv, RTR0MemObjFree(hMemObj, true /*fFreeMappings*/),  VERR_INTERNAL_ERROR_4);
-            RT_BZERO(pv, cbMmio2Aligned);
-        }
+        rc = RTR0MemObjZeroInitialize(hMemObj, false /*fForce*/);
+        AssertRCReturnStmt(rc, RTR0MemObjFree(hMemObj, true /*fFreeMappings*/), rc);
 #else
         RT_BZERO(pbMmio2BackingR3, cbMmio2Aligned);
