Index: /trunk/include/VBox/vmm/dbgf.h
===================================================================
--- /trunk/include/VBox/vmm/dbgf.h	(revision 61569)
+++ /trunk/include/VBox/vmm/dbgf.h	(revision 61570)
@@ -940,4 +940,6 @@
 /** The handler must run on the EMT. */
 #define DBGFINFO_FLAGS_RUN_ON_EMT       RT_BIT(0)
+/** Call on all EMTs when a specific isn't specified. */
+#define DBGFINFO_FLAGS_ALL_EMTS         RT_BIT(1)
 /** @} */
 
Index: /trunk/src/VBox/VMM/VMMR3/CPUM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 61569)
+++ /trunk/src/VBox/VMM/VMMR3/CPUM.cpp	(revision 61570)
@@ -899,10 +899,15 @@
      * Register info handlers and registers with the debugger facility.
      */
-    DBGFR3InfoRegisterInternal(pVM, "cpum",             "Displays the all the cpu states.",         &cpumR3InfoAll);
-    DBGFR3InfoRegisterInternal(pVM, "cpumguest",        "Displays the guest cpu state.",            &cpumR3InfoGuest);
-    DBGFR3InfoRegisterInternal(pVM, "cpumhyper",        "Displays the hypervisor cpu state.",       &cpumR3InfoHyper);
-    DBGFR3InfoRegisterInternal(pVM, "cpumhost",         "Displays the host cpu state.",             &cpumR3InfoHost);
-    DBGFR3InfoRegisterInternal(pVM, "cpuid",            "Displays the guest cpuid leaves.",         &cpumR3CpuIdInfo);
-    DBGFR3InfoRegisterInternal(pVM, "cpumguestinstr",   "Displays the current guest instruction.",  &cpumR3InfoGuestInstr);
+    DBGFR3InfoRegisterInternalEx(pVM, "cpum",             "Displays the all the cpu states.",
+                                 &cpumR3InfoAll, DBGFINFO_FLAGS_ALL_EMTS);
+    DBGFR3InfoRegisterInternalEx(pVM, "cpumguest",        "Displays the guest cpu state.",
+                                 &cpumR3InfoGuest, DBGFINFO_FLAGS_ALL_EMTS);
+    DBGFR3InfoRegisterInternalEx(pVM, "cpumhyper",        "Displays the hypervisor cpu state.",
+                                 &cpumR3InfoHyper, DBGFINFO_FLAGS_ALL_EMTS);
+    DBGFR3InfoRegisterInternalEx(pVM, "cpumhost",         "Displays the host cpu state.",
+                                 &cpumR3InfoHost, DBGFINFO_FLAGS_ALL_EMTS);
+    DBGFR3InfoRegisterInternalEx(pVM, "cpumguestinstr",   "Displays the current guest instruction.",
+                                 &cpumR3InfoGuestInstr, DBGFINFO_FLAGS_ALL_EMTS);
+    DBGFR3InfoRegisterInternal(  pVM, "cpuid",            "Displays the guest cpuid leaves.",         &cpumR3CpuIdInfo);
 
     rc = cpumR3DbgInit(pVM);
@@ -2070,5 +2075,4 @@
     cpumR3InfoParseArg(pszArgs, &enmType, &pszComment);
 
-    /* @todo SMP support! */
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
@@ -2093,5 +2097,4 @@
     NOREF(pszArgs);
 
-    /** @todo SMP support! */
     PVMCPU pVCpu = VMMGetCpu(pVM);
     if (!pVCpu)
@@ -2114,9 +2117,10 @@
 static DECLCALLBACK(void) cpumR3InfoHyper(PVM pVM, PCDBGFINFOHLP pHlp, const char *pszArgs)
 {
+    PVMCPU pVCpu = VMMGetCpu(pVM);
+    if (!pVCpu)
+        pVCpu = &pVM->aCpus[0];
+
     CPUMDUMPTYPE enmType;
     const char *pszComment;
-    /* @todo SMP */
-    PVMCPU pVCpu = &pVM->aCpus[0];
-
     cpumR3InfoParseArg(pszArgs, &enmType, &pszComment);
     pHlp->pfnPrintf(pHlp, "Hypervisor CPUM state: %s\n", pszComment);
@@ -2140,9 +2144,12 @@
     pHlp->pfnPrintf(pHlp, "Host CPUM state: %s\n", pszComment);
 
+    PVMCPU pVCpu = VMMGetCpu(pVM);
+    if (!pVCpu)
+        pVCpu = &pVM->aCpus[0];
+    PCPUMHOSTCTX pCtx = &pVCpu->cpum.s.Host;
+
     /*
      * Format the EFLAGS.
      */
-    /* @todo SMP */
-    PCPUMHOSTCTX pCtx = &pVM->aCpus[0].cpum.s.Host;
 #if HC_ARCH_BITS == 32
     uint32_t efl = pCtx->eflags.u32;
Index: /trunk/src/VBox/VMM/VMMR3/DBGFInfo.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/DBGFInfo.cpp	(revision 61569)
+++ /trunk/src/VBox/VMM/VMMR3/DBGFInfo.cpp	(revision 61570)
@@ -231,5 +231,6 @@
     AssertReturn(*pszName, VERR_INVALID_PARAMETER);
     AssertPtrReturn(pszDesc, VERR_INVALID_POINTER);
-    AssertMsgReturn(!(fFlags & ~(DBGFINFO_FLAGS_RUN_ON_EMT)), ("fFlags=%#x\n", fFlags), VERR_INVALID_PARAMETER);
+    AssertMsgReturn(!(fFlags & ~(DBGFINFO_FLAGS_RUN_ON_EMT | DBGFINFO_FLAGS_ALL_EMTS)),
+                    ("fFlags=%#x\n", fFlags), VERR_INVALID_FLAGS);
 
     /*
@@ -668,5 +669,5 @@
 
 /**
- * Worker for DBGFR3Info and DBGFR3InfoEx.
+ * Worker for DBGFR3InfoEx.
  *
  * @returns VBox status code.
@@ -693,4 +694,5 @@
     else
         pHlp = &g_dbgfR3InfoLogHlp;
+    Assert(idCpu == NIL_VMCPUID || idCpu < pUVM->cCpus); /* if not nil, we're on that EMT already. */
 
     /*
@@ -710,10 +712,15 @@
          * Found it.
          */
+        VMCPUID idDstCpu = NIL_VMCPUID;
+        if ((pInfo->fFlags & (DBGFINFO_FLAGS_RUN_ON_EMT | DBGFINFO_FLAGS_ALL_EMTS)) && idCpu == NIL_VMCPUID)
+            idDstCpu = pInfo->fFlags & DBGFINFO_FLAGS_ALL_EMTS ? VMCPUID_ALL : VMCPUID_ANY;
+
         rc = VINF_SUCCESS;
         switch (pInfo->enmType)
         {
             case DBGFINFOTYPE_DEV:
-                if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
-                    rc = VMR3ReqCallVoidWaitU(pUVM, idCpu, (PFNRT)pInfo->u.Dev.pfnHandler, 3, pInfo->u.Dev.pDevIns, pHlp, pszArgs);
+                if (idDstCpu != NIL_VMCPUID)
+                    rc = VMR3ReqPriorityCallWaitU(pUVM, idDstCpu, (PFNRT)pInfo->u.Dev.pfnHandler, 3,
+                                                  pInfo->u.Dev.pDevIns, pHlp, pszArgs);
                 else
                     pInfo->u.Dev.pfnHandler(pInfo->u.Dev.pDevIns, pHlp, pszArgs);
@@ -721,6 +728,7 @@
 
             case DBGFINFOTYPE_DRV:
-                if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
-                    rc = VMR3ReqCallVoidWaitU(pUVM, idCpu, (PFNRT)pInfo->u.Drv.pfnHandler, 3, pInfo->u.Drv.pDrvIns, pHlp, pszArgs);
+                if (idDstCpu != NIL_VMCPUID)
+                    rc = VMR3ReqPriorityCallWaitU(pUVM, idDstCpu, (PFNRT)pInfo->u.Drv.pfnHandler, 3,
+                                                  pInfo->u.Drv.pDrvIns, pHlp, pszArgs);
                 else
                     pInfo->u.Drv.pfnHandler(pInfo->u.Drv.pDrvIns, pHlp, pszArgs);
@@ -730,6 +738,7 @@
                 if (RT_VALID_PTR(pUVM->pVM))
                 {
-                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
-                        rc = VMR3ReqCallVoidWaitU(pUVM, idCpu, (PFNRT)pInfo->u.Int.pfnHandler, 3, pUVM->pVM, pHlp, pszArgs);
+                    if (idDstCpu != NIL_VMCPUID)
+                        rc = VMR3ReqPriorityCallWaitU(pUVM, idDstCpu, (PFNRT)pInfo->u.Int.pfnHandler, 3,
+                                                      pUVM->pVM, pHlp, pszArgs);
                     else
                         pInfo->u.Int.pfnHandler(pUVM->pVM, pHlp, pszArgs);
@@ -740,6 +749,7 @@
 
             case DBGFINFOTYPE_EXT:
-                if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
-                    rc = VMR3ReqCallVoidWaitU(pUVM, idCpu, (PFNRT)pInfo->u.Ext.pfnHandler, 3, pInfo->u.Ext.pvUser, pHlp, pszArgs);
+                if (idDstCpu != NIL_VMCPUID)
+                    rc = VMR3ReqPriorityCallWaitU(pUVM, idDstCpu, (PFNRT)pInfo->u.Ext.pfnHandler, 3,
+                                                  pInfo->u.Ext.pvUser, pHlp, pszArgs);
                 else
                     pInfo->u.Ext.pfnHandler(pInfo->u.Ext.pvUser, pHlp, pszArgs);
@@ -749,4 +759,5 @@
                 AssertMsgFailedReturn(("Invalid info type enmType=%d\n", pInfo->enmType), VERR_IPE_NOT_REACHED_DEFAULT_CASE);
         }
+
         int rc2 = RTCritSectRwLeaveShared(&pUVM->dbgf.s.CritSect);
         AssertRC(rc2);
@@ -760,4 +771,5 @@
     return rc;
 }
+
 
 /**
@@ -772,6 +784,5 @@
 VMMR3DECL(int) DBGFR3Info(PUVM pUVM, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp)
 {
-    UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
-    return dbgfR3Info(pUVM, VMCPUID_ANY, pszName, pszArgs, pHlp);
+    return DBGFR3InfoEx(pUVM, NIL_VMCPUID, pszName, pszArgs, pHlp);
 }
 
@@ -783,5 +794,5 @@
  * @param   pUVM        The user mode VM handle.
  * @param   idCpu       The CPU to exectue the request on.  Pass NIL_VMCPUID
- *                      to not involve any EMT.
+ *                      to not involve any EMT unless necessary.
  * @param   pszName     The identifier of the info to display.
  * @param   pszArgs     Arguments to the info handler.
@@ -790,7 +801,17 @@
 VMMR3DECL(int) DBGFR3InfoEx(PUVM pUVM, VMCPUID idCpu, const char *pszName, const char *pszArgs, PCDBGFINFOHLP pHlp)
 {
+    /*
+     * Some input validation.
+     */
     UVM_ASSERT_VALID_EXT_RETURN(pUVM, VERR_INVALID_VM_HANDLE);
+    AssertReturn(   idCpu != VMCPUID_ANY_QUEUE
+                 && idCpu != VMCPUID_ALL
+                 && idCpu != VMCPUID_ALL_REVERSE, VERR_INVALID_PARAMETER);
+
+    /*
+     * Run on any specific EMT?
+     */
     if (idCpu == NIL_VMCPUID)
-        return dbgfR3Info(pUVM, VMCPUID_ANY, pszName, pszArgs, pHlp);
+        return dbgfR3Info(pUVM, NIL_VMCPUID, pszName, pszArgs, pHlp);
     return VMR3ReqPriorityCallWaitU(pUVM, idCpu,
                                     (PFNRT)dbgfR3Info, 5, pUVM, idCpu, pszName, pszArgs, pHlp);
@@ -808,5 +829,5 @@
 VMMR3DECL(int) DBGFR3InfoLogRel(PUVM pUVM, const char *pszName, const char *pszArgs)
 {
-    return DBGFR3Info(pUVM, pszName, pszArgs, &g_dbgfR3InfoLogRelHlp);
+    return DBGFR3InfoEx(pUVM, NIL_VMCPUID, pszName, pszArgs, &g_dbgfR3InfoLogRelHlp);
 }
 
@@ -822,5 +843,5 @@
 VMMR3DECL(int) DBGFR3InfoStdErr(PUVM pUVM, const char *pszName, const char *pszArgs)
 {
-    return DBGFR3Info(pUVM, pszName, pszArgs, &g_dbgfR3InfoStdErrHlp);
+    return DBGFR3InfoEx(pUVM, NIL_VMCPUID, pszName, pszArgs, &g_dbgfR3InfoStdErrHlp);
 }
 
@@ -877,11 +898,16 @@
         {
             pHlp->pfnPrintf(pHlp, pszSepFmt, pInfo->szName);
+
+            VMCPUID idDstCpu = NIL_VMCPUID;
+            if (pInfo->fFlags & (DBGFINFO_FLAGS_RUN_ON_EMT | DBGFINFO_FLAGS_ALL_EMTS))
+                idDstCpu = pInfo->fFlags & DBGFINFO_FLAGS_ALL_EMTS ? VMCPUID_ALL : VMCPUID_ANY;
+
             rc = VINF_SUCCESS;
             switch (pInfo->enmType)
             {
                 case DBGFINFOTYPE_DEV:
-                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
-                        rc = VMR3ReqCallVoidWaitU(pUVM, VMCPUID_ANY, (PFNRT)pInfo->u.Dev.pfnHandler, 3,
-                                                  pInfo->u.Dev.pDevIns, pHlp, pszArgs);
+                    if (idDstCpu != NIL_VMCPUID)
+                        rc = VMR3ReqPriorityCallVoidWaitU(pUVM, idDstCpu, (PFNRT)pInfo->u.Dev.pfnHandler, 3,
+                                                          pInfo->u.Dev.pDevIns, pHlp, pszArgs);
                     else
                         pInfo->u.Dev.pfnHandler(pInfo->u.Dev.pDevIns, pHlp, pszArgs);
@@ -889,7 +915,7 @@
 
                 case DBGFINFOTYPE_DRV:
-                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
-                        rc = VMR3ReqCallVoidWaitU(pUVM, VMCPUID_ANY, (PFNRT)pInfo->u.Drv.pfnHandler, 3,
-                                                  pInfo->u.Drv.pDrvIns, pHlp, pszArgs);
+                    if (idDstCpu != NIL_VMCPUID)
+                        rc = VMR3ReqPriorityCallVoidWaitU(pUVM, idDstCpu, (PFNRT)pInfo->u.Drv.pfnHandler, 3,
+                                                          pInfo->u.Drv.pDrvIns, pHlp, pszArgs);
                     else
                         pInfo->u.Drv.pfnHandler(pInfo->u.Drv.pDrvIns, pHlp, pszArgs);
@@ -897,6 +923,7 @@
 
                 case DBGFINFOTYPE_INT:
-                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
-                        rc = VMR3ReqCallVoidWaitU(pUVM, VMCPUID_ANY, (PFNRT)pInfo->u.Int.pfnHandler, 3, pVM, pHlp, pszArgs);
+                    if (idDstCpu != NIL_VMCPUID)
+                        rc = VMR3ReqPriorityCallVoidWaitU(pUVM, idDstCpu, (PFNRT)pInfo->u.Int.pfnHandler, 3,
+                                                          pVM, pHlp, pszArgs);
                     else
                         pInfo->u.Int.pfnHandler(pVM, pHlp, pszArgs);
@@ -904,7 +931,7 @@
 
                 case DBGFINFOTYPE_EXT:
-                    if (pInfo->fFlags & DBGFINFO_FLAGS_RUN_ON_EMT)
-                        rc = VMR3ReqCallVoidWaitU(pUVM, VMCPUID_ANY, (PFNRT)pInfo->u.Ext.pfnHandler, 3,
-                                                  pInfo->u.Ext.pvUser, pHlp, pszArgs);
+                    if (idDstCpu != NIL_VMCPUID)
+                        rc = VMR3ReqPriorityCallVoidWaitU(pUVM, idDstCpu, (PFNRT)pInfo->u.Ext.pfnHandler, 3,
+                                                          pInfo->u.Ext.pvUser, pHlp, pszArgs);
                     else
                         pInfo->u.Ext.pfnHandler(pInfo->u.Ext.pvUser, pHlp, pszArgs);
Index: /trunk/src/VBox/VMM/VMMR3/PGM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/PGM.cpp	(revision 61569)
+++ /trunk/src/VBox/VMM/VMMR3/PGM.cpp	(revision 61570)
@@ -1502,8 +1502,9 @@
          * Info & statistics
          */
-        DBGFR3InfoRegisterInternal(pVM, "mode",
-                                   "Shows the current paging mode. "
-                                   "Recognizes 'all', 'guest', 'shadow' and 'host' as arguments, defaulting to 'all' if nothing is given.",
-                                   pgmR3InfoMode);
+        DBGFR3InfoRegisterInternalEx(pVM, "mode",
+                                     "Shows the current paging mode. "
+                                     "Recognizes 'all', 'guest', 'shadow' and 'host' as arguments, defaulting to 'all' if nothing is given.",
+                                     pgmR3InfoMode,
+                                     DBGFINFO_FLAGS_ALL_EMTS);
         DBGFR3InfoRegisterInternal(pVM, "pgmcr3",
                                    "Dumps all the entries in the top level paging table. No arguments.",
@@ -2746,12 +2747,16 @@
     }
 
-    /** @todo SMP support! */
+    PVMCPU pVCpu = VMMGetCpu(pVM);
+    if (!pVCpu)
+        pVCpu = &pVM->aCpus[0];
+
+
     /* print info. */
     if (fGuest)
-        pHlp->pfnPrintf(pHlp, "Guest paging mode:  %s (changed %RU64 times), A20 %s (changed %RU64 times)\n",
-                        PGMGetModeName(pVM->aCpus[0].pgm.s.enmGuestMode), pVM->aCpus[0].pgm.s.cGuestModeChanges.c,
-                        pVM->aCpus[0].pgm.s.fA20Enabled ? "enabled" : "disabled", pVM->aCpus[0].pgm.s.cA20Changes.c);
+        pHlp->pfnPrintf(pHlp, "Guest paging mode (VCPU #%u):  %s (changed %RU64 times), A20 %s (changed %RU64 times)\n",
+                        pVCpu->idCpu, PGMGetModeName(pVCpu->pgm.s.enmGuestMode), pVCpu->pgm.s.cGuestModeChanges.c,
+                        pVCpu->pgm.s.fA20Enabled ? "enabled" : "disabled", pVCpu->pgm.s.cA20Changes.c);
     if (fShadow)
-        pHlp->pfnPrintf(pHlp, "Shadow paging mode: %s\n", PGMGetModeName(pVM->aCpus[0].pgm.s.enmShadowMode));
+        pHlp->pfnPrintf(pHlp, "Shadow paging mode (VCPU #%u): %s\n", pVCpu->idCpu, PGMGetModeName(pVCpu->pgm.s.enmShadowMode));
     if (fHost)
     {
@@ -2772,5 +2777,5 @@
             default:                                psz = "unknown"; break;
         }
-        pHlp->pfnPrintf(pHlp, "Host paging mode:   %s\n", psz);
+        pHlp->pfnPrintf(pHlp, "Host paging mode:              %s\n", psz);
     }
 }
Index: /trunk/src/VBox/VMM/VMMR3/VM.cpp
===================================================================
--- /trunk/src/VBox/VMM/VMMR3/VM.cpp	(revision 61569)
+++ /trunk/src/VBox/VMM/VMMR3/VM.cpp	(revision 61570)
@@ -2313,11 +2313,10 @@
         if (enmVMState != VMSTATE_GURU_MEDITATION)
         {
-            /** @todo SMP support? */
             /** @todo make the state dumping at VMR3PowerOff optional. */
             bool fOldBuffered = RTLogRelSetBuffering(true /*fBuffered*/);
             RTLogRelPrintf("****************** Guest state at power off ******************\n");
-            DBGFR3Info(pVM->pUVM, "cpumguest", "verbose", DBGFR3InfoLogRelHlp());
+            DBGFR3InfoEx(pVM->pUVM, 0, "cpumguest", "verbose", DBGFR3InfoLogRelHlp());
             RTLogRelPrintf("***\n");
-            DBGFR3Info(pVM->pUVM, "mode", NULL, DBGFR3InfoLogRelHlp());
+            DBGFR3InfoEx(pVM->pUVM, 0, "mode", NULL, DBGFR3InfoLogRelHlp());
             RTLogRelPrintf("***\n");
             DBGFR3Info(pVM->pUVM, "activetimers", NULL, DBGFR3InfoLogRelHlp());
@@ -2325,43 +2324,4 @@
             DBGFR3Info(pVM->pUVM, "gdt", NULL, DBGFR3InfoLogRelHlp());
             /** @todo dump guest call stack. */
-#if 1 // "temporary" while debugging #1589
-            RTLogRelPrintf("***\n");
-            uint32_t esp = CPUMGetGuestESP(pVCpu);
-            if (    CPUMGetGuestSS(pVCpu) == 0
-                &&  esp < _64K)
-            {
-                uint8_t abBuf[PAGE_SIZE];
-                RTLogRelPrintf("***\n"
-                               "ss:sp=0000:%04x ", esp);
-                uint32_t Start = esp & ~(uint32_t)63;
-                int rc = PGMPhysSimpleReadGCPhys(pVM, abBuf, Start, 0x100);
-                if (RT_SUCCESS(rc))
-                    RTLogRelPrintf("0000:%04x TO 0000:%04x:\n"
-                                   "%.*Rhxd\n",
-                                   Start, Start + 0x100 - 1,
-                                   0x100, abBuf);
-                else
-                    RTLogRelPrintf("rc=%Rrc\n", rc);
-
-                /* grub ... */
-                if (esp < 0x2000 && esp > 0x1fc0)
-                {
-                    rc = PGMPhysSimpleReadGCPhys(pVM, abBuf, 0x8000, 0x800);
-                    if (RT_SUCCESS(rc))
-                        RTLogRelPrintf("0000:8000 TO 0000:87ff:\n"
-                                       "%.*Rhxd\n",
-                                       0x800, abBuf);
-                }
-                /* microsoft cdrom hang ... */
-                if (true)
-                {
-                    rc = PGMPhysSimpleReadGCPhys(pVM, abBuf, 0x8000, 0x200);
-                    if (RT_SUCCESS(rc))
-                        RTLogRelPrintf("2000:0000 TO 2000:01ff:\n"
-                                       "%.*Rhxd\n",
-                                       0x200, abBuf);
-                }
-            }
-#endif
             RTLogRelSetBuffering(fOldBuffered);
             RTLogRelPrintf("************** End of Guest state at power off ***************\n");
