Index: trunk/src/VBox/VMM/CPUM.cpp
===================================================================
--- trunk/src/VBox/VMM/CPUM.cpp	(revision 15961)
+++ trunk/src/VBox/VMM/CPUM.cpp	(revision 15962)
@@ -656,5 +656,5 @@
 VMMR3DECL(int) CPUMR3Term(PVM pVM)
 {
-    /** @todo ? */
+    CPUMR3TermCPU(pVM);
     return 0;
 }
@@ -672,4 +672,14 @@
 VMMR3DECL(int) CPUMR3TermCPU(PVM pVM)
 {
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    for (unsigned i=0;i<pVM->cCPUs;i++)
+    {
+        PCPUMCTX pCtx = CPUMQueryGuestCtxPtrEx(pVM, &pVM->aCpus[i]);
+
+        memset(pVM->aCpus[i].cpum.s.aMagic, 0, sizeof(pVM->aCpus[i].cpum.s.aMagic));
+        pVM->aCpus[i].cpum.s.uMagic     = 0;
+        pCtx->dr[5]                     = 0;
+    }
+#endif
     return 0;
 }
@@ -760,4 +770,11 @@
         */
         pCtx->msrEFER                   = 0;
+
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+        /* Magic marker for searching in crash dumps. */
+        strcpy((char *)pVM->aCpus[i].cpum.s.aMagic, "CPUMCPU Magic");
+        pVM->aCpus[i].cpum.s.uMagic     = UINT64_C(0xDEADBEEFDEADBEEF);
+        pCtx->dr[5]                     = UINT64_C(0xDEADBEEFDEADBEEF);
+#endif
     }
 }
Index: trunk/src/VBox/VMM/CPUMInternal.h
===================================================================
--- trunk/src/VBox/VMM/CPUMInternal.h	(revision 15961)
+++ trunk/src/VBox/VMM/CPUMInternal.h	(revision 15962)
@@ -343,4 +343,9 @@
     CPUMHOSTCTX             Host;
 
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    uint8_t                 aMagic[56];
+    uint64_t                uMagic;
+#endif
+
     /**
      * Guest context.
Index: trunk/src/VBox/VMM/CPUMInternal.mac
===================================================================
--- trunk/src/VBox/VMM/CPUMInternal.mac	(revision 15961)
+++ trunk/src/VBox/VMM/CPUMInternal.mac	(revision 15962)
@@ -306,4 +306,8 @@
 %endif ; 64-bit
 
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    .aMagic              resb    56
+    .uMagic              resq    1
+%endif
     ;
     ; Guest context state
Index: trunk/src/VBox/VMM/HWACCM.cpp
===================================================================
--- trunk/src/VBox/VMM/HWACCM.cpp	(revision 15961)
+++ trunk/src/VBox/VMM/HWACCM.cpp	(revision 15962)
@@ -377,11 +377,18 @@
         Assert(pVCpu->hwaccm.s.paStatExitReasonR0 != NIL_RTR0PTR);
 # endif
+    }
+#endif /* VBOX_WITH_STATISTICS */
+
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    /* Magic marker for searching in crash dumps. */
+    for (unsigned i=0;i<pVM->cCPUs;i++)
+    {
+        PVMCPU pVCpu = &pVM->aCpus[i];
 
         PVMCSCACHE pCache = &pVCpu->hwaccm.s.vmx.VMCSCache;
-        /* Magic marker for searching in crash dumps. */
         strcpy((char *)pCache->aMagic, "VMCSCACHE Magic");
         pCache->uMagic = UINT64_C(0xDEADBEEFDEADBEEF);
     }
-#endif /* VBOX_WITH_STATISTICS */
+#endif
     return VINF_SUCCESS;
 }
@@ -1148,4 +1155,5 @@
         pVM->hwaccm.s.vmx.pRealModeTSS       = 0;
     }
+    HWACCMR3TermCPU(pVM);
     return 0;
 }
@@ -1172,5 +1180,9 @@
             pVCpu->hwaccm.s.paStatExitReasonR0 = NIL_RTR0PTR;
         }
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+        memset(pVCpu->hwaccm.s.vmx.VMCSCache.aMagic, 0, sizeof(pVCpu->hwaccm.s.vmx.VMCSCache.aMagic));
+        pVCpu->hwaccm.s.vmx.VMCSCache.uMagic = 0;
         pVCpu->hwaccm.s.vmx.VMCSCache.uPos = 0xffffffff;
+#endif
     }
     return 0;
@@ -1214,7 +1226,9 @@
             pCache->Read.aFieldVal[j] = 0;
 
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
         /* Magic marker for searching in crash dumps. */
         strcpy((char *)pCache->aMagic, "VMCSCACHE Magic");
         pCache->uMagic = UINT64_C(0xDEADBEEFDEADBEEF);
+#endif
     }
 }
Index: trunk/src/VBox/VMM/HWACCMInternal.h
===================================================================
--- trunk/src/VBox/VMM/HWACCMInternal.h	(revision 15961)
+++ trunk/src/VBox/VMM/HWACCMInternal.h	(revision 15962)
@@ -280,4 +280,9 @@
         R0PTRTYPE(uint8_t *)        pMSREntryLoad;
 
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+        RTR0MEMOBJ                  pMemObjScratch;
+        RTHCPHYS                    pScratchPhys;
+        R0PTRTYPE(uint8_t *)        pScratch;
+#endif
         /** R0 memory object for the MSR exit store page (guest MSRs). */
         RTR0MEMOBJ                  pMemObjMSRExitStore;
@@ -385,10 +390,16 @@
 typedef struct VMCSCACHE
 {
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
     /* Magic marker for searching in crash dumps. */
     uint8_t         aMagic[16];
     uint64_t        uMagic;
+    uint64_t        u64TimeEntry;
+    uint64_t        u64TimeSwitch;
+    uint64_t        cResume;
+    uint64_t        interPD;
+    uint64_t        pSwitcher;
     uint32_t        uPos;
     uint32_t        idCpu;
-
+#endif
     /* CR2 is saved here for EPT syncing. */
     uint64_t        cr2;
Index: trunk/src/VBox/VMM/HWACCMInternal.mac
===================================================================
--- trunk/src/VBox/VMM/HWACCMInternal.mac	(revision 15961)
+++ trunk/src/VBox/VMM/HWACCMInternal.mac	(revision 15962)
@@ -26,8 +26,15 @@
 ; Structure for storing read and write VMCS actions. 
 struc VMCSCACHE
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
     .aMagic                   resb    16
     .uMagic                   resq    1
+    .u64TimeEntry             resq    1
+    .u64TimeSwitch            resq    1
+    .cResume                  resq    1
+    .interPD                  resq    1
+    .pSwitcher                resq    1
     .uPos                     resd    1
     .idCpu                    resd    1
+%endif
     .cr2                      resq    1
     .Write.cValidEntries      resd    1
Index: trunk/src/VBox/VMM/VMMGC/HWACCMGCA.asm
===================================================================
--- trunk/src/VBox/VMM/VMMGC/HWACCMGCA.asm	(revision 15961)
+++ trunk/src/VBox/VMM/VMMGC/HWACCMGCA.asm	(revision 15962)
@@ -144,4 +144,8 @@
     mov     rbx, [rbp + 24 + 8]                             ; pCache
 
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     qword [rbx + VMCSCACHE.uPos], 2
+%endif
+
 %ifdef DEBUG
     mov     rax, [rbp + 8 + 8]                              ; pPageCpuPhys
@@ -171,4 +175,7 @@
 .no_cached_writes:
 
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     qword [rbx + VMCSCACHE.uPos], 3
+%endif
     ; Save the pCache pointer
     push    xBX
@@ -201,4 +208,8 @@
     vmwrite rax, [rsp+2]
     add     rsp, 8*2
+
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     qword [rbx + VMCSCACHE.uPos], 4
+%endif
     
     ; hopefully we can ignore TR (we restore it anyway on the way back to 32 bits mode)
@@ -231,4 +242,8 @@
     LOADGUESTMSR MSR_K8_SF_MASK,        CPUMCTX.msrSFMASK
     LOADGUESTMSR MSR_K8_KERNEL_GS_BASE, CPUMCTX.msrKERNELGSBASE
+
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     qword [rbx + VMCSCACHE.uPos], 5
+%endif
 
     ; Save the pCtx pointer
@@ -300,7 +315,12 @@
     pop     rdi         ; saved pCache
 
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     dword [rdi + VMCSCACHE.uPos], 7
+%endif
 %ifdef DEBUG
     mov     [rdi + VMCSCACHE.TestOut.pCache], rdi
     mov     [rdi + VMCSCACHE.TestOut.pCtx], rsi
+    mov     rax, cr8
+    mov     [rdi + VMCSCACHE.TestOut.cr8], rax
 %endif
     
@@ -322,4 +342,7 @@
     mov     rax, cr2
     mov     [rdi + VMCSCACHE.cr2], rax
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     dword [rdi + VMCSCACHE.uPos], 8
+%endif
 %endif
 
@@ -329,4 +352,7 @@
     mov     eax, VINF_SUCCESS
 
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     dword [rdi + VMCSCACHE.uPos], 9
+%endif
 .vmstart64_end:
 
@@ -354,4 +380,7 @@
     pop     rdx
     mov     [rdi + VMCSCACHE.TestOut.eflags], rdx
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     dword [rdi + VMCSCACHE.uPos], 12
+%endif
 .skip_flags_save:
 %endif
@@ -366,4 +395,7 @@
 %ifdef VMX_USE_CACHED_VMCS_ACCESSES
     pop     rdi         ; pCache
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     dword [rdi + VMCSCACHE.uPos], 10
+%endif
 
 %ifdef DEBUG
@@ -390,4 +422,7 @@
     mov     [rdi + VMCSCACHE.TestOut.pCache], rdi
     mov     [rdi + VMCSCACHE.TestOut.pCtx], rsi
+%endif
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     dword [rdi + VMCSCACHE.uPos], 11
 %endif
 
Index: trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 15961)
+++ trunk/src/VBox/VMM/VMMR0/HWVMXR0.cpp	(revision 15962)
@@ -206,4 +206,20 @@
     }
 
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    {
+        rc = RTR0MemObjAllocCont(&pVM->hwaccm.s.vmx.pMemObjScratch, 1 << PAGE_SHIFT, true /* executable R0 mapping */);
+        AssertRC(rc);
+        if (RT_FAILURE(rc))
+            return rc;
+
+        pVM->hwaccm.s.vmx.pScratch     = (uint8_t *)RTR0MemObjAddress(pVM->hwaccm.s.vmx.pMemObjScratch);
+        pVM->hwaccm.s.vmx.pScratchPhys = RTR0MemObjGetPagePhysAddr(pVM->hwaccm.s.vmx.pMemObjScratch, 0);
+
+        ASMMemZero32(pVM->hwaccm.s.vmx.pScratch, PAGE_SIZE);
+        strcpy((char *)pVM->hwaccm.s.vmx.pScratch, "SCRATCH Magic");
+        *(uint64_t *)(pVM->hwaccm.s.vmx.pScratch + 16) = UINT64_C(0xDEADBEEFDEADBEEF);
+    }
+#endif
+
     /* Allocate VMCBs for all guest CPUs. */
     for (unsigned i=0;i<pVM->cCPUs;i++)
@@ -269,4 +285,14 @@
         pVM->hwaccm.s.vmx.pMSRBitmapPhys   = 0;
     }
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    if (pVM->hwaccm.s.vmx.pMemObjScratch != NIL_RTR0MEMOBJ)
+    {
+        ASMMemZero32(pVM->hwaccm.s.vmx.pScratch, PAGE_SIZE);
+        RTR0MemObjFree(pVM->hwaccm.s.vmx.pMemObjScratch, false);
+        pVM->hwaccm.s.vmx.pMemObjScratch = NIL_RTR0MEMOBJ;
+        pVM->hwaccm.s.vmx.pScratch       = 0;
+        pVM->hwaccm.s.vmx.pScratchPhys   = 0;
+    }
+#endif
     return VINF_SUCCESS;
 }
@@ -1967,4 +1993,8 @@
 #endif
 
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    pVCpu->hwaccm.s.vmx.VMCSCache.u64TimeEntry = RTTimeNanoTS();
+#endif
+
     /* We can jump to this point to resume execution after determining that a VM-exit is innocent.
      */
@@ -2139,4 +2169,10 @@
     Assert(idCpuCheck == RTMpCpuId());
 #endif
+
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    pVCpu->hwaccm.s.vmx.VMCSCache.cResume = cResume;
+    pVCpu->hwaccm.s.vmx.VMCSCache.u64TimeSwitch = RTTimeNanoTS();
+#endif
+
     TMNotifyStartOfExecution(pVM);
     rc = pVCpu->hwaccm.s.vmx.pfnStartVM(pVCpu->hwaccm.s.fResumeVM, pCtx, &pVCpu->hwaccm.s.vmx.VMCSCache, pVM, pVCpu);
@@ -3563,4 +3599,10 @@
     pPageCpuPhys = RTR0MemObjGetPagePhysAddr(pCpu->pMemObj, 0);
 
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    pCache->uPos = 1;
+    pCache->interPD = PGMGetInterPaeCR3(pVM);
+    pCache->pSwitcher = (uint64_t)pVM->hwaccm.s.pfnHost32ToGuest64R0;
+#endif
+
 #ifdef DEBUG
     pCache->TestIn.pPageCpuPhys = 0;
@@ -3580,5 +3622,15 @@
     aParam[5] = 0;
 
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    pCtx->dr[4] = pVM->hwaccm.s.vmx.pScratchPhys + 16 + 8;
+    *(uint32_t *)(pVM->hwaccm.s.vmx.pScratch + 16 + 8) = 1;
+#endif
     rc = VMXR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnVMXGCStartVM64, 6, &aParam[0]);
+
+#ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    Assert(*(uint32_t *)(pVM->hwaccm.s.vmx.pScratch + 16 + 8) == 5);
+    Assert(pCtx->dr[4] == 10);
+    *(uint32_t *)(pVM->hwaccm.s.vmx.pScratch + 16 + 8) = 0xff;
+#endif
 
 #ifdef DEBUG
@@ -3633,4 +3685,6 @@
     /* Leave VMX Root Mode. */
     VMXDisable();
+
+    ASMSetCR4(ASMGetCR4() & ~X86_CR4_VMXE);
 
     CPUMSetHyperESP(pVM, VMMGetStackRC(pVM));
Index: trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
===================================================================
--- trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac	(revision 15961)
+++ trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac	(revision 15962)
@@ -122,4 +122,12 @@
     ;;
     CPUMCPU_FROM_CPUM(edx)
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    ; phys address of scratch page
+    mov     eax, dword [edx + CPUMCPU.Guest.dr + 4*8]
+    mov     cr2, eax
+
+    mov dword [edx + CPUMCPU.Guest.dr + 4*8], 1
+%endif
+
     ; general registers.
     mov     [edx + CPUMCPU.Host.ebx], ebx
@@ -140,4 +148,8 @@
     str     [edx + CPUMCPU.Host.tr]
 
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov dword [edx + CPUMCPU.Guest.dr + 4*8], 2
+%endif
+
     ; control registers.
     mov     eax, cr0
@@ -157,7 +169,17 @@
     mov     edx, ebx
 
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov dword [edx + CPUMCPU.Guest.dr + 4*8], 3
+%endif
+
     CPUM_FROM_CPUMCPU(edx)
     ; Load new gdt so we can do a far jump after going into 64 bits mode
     lgdt    [edx + CPUM.Hyper.gdtr]
+
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    CPUMCPU_FROM_CPUM(edx)
+    mov dword [edx + CPUMCPU.Guest.dr + 4*8], 4
+    CPUM_FROM_CPUMCPU(edx)
+%endif
 
     ;;
@@ -180,5 +202,5 @@
 GLOBALNAME IDEnterTarget
     DEBUG_CHAR('2')
-        
+
     ; 1. Disable paging.
     mov     ebx, cr0
@@ -187,4 +209,9 @@
     DEBUG_CHAR('2')
 
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     eax, cr2
+    mov     dword [eax], 3
+%endif
+
     ; 2. Enable PAE.
     mov     ecx, cr4
@@ -197,4 +224,9 @@
     mov     cr3, ecx
     DEBUG_CHAR('3')
+
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     eax, cr2
+    mov     dword [eax], 4
+%endif
 
     ; 4. Enable long mode.
@@ -207,4 +239,9 @@
     DEBUG_CHAR('4')
 
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov     eax, cr2
+    mov     dword [eax], 5
+%endif
+
     ; 5. Enable paging.
     or      ebx, X86_CR0_PG
@@ -236,4 +273,9 @@
 dq 0ffffffffffffffffh
 
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+NAME(pMarker):
+db 'Switch_marker'
+%endif
+
     ;
     ; When we arrive here we're in 64 bits mode in the intermediate context
@@ -252,4 +294,10 @@
     mov     fs, rax
     mov     gs, rax
+
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    CPUMCPU_FROM_CPUM(edx)
+    mov dword [rdx + CPUMCPU.Guest.dr + 4*8], 5
+    CPUM_FROM_CPUMCPU(edx)
+%endif
 
     ; Setup stack; use the lss_esp, ss pair for lss
@@ -260,4 +308,11 @@
     lss     esp, [rdx + CPUM.Hyper.lss_esp]
 
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    CPUMCPU_FROM_CPUM(edx)
+    mov dword [rdx + CPUMCPU.Guest.dr + 4*8], 6
+    CPUM_FROM_CPUMCPU(edx)
+%endif
+
+
     ; load the hypervisor function address
     mov     r9, [rdx + CPUM.Hyper.eip]
@@ -269,4 +324,8 @@
     test    esi, CPUM_SYNC_FPU_STATE
     jz      near gth_fpu_no  
+
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov dword [rdx + CPUMCPU.Guest.dr + 4*8], 7
+%endif
 
     mov     rax, cr0
@@ -283,4 +342,8 @@
     test    esi, CPUM_SYNC_DEBUG_STATE
     jz      near gth_debug_no
+
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov dword [rdx + CPUMCPU.Guest.dr + 4*8], 8
+%endif
     
     mov     rax, qword [rdx + CPUMCPU.Guest.dr + 0*8]
@@ -299,4 +362,8 @@
 gth_debug_no:
 
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov dword [rdx + CPUMCPU.Guest.dr + 4*8], 9
+%endif
+
     ; parameter for all helper functions (pCtx)    
     lea     rsi, [rdx + CPUMCPU.Guest.fpu]
@@ -306,7 +373,11 @@
     mov     rdx, [NAME(pCpumIC) wrt rip]
     CPUMCPU_FROM_CPUM(edx)
+
+%ifdef VBOX_WITH_CRASHDUMP_MAGIC
+    mov dword [rdx + CPUMCPU.Guest.dr + 4*8], 10
+%endif
     
     ; Save the return code
-    mov     [rdx + CPUMCPU.u32RetCode], eax
+    mov     dword [rdx + CPUMCPU.u32RetCode], eax
     
     ; now let's switch back
