3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; $Id$
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;; @file
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; CPUM - Ring-0 Assembly Routines (supporting HM and IEM).
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Copyright (C) 2006-2015 Oracle Corporation
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; This file is part of VirtualBox Open Source Edition (OSE), as
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; available from http://www.virtualbox.org. This file is free software;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; you can redistribute it and/or modify it under the terms of the GNU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; General Public License (GPL) as published by the Free Software
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Foundation, in version 2 as it comes in the "COPYING" file of the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; VirtualBox OSE distribution. VirtualBox OSE is distributed in the
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;* Header Files *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%include "VBox/asmdefs.mac"
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%include "VBox/vmm/vm.mac"
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%include "VBox/err.mac"
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%include "VBox/vmm/stam.mac"
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%include "CPUMInternal.mac"
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%include "iprt/x86.mac"
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%include "VBox/vmm/cpum.mac"
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef IN_RING3
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %error "The jump table doesn't link on leopard."
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;* Defined Constants And Macros *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;; The offset of the XMM registers in X86FXSTATE.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Use define because I'm too lazy to convert the struct.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%define XMM_OFF_IN_X86FXSTATE 160
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%define IP_OFF_IN_X86FXSTATE 08h
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%define CS_OFF_IN_X86FXSTATE 0ch
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%define DS_OFF_IN_X86FXSTATE 14h
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;; For numeric expressions
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define CPUMR0_IS_AMD64 1
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define CPUMR0_IS_AMD64 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;* External Symbols *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncextern NAME(SUPR0AbsIs64bit)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncextern NAME(SUPR0Abs64bitKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncextern NAME(SUPR0Abs64bitKernelSS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncextern NAME(SUPR0Abs64bitKernelDS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncextern NAME(SUPR0AbsKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;* Global Variables *
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;*******************************************************************************
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBEGINDATA
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%if 0 ; Currently not used.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncg_r32_Zero: dd 0.0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Store the SUPR0AbsIs64bit absolute value here so we can cmp/test without
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; needing to clobber a register. (This trick doesn't quite work for PE btw.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; but that's not relevant atm.)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncGLOBALNAME g_fCPUMIs64bitHost
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd NAME(SUPR0AbsIs64bit)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBEGINCODE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%if 0 ; Currently not used anywhere.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Macro for FXSAVE/FXRSTOR leaky behaviour on AMD CPUs, see cpumR3CheckLeakyFpu().
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Cleans the FPU state, if necessary, before restoring the FPU.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; This macro ASSUMES CR0.TS is not set!
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param xDX Pointer to CPUMCPU.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @uses xAX, EFLAGS
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Changes here should also be reflected in CPUMRCA.asm's copy!
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%macro CLEANFPU 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync test dword [xDX + CPUMCPU.fUseFlags], CPUM_USE_FFXSR_LEAKY
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz .nothing_to_clean
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync xor eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync fnstsw ax ; FSW -> AX.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync test eax, RT_BIT(7) ; If FSW.ES (bit 7) is set, clear it to not cause FPU exceptions
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; while clearing & loading the FPU bits in 'clean_fpu' below.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz .clean_fpu
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync fnclex
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.clean_fpu:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ffree st7 ; Clear FPU stack register(7)'s tag entry to prevent overflow if a wraparound occurs.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; for the upcoming push (load)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync fild dword [g_r32_Zero xWrtRIP] ; Explicit FPU load to overwrite FIP, FOP, FDP registers in the FPU.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.nothing_to_clean:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endmacro
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif ; Unused.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Clears CR0.TS and CR0.EM if necessary, saving the previous result.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; This is used to avoid FPU exceptions when touching the FPU state.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param %1 Register to save the old CR0 in (pass to RESTORE_CR0).
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param %2 Temporary scratch register.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @uses EFLAGS, CR0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%macro SAVE_CR0_CLEAR_FPU_TRAPS 2
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync xor %1, %1
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov %2, cr0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync test %2, X86_CR0_TS | X86_CR0_EM ; Make sure its safe to access the FPU state.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%skip_cr0_write
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov %1, %2 ; Save old CR0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync and %2, ~(X86_CR0_TS | X86_CR0_EM)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov cr0, %2
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%skip_cr0_write:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endmacro
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Restore CR0.TS and CR0.EM state if SAVE_CR0_CLEAR_FPU_TRAPS change it.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param %1 The register that SAVE_CR0_CLEAR_FPU_TRAPS saved the old CR0 in.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%macro RESTORE_CR0 1
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cmp %1, 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync je %%skip_cr0_restore
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov cr0, %1
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%skip_cr0_restore:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endmacro
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Saves the host state.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @uses rax, rdx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param pCpumCpu Define for the register containing the CPUMCPU pointer.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param pXState Define for the regsiter containing the extended state pointer.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%macro CPUMR0_SAVE_HOST 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Load a couple of registers we'll use later in all branches.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov eax, [pCpumCpu + CPUMCPU.Host.fXStateMask]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; The joy of 32-bit darwin kernels that runs the CPU in 64-bit mode.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cmp byte [NAME(g_fCPUMIs64bitHost)], 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%host_legacy_mode
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync db 0xea ; jmp far .sixtyfourbit_mode
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd %%host_sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_sixtyfourbit_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync or eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%host_sixtyfourbit_fxsave
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; XSAVE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov edx, [pCpumCpu + CPUMCPU.Host.fXStateMask + 4]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 xsave [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp %%host_sixtyfourbit_done
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; FXSAVE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_sixtyfourbit_fxsave:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 fxsave [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_sixtyfourbit_done:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp far [%%host_fpret wrt rip]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_fpret: ; 16:32 Pointer to %%host_done.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd %%host_done, NAME(SUPR0AbsKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 32
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_legacy_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; XSAVE or FXSAVE?
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync or eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%host_fxsave
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; XSAVE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov edx, [pCpumCpu + CPUMCPU.Host.fXStateMask + 4]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 xsave [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync xsave [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp %%host_done
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; FXSAVE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_fxsave:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 fxsave [pXState] ; Use explicit REX prefix. See @bugref{6398}.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync fxsave [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_done:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endmacro ; CPUMR0_SAVE_HOST
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Loads the host state.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @uses rax, rdx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param pCpumCpu Define for the register containing the CPUMCPU pointer.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param pXState Define for the regsiter containing the extended state pointer.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%macro CPUMR0_LOAD_HOST 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Load a couple of registers we'll use later in all branches.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov eax, [pCpumCpu + CPUMCPU.Host.fXStateMask]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; The joy of 32-bit darwin kernels that runs the CPU in 64-bit mode.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cmp byte [NAME(g_fCPUMIs64bitHost)], 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%host_legacy_mode
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync db 0xea ; jmp far .sixtyfourbit_mode
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd %%host_sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_sixtyfourbit_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync or eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%host_sixtyfourbit_fxrstor
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; XRSTOR
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov edx, [pCpumCpu + CPUMCPU.Host.fXStateMask + 4]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 xrstor [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp %%host_sixtyfourbit_done
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; FXRSTOR
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_sixtyfourbit_fxrstor:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 fxrstor [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_sixtyfourbit_done:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp far [%%host_fpret wrt rip]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_fpret: ; 16:32 Pointer to %%host_done.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd %%host_done, NAME(SUPR0AbsKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 32
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_legacy_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; XRSTOR or FXRSTOR?
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync or eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%host_fxrstor
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; XRSTOR
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov edx, [pCpumCpu + CPUMCPU.Host.fXStateMask + 4]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 xrstor [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync xrstor [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp %%host_done
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; FXRSTOR
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_fxrstor:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 fxrstor [pXState] ; Use explicit REX prefix. See @bugref{6398}.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync fxrstor [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%host_done:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endmacro ; CPUMR0_LOAD_HOST
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;; Macro for FXSAVE for the guest FPU but tries to figure out whether to
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; save the 32-bit FPU state or 64-bit FPU state.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param %1 Pointer to CPUMCPU.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param %2 Pointer to XState.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param %3 Force AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @uses xAX, xDX, EFLAGS, 20h of stack.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%macro SAVE_32_OR_64_FPU 3
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%if CPUMR0_IS_AMD64 || %3
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Save the guest FPU (32-bit or 64-bit), preserves existing broken state. See @bugref{7138}.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync test dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USE_SUPPORTS_LONGMODE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jnz short %%save_long_mode_guest
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync fxsave [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%if CPUMR0_IS_AMD64 || %3
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp %%save_done_32bit_cs_ds
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%save_long_mode_guest:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 fxsave [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync xor edx, edx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cmp dword [pXState + CS_OFF_IN_X86FXSTATE], 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jne short %%save_done
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync sub rsp, 20h ; Only need 1ch bytes but keep stack aligned otherwise we #GP(0).
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync fnstenv [rsp]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync movzx eax, word [rsp + 10h]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov [pXState + CS_OFF_IN_X86FXSTATE], eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync movzx eax, word [rsp + 18h]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync add rsp, 20h
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov [pXState + DS_OFF_IN_X86FXSTATE], eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%save_done_32bit_cs_ds:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov edx, X86_FXSTATE_RSVD_32BIT_MAGIC
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%save_done:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov dword [pXState + X86_OFF_FXSTATE_RSVD], edx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endmacro ; SAVE_32_OR_64_FPU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Save the guest state.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @uses rax, rdx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param pCpumCpu Define for the register containing the CPUMCPU pointer.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param pXState Define for the regsiter containing the extended state pointer.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%macro CPUMR0_SAVE_GUEST 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Load a couple of registers we'll use later in all branches.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov eax, [pCpumCpu + CPUMCPU.Guest.fXStateMask]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; The joy of 32-bit darwin kernels that runs the CPU in 64-bit mode.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cmp byte [NAME(g_fCPUMIs64bitHost)], 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%guest_legacy_mode
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync db 0xea ; jmp far .sixtyfourbit_mode
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd %%guest_sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_sixtyfourbit_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync or eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%guest_sixtyfourbit_fxsave
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; XSAVE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov edx, [pCpumCpu + CPUMCPU.Guest.fXStateMask + 4]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 xsave [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp %%guest_sixtyfourbit_done
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; FXSAVE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_sixtyfourbit_fxsave:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync SAVE_32_OR_64_FPU pCpumCpu, pXState, 1
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_sixtyfourbit_done:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp far [%%guest_fpret wrt rip]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_fpret: ; 16:32 Pointer to %%guest_done.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd %%guest_done, NAME(SUPR0AbsKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 32
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_legacy_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; XSAVE or FXSAVE?
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync or eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%guest_fxsave
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; XSAVE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov edx, [pCpumCpu + CPUMCPU.Guest.fXStateMask + 4]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 xsave [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync xsave [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp %%guest_done
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; FXSAVE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_fxsave:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync SAVE_32_OR_64_FPU pCpumCpu, pXState, 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_done:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endmacro ; CPUMR0_SAVE_GUEST
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Wrapper for selecting 32-bit or 64-bit FXRSTOR according to what SAVE_32_OR_64_FPU did.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param %1 Pointer to CPUMCPU.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param %2 Pointer to XState.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param %3 Force AMD64.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @uses xAX, xDX, EFLAGS
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%macro RESTORE_32_OR_64_FPU 3
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%if CPUMR0_IS_AMD64 || %3
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Restore the guest FPU (32-bit or 64-bit), preserves existing broken state. See @bugref{7138}.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync test dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USE_SUPPORTS_LONGMODE
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%restore_32bit_fpu
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cmp dword [pXState + X86_OFF_FXSTATE_RSVD], X86_FXSTATE_RSVD_32BIT_MAGIC
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jne short %%restore_64bit_fpu
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%restore_32bit_fpu:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync fxrstor [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%if CPUMR0_IS_AMD64 || %3
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; TODO: Restore XMM8-XMM15!
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp short %%restore_fpu_done
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%restore_64bit_fpu:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 fxrstor [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%restore_fpu_done:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endmacro ; RESTORE_32_OR_64_FPU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Loads the guest state.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @uses rax, rdx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param pCpumCpu Define for the register containing the CPUMCPU pointer.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param pXState Define for the regsiter containing the extended state pointer.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%macro CPUMR0_LOAD_GUEST 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Load a couple of registers we'll use later in all branches.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov pXState, [pCpumCpu + CPUMCPU.Guest.pXStateR0]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov eax, [pCpumCpu + CPUMCPU.Guest.fXStateMask]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; The joy of 32-bit darwin kernels that runs the CPU in 64-bit mode.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cmp byte [NAME(g_fCPUMIs64bitHost)], 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%guest_legacy_mode
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync db 0xea ; jmp far .sixtyfourbit_mode
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd %%guest_sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_sixtyfourbit_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync or eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%guest_sixtyfourbit_fxrstor
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; XRSTOR
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov edx, [pCpumCpu + CPUMCPU.Guest.fXStateMask + 4]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 xrstor [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp %%guest_sixtyfourbit_done
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; FXRSTOR
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_sixtyfourbit_fxrstor:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RESTORE_32_OR_64_FPU pCpumCpu, pXState, 1
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_sixtyfourbit_done:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp far [%%guest_fpret wrt rip]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_fpret: ; 16:32 Pointer to %%guest_done.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd %%guest_done, NAME(SUPR0AbsKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 32
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_legacy_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; XRSTOR or FXRSTOR?
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync or eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz %%guest_fxrstor
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; XRSTOR
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov edx, [pCpumCpu + CPUMCPU.Guest.fXStateMask + 4]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 xrstor [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync xrstor [pXState]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp %%guest_done
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; FXRSTOR
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_fxrstor:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RESTORE_32_OR_64_FPU pCpumCpu, pXState, 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%%guest_done:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endmacro ; CPUMR0_LOAD_GUEST
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Saves the host FPU/SSE/AVX state and restores the guest FPU/SSE/AVX state.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @returns 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncalign 16
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBEGINPROC cpumR0SaveHostRestoreGuestFPUState
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %ifdef RT_OS_WINDOWS
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov r11, rcx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov r11, rdi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pCpumCpu r11
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pXState r10
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync push ebp
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov ebp, esp
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync push ebx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync push esi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov ebx, dword [ebp + 8]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pCpumCpu ebx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pXState esi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pushf ; The darwin kernel can get upset or upset things if an
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync SAVE_CR0_CLEAR_FPU_TRAPS xCX, xAX ; xCX is now old CR0 value, don't use!
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync CPUMR0_SAVE_HOST
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync CPUMR0_LOAD_GUEST
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_KERNEL_USING_XMM
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Restore the non-volatile xmm registers. ASSUMING 64-bit host.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov pXState, [pCpumCpu + CPUMCPU.Host.pXStateR0]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync movdqa xmm6, [pXState + XMM_OFF_IN_X86FXSTATE + 060h]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync movdqa xmm7, [pXState + XMM_OFF_IN_X86FXSTATE + 070h]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync movdqa xmm8, [pXState + XMM_OFF_IN_X86FXSTATE + 080h]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync movdqa xmm9, [pXState + XMM_OFF_IN_X86FXSTATE + 090h]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync movdqa xmm10, [pXState + XMM_OFF_IN_X86FXSTATE + 0a0h]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync movdqa xmm11, [pXState + XMM_OFF_IN_X86FXSTATE + 0b0h]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync movdqa xmm12, [pXState + XMM_OFF_IN_X86FXSTATE + 0c0h]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync movdqa xmm13, [pXState + XMM_OFF_IN_X86FXSTATE + 0d0h]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync movdqa xmm14, [pXState + XMM_OFF_IN_X86FXSTATE + 0e0h]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync movdqa xmm15, [pXState + XMM_OFF_IN_X86FXSTATE + 0f0h]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RESTORE_CR0 xCX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync or dword [pCpumCpu + CPUMCPU.fUseFlags], (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync popf
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_X86
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pop esi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pop ebx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync leave
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync xor eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ret
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncENDPROC cpumR0SaveHostRestoreGuestFPUState
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifndef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_64_BITS_GUESTS
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifndef VBOX_WITH_HYBRID_32BIT_KERNEL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Saves the host FPU/SSE/AVX state.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @returns VINF_SUCCESS (0) in EAX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncalign 16
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBEGINPROC cpumR0SaveHostFPUState
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %ifdef RT_OS_WINDOWS
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov r11, rcx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov r11, rdi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pCpumCpu r11
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pXState r10
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync push ebp
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov ebp, esp
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync push ebx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync push esi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov ebx, dword [ebp + 8]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pCpumCpu ebx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pXState esi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pushf ; The darwin kernel can get upset or upset things if an
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync SAVE_CR0_CLEAR_FPU_TRAPS xCX, xAX ; xCX is now old CR0 value, don't use!
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync CPUMR0_SAVE_HOST
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RESTORE_CR0 xCX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync or dword [pCpumCpu + CPUMCPU.fUseFlags], (CPUM_USED_FPU | CPUM_USED_FPU_SINCE_REM)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync popf
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_X86
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pop esi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pop ebx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync leave
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync xor eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ret
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncALIGNCODE(16)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.sixtyfourbit_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Save the guest FPU (32-bit or 64-bit), preserves existing broken state. See @bugref{7138}.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync o64 fxsave [pXstate]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp far [.fpret wrt rip]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.fpret: ; 16:32 Pointer to .the_end.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd .done, NAME(SUPR0AbsKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 32
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%undef pCpumCpu
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%undef pXState
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncENDPROC cpumR0SaveHostFPUState
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Saves the guest FPU/SSE/AVX state and restores the host FPU/SSE/AVX state.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @returns VINF_SUCCESS (0) in eax.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncalign 16
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBEGINPROC cpumR0SaveGuestRestoreHostFPUState
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %ifdef RT_OS_WINDOWS
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov r11, rcx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov r11, rdi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pCpumCpu r11
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pXState r10
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync push ebp
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov ebp, esp
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync push ebx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync push esi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov ebx, dword [ebp + 8]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pCpumCpu ebx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pXState esi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Only restore FPU if guest has used it.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync test dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USED_FPU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz .fpu_not_used
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pushf ; The darwin kernel can get upset or upset things if an
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync SAVE_CR0_CLEAR_FPU_TRAPS xCX, xAX ; xCX is now old CR0 value, don't use!
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync CPUMR0_SAVE_GUEST
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync CPUMR0_LOAD_HOST
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RESTORE_CR0 xCX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync and dword [pCpumCpu + CPUMCPU.fUseFlags], ~CPUM_USED_FPU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync popf
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.fpu_not_used:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_X86
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pop esi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pop ebx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync leave
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync xor eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ret
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%undef pCpumCpu
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%undef pXState
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncENDPROC cpumR0SaveGuestRestoreHostFPUState
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; Restores the host's FPU/SSE/AVX state from pCpumCpu->Host.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @returns 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; @param pCpumCpu x86:[ebp+8] gcc:rdi msc:rcx CPUMCPU pointer
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncalign 16
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBEGINPROC cpumR0RestoreHostFPUState
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Prologue - xAX+xDX must be free for XSAVE/XRSTOR input.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %ifdef RT_OS_WINDOWS
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov r11, rcx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov r11, rdi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pCpumCpu r11
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pXState r10
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync push ebp
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov ebp, esp
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync push ebx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync push esi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov ebx, dword [ebp + 8]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pCpumCpu ebx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %define pXState esi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Restore FPU if guest has used it.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync test dword [pCpumCpu + CPUMCPU.fUseFlags], CPUM_USED_FPU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz short .fpu_not_used
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pushf ; The darwin kernel can get upset or upset things if an
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cli ; interrupt occurs while we're doing fxsave/fxrstor/cr0.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync SAVE_CR0_CLEAR_FPU_TRAPS xCX, xAX ; xCX is now old CR0 value, don't use!
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync CPUMR0_LOAD_HOST
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync RESTORE_CR0 xCX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync and dword [pCpumCpu + CPUMCPU.fUseFlags], ~CPUM_USED_FPU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync popf
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.fpu_not_used:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_X86
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pop esi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pop ebx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync leave
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync xor eax, eax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ret
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%undef pCpumCPu
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%undef pXState
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncENDPROC cpumR0RestoreHostFPUState
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; DECLASM(void) cpumR0SaveDRx(uint64_t *pa4Regs);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncALIGNCODE(16)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBEGINPROC cpumR0SaveDRx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %ifdef ASM_CALL64_GCC
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov xCX, rdi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov xCX, dword [esp + 4]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pushf ; Just to be on the safe side.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cli
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cmp byte [NAME(g_fCPUMIs64bitHost)], 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz .legacy_mode
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync db 0xea ; jmp far .sixtyfourbit_mode
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.legacy_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Do the job.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov xAX, dr0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov xDX, dr1
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov [xCX], xAX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov [xCX + 8 * 1], xDX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov xAX, dr2
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov xDX, dr3
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov [xCX + 8 * 2], xAX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov [xCX + 8 * 3], xDX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.done:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync popf
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ret
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncALIGNCODE(16)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.sixtyfourbit_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync and ecx, 0ffffffffh
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov rax, dr0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov rdx, dr1
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov r8, dr2
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov r9, dr3
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov [rcx], rax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov [rcx + 8 * 1], rdx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov [rcx + 8 * 2], r8
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov [rcx + 8 * 3], r9
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp far [.fpret wrt rip]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.fpret: ; 16:32 Pointer to .the_end.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd .done, NAME(SUPR0AbsKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 32
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncENDPROC cpumR0SaveDRx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync; DECLASM(void) cpumR0LoadDRx(uint64_t const *pa4Regs);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncALIGNCODE(16)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBEGINPROC cpumR0LoadDRx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef RT_ARCH_AMD64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %ifdef ASM_CALL64_GCC
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov xCX, rdi
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync %endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%else
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov xCX, dword [esp + 4]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync pushf ; Just to be on the safe side.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cli
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync cmp byte [NAME(g_fCPUMIs64bitHost)], 0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jz .legacy_mode
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync db 0xea ; jmp far .sixtyfourbit_mode
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd .sixtyfourbit_mode, NAME(SUPR0Abs64bitKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.legacy_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ; Do the job.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov xAX, [xCX]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov xDX, [xCX + 8 * 1]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov dr0, xAX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov dr1, xDX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov xAX, [xCX + 8 * 2]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov xDX, [xCX + 8 * 3]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov dr2, xAX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov dr3, xDX
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.done:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync popf
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync ret
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%ifdef VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncALIGNCODE(16)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 64
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.sixtyfourbit_mode:
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync and ecx, 0ffffffffh
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov rax, [rcx]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov rdx, [rcx + 8 * 1]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov r8, [rcx + 8 * 2]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov r9, [rcx + 8 * 3]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov dr0, rax
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov dr1, rdx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov dr2, r8
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync mov dr3, r9
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync jmp far [.fpret wrt rip]
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync.fpret: ; 16:32 Pointer to .the_end.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync dd .done, NAME(SUPR0AbsKernelCS)
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncBITS 32
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncENDPROC cpumR0LoadDRx
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync%endif ; VBOX_WITH_HYBRID_32BIT_KERNEL_IN_R0
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync