Index: trunk/src/VBox/VMM/CPUMInternal.mac
===================================================================
--- trunk/src/VBox/VMM/CPUMInternal.mac	(revision 14992)
+++ trunk/src/VBox/VMM/CPUMInternal.mac	(revision 14993)
@@ -28,4 +28,6 @@
 %define CPUM_USE_DEBUG_REGS_HOST        RT_BIT(4)
 %define CPUM_USE_DEBUG_REGS             RT_BIT(5)
+%define CPUM_SYNC_FPU_STATE             RT_BIT(7)
+%define CPUM_SYNC_DEBUG_STATE           RT_BIT(8)
 
 %define CPUM_HANDLER_DS                 1
Index: trunk/src/VBox/VMM/VMMGC/HWACCMGCA.asm
===================================================================
--- trunk/src/VBox/VMM/VMMGC/HWACCMGCA.asm	(revision 14992)
+++ trunk/src/VBox/VMM/VMMGC/HWACCMGCA.asm	(revision 14993)
@@ -170,5 +170,5 @@
 ; *
 ; * @returns VBox status code
-; * @param   pCtx       Guest context
+; * @param   pCtx       Guest context (rsi)
 ; */
 BEGINPROC VMXGCStartVM64
@@ -371,20 +371,9 @@
 ; *
 ; * @returns VBox status code
-; * @param   HCPhysVMCB     Physical address of host VMCB
-; * @param   HCPhysVMCB     Physical address of guest VMCB
-; * @param   pCtx           Guest context
+; * @param   HCPhysVMCB     Physical address of host VMCB       (rsp+8)
+; * @param   HCPhysVMCB     Physical address of guest VMCB      (rsp+16)
+; * @param   pCtx           Guest context                       (rsi)
 ; */
 BEGINPROC SVMGCVMRun64
-    ; fake a cdecl stack frame
- %ifdef ASM_CALL64_GCC
-    push    rdx
-    push    rsi
-    push    rdi
- %else
-    push    r8
-    push    rdx
-    push    rcx
- %endif
-    push    0
     push    rbp
     mov     rbp, rsp
@@ -405,5 +394,4 @@
 
     ;/* Save the Guest CPU context pointer. */
-    mov     rsi, [rbp + 8*2 + RTHCPHYS_CB*2]   ; pCtx
     push    rsi                     ; push for saving the state at the end
 
@@ -413,10 +401,10 @@
 
     ; save host fs, gs, sysenter msr etc
-    mov     rax, [rbp + 8*2]       ; pVMCBHostPhys (64 bits physical address; x86: take low dword only)
-    push    rax                     ; save for the vmload after vmrun
+    mov     rax, [rbp + 8]                  ; pVMCBHostPhys (64 bits physical address)
+    push    rax                             ; save for the vmload after vmrun
     vmsave
 
     ; setup eax for VMLOAD
-    mov     rax, [rbp + 8*2 + RTHCPHYS_CB]     ; pVMCBPhys (64 bits physical address; take low dword only)
+    mov     rax, [rbp + 8 + RTHCPHYS_CB]    ; pVMCBPhys (64 bits physical address)
 
     ;/* Restore Guest's general purpose registers. */
@@ -483,5 +471,4 @@
     popf
     pop     rbp
-    add     rsp, 4*8
     ret
 ENDPROC SVMGCVMRun64
Index: trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp
===================================================================
--- trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 14992)
+++ trunk/src/VBox/VMM/VMMR0/HWSVMR0.cpp	(revision 14993)
@@ -2284,5 +2284,24 @@
 DECLASM(int) SVMR0VMSwitcherRun64(RTHCPHYS pVMCBHostPhys, RTHCPHYS pVMCBPhys, PCPUMCTX pCtx, PVM pVM, PVMCPU pVCpu)
 {
-    return SVMR0Execute64BitsHandler(pVM, pVCpu, pCtx, pVM->hwaccm.s.pfnVMXGCStartVM64);
+    int             rc;
+    RTCCUINTREG     uFlags;
+
+    /* @todo This code is not guest SMP safe (hyper context) */
+    AssertReturn(pVM->cCPUs == 1, VERR_ACCESS_DENIED);
+
+    uFlags = ASMIntDisableFlags();
+
+    CPUMSetHyperESP(pVM, VMMGetStackRC(pVM));
+    CPUMPushHyper(pVM, (uint32_t)(pVMCBHostPhys >> 32));    /* Param 2: pVMCBHostPhys - Hi. */
+    CPUMPushHyper(pVM, (uint32_t)pVMCBHostPhys);            /* Param 2: pVMCBHostPhys - Lo. */
+    CPUMPushHyper(pVM, (uint32_t)(pVMCBPhys >> 32));        /* Param 1: pVMCBPhys - Hi. */
+    CPUMPushHyper(pVM, (uint32_t)pVMCBPhys);                /* Param 1: pVMCBPhys - Lo. */
+    CPUMSetHyperEIP(pVM, pVM->hwaccm.s.pfnVMXGCStartVM64);
+
+    /* Call switcher. */
+    rc = pVM->hwaccm.s.pfnHost32ToGuest64R0(pVM);
+
+    ASMSetFlags(uFlags);
+    return rc;
 }
 
Index: trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac
===================================================================
--- trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac	(revision 14992)
+++ trunk/src/VBox/VMM/VMMSwitcher/LegacyandAMD64.mac	(revision 14993)
@@ -136,9 +136,4 @@
     pop     dword [edx + CPUMCPU.Host.eflags]
 
-    ;; handle use flags.
-    mov     esi, [edx + CPUMCPU.fUseFlags] ; esi == use flags.
-    and     esi, ~CPUM_USED_FPU         ; Clear CPUM_USED_* flags. ;;@todo FPU check can be optimized to use cr0 flags!
-    mov     [edx + CPUMCPU.fUseFlags], esi
-
     ; control registers.
     mov     eax, cr0
@@ -240,5 +235,5 @@
     mov     ds, rax
     mov     es, rax
-   
+
     ; Setup stack; use the lss_esp, ss pair for lss
     DEBUG_CHAR('7')
@@ -248,11 +243,42 @@
     lss     esp, [rdx + CPUM.Hyper.lss_esp]
 
-    ; call the hypervisor function with rdx=pCpumCpu
-    mov     eax, [rdx + CPUM.Hyper.eip]
+    ; load the hypervisor function address
+    mov     r9, [rdx + CPUM.Hyper.eip]
+
     CPUMCPU_FROM_CPUM(edx)
+    
+    ; Check if we need to restore the guest FPU state
+    mov     esi, [rdx + CPUMCPU.fUseFlags] ; esi == use flags.
+    test    esi, CPUM_SYNC_FPU_STATE
+    jz      near gth_fpu_no  
+
+    mov     rax, cr0
+    mov     rcx, rax                    ; save old CR0
+    and     rax, ~(X86_CR0_TS | X86_CR0_EM)
+    mov     cr0, rax
+    fxrstor [rdx + CPUMCPU.Guest.fpu]
+    mov     cr0, rcx                    ; and restore old CR0 again
+
+gth_fpu_no:
+    ; Check if we need to restore the guest debug state
+    test    esi, CPUM_SYNC_DEBUG_STATE
+    jz      near gth_debug_no
+    
+    mov rax, qword [rdx + CPUMCPU.Guest.dr + 0*8]
+    mov dr0, rax
+    mov rax, qword [rdx + CPUMCPU.Guest.dr + 1*8]
+    mov dr1, rax
+    mov rax, qword [rdx + CPUMCPU.Guest.dr + 2*8]
+    mov dr2, rax
+    mov rax, qword [rdx + CPUMCPU.Guest.dr + 3*8]
+    mov dr3, rax
+    mov rax, qword [rdx + CPUMCPU.Guest.dr + 6*8]
+    mov dr6, rax    ; not required for AMD-V
+
+gth_debug_no:
 
     ; parameter for all helper functions (pCtx)    
     lea     rsi, [rdx + CPUMCPU.Guest.fpu]
-    call    rax
+    call    r9
     
     ; Load CPUM pointer into rdx
