Index: trunk/src/VBox/VMM/VMMR3/VM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/VM.cpp	(revision 72771)
+++ trunk/src/VBox/VMM/VMMR3/VM.cpp	(revision 72778)
@@ -107,7 +107,4 @@
 #endif
 static int                  vmR3InitDoCompleted(PVM pVM, VMINITCOMPLETED enmWhat);
-#ifdef LOG_ENABLED
-static DECLCALLBACK(size_t) vmR3LogPrefixCallback(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser);
-#endif
 static void                 vmR3DestroyUVM(PUVM pUVM, uint32_t cMilliesEMTWait);
 static bool                 vmR3ValidateStateTransition(VMSTATE enmStateOld, VMSTATE enmStateNew);
@@ -709,8 +706,4 @@
                                          */
                                         vmR3SetState(pVM, VMSTATE_CREATED, VMSTATE_CREATING);
-
-#ifdef LOG_ENABLED
-                                        RTLogSetCustomPrefixCallback(NULL, vmR3LogPrefixCallback, pUVM);
-#endif
                                         return VINF_SUCCESS;
                                     }
@@ -1218,38 +1211,4 @@
 
 
-#ifdef LOG_ENABLED
-/**
- * Logger callback for inserting a custom prefix.
- *
- * @returns Number of chars written.
- * @param   pLogger             The logger.
- * @param   pchBuf              The output buffer.
- * @param   cchBuf              The output buffer size.
- * @param   pvUser              Pointer to the UVM structure.
- */
-static DECLCALLBACK(size_t) vmR3LogPrefixCallback(PRTLOGGER pLogger, char *pchBuf, size_t cchBuf, void *pvUser)
-{
-    AssertReturn(cchBuf >= 2, 0);
-    PUVM        pUVM   = (PUVM)pvUser;
-    PUVMCPU     pUVCpu = (PUVMCPU)RTTlsGet(pUVM->vm.s.idxTLS);
-    if (pUVCpu)
-    {
-        static const char s_szHex[17] = "0123456789abcdef";
-        VMCPUID const     idCpu       = pUVCpu->idCpu;
-        pchBuf[1] = s_szHex[ idCpu       & 15];
-        pchBuf[0] = s_szHex[(idCpu >> 4) & 15];
-    }
-    else
-    {
-        pchBuf[0] = 'x';
-        pchBuf[1] = 'y';
-    }
-
-    NOREF(pLogger);
-    return 2;
-}
-#endif /* LOG_ENABLED */
-
-
 /**
  * Calls the relocation functions for all VMM components so they can update
@@ -2749,7 +2708,4 @@
      * Clean up and flush logs.
      */
-#ifdef LOG_ENABLED
-    RTLogSetCustomPrefixCallback(NULL, NULL, NULL);
-#endif
     RTLogFlush(NULL);
 }
Index: trunk/src/VBox/VMM/VMMR3/VMM.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR3/VMM.cpp	(revision 72771)
+++ trunk/src/VBox/VMM/VMMR3/VMM.cpp	(revision 72778)
@@ -157,4 +157,14 @@
 #define VMM_SAVED_STATE_VERSION_3_0 3
 
+/** Macro for flushing the ring-0 logging. */
+#define VMM_FLUSH_R0_LOG(a_pR0Logger, a_pR3Logger) \
+    do { \
+        PVMMR0LOGGER pVmmLogger = (a_pR0Logger); \
+        if (!pVmmLogger || pVmmLogger->Logger.offScratch == 0) \
+        { /* likely? */ } \
+        else \
+            RTLogFlushR0(a_pR3Logger, &pVmmLogger->Logger); \
+    } while (0)
+
 
 /*********************************************************************************************************************************
@@ -417,12 +427,15 @@
 #endif /* LOG_ENABLED */
 
+    /*
+     * Release logging.
+     */
+    PRTLOGGER pRelLogger = RTLogRelGetDefaultInstance();
+    if (pRelLogger)
+    {
 #ifdef VBOX_WITH_RC_RELEASE_LOGGING
-    /*
-     * Allocate RC release logger instances (finalized in the relocator).
-     */
-    if (VM_IS_RAW_MODE_ENABLED(pVM))
-    {
-        PRTLOGGER pRelLogger = RTLogRelGetDefaultInstance();
-        if (pRelLogger)
+        /*
+         * Allocate RC release logger instances (finalized in the relocator).
+         */
+        if (VM_IS_RAW_MODE_ENABLED(pVM))
         {
             pVM->vmm.s.cbRCRelLogger = RT_OFFSETOF(RTLOGGERRC, afGroups[pRelLogger->cGroups]);
@@ -432,6 +445,52 @@
             pVM->vmm.s.pRCRelLoggerRC = MMHyperR3ToRC(pVM, pVM->vmm.s.pRCRelLoggerR3);
         }
-    }
-#endif /* VBOX_WITH_RC_RELEASE_LOGGING */
+#endif
+
+        /*
+         * Ring-0 release logger.
+         */
+        RTR0PTR pfnLoggerWrapper = NIL_RTR0PTR;
+        rc = PDMR3LdrGetSymbolR0(pVM, VMMR0_MAIN_MODULE_NAME, "vmmR0LoggerWrapper", &pfnLoggerWrapper);
+        AssertReleaseMsgRCReturn(rc, ("vmmR0LoggerWrapper not found! rc=%Rra\n", rc), rc);
+
+        RTR0PTR pfnLoggerFlush = NIL_RTR0PTR;
+        rc = PDMR3LdrGetSymbolR0(pVM, VMMR0_MAIN_MODULE_NAME, "vmmR0LoggerFlush", &pfnLoggerFlush);
+        AssertReleaseMsgRCReturn(rc, ("vmmR0LoggerFlush not found! rc=%Rra\n", rc), rc);
+
+        size_t const cbLogger = RTLogCalcSizeForR0(pLogger->cGroups, 0);
+
+        for (VMCPUID i = 0; i < pVM->cCpus; i++)
+        {
+            PVMCPU pVCpu = &pVM->aCpus[i];
+            rc = MMR3HyperAllocOnceNoRelEx(pVM, cbLogger, PAGE_SIZE, MM_TAG_VMM, MMHYPER_AONR_FLAGS_KERNEL_MAPPING,
+                                           (void **)&pVCpu->vmm.s.pR0RelLoggerR3);
+            if (RT_FAILURE(rc))
+                return rc;
+            PVMMR0LOGGER pVmmLogger = pVCpu->vmm.s.pR0RelLoggerR3;
+            RTR0PTR      R0PtrVmmLogger = MMHyperR3ToR0(pVM, pVmmLogger);
+            pVCpu->vmm.s.pR0RelLoggerR0     = R0PtrVmmLogger;
+            pVmmLogger->pVM                 = pVM->pVMR0;
+            pVmmLogger->cbLogger            = (uint32_t)cbLogger;
+            pVmmLogger->fCreated            = false;
+            pVmmLogger->fFlushingDisabled   = false;
+            pVmmLogger->fRegistered         = false;
+            pVmmLogger->idCpu               = i;
+
+            char szR0ThreadName[16];
+            RTStrPrintf(szR0ThreadName, sizeof(szR0ThreadName), "EMT-%u-R0", i);
+            rc = RTLogCreateForR0(&pVmmLogger->Logger, pVmmLogger->cbLogger, R0PtrVmmLogger + RT_OFFSETOF(VMMR0LOGGER, Logger),
+                                  pfnLoggerWrapper, pfnLoggerFlush,
+                                  RTLOGFLAGS_BUFFERED, RTLOGDEST_DUMMY, szR0ThreadName);
+            AssertReleaseMsgRCReturn(rc, ("RTLogCreateForR0 failed! rc=%Rra\n", rc), rc);
+
+            /* We only update the release log instance here. */
+            rc = RTLogCopyGroupsAndFlagsForR0(&pVmmLogger->Logger, R0PtrVmmLogger + RT_OFFSETOF(VMMR0LOGGER, Logger),
+                                              pRelLogger, RTLOGFLAGS_BUFFERED, UINT32_MAX);
+            AssertReleaseMsgRCReturn(rc, ("RTLogCopyGroupsAndFlagsForR0 failed! rc=%Rra\n", rc), rc);
+
+            pVmmLogger->fCreated = true;
+        }
+    }
+
     return VINF_SUCCESS;
 }
@@ -581,8 +640,7 @@
          */
 #ifdef LOG_ENABLED
-        if (    pVCpu->vmm.s.pR0LoggerR3
-            &&  pVCpu->vmm.s.pR0LoggerR3->Logger.offScratch > 0)
-            RTLogFlushR0(NULL, &pVCpu->vmm.s.pR0LoggerR3->Logger);
-#endif
+        VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0LoggerR3, NULL);
+#endif
+        VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0RelLoggerR3, RTLogRelGetDefaultInstance());
         if (rc != VINF_VMM_CALL_HOST)
             break;
@@ -833,8 +891,7 @@
          */
 #ifdef LOG_ENABLED
-        if (    pVCpu->vmm.s.pR0LoggerR3
-            &&  pVCpu->vmm.s.pR0LoggerR3->Logger.offScratch > 0)
-            RTLogFlushR0(NULL, &pVCpu->vmm.s.pR0LoggerR3->Logger);
-#endif
+        VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0LoggerR3, NULL);
+#endif
+        VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0RelLoggerR3, RTLogRelGetDefaultInstance());
         if (rc != VINF_VMM_CALL_HOST)
             break;
@@ -1035,16 +1092,7 @@
                 AssertReleaseMsgRCReturn(rc, ("RTLogCreateForR0 failed! rc=%Rra\n", rc), rc);
 
-                RTR0PTR pfnLoggerPrefix = NIL_RTR0PTR;
-                rc = PDMR3LdrGetSymbolR0(pVM, VMMR0_MAIN_MODULE_NAME, "vmmR0LoggerPrefix", &pfnLoggerPrefix);
-                AssertReleaseMsgRCReturn(rc, ("vmmR0LoggerPrefix not found! rc=%Rra\n", rc), rc);
-                rc = RTLogSetCustomPrefixCallbackForR0(&pR0LoggerR3->Logger,
-                                                       pVCpu->vmm.s.pR0LoggerR0 + RT_OFFSETOF(VMMR0LOGGER, Logger),
-                                                       pfnLoggerPrefix, NIL_RTR0PTR);
-                AssertReleaseMsgRCReturn(rc, ("RTLogSetCustomPrefixCallback failed! rc=%Rra\n", rc), rc);
-
                 pR0LoggerR3->idCpu = i;
                 pR0LoggerR3->fCreated = true;
                 pR0LoggerR3->fFlushingDisabled = false;
-
             }
 
@@ -1447,13 +1495,11 @@
 #endif
 
+        /*
+         * Flush the logs
+         */
 #ifdef LOG_ENABLED
-        /*
-         * Flush the log
-         */
-        PVMMR0LOGGER pR0LoggerR3 = pVCpu->vmm.s.pR0LoggerR3;
-        if (    pR0LoggerR3
-            &&  pR0LoggerR3->Logger.offScratch > 0)
-            RTLogFlushR0(NULL, &pR0LoggerR3->Logger);
-#endif /* !LOG_ENABLED */
+        VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0LoggerR3, NULL);
+#endif
+        VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0RelLoggerR3, RTLogRelGetDefaultInstance());
         if (rc != VINF_VMM_CALL_HOST)
         {
@@ -1493,13 +1539,11 @@
         } while (rcStrict == VINF_EM_RAW_INTERRUPT_HYPER);
 
+        /*
+         * Flush the logs
+         */
 #ifdef LOG_ENABLED
-        /*
-         * Flush the log
-         */
-        PVMMR0LOGGER pR0LoggerR3 = pVCpu->vmm.s.pR0LoggerR3;
-        if (    pR0LoggerR3
-            &&  pR0LoggerR3->Logger.offScratch > 0)
-            RTLogFlushR0(NULL, &pR0LoggerR3->Logger);
-#endif /* !LOG_ENABLED */
+        VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0LoggerR3, NULL);
+#endif
+        VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0RelLoggerR3, RTLogRelGetDefaultInstance());
         if (rcStrict != VINF_VMM_CALL_HOST)
             return rcStrict;
@@ -2590,8 +2634,7 @@
          */
 #ifdef LOG_ENABLED
-        if (    pVCpu->vmm.s.pR0LoggerR3
-            &&  pVCpu->vmm.s.pR0LoggerR3->Logger.offScratch > 0)
-            RTLogFlushR0(NULL, &pVCpu->vmm.s.pR0LoggerR3->Logger);
-#endif
+        VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0LoggerR3, NULL);
+#endif
+        VMM_FLUSH_R0_LOG(pVCpu->vmm.s.pR0RelLoggerR3, RTLogRelGetDefaultInstance());
         if (rc != VINF_VMM_CALL_HOST)
             break;
