Index: trunk/src/VBox/VMM/VMMSwitcher/AMD64ToPAE.asm
===================================================================
--- trunk/src/VBox/VMM/VMMSwitcher/AMD64ToPAE.asm	(revision 13830)
+++ trunk/src/VBox/VMM/VMMSwitcher/AMD64ToPAE.asm	(revision 13960)
@@ -198,5 +198,5 @@
 ;
 ; USES/DESTROYS:
-;       - eax, ecx, edx
+;       - eax, ecx, edx, r8
 ;
 ; ASSUMPTION:
@@ -206,4 +206,7 @@
 ALIGNCODE(16)
 BEGINPROC vmmR0HostToGuestAsm
+    ;; Store the offset from CPUM to CPUMCPU in r8
+    mov     r8, [rdx + CPUM.ulOffCPUMCPU]
+    
     ;;
     ;; Save CPU host context
@@ -211,50 +214,50 @@
     ;;
     ; general registers.
-    ; mov     [rdx + CPUM.Host.rax], rax - scratch
-    mov     [rdx + CPUM.Host.rbx], rbx
-    ; mov     [rdx + CPUM.Host.rcx], rcx - scratch
-    ; mov     [rdx + CPUM.Host.rdx], rdx - scratch
-    mov     [rdx + CPUM.Host.rdi], rdi
-    mov     [rdx + CPUM.Host.rsi], rsi
-    mov     [rdx + CPUM.Host.rsp], rsp
-    mov     [rdx + CPUM.Host.rbp], rbp
-    ; mov     [rdx + CPUM.Host.r8 ], r8 - scratch
-    ; mov     [rdx + CPUM.Host.r9 ], r9 - scratch
-    mov     [rdx + CPUM.Host.r10], r10
-    mov     [rdx + CPUM.Host.r11], r11
-    mov     [rdx + CPUM.Host.r12], r12
-    mov     [rdx + CPUM.Host.r13], r13
-    mov     [rdx + CPUM.Host.r14], r14
-    mov     [rdx + CPUM.Host.r15], r15
+    ; mov     [rdx + r8 + CPUMCPU.Host.rax], rax - scratch
+    mov     [rdx + r8 + CPUMCPU.Host.rbx], rbx
+    ; mov     [rdx + r8 + CPUMCPU.Host.rcx], rcx - scratch
+    ; mov     [rdx + r8 + CPUMCPU.Host.rdx], rdx - scratch
+    mov     [rdx + r8 + CPUMCPU.Host.rdi], rdi
+    mov     [rdx + r8 + CPUMCPU.Host.rsi], rsi
+    mov     [rdx + r8 + CPUMCPU.Host.rsp], rsp
+    mov     [rdx + r8 + CPUMCPU.Host.rbp], rbp
+    ; mov     [rdx + r8 + CPUMCPU.Host.r8 ], r8 - scratch
+    ; mov     [rdx + r8 + CPUMCPU.Host.r9 ], r9 - scratch
+    mov     [rdx + r8 + CPUMCPU.Host.r10], r10
+    mov     [rdx + r8 + CPUMCPU.Host.r11], r11
+    mov     [rdx + r8 + CPUMCPU.Host.r12], r12
+    mov     [rdx + r8 + CPUMCPU.Host.r13], r13
+    mov     [rdx + r8 + CPUMCPU.Host.r14], r14
+    mov     [rdx + r8 + CPUMCPU.Host.r15], r15
     ; selectors.
-    mov     [rdx + CPUM.Host.ds], ds
-    mov     [rdx + CPUM.Host.es], es
-    mov     [rdx + CPUM.Host.fs], fs
-    mov     [rdx + CPUM.Host.gs], gs
-    mov     [rdx + CPUM.Host.ss], ss
+    mov     [rdx + r8 + CPUMCPU.Host.ds], ds
+    mov     [rdx + r8 + CPUMCPU.Host.es], es
+    mov     [rdx + r8 + CPUMCPU.Host.fs], fs
+    mov     [rdx + r8 + CPUMCPU.Host.gs], gs
+    mov     [rdx + r8 + CPUMCPU.Host.ss], ss
     ; MSRs
     mov     rbx, rdx
     mov     ecx, MSR_K8_FS_BASE
     rdmsr
-    mov     [rbx + CPUM.Host.FSbase], eax
-    mov     [rbx + CPUM.Host.FSbase + 4], edx
+    mov     [rbx + r8 + CPUMCPU.Host.FSbase], eax
+    mov     [rbx + r8 + CPUMCPU.Host.FSbase + 4], edx
     mov     ecx, MSR_K8_GS_BASE
     rdmsr
-    mov     [rbx + CPUM.Host.GSbase], eax
-    mov     [rbx + CPUM.Host.GSbase + 4], edx
+    mov     [rbx + r8 + CPUMCPU.Host.GSbase], eax
+    mov     [rbx + r8 + CPUMCPU.Host.GSbase + 4], edx
     mov     ecx, MSR_K6_EFER
     rdmsr
-    mov     [rbx + CPUM.Host.efer], eax
-    mov     [rbx + CPUM.Host.efer + 4], edx
+    mov     [rbx + r8 + CPUMCPU.Host.efer], eax
+    mov     [rbx + r8 + CPUMCPU.Host.efer + 4], edx
     mov     ecx, MSR_K6_EFER
     mov     rdx, rbx
     ; special registers.
-    sldt    [rdx + CPUM.Host.ldtr]
-    sidt    [rdx + CPUM.Host.idtr]
-    sgdt    [rdx + CPUM.Host.gdtr]
-    str     [rdx + CPUM.Host.tr]        ; yasm BUG, generates sldt. YASMCHECK!
+    sldt    [rdx + r8 + CPUMCPU.Host.ldtr]
+    sidt    [rdx + r8 + CPUMCPU.Host.idtr]
+    sgdt    [rdx + r8 + CPUMCPU.Host.gdtr]
+    str     [rdx + r8 + CPUMCPU.Host.tr]        ; yasm BUG, generates sldt. YASMCHECK!
     ; flags
     pushf
-    pop     qword [rdx + CPUM.Host.rflags]
+    pop     qword [rdx + r8 + CPUMCPU.Host.rflags]
 
     FIXUP FIX_NO_SYSENTER_JMP, 0, htg_no_sysenter - NAME(Start) ; this will insert a jmp htg_no_sysenter if host doesn't use sysenter.
@@ -263,6 +266,6 @@
     mov     rbx, rdx                    ; save edx
     rdmsr                               ; edx:eax <- MSR[ecx]
-    mov     [rbx + CPUM.Host.SysEnter.cs], rax
-    mov     [rbx + CPUM.Host.SysEnter.cs + 4], rdx
+    mov     [rbx + r8 + CPUMCPU.Host.SysEnter.cs], rax
+    mov     [rbx + r8 + CPUMCPU.Host.SysEnter.cs + 4], rdx
     xor     rax, rax                    ; load 0:0 to cause #GP upon sysenter
     xor     rdx, rdx
@@ -275,7 +278,7 @@
 
     ;; handle use flags.
-    mov     esi, [rdx + CPUM.fUseFlags] ; esi == use flags.
+    mov     esi, [rdx + r8 + 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     [rdx + CPUM.fUseFlags], esi
+    mov     [rdx + r8 + CPUMCPU.fUseFlags], esi
 
     ; debug registers.
@@ -288,11 +291,11 @@
     ; control registers.
     mov     rax, cr0
-    mov     [rdx + CPUM.Host.cr0], rax
-    ;mov     rax, cr2                   ; assume host os don't suff things in cr2. (safe)
-    ;mov     [rdx + CPUM.Host.cr2], rax
+    mov     [rdx + r8 + CPUMCPU.Host.cr0], rax
+    ;mov     rax, cr2                   ; assume host os don't stuff things in cr2. (safe)
+    ;mov     [rdx + r8 + CPUMCPU.Host.cr2], rax
     mov     rax, cr3
-    mov     [rdx + CPUM.Host.cr3], rax
+    mov     [rdx + r8 + CPUMCPU.Host.cr3], rax
     mov     rax, cr4
-    mov     [rdx + CPUM.Host.cr4], rax
+    mov     [rdx + r8 + CPUMCPU.Host.cr4], rax
 
     ;;
@@ -306,7 +309,7 @@
     ;
     and     rax, X86_CR4_MCE | X86_CR4_PSE | X86_CR4_PAE
-    mov     ecx, [rdx + CPUM.Guest.cr4]
+    mov     ecx, [rdx + r8 + CPUMCPU.Guest.cr4]
     DEBUG_CHAR('b')                     ; trashes esi
-    ;; @todo Switcher cleanup: Determin base CR4 during CPUMR0Init / VMMR3SelectSwitcher putting it
+    ;; @todo Switcher cleanup: Determine base CR4 during CPUMR0Init / VMMR3SelectSwitcher putting it
     ;                          in CPUM.Hyper.cr4 (which isn't currently being used). That should
     ;                          simplify this operation a bit (and improve locality of the data).
@@ -322,5 +325,5 @@
     DEBUG_CHAR('c')                     ; trashes esi
 
-    mov     eax, [rdx + CPUM.Guest.cr0]
+    mov     eax, [rdx + r8 + CPUMCPU.Guest.cr0]
     and     eax, X86_CR0_EM
     or      eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_TS | X86_CR0_ET | X86_CR0_NE | X86_CR0_MP
@@ -360,9 +363,9 @@
 DEBUG_S_CHAR('s');
     mov     rax, dr7                    ; not sure, but if I read the docs right this will trap if GD is set. FIXME!!!
-    mov     [rdx + CPUM.Host.dr7], rax
+    mov     [rdx + r8 + CPUMCPU.Host.dr7], rax
     xor     eax, eax                    ; clear everything. (bit 12? is read as 1...)
     mov     dr7, rax
     mov     rax, dr6                    ; just in case we save the state register too.
-    mov     [rdx + CPUM.Host.dr6], rax
+    mov     [rdx + r8 + CPUMCPU.Host.dr6], rax
     ; save host DR0-3?
     test    esi, CPUM_USE_DEBUG_REGS
@@ -370,11 +373,11 @@
 DEBUG_S_CHAR('S');
     mov     rax, dr0
-    mov     [rdx + CPUM.Host.dr0], rax
+    mov     [rdx + r8 + CPUMCPU.Host.dr0], rax
     mov     rbx, dr1
-    mov     [rdx + CPUM.Host.dr1], rbx
+    mov     [rdx + r8 + CPUMCPU.Host.dr1], rbx
     mov     rcx, dr2
-    mov     [rdx + CPUM.Host.dr2], rcx
+    mov     [rdx + r8 + CPUMCPU.Host.dr2], rcx
     mov     rax, dr3
-    mov     [rdx + CPUM.Host.dr3], rax
+    mov     [rdx + r8 + CPUMCPU.Host.dr3], rax
     jmp     htg_debug_regs_no
 
@@ -472,5 +475,6 @@
 
     ;; use flags.
-    mov     esi, [edx + CPUM.fUseFlags]
+    mov     esi, [edx + CPUM.ulOffCPUMCPU]
+    mov     esi, [edx + esi + CPUMCPU.fUseFlags]
 
     ; debug registers
@@ -632,5 +636,7 @@
     FIXUP FIX_GC_CPUM_OFF, 1, 0
     mov     edx, 0ffffffffh
-
+    ; Convert to CPUMCPU pointer
+    add     edx, [edx + CPUM.ulOffCPUMCPU]
+    
     ; Skip return address (assumes called!)
     lea     esp, [esp + 4]
@@ -642,40 +648,42 @@
     push    eax                         ; save return code.
     mov     eax, [esp + 4 + CPUMCTXCORE.edi]
-    mov     [edx + CPUM.Guest.edi], eax
+    mov     [edx + CPUMCPU.Guest.edi], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.esi]
-    mov     [edx + CPUM.Guest.esi], eax
+    mov     [edx + CPUMCPU.Guest.esi], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.ebp]
-    mov     [edx + CPUM.Guest.ebp], eax
+    mov     [edx + CPUMCPU.Guest.ebp], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.eax]
-    mov     [edx + CPUM.Guest.eax], eax
+    mov     [edx + CPUMCPU.Guest.eax], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.ebx]
-    mov     [edx + CPUM.Guest.ebx], eax
+    mov     [edx + CPUMCPU.Guest.ebx], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.edx]
-    mov     [edx + CPUM.Guest.edx], eax
+    mov     [edx + CPUMCPU.Guest.edx], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.ecx]
-    mov     [edx + CPUM.Guest.ecx], eax
+    mov     [edx + CPUMCPU.Guest.ecx], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.esp]
-    mov     [edx + CPUM.Guest.esp], eax
+    mov     [edx + CPUMCPU.Guest.esp], eax
     ; selectors
     mov     eax, [esp + 4 + CPUMCTXCORE.ss]
-    mov     [edx + CPUM.Guest.ss], eax
+    mov     [edx + CPUMCPU.Guest.ss], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.gs]
-    mov     [edx + CPUM.Guest.gs], eax
+    mov     [edx + CPUMCPU.Guest.gs], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.fs]
-    mov     [edx + CPUM.Guest.fs], eax
+    mov     [edx + CPUMCPU.Guest.fs], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.es]
-    mov     [edx + CPUM.Guest.es], eax
+    mov     [edx + CPUMCPU.Guest.es], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.ds]
-    mov     [edx + CPUM.Guest.ds], eax
+    mov     [edx + CPUMCPU.Guest.ds], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.cs]
-    mov     [edx + CPUM.Guest.cs], eax
+    mov     [edx + CPUMCPU.Guest.cs], eax
     ; flags
     mov     eax, [esp + 4 + CPUMCTXCORE.eflags]
-    mov     [edx + CPUM.Guest.eflags], eax
+    mov     [edx + CPUMCPU.Guest.eflags], eax
     ; eip
     mov     eax, [esp + 4 + CPUMCTXCORE.eip]
-    mov     [edx + CPUM.Guest.eip], eax
+    mov     [edx + CPUMCPU.Guest.eip], eax
     ; jump to common worker code.
     pop     eax                         ; restore return code.
+    ; Load CPUM into edx again
+    sub     edx, [edx + CPUMCPU.ulOffCPUM]
 
     add     esp, CPUMCTXCORE_size      ; skip CPUMCTXCORE structure
@@ -913,5 +921,5 @@
 
     ; load final cr3
-    mov     rsi, [rdx + CPUM.Host.cr3]
+    mov     rsi, [rdx + r8 + CPUMCPU.Host.cr3]
     mov     cr3, rsi
     DEBUG_CHAR('@')
@@ -922,49 +930,52 @@
     ; Load CPUM pointer into edx
     mov     rdx, [NAME(pCpumHC) wrt rip]
+    ; Load the CPUMCPU offset.
+    mov     r8, [rdx + CPUM.ulOffCPUMCPU]
+    
     ; activate host gdt and idt
-    lgdt    [rdx + CPUM.Host.gdtr]
+    lgdt    [rdx + r8 + CPUMCPU.Host.gdtr]
     DEBUG_CHAR('0')
-    lidt    [rdx + CPUM.Host.idtr]
+    lidt    [rdx + r8 + CPUMCPU.Host.idtr]
     DEBUG_CHAR('1')
     ; Restore TSS selector; must mark it as not busy before using ltr (!)
 %if 1 ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
-    movzx   eax, word [rdx + CPUM.Host.tr]          ; eax <- TR
+    movzx   eax, word [rdx + r8 + CPUMCPU.Host.tr]          ; eax <- TR
     and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
-    add     rax, [rdx + CPUM.Host.gdtr + 2]         ; eax <- GDTR.address + descriptor offset.
+    add     rax, [rdx + r8 + CPUMCPU.Host.gdtr + 2]         ; eax <- GDTR.address + descriptor offset.
     and     dword [rax + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
-    ltr     word [rdx + CPUM.Host.tr]
+    ltr     word [rdx + r8 + CPUMCPU.Host.tr]
 %else
-    movzx   eax, word [rdx + CPUM.Host.tr]          ; eax <- TR
+    movzx   eax, word [rdx + r8 + CPUMCPU.Host.tr]          ; eax <- TR
     and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
-    add     rax, [rdx + CPUM.Host.gdtr + 2]         ; eax <- GDTR.address + descriptor offset.
+    add     rax, [rdx + r8 + CPUMCPU.Host.gdtr + 2]         ; eax <- GDTR.address + descriptor offset.
     mov     ecx, [rax + 4]                          ; ecx <- 2nd descriptor dword
     mov     ebx, ecx                                ; save orginal value
     and     ecx, ~0200h                             ; clear busy flag (2nd type2 bit)
     mov     [rax + 4], ccx                          ; not using xchg here is paranoia..
-    ltr     word [rdx + CPUM.Host.tr]
+    ltr     word [rdx + r8 + CPUMCPU.Host.tr]
     xchg    [rax + 4], ebx                          ; using xchg is paranoia too...
 %endif
     ; activate ldt
     DEBUG_CHAR('2')
-    lldt    [rdx + CPUM.Host.ldtr]
+    lldt    [rdx + r8 + CPUMCPU.Host.ldtr]
     ; Restore segment registers
-    mov     eax, [rdx + CPUM.Host.ds]
+    mov     eax, [rdx + r8 + CPUMCPU.Host.ds]
     mov     ds, eax
-    mov     eax, [rdx + CPUM.Host.es]
+    mov     eax, [rdx + r8 + CPUMCPU.Host.es]
     mov     es, eax
-    mov     eax, [rdx + CPUM.Host.fs]
+    mov     eax, [rdx + r8 + CPUMCPU.Host.fs]
     mov     fs, eax
-    mov     eax, [rdx + CPUM.Host.gs]
+    mov     eax, [rdx + r8 + CPUMCPU.Host.gs]
     mov     gs, eax
     ; restore stack
-    mov     eax, [rdx + CPUM.Host.ss]
+    mov     eax, [rdx + r8 + CPUMCPU.Host.ss]
     mov     ss, eax
-    mov     rsp, [rdx + CPUM.Host.rsp]
+    mov     rsp, [rdx + r8 + CPUMCPU.Host.rsp]
 
     FIXUP FIX_NO_SYSENTER_JMP, 0, gth_sysenter_no - NAME(Start) ; this will insert a jmp gth_sysenter_no if host doesn't use sysenter.
     ; restore MSR_IA32_SYSENTER_CS register.
     mov     ecx, MSR_IA32_SYSENTER_CS
-    mov     eax, [rdx + CPUM.Host.SysEnter.cs]
-    mov     ebx, [rdx + CPUM.Host.SysEnter.cs + 4]
+    mov     eax, [rdx + r8 + CPUMCPU.Host.SysEnter.cs]
+    mov     ebx, [rdx + r8 + CPUMCPU.Host.SysEnter.cs + 4]
     mov     rbx, rdx                    ; save/load edx
     wrmsr                               ; MSR[ecx] <- edx:eax
@@ -979,5 +990,5 @@
     ; Restore FPU if guest has used it.
     ; Using fxrstor should ensure that we're not causing unwanted exception on the host.
-    mov     esi, [rdx + CPUM.fUseFlags] ; esi == use flags.
+    mov     esi, [rdx + r8 + CPUMCPU.fUseFlags] ; esi == use flags.
     test    esi, CPUM_USED_FPU
     jz short gth_fpu_no
@@ -986,6 +997,6 @@
     mov     cr0, rcx
 
-    fxsave  [rdx + CPUM.Guest.fpu]
-    fxrstor [rdx + CPUM.Host.fpu]
+    fxsave  [rdx + r8 + CPUMCPU.Guest.fpu]
+    fxrstor [rdx + r8 + CPUMCPU.Host.fpu]
     jmp short gth_fpu_no
 
@@ -996,9 +1007,9 @@
     ; Would've liked to have these highere up in case of crashes, but
     ; the fpu stuff must be done before we restore cr0.
-    mov     rcx, [rdx + CPUM.Host.cr4]
+    mov     rcx, [rdx + r8 + CPUMCPU.Host.cr4]
     mov     cr4, rcx
-    mov     rcx, [rdx + CPUM.Host.cr0]
+    mov     rcx, [rdx + r8 + CPUMCPU.Host.cr0]
     mov     cr0, rcx
-    ;mov     rcx, [rdx + CPUM.Host.cr2] ; assumes this is waste of time.
+    ;mov     rcx, [rdx + r8 + CPUMCPU.Host.cr2] ; assumes this is waste of time.
     ;mov     cr2, rcx
 
@@ -1013,14 +1024,14 @@
     mov     rbx, rdx
     mov     ecx, MSR_K8_FS_BASE
-    mov     eax, [rbx + CPUM.Host.FSbase]
-    mov     edx, [rbx + CPUM.Host.FSbase + 4]
+    mov     eax, [rbx + r8 + CPUMCPU.Host.FSbase]
+    mov     edx, [rbx + r8 + CPUMCPU.Host.FSbase + 4]
     wrmsr
     mov     ecx, MSR_K8_GS_BASE
-    mov     eax, [rbx + CPUM.Host.GSbase]
-    mov     edx, [rbx + CPUM.Host.GSbase + 4]
+    mov     eax, [rbx + r8 + CPUMCPU.Host.GSbase]
+    mov     edx, [rbx + r8 + CPUMCPU.Host.GSbase + 4]
     wrmsr
     mov     ecx, MSR_K6_EFER
-    mov     eax, [rbx + CPUM.Host.efer]
-    mov     edx, [rbx + CPUM.Host.efer + 4]
+    mov     eax, [rbx + r8 + CPUMCPU.Host.efer]
+    mov     edx, [rbx + r8 + CPUMCPU.Host.efer + 4]
     wrmsr
     mov     rdx, rbx
@@ -1029,23 +1040,23 @@
     ; restore general registers.
     mov     eax, edi                    ; restore return code. eax = return code !!
-    ; mov     rax, [rdx + CPUM.Host.rax] - scratch + return code
-    mov     rbx, [rdx + CPUM.Host.rbx]
-    ; mov     rcx, [rdx + CPUM.Host.rcx] - scratch
-    ; mov     rdx, [rdx + CPUM.Host.rdx] - scratch
-    mov     rdi, [rdx + CPUM.Host.rdi]
-    mov     rsi, [rdx + CPUM.Host.rsi]
-    mov     rsp, [rdx + CPUM.Host.rsp]
-    mov     rbp, [rdx + CPUM.Host.rbp]
-    ; mov     r8,  [rdx + CPUM.Host.r8 ] - scratch
-    ; mov     r9,  [rdx + CPUM.Host.r9 ] - scratch
-    mov     r10, [rdx + CPUM.Host.r10]
-    mov     r11, [rdx + CPUM.Host.r11]
-    mov     r12, [rdx + CPUM.Host.r12]
-    mov     r13, [rdx + CPUM.Host.r13]
-    mov     r14, [rdx + CPUM.Host.r14]
-    mov     r15, [rdx + CPUM.Host.r15]
+    ; mov     rax, [rdx + r8 + CPUMCPU.Host.rax] - scratch + return code
+    mov     rbx, [rdx + r8 + CPUMCPU.Host.rbx]
+    ; mov     rcx, [rdx + r8 + CPUMCPU.Host.rcx] - scratch
+    ; mov     rdx, [rdx + r8 + CPUMCPU.Host.rdx] - scratch
+    mov     rdi, [rdx + r8 + CPUMCPU.Host.rdi]
+    mov     rsi, [rdx + r8 + CPUMCPU.Host.rsi]
+    mov     rsp, [rdx + r8 + CPUMCPU.Host.rsp]
+    mov     rbp, [rdx + r8 + CPUMCPU.Host.rbp]
+    ; mov     r8,  [rdx + r8 + CPUMCPU.Host.r8 ] - scratch
+    ; mov     r9,  [rdx + r8 + CPUMCPU.Host.r9 ] - scratch
+    mov     r10, [rdx + r8 + CPUMCPU.Host.r10]
+    mov     r11, [rdx + r8 + CPUMCPU.Host.r11]
+    mov     r12, [rdx + r8 + CPUMCPU.Host.r12]
+    mov     r13, [rdx + r8 + CPUMCPU.Host.r13]
+    mov     r14, [rdx + r8 + CPUMCPU.Host.r14]
+    mov     r15, [rdx + r8 + CPUMCPU.Host.r15]
 
     ; finally restore flags. (probably not required)
-    push    qword [rdx + CPUM.Host.rflags]
+    push    qword [rdx + r8 + CPUMCPU.Host.rflags]
     popf
 
@@ -1067,16 +1078,16 @@
     jz short gth_debug_regs_dr7
     DEBUG_S_CHAR('r')
-    mov     rax, [rdx + CPUM.Host.dr0]
+    mov     rax, [rdx + r8 + CPUMCPU.Host.dr0]
     mov     dr0, rax
-    mov     rbx, [rdx + CPUM.Host.dr1]
+    mov     rbx, [rdx + r8 + CPUMCPU.Host.dr1]
     mov     dr1, rbx
-    mov     rcx, [rdx + CPUM.Host.dr2]
+    mov     rcx, [rdx + r8 + CPUMCPU.Host.dr2]
     mov     dr2, rcx
-    mov     rax, [rdx + CPUM.Host.dr3]
+    mov     rax, [rdx + r8 + CPUMCPU.Host.dr3]
     mov     dr3, rax
 gth_debug_regs_dr7:
-    mov     rbx, [rdx + CPUM.Host.dr6]
+    mov     rbx, [rdx + r8 + CPUMCPU.Host.dr6]
     mov     dr6, rbx
-    mov     rcx, [rdx + CPUM.Host.dr7]
+    mov     rcx, [rdx + r8 + CPUMCPU.Host.dr7]
     mov     dr7, rcx
     jmp     gth_debug_regs_no
Index: trunk/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac
===================================================================
--- trunk/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac	(revision 13830)
+++ trunk/src/VBox/VMM/VMMSwitcher/PAEand32Bit.mac	(revision 13960)
@@ -119,24 +119,25 @@
     ;;      Skip eax, edx and ecx as these are not preserved over calls.
     ;;
+    CPUMCPU_FROM_CPUM(edx)
     ; general registers.
-    mov     [edx + CPUM.Host.ebx], ebx
-    mov     [edx + CPUM.Host.edi], edi
-    mov     [edx + CPUM.Host.esi], esi
-    mov     [edx + CPUM.Host.esp], esp
-    mov     [edx + CPUM.Host.ebp], ebp
+    mov     [edx + CPUMCPU.Host.ebx], ebx
+    mov     [edx + CPUMCPU.Host.edi], edi
+    mov     [edx + CPUMCPU.Host.esi], esi
+    mov     [edx + CPUMCPU.Host.esp], esp
+    mov     [edx + CPUMCPU.Host.ebp], ebp
     ; selectors.
-    mov     [edx + CPUM.Host.ds], ds
-    mov     [edx + CPUM.Host.es], es
-    mov     [edx + CPUM.Host.fs], fs
-    mov     [edx + CPUM.Host.gs], gs
-    mov     [edx + CPUM.Host.ss], ss
+    mov     [edx + CPUMCPU.Host.ds], ds
+    mov     [edx + CPUMCPU.Host.es], es
+    mov     [edx + CPUMCPU.Host.fs], fs
+    mov     [edx + CPUMCPU.Host.gs], gs
+    mov     [edx + CPUMCPU.Host.ss], ss
     ; special registers.
-    sldt    [edx + CPUM.Host.ldtr]
-    sidt    [edx + CPUM.Host.idtr]
-    sgdt    [edx + CPUM.Host.gdtr]
-    str     [edx + CPUM.Host.tr]
+    sldt    [edx + CPUMCPU.Host.ldtr]
+    sidt    [edx + CPUMCPU.Host.idtr]
+    sgdt    [edx + CPUMCPU.Host.gdtr]
+    str     [edx + CPUMCPU.Host.tr]
     ; flags
     pushfd
-    pop     dword [edx + CPUM.Host.eflags]
+    pop     dword [edx + CPUMCPU.Host.eflags]
 
     FIXUP FIX_NO_SYSENTER_JMP, 0, htg_no_sysenter - NAME(Start) ; this will insert a jmp htg_no_sysenter if host doesn't use sysenter.
@@ -145,6 +146,6 @@
     mov     ebx, edx                    ; save edx
     rdmsr                               ; edx:eax <- MSR[ecx]
-    mov     [ebx + CPUM.Host.SysEnter.cs], eax
-    mov     [ebx + CPUM.Host.SysEnter.cs + 4], edx
+    mov     [ebx + CPUMCPU.Host.SysEnter.cs], eax
+    mov     [ebx + CPUMCPU.Host.SysEnter.cs + 4], edx
     xor     eax, eax                    ; load 0:0 to cause #GP upon sysenter
     xor     edx, edx
@@ -157,7 +158,7 @@
 
     ;; handle use flags.
-    mov     esi, [edx + CPUM.fUseFlags] ; esi == 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 + CPUM.fUseFlags], esi
+    mov     [edx + CPUMCPU.fUseFlags], esi
 
     ; debug registers.
@@ -169,11 +170,11 @@
     ; control registers.
     mov     eax, cr0
-    mov     [edx + CPUM.Host.cr0], eax
+    mov     [edx + CPUMCPU.Host.cr0], eax
     ;mov     eax, cr2                   ; assume host os don't suff things in cr2. (safe)
-    ;mov     [edx + CPUM.Host.cr2], eax
+    ;mov     [edx + CPUMCPU.Host.cr2], eax
     mov     eax, cr3
-    mov     [edx + CPUM.Host.cr3], eax
+    mov     [edx + CPUMCPU.Host.cr3], eax
     mov     eax, cr4
-    mov     [edx + CPUM.Host.cr4], eax
+    mov     [edx + CPUMCPU.Host.cr4], eax
 
     ;;
@@ -188,5 +189,5 @@
     ;
     and     eax, X86_CR4_MCE | X86_CR4_PSE | X86_CR4_PAE | X86_CR4_VMXE
-    mov     ecx, [edx + CPUM.Guest.cr4]
+    mov     ecx, [edx + CPUMCPU.Guest.cr4]
     ;; @todo Switcher cleanup: Determin base CR4 during CPUMR0Init / VMMR3SelectSwitcher putting it
     ;                          in CPUM.Hyper.cr4 (which isn't currently being used). That should
@@ -197,4 +198,5 @@
     ; FXSAVE support on the host CPU
     ;
+    CPUM_FROM_CPUMCPU(edx)
     and     ecx, [edx + CPUM.CR4.AndMask]
     or      eax, ecx
@@ -202,9 +204,11 @@
     mov     cr4, eax
 
-    mov     eax, [edx + CPUM.Guest.cr0]
+    CPUMCPU_FROM_CPUM(edx)
+    mov     eax, [edx + CPUMCPU.Guest.cr0]
     and     eax, X86_CR0_EM
     or      eax, X86_CR0_PE | X86_CR0_PG | X86_CR0_TS | X86_CR0_ET | X86_CR0_NE | X86_CR0_MP
     mov     cr0, eax
 
+    CPUM_FROM_CPUMCPU(edx)
     ; Load new gdt so we can do far jump to guest code after cr3 reload.
     lgdt    [edx + CPUM.Hyper.gdtr]
@@ -307,6 +311,8 @@
     DEBUG_CHAR('7')
 
+    CPUMCPU_FROM_CPUM(edx)
     ;; use flags.
-    mov     esi, [edx + CPUM.fUseFlags]
+    mov     esi, [edx + CPUMCPU.fUseFlags]
+    CPUM_FROM_CPUMCPU(edx)
 
     ; debug registers
@@ -389,10 +395,12 @@
 htg_debug_regs_save_dr7and6:
 DEBUG_S_CHAR('s');
+    CPUMCPU_FROM_CPUM(edx)
     mov     eax, dr7                    ; not sure, but if I read the docs right this will trap if GD is set. FIXME!!!
-    mov     [edx + CPUM.Host.dr7], eax
+    mov     [edx + CPUMCPU.Host.dr7], eax
     xor     eax, eax                    ; clear everything. (bit 12? is read as 1...)
     mov     dr7, eax
     mov     eax, dr6                    ; just in case we save the state register too.
-    mov     [edx + CPUM.Host.dr6], eax
+    mov     [edx + CPUMCPU.Host.dr6], eax
+    CPUM_FROM_CPUMCPU(edx)
     jmp     htg_debug_regs_no
 
@@ -404,13 +412,16 @@
     DEBUG_S_CHAR('R')
     DEBUG_S_CHAR('x')
+    CPUMCPU_FROM_CPUM(edx)
     ; save host DR0-3.
     mov     eax, dr0
-    mov     [edx + CPUM.Host.dr0], eax
+    mov     [edx + CPUMCPU.Host.dr0], eax
     mov     ebx, dr1
-    mov     [edx + CPUM.Host.dr1], ebx
+    mov     [edx + CPUMCPU.Host.dr1], ebx
     mov     ecx, dr2
-    mov     [edx + CPUM.Host.dr2], ecx
+    mov     [edx + CPUMCPU.Host.dr2], ecx
     mov     eax, dr3
-    mov     [edx + CPUM.Host.dr3], eax
+    mov     [edx + CPUMCPU.Host.dr3], eax
+    CPUM_FROM_CPUMCPU(edx)
+    
     ; load hyper DR0-7
     mov     ebx, [edx + CPUM.Hyper.dr]
@@ -538,37 +549,39 @@
     push    eax
 
+    CPUMCPU_FROM_CPUM(edx)
     mov     eax, [esp + 4 + CPUMCTXCORE.eax]
-    mov     [edx + CPUM.Guest.eax], eax
+    mov     [edx + CPUMCPU.Guest.eax], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.ecx]
-    mov     [edx + CPUM.Guest.ecx], eax
+    mov     [edx + CPUMCPU.Guest.ecx], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.edx]
-    mov     [edx + CPUM.Guest.edx], eax
+    mov     [edx + CPUMCPU.Guest.edx], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.ebx]
-    mov     [edx + CPUM.Guest.ebx], eax
+    mov     [edx + CPUMCPU.Guest.ebx], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.esp]
-    mov     [edx + CPUM.Guest.esp], eax
+    mov     [edx + CPUMCPU.Guest.esp], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.ebp]
-    mov     [edx + CPUM.Guest.ebp], eax
+    mov     [edx + CPUMCPU.Guest.ebp], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.esi]
-    mov     [edx + CPUM.Guest.esi], eax
+    mov     [edx + CPUMCPU.Guest.esi], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.edi]
-    mov     [edx + CPUM.Guest.edi], eax
+    mov     [edx + CPUMCPU.Guest.edi], eax
     mov     eax, dword [esp + 4 + CPUMCTXCORE.es]
-    mov     dword [edx + CPUM.Guest.es], eax
+    mov     dword [edx + CPUMCPU.Guest.es], eax
     mov     eax, dword [esp + 4 + CPUMCTXCORE.cs]
-    mov     dword [edx + CPUM.Guest.cs], eax
+    mov     dword [edx + CPUMCPU.Guest.cs], eax
     mov     eax, dword [esp + 4 + CPUMCTXCORE.ss]
-    mov     dword [edx + CPUM.Guest.ss], eax
+    mov     dword [edx + CPUMCPU.Guest.ss], eax
     mov     eax, dword [esp + 4 + CPUMCTXCORE.ds]
-    mov     dword [edx + CPUM.Guest.ds], eax
+    mov     dword [edx + CPUMCPU.Guest.ds], eax
     mov     eax, dword [esp + 4 + CPUMCTXCORE.fs]
-    mov     dword [edx + CPUM.Guest.fs], eax
+    mov     dword [edx + CPUMCPU.Guest.fs], eax
     mov     eax, dword [esp + 4 + CPUMCTXCORE.gs]
-    mov     dword [edx + CPUM.Guest.gs], eax
+    mov     dword [edx + CPUMCPU.Guest.gs], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.eflags]
-    mov     dword [edx + CPUM.Guest.eflags], eax
+    mov     dword [edx + CPUMCPU.Guest.eflags], eax
     mov     eax, [esp + 4 + CPUMCTXCORE.eip]
-    mov     dword [edx + CPUM.Guest.eip], eax
+    mov     dword [edx + CPUMCPU.Guest.eip], eax
     pop     eax
+    CPUM_FROM_CPUMCPU(edx)
 
     add     esp, CPUMCTXCORE_size      ; skip CPUMCTXCORE structure
@@ -734,5 +747,7 @@
     ;;
     mov     edi, eax                    ; save return code in EDI (careful with COM_DWORD_REG from here on!)
-    mov     ecx, [edx + CPUM.Host.cr3]
+    CPUMCPU_FROM_CPUM(edx)
+    mov     ecx, [edx + CPUMCPU.Host.cr3]
+    CPUM_FROM_CPUMCPU(edx)
     FIXUP SWITCHER_FIX_INTER_CR3_GC, 1
     mov     eax, 0ffffffffh
@@ -803,41 +818,42 @@
     FIXUP FIX_HC_CPUM_OFF, 1, 0
     mov     edx, 0ffffffffh
+    CPUMCPU_FROM_CPUM(edx)
     ; activate host gdt and idt
-    lgdt    [edx + CPUM.Host.gdtr]
+    lgdt    [edx + CPUMCPU.Host.gdtr]
     DEBUG_CHAR('0')
-    lidt    [edx + CPUM.Host.idtr]
+    lidt    [edx + CPUMCPU.Host.idtr]
     DEBUG_CHAR('1')
     ; Restore TSS selector; must mark it as not busy before using ltr (!)
 %if 1 ; ASSUME that this is supposed to be 'BUSY'. (saves 20-30 ticks on the T42p)
-    movzx   eax, word [edx + CPUM.Host.tr]          ; eax <- TR
+    movzx   eax, word [edx + CPUMCPU.Host.tr]          ; eax <- TR
     and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
-    add     eax, [edx + CPUM.Host.gdtr + 2]         ; eax <- GDTR.address + descriptor offset.
+    add     eax, [edx + CPUMCPU.Host.gdtr + 2]         ; eax <- GDTR.address + descriptor offset.
     and     dword [eax + 4], ~0200h                 ; clear busy flag (2nd type2 bit)
-    ltr     word [edx + CPUM.Host.tr]
+    ltr     word [edx + CPUMCPU.Host.tr]
 %else
-    movzx   eax, word [edx + CPUM.Host.tr]          ; eax <- TR
+    movzx   eax, word [edx + CPUMCPU.Host.tr]          ; eax <- TR
     and     al, 0F8h                                ; mask away TI and RPL bits, get descriptor offset.
-    add     eax, [edx + CPUM.Host.gdtr + 2]         ; eax <- GDTR.address + descriptor offset.
+    add     eax, [edx + CPUMCPU.Host.gdtr + 2]         ; eax <- GDTR.address + descriptor offset.
     mov     ecx, [eax + 4]                          ; ecx <- 2nd descriptor dword
     mov     ebx, ecx                                ; save orginal value
     and     ecx, ~0200h                             ; clear busy flag (2nd type2 bit)
     mov     [eax + 4], ecx                          ; not using xchg here is paranoia..
-    ltr     word [edx + CPUM.Host.tr]
+    ltr     word [edx + CPUMCPU.Host.tr]
     xchg    [eax + 4], ebx                          ; using xchg is paranoia too...
 %endif
     ; activate ldt
     DEBUG_CHAR('2')
-    lldt    [edx + CPUM.Host.ldtr]
+    lldt    [edx + CPUMCPU.Host.ldtr]
     ; Restore segment registers
-    mov     eax, [edx + CPUM.Host.ds]
+    mov     eax, [edx + CPUMCPU.Host.ds]
     mov     ds, eax
-    mov     eax, [edx + CPUM.Host.es]
+    mov     eax, [edx + CPUMCPU.Host.es]
     mov     es, eax
-    mov     eax, [edx + CPUM.Host.fs]
+    mov     eax, [edx + CPUMCPU.Host.fs]
     mov     fs, eax
-    mov     eax, [edx + CPUM.Host.gs]
+    mov     eax, [edx + CPUMCPU.Host.gs]
     mov     gs, eax
     ; restore stack
-    lss     esp, [edx + CPUM.Host.esp]
+    lss     esp, [edx + CPUMCPU.Host.esp]
 
 
@@ -845,6 +861,6 @@
     ; restore MSR_IA32_SYSENTER_CS register.
     mov     ecx, MSR_IA32_SYSENTER_CS
-    mov     eax, [edx + CPUM.Host.SysEnter.cs]
-    mov     ebx, [edx + CPUM.Host.SysEnter.cs + 4]
+    mov     eax, [edx + CPUMCPU.Host.SysEnter.cs]
+    mov     ebx, [edx + CPUMCPU.Host.SysEnter.cs + 4]
     xchg    edx, ebx                    ; save/load edx
     wrmsr                               ; MSR[ecx] <- edx:eax
@@ -859,5 +875,5 @@
     ; Restore FPU if guest has used it.
     ; Using fxrstor should ensure that we're not causing unwanted exception on the host.
-    mov     esi, [edx + CPUM.fUseFlags] ; esi == use flags.
+    mov     esi, [edx + CPUMCPU.fUseFlags] ; esi == use flags.
     test    esi, CPUM_USED_FPU
     jz near gth_fpu_no
@@ -867,21 +883,21 @@
 
     FIXUP FIX_NO_FXSAVE_JMP, 0, gth_no_fxsave - NAME(Start) ; this will insert a jmp gth_no_fxsave if fxsave isn't supported.
-    fxsave  [edx + CPUM.Guest.fpu]
-    fxrstor [edx + CPUM.Host.fpu]
+    fxsave  [edx + CPUMCPU.Guest.fpu]
+    fxrstor [edx + CPUMCPU.Host.fpu]
     jmp near gth_fpu_no
 
 gth_no_fxsave:
-    fnsave  [edx + CPUM.Guest.fpu]
-    mov     eax, [edx + CPUM.Host.fpu]     ; control word
+    fnsave  [edx + CPUMCPU.Guest.fpu]
+    mov     eax, [edx + CPUMCPU.Host.fpu]     ; control word
     not     eax                            ; 1 means exception ignored (6 LS bits)
     and     eax, byte 03Fh                 ; 6 LS bits only
-    test    eax, [edx + CPUM.Host.fpu + 4] ; status word
+    test    eax, [edx + CPUMCPU.Host.fpu + 4] ; status word
     jz      gth_no_exceptions_pending
 
     ; technically incorrect, but we certainly don't want any exceptions now!!
-    and     dword [edx + CPUM.Host.fpu + 4], ~03Fh
+    and     dword [edx + CPUMCPU.Host.fpu + 4], ~03Fh
 
 gth_no_exceptions_pending:
-    frstor  [edx + CPUM.Host.fpu]
+    frstor  [edx + CPUMCPU.Host.fpu]
     jmp short gth_fpu_no
 
@@ -892,9 +908,9 @@
     ; Would've liked to have these highere up in case of crashes, but
     ; the fpu stuff must be done before we restore cr0.
-    mov     ecx, [edx + CPUM.Host.cr4]
+    mov     ecx, [edx + CPUMCPU.Host.cr4]
     mov     cr4, ecx
-    mov     ecx, [edx + CPUM.Host.cr0]
+    mov     ecx, [edx + CPUMCPU.Host.cr0]
     mov     cr0, ecx
-    ;mov     ecx, [edx + CPUM.Host.cr2] ; assumes this is waste of time.
+    ;mov     ecx, [edx + CPUMCPU.Host.cr2] ; assumes this is waste of time.
     ;mov     cr2, ecx
 
@@ -908,9 +924,9 @@
     ; restore general registers.
     mov     eax, edi                    ; restore return code. eax = return code !!
-    mov     edi, [edx + CPUM.Host.edi]
-    mov     esi, [edx + CPUM.Host.esi]
-    mov     ebx, [edx + CPUM.Host.ebx]
-    mov     ebp, [edx + CPUM.Host.ebp]
-    push    dword [edx + CPUM.Host.eflags]
+    mov     edi, [edx + CPUMCPU.Host.edi]
+    mov     esi, [edx + CPUMCPU.Host.esi]
+    mov     ebx, [edx + CPUMCPU.Host.ebx]
+    mov     ebp, [edx + CPUMCPU.Host.ebp]
+    push    dword [edx + CPUMCPU.Host.eflags]
     popfd
 
@@ -930,16 +946,16 @@
     jz short gth_debug_regs_dr7
     DEBUG_S_CHAR('r')
-    mov     eax, [edx + CPUM.Host.dr0]
+    mov     eax, [edx + CPUMCPU.Host.dr0]
     mov     dr0, eax
-    mov     ebx, [edx + CPUM.Host.dr1]
+    mov     ebx, [edx + CPUMCPU.Host.dr1]
     mov     dr1, ebx
-    mov     ecx, [edx + CPUM.Host.dr2]
+    mov     ecx, [edx + CPUMCPU.Host.dr2]
     mov     dr2, ecx
-    mov     eax, [edx + CPUM.Host.dr3]
+    mov     eax, [edx + CPUMCPU.Host.dr3]
     mov     dr3, eax
 gth_debug_regs_dr7:
-    mov     ebx, [edx + CPUM.Host.dr6]
+    mov     ebx, [edx + CPUMCPU.Host.dr6]
     mov     dr6, ebx
-    mov     ecx, [edx + CPUM.Host.dr7]
+    mov     ecx, [edx + CPUMCPU.Host.dr7]
     mov     dr7, ecx
     jmp     gth_debug_regs_no
